Hoe kinne jo it adres fan in tûk kontrakt foar ynset bepale: CREATE2 brûke foar in krypto-útwikseling

It ûnderwerp fan blockchain hâldt nea op in boarne fan net allinich alle soarten hype, mar ek ideeën dy't tige weardefol binne út in technologysk eachpunt. Dêrom rûn it de ynwenners fan 'e sinnige stêd net foarby. Minsken sykje nau, studearje, besykje har ekspertize yn tradisjonele ynformaasjefeiligens oer te bringen nei blockchain-systemen. Oant no ta is it plak op: ien fan 'e ûntwikkelingen fan Rostelecom-Solar kin de feiligens fan blockchain-basearre software kontrolearje. En ûnderweis komme guon gedachten op oer it oplossen fan tapaste problemen fan 'e blockchain-mienskip. Ien fan dizze libbenshacks - hoe't jo it adres fan in tûk kontrakt kinne bepale foar ynset mei CREATE2 - hjoed wol ik mei jo diele ûnder de besuniging.

Hoe kinne jo it adres fan in tûk kontrakt foar ynset bepale: CREATE2 brûke foar in krypto-útwikseling
De CREATE2 opcode waard tafoege yn 'e Konstantinopel hurde gabel op febrewaris 28th fan dit jier. Lykas sein yn 'e EIP, dizze opcode waard yntrodusearre primêr foar steat kanalen. Wy hawwe it lykwols brûkt om in oar probleem op te lossen.

D'r binne brûkers mei saldo's op 'e útwikseling. Wy moatte elke brûker in Ethereum-adres leverje wêr't elkenien tokens kin stjoere, en dêrmei har akkount oanfolje. Litte wy dizze adressen "slúven" neame. As tokens oankomme yn slúven, moatte wy se stjoere nei in inkele beurs (hotwallet).

Yn 'e folgjende seksjes analysearje ik opsjes foar it oplossen fan dit probleem sûnder CREATE2 en fertel jo wêrom't wy se ferlitten hawwe. As jo ​​allinich ynteressearre binne yn it definitive resultaat, kinne jo it fine yn 'e seksje "Finale oplossing".

Ethereum adressen

De ienfâldichste oplossing is om nije Ethereum-adressen te generearjen foar nije brûkers. Dizze adressen sille de wallets wêze. Om tokens fan in slûf nei hotwallet oer te setten, moatte jo de transaksje ûndertekenje troch de funksje op te roppen oerdracht () mei de privee kaai fan 'e beurs fan' e efterkant.

Dizze oanpak hat de folgjende foardielen:

  • it is ienfâldich
  • de kosten fan it oerdragen fan tokens fan in slúf nei hotwallet is gelyk oan de kosten fan in funksje oprop oerdracht ()

Wy hawwe lykwols besletten tsjin dizze oanpak, om't it ien grut nadeel hat: jo moatte de privee kaaien earne opslaan. Se kinne net allinich ferlern gean, mar jo moatte ek de tagong ta dizze kaaien soarchfâldich beheare. As op syn minst ien fan har is kompromittearre, dan sille de tokens fan in bepaalde brûker de heule beurs net berikke.

Hoe kinne jo it adres fan in tûk kontrakt foar ynset bepale: CREATE2 brûke foar in krypto-útwikseling

Meitsje in apart smart kontrakt foar elke brûker

It ynsetten fan in apart tûk kontrakt foar elke brûker lit jo foarkomme dat jo privee kaaien foar slúven op 'e tsjinner opslaan. De útwikseling sil dit tûke kontrakt neame om de tokens oer te bringen nei de hotwallet.

Wy hawwe dizze oplossing ek ferlitten, om't de brûker syn portemonneeadres net sjen kin sûnder in tûk kontrakt yn te setten (dit is eins mooglik, mar op in frij komplekse manier mei oare neidielen dy't wy hjir net sille beprate). Op 'e útwikseling kin in brûker safolle akkounts oanmeitsje as hy nedich is, en elk hat syn eigen wallet nedich. Dit betsjut dat wy jild moatte besteegje oan it ynsetten fan in kontrakt sûnder sels wis te wêzen dat de brûker dit akkount sil brûke.

Opcode CREATE2

Om it probleem fan 'e foarige metoade te reparearjen, besleaten wy de CREATE2 opcode te brûken. CREATE2 lit jo it adres foarôf bepale wêr't it tûke kontrakt ynset wurdt. It adres wurdt berekkene mei de folgjende formule:

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


, dêr't:

  • adres - it adres fan it tûke kontrakt dat CREATE2 sil neame
  • sâlt - willekeurige wearde
  • init_code - smart kontrakt bytecode foar ynset

Dit soarget derfoar dat it adres dat wy jouwe oan de brûker eins befettet de winske bytecode. Boppedat kin dit tûke kontrakt wurde ynset as wy nedich binne. Bygelyks, as in brûker beslút om har wallet foar it earst te brûken.
Hoe kinne jo it adres fan in tûk kontrakt foar ynset bepale: CREATE2 brûke foar in krypto-útwikseling
Boppedat kinne jo elke kear it tûke kontraktadres berekkenje ynstee fan it op te slaan, om't:

  • adres yn 'e formule is konstant, sûnt dit is it adres fan ús wallet fabryk
  • sâlt - user_id hash
  • init_code is konstant sûnt wy brûke deselde beurs

Mear ferbetterings

De foarige oplossing hat noch ien nadeel: jo moatte betelje om it tûke kontrakt yn te setten. Jo kinne it lykwols kwytreitsje. Om dit te dwaan kinne jo de funksje neame oerdracht (), en doe selfdestruct() yn 'e wallet constructor. En dan komt it gas foar it ynsetten fan it tûke kontrakt werom.

Yn tsjinstelling ta populêr leauwe kinne jo meardere kearen in tûk kontrakt op itselde adres ynsette mei de CREATE2 opcode. Dit komt om't CREATE2 kontrolearret dat de nonce fan it doeladres nul is (it wurdt de wearde "1" oan it begjin fan 'e konstruktor tawiisd). Yn dit gefal, de funksje selfdestruct() reset nonce adressen eltse kear. Dus as jo CREATE2 opnij neame mei deselde arguminten, sil de nonce-kontrôle passe.

Tink derom dat dizze oplossing fergelykber is mei de Ethereum-adresopsje, mar sûnder de needsaak om privee kaaien op te slaan. De kosten foar it oerdragen fan jild fan in slúf nei hotwallet binne sawat gelyk oan de kosten foar it oproppen fan in funksje oerdracht (), om't wy net betelje foar tûke kontrakt ynset.

Einbeslút

Hoe kinne jo it adres fan in tûk kontrakt foar ynset bepale: CREATE2 brûke foar in krypto-útwikseling

Oarspronklik taret troch:

  • funksje om sâlt troch te krijen brûker_id
  • in tûk kontrakt dat de CREATE2-opkoade sil neame mei it passende sâlt (dus walletfabryk)
  • wallet bytecode oerienkomt mei it kontrakt mei de folgjende constructor:

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


Foar elke nije brûker litte wy syn/har portemonnee-adres troch berekkening sjen

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


As in brûker tokens oerbringt nei it korrespondearjende slûfadres, sjocht ús backend in Transfer-evenemint mei de parameter _nei, lyk oan it beursadres. Op dit punt is it al mooglik om it lykwicht fan 'e brûker op' e útwikseling te fergrutsjen foardat de slûf ynset wurdt.

As in slúfadres in foldwaande oantal tokens sammelet, kinne wy ​​se allegear tagelyk oerdrage nei hotwallet. Om dit te dwaan ropt de backend de smart contract factory funksje, dy't de folgjende aksjes útfiert:

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


Sa wurdt de wallet smart contract constructor neamd, dy't al syn tokens oerbringt nei it hotwallet-adres en dan sels ferneatiget.

De folsleine koade is te finen hjir. Tink derom dat dit net ús produksjekoade is, om't wy besletten om de wallet-bytekoade te optimalisearjen en it yn opcodes skreaunen.

Skriuwer Pavel Kondratenkov, Ethereum-spesjalist

Boarne: www.habr.com

Add a comment