Paano matukoy ang address ng isang matalinong kontrata bago ang pag-deploy: gamit ang CREATE2 para sa isang crypto exchange

Ang paksa ng blockchain ay hindi tumitigil na maging mapagkukunan ng hindi lamang lahat ng uri ng hype, kundi pati na rin ang mga ideya na napakahalaga mula sa isang teknolohikal na pananaw. Samakatuwid, hindi nito nalampasan ang mga residente ng maaraw na lungsod. Tinitingnang mabuti ng mga tao, nag-aaral, sinusubukang ilipat ang kanilang kadalubhasaan sa tradisyonal na seguridad ng impormasyon sa mga sistema ng blockchain. Sa ngayon, nasa punto ito: ang isa sa mga development ng Rostelecom-Solar ay maaaring suriin ang seguridad ng software na nakabatay sa blockchain. At kasama ang paraan, ang ilang mga saloobin ay lumitaw sa paglutas ng mga inilapat na problema ng komunidad ng blockchain. Isa sa mga life hack na ito - kung paano matukoy ang address ng isang smart contract bago i-deploy gamit ang CREATE2 - ngayon gusto kong ibahagi sa iyo sa ilalim ng cut.

Paano matukoy ang address ng isang matalinong kontrata bago ang pag-deploy: gamit ang CREATE2 para sa isang crypto exchange
Ang CREATE2 opcode ay idinagdag sa Constantinople hard fork noong ika-28 ng Pebrero ng taong ito. Gaya ng nakasaad sa EIP, ang opcode na ito ay pangunahing ipinakilala para sa mga channel ng estado. Gayunpaman, ginamit namin ito upang malutas ang ibang problema.

May mga user na may mga balanse sa exchange. Dapat naming bigyan ang bawat gumagamit ng isang Ethereum address kung saan maaaring magpadala ng mga token ang sinuman, sa gayon ay mapupuno muli ang kanilang account. Tawagin natin ang mga address na ito na "mga wallet". Kapag dumating ang mga token sa mga wallet, dapat nating ipadala ang mga ito sa isang wallet (hotwallet).

Sa mga sumusunod na seksyon, sinusuri ko ang mga opsyon para sa paglutas ng problemang ito nang walang CREATE2 at sasabihin sa iyo kung bakit namin sila inabandona. Kung interesado ka lamang sa huling resulta, mahahanap mo ito sa seksyong "Panghuling Solusyon".

Mga address ng Ethereum

Ang pinakasimpleng solusyon ay ang bumuo ng mga bagong Ethereum address para sa mga bagong user. Ang mga address na ito ang magiging mga wallet. Upang ilipat ang mga token mula sa isang wallet patungo sa hotwallet, kailangan mong lagdaan ang transaksyon sa pamamagitan ng pagtawag sa function paglipat() gamit ang pribadong key ng wallet mula sa backend.

Ang diskarte na ito ay may mga sumusunod na pakinabang:

  • ito lang
  • ang halaga ng paglilipat ng mga token mula sa isang wallet patungo sa hotwallet ay katumbas ng halaga ng isang function call paglipat()

Gayunpaman, nagpasya kami laban sa diskarteng ito dahil mayroon itong isang pangunahing disbentaha: kailangan mong iimbak ang mga pribadong key sa isang lugar. Hindi lamang maaaring mawala ang mga ito, ngunit kailangan mo ring maingat na pamahalaan ang pag-access sa mga key na ito. Kung hindi bababa sa isa sa mga ito ang nakompromiso, kung gayon ang mga token ng isang partikular na user ay hindi makakarating sa mainit na pitaka.

Paano matukoy ang address ng isang matalinong kontrata bago ang pag-deploy: gamit ang CREATE2 para sa isang crypto exchange

Gumawa ng hiwalay na smart contract para sa bawat user

Ang pag-deploy ng hiwalay na smart contract para sa bawat user ay nagbibigay-daan sa iyong maiwasan ang pag-imbak ng mga pribadong key para sa mga wallet sa server. Tatawagin ng exchange ang smart contract na ito para ilipat ang mga token sa hotwallet.

Inabandona rin namin ang solusyon na ito, dahil hindi maipapakita sa user ang kanyang wallet address nang hindi nagde-deploy ng smart contract (ito ay posible talaga, ngunit sa medyo kumplikadong paraan sa iba pang mga disadvantages na hindi namin tatalakayin dito). Sa palitan, ang isang gumagamit ay maaaring lumikha ng maraming mga account na kailangan niya, at ang bawat isa ay nangangailangan ng sarili nitong pitaka. Nangangahulugan ito na kailangan nating gumastos ng pera sa pag-deploy ng kontrata nang hindi man lang nakakasigurado na gagamitin ng user ang account na ito.

Opcode CREATE2

Upang ayusin ang problema ng nakaraang pamamaraan, nagpasya kaming gamitin ang CREATE2 opcode. Nagbibigay-daan sa iyo ang CREATE2 na paunang tukuyin ang address kung saan ide-deploy ang smart contract. Ang address ay kinakalkula gamit ang sumusunod na formula:

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


, kung saan:

  • tirahan β€” ang address ng smart contract na tatawag sa CREATE2
  • asin - random na halaga
  • init_code β€” smart contract bytecode para sa deployment

Tinitiyak nito na ang address na ibinibigay namin sa user ay talagang naglalaman ng gustong bytecode. Bukod dito, ang matalinong kontratang ito ay maaaring i-deploy sa tuwing kailangan namin. Halimbawa, kapag nagpasya ang isang user na gamitin ang kanyang wallet sa unang pagkakataon.
Paano matukoy ang address ng isang matalinong kontrata bago ang pag-deploy: gamit ang CREATE2 para sa isang crypto exchange
Bukod dito, maaari mong kalkulahin ang address ng matalinong kontrata sa bawat oras sa halip na iimbak ito dahil:

  • tirahan sa formula ay pare-pareho, dahil ito ang address ng aming pabrika ng wallet
  • asin β€” user_id hash
  • init_code ay pare-pareho dahil ginagamit namin ang parehong wallet

Higit pang mga pagpapabuti

Ang nakaraang solusyon ay mayroon pa ring isang sagabal: kailangan mong magbayad para i-deploy ang matalinong kontrata. Gayunpaman, maaari mong alisin ito. Upang gawin ito maaari mong tawagan ang function paglipat()at pagkatapos selfdestruct() sa wallet constructor. At pagkatapos ay ibabalik ang gas para sa pag-deploy ng matalinong kontrata.

Taliwas sa popular na paniniwala, maaari kang mag-deploy ng matalinong kontrata sa parehong address nang maraming beses gamit ang CREATE2 opcode. Ito ay dahil sinusuri ng CREATE2 na ang nonce ng target na address ay zero (ito ay itinalaga ang halagang "1" sa simula ng constructor). Sa kasong ito, ang function selfdestruct() nire-reset ang mga nonce address sa bawat oras. Kaya kung tatawagan mong muli ang CREATE2 na may parehong mga argumento, ang nonce check ay lilipas.

Pakitandaan na ang solusyon na ito ay katulad ng opsyon sa Ethereum address, ngunit hindi na kailangang mag-imbak ng mga pribadong key. Ang halaga ng paglilipat ng pera mula sa isang wallet patungo sa hotwallet ay humigit-kumulang katumbas ng halaga ng pagtawag sa isang function paglipat(), dahil hindi kami nagbabayad para sa smart contract deployment.

Huling desisyon

Paano matukoy ang address ng isang matalinong kontrata bago ang pag-deploy: gamit ang CREATE2 para sa isang crypto exchange

Orihinal na inihanda ni:

  • function upang makakuha ng asin sa pamamagitan ng user_id
  • isang matalinong kontrata na tatawag sa CREATE2 opcode na may naaangkop na asin (i.e. factory ng wallet)
  • wallet bytecode na naaayon sa kontrata sa sumusunod na constructor:

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


Para sa bawat bagong user ipinapakita namin ang kanyang wallet address sa pamamagitan ng pagkalkula

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


Kapag naglipat ang isang user ng mga token sa kaukulang address ng wallet, makakakita ang aming backend ng kaganapan sa Paglipat na may parameter _sa, katumbas ng address ng wallet. Sa puntong ito, posible nang taasan ang balanse ng user sa exchange bago i-deploy ang wallet.

Kapag ang isang wallet address ay nakaipon ng sapat na bilang ng mga token, maaari naming ilipat ang mga ito nang sabay-sabay sa hotwallet. Upang gawin ito, tinatawagan ng backend ang smart contract factory function, na nagsasagawa ng mga sumusunod na pagkilos:

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


Kaya, tinawag ang wallet smart contract constructor, na naglilipat ng lahat ng token nito sa hotwallet address at pagkatapos ay sinisira ang sarili.

Ang buong code ay matatagpuan dito. Pakitandaan na hindi ito ang aming production code, dahil nagpasya kaming i-optimize ang wallet bytecode at isinulat ito sa mga opcode.

May-akda Pavel Kondratenkov, espesyalista sa Ethereum

Pinagmulan: www.habr.com

Magdagdag ng komento