Ako určiť adresu inteligentného kontraktu pred nasadením: pomocou CREATE2 pre kryptoburzu

Téma blockchainu neprestáva byť zdrojom nielen všelijakého humbuku, ale aj nápadov, ktoré sú z technologického hľadiska veľmi cenné. Preto neobišla ani obyvateľov slnečného mesta. Ľudia sa pozorne pozerajú, študujú a snažia sa preniesť svoje odborné znalosti v oblasti tradičnej informačnej bezpečnosti do blockchainových systémov. Zatiaľ je to na mieste: jeden z vývojov spoločnosti Rostelecom-Solar môže skontrolovať bezpečnosť softvéru založeného na blockchaine. A popri tom vznikajú nejaké myšlienky na riešenie aplikovaných problémov blockchainovej komunity. Jeden z týchto life hackov – ako určiť adresu inteligentnej zmluvy pred nasadením pomocou CREATE2 – sa dnes chcem s vami podeliť pod strihom.

Ako určiť adresu inteligentného kontraktu pred nasadením: pomocou CREATE2 pre kryptoburzu
Operačný kód CREATE2 bol pridaný do hard forku Konštantínopolu 28. februára tohto roku. Ako je uvedené v EIP, tento operačný kód bol zavedený predovšetkým pre štátne kanály. Použili sme ho však na vyriešenie iného problému.

Na burze sú používatelia so zostatkami. Každému používateľovi musíme poskytnúť Ethereum adresu, na ktorú môže ktokoľvek poslať tokeny, čím si doplní svoj účet. Nazvime tieto adresy „peňaženky“. Keď tokeny dorazia do peňaženiek, musíme ich poslať do jednej peňaženky (hotwallet).

V nasledujúcich častiach analyzujem možnosti riešenia tohto problému bez CREATE2 a poviem vám, prečo sme ich opustili. Ak vás zaujíma iba konečný výsledok, nájdete ho v sekcii „Konečné riešenie“.

Ethereum adresy

Najjednoduchším riešením je vygenerovať nové Ethereum adresy pre nových používateľov. Tieto adresy budú peňaženky. Ak chcete preniesť tokeny z peňaženky do hotwallet, musíte transakciu podpísať volaním funkcie prenos () so súkromným kľúčom peňaženky z backendu.

Tento prístup má nasledujúce výhody:

  • je to jednoduché
  • náklady na prenos tokenov z peňaženky do hotwallet sa rovnajú nákladom na volanie funkcie prenos ()

Rozhodli sme sa však proti tomuto prístupu, pretože má jednu veľkú nevýhodu: súkromné ​​kľúče musíte niekde uložiť. Nielenže sa môžu stratiť, ale musíte tiež starostlivo spravovať prístup k týmto kľúčom. Ak je aspoň jeden z nich kompromitovaný, potom sa tokeny konkrétneho používateľa nedostanú do horúcej peňaženky.

Ako určiť adresu inteligentného kontraktu pred nasadením: pomocou CREATE2 pre kryptoburzu

Vytvorte samostatnú inteligentnú zmluvu pre každého používateľa

Nasadenie samostatnej inteligentnej zmluvy pre každého používateľa vám umožní vyhnúť sa ukladaniu súkromných kľúčov pre peňaženky na serveri. Burza zavolá túto inteligentnú zmluvu na prenos tokenov do hotwallet.

Od tohto riešenia sme tiež upustili, keďže bez nasadenia smart kontraktu nie je možné používateľovi zobraziť adresu jeho peňaženky (v skutočnosti je to možné, ale pomerne komplexne s ďalšími nevýhodami, ktoré tu nebudeme rozoberať). Na burze si používateľ môže vytvoriť toľko účtov, koľko potrebuje, a každý potrebuje svoju vlastnú peňaženku. To znamená, že musíme minúť peniaze na nasadenie zmluvy bez toho, aby sme si boli istí, že používateľ tento účet použije.

Operačný kód CREATE2

Na vyriešenie problému predchádzajúcej metódy sme sa rozhodli použiť operačný kód CREATE2. CREATE2 vám umožňuje vopred určiť adresu, kde bude smart kontrakt nasadený. Adresa sa vypočíta podľa nasledujúceho vzorca:

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


, kde:

  • adresa — adresa inteligentnej zmluvy, ktorá bude volať CREATE2
  • soľ - náhodná hodnota
  • init_code — bajtový kód inteligentnej zmluvy na nasadenie

To zaisťuje, že adresa, ktorú poskytneme používateľovi, skutočne obsahuje požadovaný bajtový kód. Navyše, túto inteligentnú zmluvu možno nasadiť kedykoľvek to potrebujeme. Napríklad, keď sa používateľ rozhodne prvýkrát použiť svoju peňaženku.
Ako určiť adresu inteligentného kontraktu pred nasadením: pomocou CREATE2 pre kryptoburzu
Okrem toho môžete adresu inteligentnej zmluvy vypočítať zakaždým namiesto jej uloženia, pretože:

  • adresa vo vzorci je konštantná, pretože toto je adresa našej továrne na peňaženky
  • soľ — hash user_id
  • init_code je konštantná, pretože používame rovnakú peňaženku

Ďalšie vylepšenia

Predchádzajúce riešenie má stále jednu nevýhodu: za nasadenie smart kontraktu musíte zaplatiť. Môžete sa ho však zbaviť. Ak to chcete urobiť, môžete zavolať funkciu prenos ()a potom sebadeštrukcia() v nástroji peňaženky. A potom sa plyn na nasadenie smart kontraktu vráti.

Na rozdiel od všeobecného presvedčenia môžete inteligentnú zmluvu nasadiť na rovnakú adresu viackrát pomocou operačného kódu CREATE2. CREATE2 totiž kontroluje, či je nonce cieľovej adresy nula (na začiatku konštruktora má priradenú hodnotu „1“). V tomto prípade funkcia sebadeštrukcia() zakaždým resetuje adresy nonce. Takže ak znova zavoláte CREATE2 s rovnakými argumentmi, kontrola nonce prejde.

Upozorňujeme, že toto riešenie je podobné možnosti adresy Ethereum, ale bez potreby ukladania súkromných kľúčov. Náklady na prevod peňazí z peňaženky do hotwallet sa približne rovnajú nákladom na volanie funkcie prenos (), keďže za nasadenie smart kontraktov neplatíme.

Konečné rozhodnutie

Ako určiť adresu inteligentného kontraktu pred nasadením: pomocou CREATE2 pre kryptoburzu

Pôvodne pripravil:

  • funkcia na získanie soli USER_ID
  • inteligentná zmluva, ktorá zavolá operačný kód CREATE2 s príslušnou soľou (t. j. továreň na peňaženky)
  • bytecode peňaženky zodpovedajúci zmluve s nasledujúcim konštruktorom:

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


Každému novému používateľovi zobrazujeme jeho/jej adresu peňaženky výpočtom

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


Keď používateľ prenesie tokeny na zodpovedajúcu adresu peňaženky, náš backend uvidí udalosť prenosu s parametrom _to, ktorá sa rovná adrese peňaženky. V tomto bode je už možné zvýšiť zostatok používateľa na burze pred nasadením peňaženky.

Keď sa na adrese peňaženky nahromadí dostatočný počet tokenov, môžeme ich všetky naraz preniesť do hotwallet. Za týmto účelom backend zavolá funkciu továrne inteligentnej zmluvy, ktorá vykoná nasledujúce akcie:

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


Zavolá sa teda konštruktor inteligentnej zmluvy peňaženky, ktorý prenesie všetky svoje tokeny na adresu hotwallet a následne sa sám zničí.

Celý kód nájdete tu. Upozorňujeme, že toto nie je náš produkčný kód, pretože sme sa rozhodli optimalizovať bajtkód peňaženky a zapísali sme ho do operačných kódov.

Autor Pavel Kondratenkov, špecialista na Ethereum

Zdroj: hab.com

Pridať komentár