Kako odrediti adresu pametnog ugovora prije implementacije: korištenje CREATE2 za kripto razmjenu

Tema blockchaina ne prestaje biti izvor ne samo svih vrsta hypea, već i ideja koje su vrlo vrijedne s tehnološkog gledišta. Stoga nije zaobišao ni stanovnike sunčanog grada. Ljudi pomno gledaju, proučavaju, pokušavaju prenijeti svoju stručnost u tradicionalnoj informacijskoj sigurnosti na blockchain sustave. Zasad je sve na mjestu: jedan od razvoja Rostelecom-Solar-a može provjeriti sigurnost softvera temeljenog na blockchainu. Usput se pojavljuju i neka razmišljanja o rješavanju primijenjenih problema blockchain zajednice. Jedan od ovih životnih hakova - kako odrediti adresu pametnog ugovora prije implementacije pomoću CREATE2 - danas želim podijeliti s vama ispod reza.

Kako odrediti adresu pametnog ugovora prije implementacije: korištenje CREATE2 za kripto razmjenu
CREATE2 opcode je dodan u Constantinople hard fork 28. veljače ove godine. Kao što je navedeno u EIP-u, ovaj opcode uveden je prvenstveno za državne kanale. Međutim, upotrijebili smo ga za rješavanje drugog problema.

Postoje korisnici sa stanjem na burzi. Svakom korisniku moramo dati Ethereum adresu na koju svatko može slati tokene i tako nadopuniti svoj račun. Nazovimo ove adrese "novčanici". Kada tokeni stignu u novčanike, moramo ih poslati u jedan novčanik (hotwallet).

U sljedećim odjeljcima analiziram opcije za rješavanje ovog problema bez CREATE2 i govorim vam zašto smo ih napustili. Ako vas zanima samo konačni rezultat, možete ga pronaći u odjeljku "Konačno rješenje".

Ethereum adrese

Najjednostavnije rješenje je generiranje novih Ethereum adresa za nove korisnike. Ove adrese bit će novčanici. Za prijenos tokena iz novčanika u hotwallet morate potpisati transakciju pozivanjem funkcije prijenos() s privatnim ključem novčanika iz pozadine.

Ovaj pristup ima sljedeće prednosti:

  • to je samo
  • trošak prijenosa tokena iz novčanika u hotwallet jednak je trošku poziva funkcije prijenos()

Međutim, odlučili smo se protiv ovog pristupa jer ima jedan veliki nedostatak: morate negdje pohraniti privatne ključeve. Ne samo da se mogu izgubiti, već morate pažljivo upravljati pristupom tim ključevima. Ako je barem jedan od njih ugrožen, tokeni određenog korisnika neće doći do vrućeg novčanika.

Kako odrediti adresu pametnog ugovora prije implementacije: korištenje CREATE2 za kripto razmjenu

Napravite zaseban pametni ugovor za svakog korisnika

Implementacija zasebnog pametnog ugovora za svakog korisnika omogućuje vam da izbjegnete pohranjivanje privatnih ključeva za novčanike na poslužitelju. Burza će pozvati ovaj pametni ugovor za prijenos tokena u hotwallet.

Također smo napustili ovo rješenje, budući da se korisniku ne može pokazati njegova adresa novčanika bez postavljanja pametnog ugovora (ovo je zapravo moguće, ali na prilično složen način s drugim nedostacima o kojima ovdje nećemo raspravljati). Na burzi korisnik može kreirati onoliko računa koliko mu treba, a svaki treba svoj novčanik. To znači da moramo potrošiti novac na implementaciju ugovora, a da nismo sigurni da će korisnik koristiti ovaj račun.

Opcijski kod CREATE2

Kako bismo riješili problem prethodne metode, odlučili smo upotrijebiti operativni kod CREATE2. CREATE2 vam omogućuje da unaprijed odredite adresu na kojoj će se pametni ugovor implementirati. Adresa se izračunava pomoću sljedeće formule:

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


, gdje:

  • adresa — adresa pametnog ugovora koji će pozvati CREATE2
  • sol - slučajna vrijednost
  • početni_kod — bajt kod pametnog ugovora za implementaciju

To osigurava da adresa koju dajemo korisniku zapravo sadrži željeni bajt kod. Štoviše, ovaj pametni ugovor može se primijeniti kad god nam zatreba. Na primjer, kada korisnik prvi put odluči koristiti svoj novčanik.
Kako odrediti adresu pametnog ugovora prije implementacije: korištenje CREATE2 za kripto razmjenu
Štoviše, možete izračunati adresu pametnog ugovora svaki put umjesto da je pohranite jer:

  • adresa u formuli je konstanta, budući da je ovo adresa naše tvornice novčanika
  • sol — hash korisničkog_id-a
  • početni_kod je konstantan jer koristimo isti novčanik

Više poboljšanja

Prethodno rješenje i dalje ima jedan nedostatak: morate platiti za implementaciju pametnog ugovora. Međutim, možete ga se riješiti. Da biste to učinili, možete pozvati funkciju prijenos()a onda samouništenje() u konstruktoru novčanika. A onda će se gas za implementaciju pametnog ugovora vratiti.

Suprotno uvriježenom mišljenju, možete implementirati pametni ugovor na istu adresu više puta s opkodom CREATE2. To je zato što CREATE2 provjerava da je nonce ciljne adrese nula (dodijeljena joj je vrijednost "1" na početku konstruktora). U ovom slučaju funkcija samouništenje() resetira nonce adrese svaki put. Dakle, ako ponovo pozovete CREATE2 s istim argumentima, jednokratna provjera će proći.

Imajte na umu da je ovo rješenje slično opciji Ethereum adrese, ali bez potrebe za pohranjivanjem privatnih ključeva. Trošak prijenosa novca iz novčanika u hotwallet približno je jednak trošku pozivanja funkcije prijenos(), budući da ne plaćamo implementaciju pametnog ugovora.

Konačna odluka

Kako odrediti adresu pametnog ugovora prije implementacije: korištenje CREATE2 za kripto razmjenu

Izvorno pripremio:

  • funkcija za dobivanje soli user_id
  • pametni ugovor koji će pozivati ​​CREATE2 opcode s odgovarajućom soli (tj. tvornica novčanika)
  • bajt kod novčanika koji odgovara ugovoru sa sljedećim konstruktorom:

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


Za svakog novog korisnika izračunom prikazujemo njegovu/njezinu adresu novčanika

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


Kada korisnik prenese tokene na odgovarajuću adresu novčanika, naša pozadina vidi događaj prijenosa s parametrom _do, jednako adresi novčanika. U ovom trenutku već je moguće povećati stanje korisnika na burzi prije postavljanja novčanika.

Kada adresa novčanika prikupi dovoljan broj tokena, možemo ih sve odjednom prenijeti na hotwallet. Da bi to učinio, pozadina poziva funkciju tvornice pametnih ugovora koja izvodi sljedeće radnje:

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


Dakle, poziva se konstruktor pametnog ugovora novčanika, koji prenosi sve svoje tokene na adresu hotwalleta i zatim se samouništava.

Cijeli kod možete pronaći здесь. Imajte na umu da ovo nije naš proizvodni kod jer smo odlučili optimizirati bajt kod novčanika i napisali ga u opkodovima.

Autor Pavel Kondratenkov, stručnjak za Ethereum

Izvor: www.habr.com

Dodajte komentar