Dağıtımdan önce akıllı sözleşmenin adresi nasıl belirlenir: Kripto değişimi için CREATE2'nin kullanılması

Blockchain konusu sadece her türlü heyecanın kaynağı değil, aynı zamanda teknolojik açıdan da çok değerli fikirlerin kaynağı olmaktan çıkmıyor. Bu nedenle güneşli şehrin sakinlerini atlamadı. İnsanlar yakından bakıyor, çalışıyor ve geleneksel bilgi tabanındaki uzmanlıklarını blockchain sistemlerine kaydırmaya çalışıyor. Şimdiye kadar, noktasal olarak: Rostelecom-Solar'ın gelişmelerinden biri, blockchain tabanlı yazılımın güvenliğini kontrol edebiliyor. Ve bu arada, blockchain topluluğunun uygulamalı sorunlarının çözümüne ilişkin bazı düşünceler ortaya çıkıyor. Bu tüyolardan biri - CREATE2 kullanarak dağıtımdan önce akıllı bir sözleşmenin adresinin nasıl belirleneceği - bugün sizlerle kesim altında paylaşmak istiyorum.

Dağıtımdan önce akıllı sözleşmenin adresi nasıl belirlenir: Kripto değişimi için CREATE2'nin kullanılması
CREATE2 işlem kodu bu yıl 28 Şubat'ta Constantinople hard fork'una eklendi. EIP'de belirtildiği gibi bu işlem kodu öncelikle durum kanalları için tanıtıldı. Ancak biz bunu farklı bir sorunu çözmek için kullandık.

Borsada bakiyesi olan kullanıcılar var. Her kullanıcıya herkesin token gönderebileceği bir Ethereum adresi sağlamalı ve böylece hesaplarını yenilemeliyiz. Bu adreslere "cüzdan" adını verelim. Tokenlar cüzdanlara ulaştığında onları tek bir cüzdana (hotwallet) göndermeliyiz.

Aşağıdaki bölümlerde bu sorunu CREATE2 olmadan çözmeye yönelik seçenekleri analiz edeceğim ve neden bunlardan vazgeçtiğimizi açıklayacağım. Yalnızca nihai sonuçla ilgileniyorsanız, Nihai Çözüm bölümünde bulabilirsiniz.

Ethereum adresleri

En basit çözüm, yeni kullanıcılar için yeni Ethereum adresleri oluşturmaktır. Bu adresler cüzdanlar olacaktır. Tokenları cüzdandan sıcak cüzdana aktarmak için işlevi çağırarak işlemi imzalamanız gerekir. Aktar() arka uçtan cüzdanın özel anahtarıyla.

Bu yaklaşımın aşağıdaki avantajları vardır:

  • bu basit
  • tokenleri cüzdandan sıcak cüzdana aktarmanın maliyeti, işlevi çağırmanın maliyetine eşittir Aktar()

Ancak bu yaklaşımı terk ettik çünkü önemli bir dezavantajı var: özel anahtarları bir yerde saklamanız gerekiyor. Ve mesele yalnızca bunların kaybolması değil, aynı zamanda bu anahtarlara erişimi dikkatli bir şekilde yönetmeniz gerektiğidir. Bunlardan en az birinin güvenliği ihlal edilirse belirli bir kullanıcının tokenleri sıcak cüzdana ulaşamayacaktır.

Dağıtımdan önce akıllı sözleşmenin adresi nasıl belirlenir: Kripto değişimi için CREATE2'nin kullanılması

Her kullanıcı için ayrı bir akıllı sözleşme oluşturun

Her kullanıcı için ayrı bir akıllı sözleşme dağıtmak, cüzdanlardaki özel anahtarları sunucuda saklamamanıza olanak tanır. Borsa, tokenleri sıcak cüzdana aktarmak için bu akıllı sözleşmeyi çağıracak.

Ayrıca, akıllı sözleşme dağıtılmadan kullanıcıya cüzdan adresi gösterilemeyeceği için bu çözümü de terk ettik (bu aslında mümkündür, ancak burada tartışmayacağımız diğer dezavantajlarla birlikte oldukça karmaşık bir şekilde). Borsada kullanıcı ihtiyaç duyduğu kadar hesap oluşturabilir ve herkesin kendi cüzdanına ihtiyacı vardır. Bu, kullanıcının bu hesabı kullanacağından bile emin olmadan bir sözleşmeyi dağıtmak için para harcamamız gerektiği anlamına gelir.

İşlem kodu CREATE2

Önceki yöntemin sorununu çözmek için CREATE2 işlem kodunu kullanmaya karar verdik. CREATE2, akıllı sözleşmenin konuşlandırılacağı adresi önceden belirlemenizi sağlar. Adres aşağıdaki formül kullanılarak hesaplanır:

keccak256 (0xff ++ address ++ salt ++ keccak256 (init_code)) [12:]


, nerede:

  • adres — CREATE2'yi çağıracak akıllı sözleşmenin adresi
  • tuz - rastgele değer
  • başlangıç_kodu - dağıtım için akıllı sözleşme bayt kodu

Bu, kullanıcıya verdiğimiz adresin aslında istenen bayt kodunu içermesini sağlar. Ayrıca bu akıllı sözleşme ihtiyaç duyduğumuzda devreye alınabilir. Örneğin bir kullanıcının cüzdanını ilk kez kullanmaya karar vermesi.
Dağıtımdan önce akıllı sözleşmenin adresi nasıl belirlenir: Kripto değişimi için CREATE2'nin kullanılması
Üstelik akıllı sözleşme adresini saklamak yerine her seferinde hesaplayabilirsiniz, çünkü:

  • adres cüzdan fabrikamızın adresi olduğu için formülde sabittir
  • tuz - user_id karması
  • başlangıç_kodu aynı cüzdanı kullandığımız için kalıcıdır

Daha fazla iyileştirme

Önceki çözümün hâlâ bir dezavantajı var: Akıllı sözleşmeyi dağıtmak için ödeme yapmanız gerekiyor. Ancak ondan kurtulabilirsiniz. Bunun için fonksiyonu çağırabilirsiniz. Aktar()ve Bırak kendini imha() cüzdan yapıcısında. Daha sonra akıllı sözleşmenin uygulanmasına yönelik gaz iade edilecek.

Popüler inanışın aksine, CREATE2 işlem koduyla bir akıllı sözleşmeyi aynı adrese birden çok kez dağıtabilirsiniz. Bunun nedeni, CREATE2'nin hedef adresin tek seferlik değerinin sıfır olup olmadığını kontrol etmesidir (yapıcının başında "1" değeri atanır). Aynı zamanda fonksiyon kendini imha() her seferinde nonce adresini sıfırlar. Bu nedenle, CREATE2'yi aynı argümanlarla tekrar çağırırsanız, nonce kontrolü başarılı olacaktır.

Lütfen bu çözümün Ethereum adres çözümüne benzer olduğunu ancak özel anahtarların saklanmasına gerek olmadığını unutmayın. Cüzdandan sıcak cüzdana para aktarmanın maliyeti, bir işlevi çağırmanın maliyetine yaklaşık olarak eşittir Aktar(), çünkü akıllı sözleşmenin dağıtımı için ödeme yapmıyoruz.

Son karar

Dağıtımdan önce akıllı sözleşmenin adresi nasıl belirlenir: Kripto değişimi için CREATE2'nin kullanılması

Başlangıçta hazırlandı:

  • tuz alma işlevi user_id
  • CREATE2 işlem kodunu uygun tuzla çağıracak akıllı sözleşme (ör. cüzdan fabrikası)
  • Aşağıdaki kurucuyla yapılan sözleşmeye karşılık gelen cüzdan bayt kodu:

constructor () {
    address hotWallet = 0x…;
    address token = 0x…;
    token.transfer (hotWallet, token.balanceOf (address (this)));
    selfdestruct (address (0));
}


Her yeni kullanıcı için cüzdan adresini hesaplayarak gösteriyoruz.

keccak256 (0xff ++ address ++ salt ++ keccak256 (init_code)) [12:]


Kullanıcı tokenleri ilgili cüzdan adresine aktardığında, arka ucumuz Transfer olayını parametreyle birlikte görür. _ilecüzdan adresine eşittir. Bu noktada, cüzdanı dağıtmadan önce kullanıcının borsadaki bakiyesini artırmak zaten mümkün.

Cüzdan adresinde yeterli miktarda jeton biriktiğinde hepsini tek seferde sıcak cüzdana aktarabiliriz. Bunu yapmak için arka uç, aşağıdaki eylemleri gerçekleştiren akıllı sözleşme fabrikası işlevini çağırır:

function deployWallet (соль uint256) {
    bytes memory walletBytecode =…;
    // invoke CREATE2 with wallet bytecode and salt
}


Böylece, tüm tokenlerini sıcak cüzdan adresine aktaran ve ardından kendi kendini yok eden cüzdan akıllı sözleşme yapıcısı çağrılır.

Kodun tamamı bulunabilir burada. Cüzdan bayt kodunu optimize etmeye ve işlem kodlarına yazmaya karar verdiğimiz için bunun bizim üretim kodumuz olmadığını lütfen unutmayın.

Yazar Pavel Kondratenkov, Ethereum uzmanı

Kaynak: habr.com

Yorum ekle