Kako določiti naslov pametne pogodbe pred uvedbo: uporaba CREATE2 za kripto izmenjavo

Tema blockchaina je vedno vir ne le najrazličnejših hype, ampak tudi idej, ki so s tehnološkega vidika zelo dragocene. Zato ni obšla prebivalcev sončnega mesta. Ljudje pozorno gledajo, preučujejo in poskušajo prenesti svoje strokovno znanje o tradicionalni informacijski varnosti v sisteme blockchain. Zaenkrat je na mestu: eden od razvojnih del Rostelecom-Solar lahko preveri varnost programske opreme, ki temelji na verigi blokov. In na tej poti se pojavijo nekatere misli o reševanju uporabnih problemov skupnosti blockchain. Enega od teh življenjskih vdorov - kako določiti naslov pametne pogodbe pred uvedbo z uporabo CREATE2 - želim danes deliti z vami pod rezom.

Kako določiti naslov pametne pogodbe pred uvedbo: uporaba CREATE2 za kripto izmenjavo
Operacijska koda CREATE2 je bila dodana v Constantinople hard fork 28. februarja letos. Kot je navedeno v EIP, je bila ta operacijska koda uvedena predvsem za državne kanale. Vendar smo ga uporabili za rešitev drugačnega problema.

Na borzi so uporabniki s stanjem. Vsakemu uporabniku moramo zagotoviti naslov Ethereum, na katerega lahko vsakdo pošlje žetone in s tem napolni svoj račun. Te naslove imenujemo "denarnice". Ko žetoni prispejo v denarnice, jih moramo poslati v eno denarnico (hotwallet).

V naslednjih razdelkih analiziram možnosti za rešitev te težave brez CREATE2 in vam povem, zakaj smo jih opustili. Če vas zanima samo končni rezultat, ga najdete v razdelku »Končna rešitev«.

Ethereum naslovi

Najenostavnejša rešitev je ustvarjanje novih naslovov Ethereum za nove uporabnike. Ti naslovi bodo denarnice. Če želite prenesti žetone iz denarnice v hotwallet, morate podpisati transakcijo s klicem funkcije prenos () z zasebnim ključem denarnice iz ozadja.

Ta pristop ima naslednje prednosti:

  • samo je
  • strošek prenosa žetonov iz denarnice v hotwallet je enak strošku klica funkcije prenos ()

Vendar smo se odločili proti temu pristopu, ker ima eno veliko pomanjkljivost: zasebne ključe morate nekje shraniti. Ne samo, da se lahko izgubijo, ampak morate tudi skrbno upravljati dostop do teh ključev. Če je vsaj eden od njih ogrožen, žetoni določenega uporabnika ne bodo dosegli vroče denarnice.

Kako določiti naslov pametne pogodbe pred uvedbo: uporaba CREATE2 za kripto izmenjavo

Ustvarite ločeno pametno pogodbo za vsakega uporabnika

Uvedba ločene pametne pogodbe za vsakega uporabnika vam omogoča, da se izognete shranjevanju zasebnih ključev za denarnice na strežniku. Borza bo poklicala to pametno pogodbo za prenos žetonov v hotwallet.

Tudi to rešitev smo opustili, saj uporabniku ni mogoče prikazati njegovega naslova denarnice brez uvedbe pametne pogodbe (to je dejansko mogoče, vendar na precej zapleten način z drugimi pomanjkljivostmi, o katerih tukaj ne bomo razpravljali). Na borzi lahko uporabnik ustvari poljubno število računov, vsak pa potrebuje svojo denarnico. To pomeni, da moramo porabiti denar za uvedbo pogodbe, ne da bi sploh bili prepričani, da bo uporabnik uporabljal ta račun.

Opcode CREATE2

Da bi odpravili težavo prejšnje metode, smo se odločili uporabiti kodo CREATE2. CREATE2 vam omogoča, da vnaprej določite naslov, kjer bo pametna pogodba nameščena. Naslov se izračuna po naslednji formuli:

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


, kjer:

  • Naslov — naslov pametne pogodbe, ki bo poklicala CREATE2
  • sol - naključna vrednost
  • inicialna_koda — bajtna koda pametne pogodbe za uvedbo

To zagotavlja, da naslov, ki ga posredujemo uporabniku, dejansko vsebuje želeno bajtno kodo. Poleg tega lahko to pametno pogodbo uvedemo, kadar koli jo potrebujemo. Na primer, ko se uporabnik odloči, da bo svojo denarnico uporabil prvič.
Kako določiti naslov pametne pogodbe pred uvedbo: uporaba CREATE2 za kripto izmenjavo
Poleg tega lahko vsakič izračunate naslov pametne pogodbe, namesto da bi ga shranili, ker:

  • Naslov v formuli je konstanten, saj je to naslov naše tovarne denarnic
  • sol — hash ID_uporabnika
  • inicialna_koda je konstantna, ker uporabljamo isto denarnico

Več izboljšav

Prejšnja rešitev ima še vedno eno pomanjkljivost: za uvedbo pametne pogodbe morate plačati. Vendar se ga lahko znebite. Če želite to narediti, lahko pokličete funkcijo prenos (), in potem samouničenje() v konstruktorju denarnice. In potem bo plin za uvedbo pametne pogodbe vrnjen.

V nasprotju s splošnim prepričanjem lahko pametno pogodbo večkrat namestite na isti naslov z operacijsko kodo CREATE2. To je zato, ker CREATE2 preveri, ali je nonce ciljnega naslova nič (na začetku konstruktorja mu je dodeljena vrednost "1"). V tem primeru funkcija samouničenje() vsakič ponastavi nonce naslove. Torej, če ponovno pokličete CREATE2 z istimi argumenti, bo preverjanje nonce uspešno uspelo.

Upoštevajte, da je ta rešitev podobna možnosti naslova Ethereum, vendar brez potrebe po shranjevanju zasebnih ključev. Stroški prenosa denarja iz denarnice v hotwallet so približno enaki stroškom klica funkcije prenos (), saj ne plačujemo za uvedbo pametne pogodbe.

Končna odločitev

Kako določiti naslov pametne pogodbe pred uvedbo: uporaba CREATE2 za kripto izmenjavo

Prvotno pripravil:

  • funkcija pridobivanja soli USER_ID
  • pametna pogodba, ki bo poklicala opcijsko kodo CREATE2 z ustrezno soljo (tj. tovarna denarnice)
  • bajtna koda denarnice, ki ustreza pogodbi z naslednjim konstruktorjem:

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


Za vsakega novega uporabnika z izračunom prikažemo njegov/njen naslov denarnice

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


Ko uporabnik prenese žetone na ustrezen naslov denarnice, naše zaledje vidi dogodek prenosa s parametrom _za, enak naslovu denarnice. Na tej točki je že mogoče povečati stanje uporabnika na borzi pred uvedbo denarnice.

Ko naslov denarnice zbere zadostno število žetonov, jih lahko vse naenkrat prenesemo v hotwallet. Za to zaledje pokliče funkcijo tovarne pametnih pogodb, ki izvede naslednja dejanja:

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


Tako se pokliče konstruktor pametne pogodbe denarnice, ki prenese vse svoje žetone na naslov hotwallet in se nato samouniči.

Celotno kodo lahko najdete tukaj. Upoštevajte, da to ni naša proizvodna koda, saj smo se odločili optimizirati bajtno kodo denarnice in jo zapisali v opcodes.

Avtor Pavel Kondratenkov, strokovnjak za Ethereum

Vir: www.habr.com

Dodaj komentar