Hvernig á að ákvarða heimilisfang snjallsamnings fyrir dreifingu: nota CREATE2 fyrir dulritunarskipti

Umræðuefnið blockchain hættir aldrei að vera uppspretta alls kyns efla, heldur einnig hugmynda sem eru mjög verðmætar frá tæknilegu sjónarhorni. Því fór það ekki framhjá íbúum sólríku borgarinnar. Fólk er að skoða vel, rannsaka, reyna að flytja sérfræðiþekkingu sína á hefðbundnu upplýsingaöryggi yfir í blockchain kerfi. Hingað til er það áberandi: ein af þróun Rostelecom-Solar getur athugað öryggi hugbúnaðar sem byggir á blockchain. Og á leiðinni vakna nokkrar hugsanir um að leysa beitt vandamál blockchain samfélagsins. Eitt af þessum lífshakkum - hvernig á að ákvarða heimilisfang snjallsamnings fyrir uppsetningu með CREATE2 - í dag vil ég deila með þér undir skurðinum.

Hvernig á að ákvarða heimilisfang snjallsamnings fyrir dreifingu: nota CREATE2 fyrir dulritunarskipti
CREATE2 opkóðanum var bætt við í Konstantínópel harða gafflinum þann 28. febrúar á þessu ári. Eins og fram kemur í EIP var þessi opcode kynntur fyrst og fremst fyrir ríkisrásir. Hins vegar notuðum við það til að leysa annað vandamál.

Það eru notendur með innstæður á kauphöllinni. Við verðum að útvega hverjum notanda Ethereum heimilisfang sem hver sem er getur sent tákn til og fyllt þannig á reikninginn sinn. Við skulum kalla þessi heimilisföng „veski“. Þegar tákn berast í veski verðum við að senda þau í eitt veski (hotwallet).

Í eftirfarandi köflum greini ég valkosti til að leysa þetta vandamál án CREATE2 og segi þér hvers vegna við hættum þeim. Ef þú hefur aðeins áhuga á lokaniðurstöðunni geturðu fundið hana í hlutanum „Loklausn“.

Ethereum heimilisföng

Einfaldasta lausnin er að búa til ný Ethereum heimilisföng fyrir nýja notendur. Þessi heimilisföng verða veskið. Til að flytja tákn úr veski yfir í hotwallet þarftu að skrifa undir færsluna með því að hringja í aðgerðina flytja() með einkalykli vesksins frá bakendanum.

Þessi aðferð hefur eftirfarandi kosti:

  • það er einfalt
  • kostnaður við að flytja tákn úr veski yfir í hotwallet er jafn kostnaði við aðgerðarsímtal flytja()

Hins vegar ákváðum við gegn þessari nálgun vegna þess að hún hefur einn stóran galla: þú þarft að geyma einkalyklana einhvers staðar. Þeir geta ekki aðeins glatast heldur þarftu líka að stjórna aðgangi að þessum lyklum vandlega. Ef að minnsta kosti einn þeirra er í hættu, þá munu tákn tiltekins notanda ekki ná í heita veskið.

Hvernig á að ákvarða heimilisfang snjallsamnings fyrir dreifingu: nota CREATE2 fyrir dulritunarskipti

Búðu til sérstakan snjallsamning fyrir hvern notanda

Með því að nota sérstakan snjallsamning fyrir hvern notanda geturðu forðast að geyma einkalykla fyrir veski á þjóninum. Kauphöllin mun kalla þennan snjalla samning til að flytja táknin í hotwallet.

Við hættum líka við þessa lausn, þar sem ekki er hægt að sýna notandanum veskis heimilisfang sitt án þess að nota snjallsamning (þetta er í raun mögulegt, en á frekar flókinn hátt með öðrum ókostum sem við munum ekki ræða hér). Í kauphöllinni getur notandi búið til eins marga reikninga og hann þarf og hver og einn þarf sitt eigið veski. Þetta þýðir að við þurfum að eyða peningum í að dreifa samningi án þess að vera viss um að notandinn muni nota þennan reikning.

Opcode CREATE2

Til að laga vandamálið við fyrri aðferðina ákváðum við að nota CREATE2 opkóðann. CREATE2 gerir þér kleift að fyrirframákveða heimilisfangið þar sem snjallsamningurinn verður settur á. Heimilisfangið er reiknað út með eftirfarandi formúlu:

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


hvar:

  • heimilisfang — heimilisfang snjallsamningsins sem mun kalla CREATE2
  • salt - tilviljunarkennd gildi
  • init_code - snjall samnings bækikóði fyrir dreifingu

Þetta tryggir að heimilisfangið sem við gefum notandanum innihaldi í raun þann bækikóða sem óskað er eftir. Þar að auki er hægt að nota þennan snjalla samning hvenær sem við þurfum. Til dæmis þegar notandi ákveður að nota veskið sitt í fyrsta skipti.
Hvernig á að ákvarða heimilisfang snjallsamnings fyrir dreifingu: nota CREATE2 fyrir dulritunarskipti
Þar að auki geturðu reiknað út snjallsamningsfangið í hvert skipti í stað þess að geyma það vegna þess að:

  • heimilisfang í formúlunni er stöðug, þar sem þetta er heimilisfang veskisverksmiðjunnar okkar
  • salt — user_id hash
  • init_code er varanlegt þar sem við notum sama veskið

Fleiri endurbætur

Fyrri lausnin hefur enn einn galla: þú þarft að borga fyrir að dreifa snjallsamningnum. Hins vegar er hægt að losna við það. Fyrir þetta geturðu hringt í aðgerðina flytja()og þá sjálfseyðing() í veskisframleiðandanum. Og þá verður bensíninu til að dreifa snjallsamningnum skilað.

Andstætt því sem almennt er talið geturðu sent snjallsamning á sama heimilisfang margoft með CREATE2 opkóðanum. Þetta er vegna þess að CREATE2 athugar að ekkert markvistfang sé núll (það er úthlutað gildinu "1" í upphafi smiðsins). Á sama tíma er aðgerðin sjálfseyðing() endurstillir nonce heimilisfangið í hvert skipti. Þannig að ef þú hringir aftur í CREATE2 með sömu rökum, mun nonce checkið standast.

Vinsamlegast athugaðu að þessi lausn er svipuð og Ethereum heimilisfang valkostur, en án þess að þurfa að geyma einkalykla. Kostnaður við að flytja peninga úr veski yfir í hotwallet er um það bil jafn kostnaði við að hringja í fall flytja(), þar sem við borgum ekki fyrir dreifingu snjallsamningsins.

Endanleg ákvörðun

Hvernig á að ákvarða heimilisfang snjallsamnings fyrir dreifingu: nota CREATE2 fyrir dulritunarskipti

Upphaflega undirbúið:

  • virka til að fá salt með USER_ID
  • snjall samningur sem kallar á CREATE2 opcode með viðeigandi salti (þ.e. veskisverksmiðju)
  • bætikóði veskis sem samsvarar samningi við eftirfarandi byggingaraðila:

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


Fyrir hvern nýjan notanda sýnum við veskis heimilisfang hans/hennar með útreikningi

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


Þegar notandi flytur tákn á samsvarandi veskis heimilisfang, sér bakendi okkar flutningsatburð með færibreytunni _tiljafnt og heimilisfang veskisins. Á þessum tímapunkti er nú þegar hægt að auka stöðu notandans á kauphöllinni áður en veskið er notað.

Þegar veskis heimilisfang safnar nægjanlegum fjölda tákna, getum við flutt þá alla í einu yfir á hotwallet. Til að gera þetta kallar bakendinn snjallsamningsverksmiðjuaðgerðina, sem framkvæmir eftirfarandi aðgerðir:

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


Þannig er kallaður veskissnjall samningsframleiðandinn, sem flytur öll tákn sín á hotwallet heimilisfangið og eyðir síðan sjálfum sér.

Hægt er að finna heildarkóðann hér. Vinsamlegast athugaðu að þetta er ekki framleiðslukóði okkar, þar sem við ákváðum að fínstilla bækikóðann fyrir veski og skrifuðum hann í opkóða.

Höfundur Pavel Kondratenkov, Ethereum sérfræðingur

Heimild: www.habr.com

Bæta við athugasemd