Hur man bestÀmmer adressen till ett smart kontrakt före implementering: AnvÀnd CREATE2 för ett kryptoutbyte

Ämnet blockchain upphör aldrig att vara en kĂ€lla till inte bara alla typer av hype, utan ocksĂ„ idĂ©er som Ă€r mycket vĂ€rdefulla ur teknisk synvinkel. DĂ€rför gick det inte förbi invĂ„narna i den soliga staden. MĂ€nniskor tittar noga, studerar, försöker överföra sin expertis inom traditionell informationssĂ€kerhet till blockkedjesystem. Hittills Ă€r det perfekt: en av Rostelecom-Solars utvecklingar kan kontrollera sĂ€kerheten för blockchain-baserad programvara. Och pĂ„ vĂ€gen dyker det upp nĂ„gra tankar om att lösa tillĂ€mpade problem i blockchain-gemenskapen. Ett av dessa life hacks - hur man bestĂ€mmer adressen till ett smart kontrakt före implementering med CREATE2 - idag vill jag dela med dig under klippet.

Hur man bestÀmmer adressen till ett smart kontrakt före implementering: AnvÀnd CREATE2 för ett kryptoutbyte
CREATE2-opkoden lades till i Konstantinopel hÄrdgaffel den 28 februari i Är. Som anges i EIP introducerades denna op-kod frÀmst för statliga kanaler. Men vi anvÀnde det för att lösa ett annat problem.

Det finns anvÀndare med saldon pÄ börsen. Vi mÄste förse varje anvÀndare med en Ethereum-adress till vilken vem som helst kan skicka tokens och dÀrigenom fylla pÄ sitt konto. LÄt oss kalla dessa adresser för "plÄnböcker". NÀr tokens kommer in i plÄnböcker mÄste vi skicka dem till en enda plÄnbok (hotwallet).

I följande avsnitt analyserar jag alternativen för att lösa detta problem utan CREATE2 och berÀttar varför vi övergav dem. Om du bara Àr intresserad av det slutliga resultatet kan du hitta det i avsnittet "Slutlig lösning".

Ethereum adresser

Den enklaste lösningen Àr att generera nya Ethereum-adresser för nya anvÀndare. Dessa adresser kommer att vara plÄnböckerna. För att överföra tokens frÄn en plÄnbok till hotwallet mÄste du signera transaktionen genom att anropa funktionen överföra() med plÄnbokens privata nyckel frÄn backend.

Detta tillvÀgagÄngssÀtt har följande fördelar:

  • det Ă€r enkelt
  • kostnaden för att överföra tokens frĂ„n en plĂ„nbok till hotwallet Ă€r lika med kostnaden för ett funktionssamtal överföra()

Vi beslutade oss dock för detta tillvÀgagÄngssÀtt eftersom det har en stor nackdel: du mÄste lagra de privata nycklarna nÄgonstans. De kan inte bara gÄ förlorade, utan du mÄste ocksÄ noggrant hantera Ätkomsten till dessa nycklar. Om Ätminstone en av dem Àventyras, kommer tokens för en viss anvÀndare inte att nÄ den heta plÄnboken.

Hur man bestÀmmer adressen till ett smart kontrakt före implementering: AnvÀnd CREATE2 för ett kryptoutbyte

Skapa ett separat smart kontrakt för varje anvÀndare

Att distribuera ett separat smart kontrakt för varje anvÀndare eliminerar behovet av att lagra privata nycklar för plÄnböcker serverBörsen kommer att anropa detta smarta kontrakt för att överföra tokens till hotwalleten.

Vi övergav ocksÄ denna lösning, eftersom anvÀndaren inte kan visas sin plÄnboksadress utan att anvÀnda ett smart kontrakt (detta Àr faktiskt möjligt, men pÄ ett ganska komplicerat sÀtt med andra nackdelar som vi inte kommer att diskutera hÀr). PÄ börsen kan en anvÀndare skapa sÄ mÄnga konton han behöver, och var och en behöver sin egen plÄnbok. Det betyder att vi mÄste spendera pengar pÄ att implementera ett kontrakt utan att ens vara sÀkra pÄ att anvÀndaren kommer att anvÀnda detta konto.

Opcode CREATE2

För att ÄtgÀrda problemet med den tidigare metoden bestÀmde vi oss för att anvÀnda CREATE2 opcode. CREATE2 lÄter dig förbestÀmma adressen dÀr det smarta kontraktet kommer att distribueras. Adressen berÀknas med följande formel:

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


, Var:

  • adress — adressen till det smarta kontraktet som kommer att anropa CREATE2
  • salt - slumpmĂ€ssigt vĂ€rde
  • init_code — smart kontraktsbytekod för distribution

Detta sÀkerstÀller att adressen vi tillhandahÄller anvÀndaren faktiskt innehÄller den önskade bytekoden. Dessutom kan detta smarta kontrakt anvÀndas nÀr vi behöver. Till exempel nÀr en anvÀndare bestÀmmer sig för att anvÀnda sin plÄnbok för första gÄngen.
Hur man bestÀmmer adressen till ett smart kontrakt före implementering: AnvÀnd CREATE2 för ett kryptoutbyte
Dessutom kan du berÀkna den smarta kontraktsadressen varje gÄng istÀllet för att lagra den eftersom:

  • adress i formeln Ă€r konstant, eftersom detta Ă€r adressen till vĂ„r plĂ„nboksfabrik
  • salt — user_id hash
  • init_code Ă€r konstant eftersom vi anvĂ€nder samma plĂ„nbok

Fler förbÀttringar

Den tidigare lösningen har fortfarande en nackdel: du mÄste betala för att implementera det smarta kontraktet. Du kan dock bli av med det. För att göra detta kan du anropa funktionen överföra()och dÄ sjÀlvförstörelse() i plÄnbokskonstruktören. Och sedan kommer gasen för att implementera det smarta kontraktet att returneras.

TvÀrtemot vad mÄnga tror kan du distribuera ett smart kontrakt till samma adress flera gÄnger med CREATE2-opkoden. Detta beror pÄ att CREATE2 kontrollerar att nonce av mÄladressen Àr noll (den tilldelas vÀrdet "1" i början av konstruktorn). I det hÀr fallet funktionen sjÀlvförstörelse() ÄterstÀller nonce-adresser varje gÄng. SÄ om du anropar CREATE2 igen med samma argument kommer nonce-kontrollen att passera.

Observera att denna lösning liknar Ethereum-adressalternativet, men utan att behöva lagra privata nycklar. Kostnaden för att överföra pengar frÄn en plÄnbok till hotwallet Àr ungefÀr lika med kostnaden för att ringa en funktion överföra(), eftersom vi inte betalar för smart kontraktsinstallation.

Slutgiltigt beslut

Hur man bestÀmmer adressen till ett smart kontrakt före implementering: AnvÀnd CREATE2 för ett kryptoutbyte

Ursprungligen beredd av:

  • funktion för att fĂ„ salt genom USER_ID
  • ett smart kontrakt som kommer att anropa CREATE2-opkoden med lĂ€mpligt salt (d.v.s. plĂ„nboksfabriken)
  • plĂ„nboksbytekod som motsvarar kontraktet med följande konstruktör:

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


För varje ny anvÀndare visar vi hans/hennes plÄnboksadress genom berÀkning

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


NÀr en anvÀndare överför tokens till motsvarande plÄnboksadress, ser vÄr backend en Transfer-hÀndelse med parametern _till, lika med plÄnboksadressen. Vid denna tidpunkt Àr det redan möjligt att öka anvÀndarens saldo pÄ börsen innan plÄnboken distribueras.

NÀr en plÄnboksadress samlar pÄ sig ett tillrÀckligt antal tokens kan vi överföra dem alla pÄ en gÄng till hotwallet. För att göra detta anropar backend den smarta kontraktsfabriksfunktionen, som utför följande ÄtgÀrder:

function deployWallet (ŃĐŸĐ»ŃŒ uint256) {
    bytes memory walletBytecode =
;
    // invoke CREATE2 with wallet bytecode and salt
}


SÄledes kallas den smarta kontraktskonstruktören för plÄnboken, som överför alla sina tokens till hotwallet-adressen och sedan sjÀlvdestruerar.

Hela koden finns hÀr. Observera att detta inte Àr vÄr produktionskod, eftersom vi bestÀmde oss för att optimera plÄnboksbytekoden och skrev den i opcodes.

Författare Pavel Kondratenkov, Ethereum-specialist

KĂ€lla: will.com

Köp pĂ„litlig hosting för webbplatser med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster