Cumu determinà l'indirizzu di un cuntrattu intelligente prima di implementazione: utilizendu CREATE2 per un scambiu di criptu

U tema di u blockchain ùn cessà di esse una fonte di micca solu ogni tipu di hype, ma ancu idee assai preziose da un puntu di vista tecnologicu. Per quessa, ùn hà micca bypassatu l'abitanti di a cità assulanata. A ghjente cerca attentamente, studia, prova di trasfurmà a so cumpetenza in l'infobase tradiziunale à i sistemi di blockchain. Finu a ora, puntu: unu di i sviluppi di Rostelecom-Solar hè capaci di verificà a sicurità di u software basatu nantu à u blockchain. È in u caminu, certi pinsamenti nascenu nantu à risolve i prublemi applicati di a cumunità blockchain. Unu di sti pirate di vita - cumu per determinà l'indirizzu di un cuntrattu intelligente prima di implementazione cù CREATE2 - oghje vogliu sparte cun voi sottu u cut.

Cumu determinà l'indirizzu di un cuntrattu intelligente prima di implementazione: utilizendu CREATE2 per un scambiu di criptu
L'opcode CREATE2 hè statu aghjustatu in a furchetta dura di Custantinopuli u 28 di ferraghju di questu annu. Cum'è dichjaratu in l'EIP, stu opcode hè statu introduttu principalmente per i canali statali. Tuttavia, avemu usatu per risolve un prublema sfarente.

Ci sò utilizatori cù equilibri nantu à u scambiu. Avemu da furnisce à ogni utilizatore cù un indirizzu Ethereu, à quale qualcunu pò mandà tokens, cusì rinfriscà u so contu. Chjamemu questi indirizzi "portafogli". Quandu i tokens ghjunghjenu in portafogli, avemu da mandà à un portafogliu unicu (hotwallet).

In e seguenti sezzioni, analizà l'opzioni per risolve stu prublema senza CREATE2 è spieghemu perchè l'avemu abbandunatu. Sè vo site interessatu solu in u risultatu finali, pudete truvà in a rùbbrica Soluzione Finale.

Indirizzi Ethereu

A suluzione più simplice hè di generà novi indirizzi ethereu per novi utilizatori. Questi indirizzi seranu i portafogli. Per trasfiriri tokens da a billetera à u hotwallet, avete bisognu di firmà a transazzione chjamendu a funzione trasferimentu () cù a chjave privata di a billetera da u backend.

Stu approcciu hà i seguenti vantaghji:

  • hè solu
  • u costu di trasferimentu di tokens da wallet à hotwallet hè uguali à u costu di chjamà a funzione trasferimentu ()

Tuttavia, avemu abbandunatu stu approcciu perchè hà un inconveniente significativu: avete bisognu di almacenà e chjave private in un locu. È ùn hè micca solu chì ponu esse persu, ma ancu chì avete bisognu di gestisce cù cura l'accessu à queste chjave. Se almenu unu di elli hè cumprumissu, allura i tokens di un certu utilizatore ùn ghjunghjeranu micca à a billetera calda.

Cumu determinà l'indirizzu di un cuntrattu intelligente prima di implementazione: utilizendu CREATE2 per un scambiu di criptu

Crea un cuntrattu intelligente separatu per ogni utilizatore

A implementazione di un cuntrattu intelligente separatu per ogni utilizatore permette di ùn almacenà chjavi privati ​​​​da portafogli in u servitore. U scambiu chjamà stu cuntrattu intelligente per trasfiriri i tokens à u hotwallet.

Avemu ancu abbandunà sta suluzione, postu chì l'utilizatore ùn pò micca esse mostratu u so indirizzu di portafogli senza implementà un cuntrattu intelligente (questu hè veramente pussibule, ma in una manera piuttostu cumplicata cù altri svantaghji chì ùn discutemu micca quì). Nant'à u scambiu, l'utilizatore pò creà tanti cunti quant'è bisognu, è ognunu hà bisognu di a so propria billetera. Questu significa chì avemu bisognu di gastru soldi per implementà un cuntrattu senza ancu esse sicuru chì l'utilizatore aduprà stu contu.

Opcode CREATE2

Per risolve u prublema di u metudu precedente, avemu decisu di utilizà l'opcode CREATE2. CREATE2 permette di predeterminate l'indirizzu induve u cuntrattu intelligente serà implementatu. L'indirizzu hè calculatu cù a seguente formula:

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


, induve:

  • adrizzu - indirizzu di u cuntrattu intelligente chì chjamarà CREATE2
  • u sali - valore aleatoriu
  • init_code - codice di byte di cuntrattu intelligenti per a implementazione

Questu assicura chì l'indirizzu chì furnimu à l'utilizatore cuntene veramente u bytecode desideratu. Inoltre, stu cuntrattu intelligente pò esse implementatu quandu avemu bisognu. Per esempiu, quandu un utilizatore decide di utilizà a so billetera per a prima volta.
Cumu determinà l'indirizzu di un cuntrattu intelligente prima di implementazione: utilizendu CREATE2 per un scambiu di criptu
Inoltre, pudete calculà l'indirizzu di u cuntrattu intelligente ogni volta invece di guardà, perchè:

  • adrizzu in a formula hè custante cum'è l'indirizzu di a nostra fabbrica di portafogli
  • u sali - user_id hash
  • init_code hè permanente postu chì usemu a stessa billetera

Più miglioramenti

A suluzione precedente hà ancu un inconveniente: avete bisognu di pagà per l'implementazione di u cuntrattu intelligente. Tuttavia, si pò caccià. Per questu pudete chjamà a funzione trasferimentu (), è dopu autodistruzzione () in u custruttore di portafogli. E poi u gasu per implementà u cuntrattu intelligenti serà tornatu.

Contrariamente à a credenza populari, pudete implementà un cuntrattu intelligente à u stessu indirizzu parechje volte cù l'opcode CREATE2. Questu hè perchè CREATE2 verifica chì u nuddu di l'indirizzu di destinazione hè zero (hè assignatu u valore "1" à u principiu di u custruttore). À u listessu tempu, a funzione autodistruzzione () resetta l'indirizzu nonce ogni volta. Cusì, se chjamate CREATE2 di novu cù i stessi argumenti, a verificazione nonce passerà.

Per piacè nutate chì sta suluzione hè simile à a suluzione di l'indirizzu ethereu, ma senza a necessità di almacenà e chjave private. U costu di trasferimentu di soldi da un wallet à un hotwallet hè apprussimatamente uguale à u costu di chjamà una funzione trasferimentu (), Siccomu ùn paghemu micca per a implementazione di u cuntrattu intelligente.

Decisione finale

Cumu determinà l'indirizzu di un cuntrattu intelligente prima di implementazione: utilizendu CREATE2 per un scambiu di criptu

Inizialmente preparatu:

  • funzione per ottene u sali user_id
  • cuntrattu intelligente chì chjamarà l'opcode CREATE2 cù u sali appropritatu (vale à dì a fabbrica di portafogli)
  • wallet bytecode currispondente à u cuntrattu cù u custruttore seguente:

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


Per ogni novu utilizatore, mostremu u so indirizzu di portafogli calculendu

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


Quandu l'utilizatore trasferisce tokens à l'indirizzu di a billetera currispondente, u nostru backend vede l'avvenimentu di trasferimentu cù u paràmetru uguale à l'indirizzu di a billetera. À questu puntu, hè digià pussibule di aumentà u equilibriu di l'utilizatore nantu à u scambiu prima di implementà a billetera.

Quandu abbastanza tokens s'acumule in l'indirizzu di a billetera, pudemu trasfiriri tutti in una volta à u hotwallet. Per fà questu, u backend chjama a funzione di fabbrica di cuntrattu intelligenti, chì esegue e seguenti azzioni:

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


Cusì, u custruttore di u cuntrattu intelligente di u wallet hè chjamatu, chì trasferisce tutti i so tokens à l'indirizzu hotwallet è poi s'autodestruisce.

U codice cumpleta pò esse trovu ccà. Per piacè nutate chì questu ùn hè micca u nostru codice di pruduzzione, postu chì avemu decisu di ottimisà u bytecode di a billetera è di scrive in opcodes.

L'autore Pavel Kondratenkov, specialista in Ethereu

Source: www.habr.com

Add a comment