Ինչպես որոշել խելացի պայմանագրի հասցեն նախքան տեղակայումը. CREATE2-ի օգտագործումը կրիպտո փոխանակման համար

Բլոկչեյնի թեման երբեք չի դադարում լինել ոչ միայն բոլոր տեսակի հիփերի, այլև գաղափարների, որոնք շատ արժեքավոր են տեխնոլոգիական տեսանկյունից: Ուստի այն չի շրջանցել արևոտ քաղաքի բնակիչներին։ Մարդիկ ուշադիր նայում են, ուսումնասիրում, փորձում ավանդական տեղեկատվական անվտանգության իրենց փորձը փոխանցել բլոկչեյն համակարգերին: Առայժմ դա տեղում է. Rostelecom-Solar-ի մշակումներից մեկը կարող է ստուգել բլոկչեյնի վրա հիմնված ծրագրաշարի անվտանգությունը: Եվ ճանապարհին որոշ մտքեր են առաջանում բլոկչեյն համայնքի կիրառական խնդիրների լուծման վերաբերյալ։ Այս կյանքի հաքերներից մեկը՝ ինչպես որոշել խելացի պայմանագրի հասցեն նախքան տեղակայումը CREATE2-ի միջոցով, այսօր ես ուզում եմ կիսվել ձեզ հետ կտրվածքի տակ:

Ինչպես որոշել խելացի պայմանագրի հասցեն նախքան տեղակայումը. CREATE2-ի օգտագործումը կրիպտո փոխանակման համար
CREATE2 օպերացիոն ծածկագիրը ավելացվել է Constantinople hard fork-ում այս տարվա փետրվարի 28-ին: Ինչպես նշվում է EIP-ում, այս opcode-ը ներդրվել է հիմնականում պետական ​​ալիքների համար: Սակայն մենք այն օգտագործեցինք այլ խնդիր լուծելու համար։

Բորսայում կան մնացորդներ ունեցող օգտատերեր։ Մենք պետք է յուրաքանչյուր օգտվողին տրամադրենք Ethereum հասցե, որին յուրաքանչյուրը կարող է ուղարկել թոքեններ՝ դրանով իսկ համալրելով իր հաշիվը: Այս հասցեները կոչենք «դրամապանակներ»։ Երբ ժետոնները հասնում են դրամապանակներում, մենք պետք է դրանք ուղարկենք մեկ դրամապանակին (թեժ դրամապանակ):

Հետևյալ բաժիններում ես վերլուծում եմ այս խնդիրը լուծելու տարբերակները առանց CREATE2-ի և պատմում եմ ձեզ, թե ինչու մենք լքեցինք դրանք: Եթե ​​ձեզ հետաքրքրում է միայն վերջնական արդյունքը, այն կարող եք գտնել «Վերջնական լուծում» բաժնում:

Ethereum հասցեներ

Ամենապարզ լուծումը նոր օգտատերերի համար նոր Ethereum հասցեներ ստեղծելն է: Այս հասցեները կլինեն դրամապանակները։ Թոքենները դրամապանակից տաք դրամապանակ փոխանցելու համար անհրաժեշտ է գործարքը ստորագրել՝ զանգահարելով ֆունկցիան փոխանցում () հետնամասի դրամապանակի անձնական բանալիով:

Այս մոտեցումն ունի հետևյալ առավելությունները.

  • դա պարզապես
  • Թոքենները դրամապանակից տաք դրամապանակ փոխանցելու արժեքը հավասար է ֆունկցիայի զանգի արժեքին փոխանցում ()

Այնուամենայնիվ, մենք որոշեցինք դեմ լինել այս մոտեցմանը, քանի որ այն ունի մեկ կարևոր թերություն. դուք պետք է ինչ-որ տեղ պահեք անձնական բանալիները: Նրանք ոչ միայն կարող են կորչել, այլ նաև պետք է ուշադիր կառավարել մուտքը դեպի այս բանալիները: Եթե ​​դրանցից գոնե մեկը վտանգի ենթարկվի, ապա կոնկրետ օգտագործողի նշանները չեն հասնի տաք դրամապանակին:

Ինչպես որոշել խելացի պայմանագրի հասցեն նախքան տեղակայումը. CREATE2-ի օգտագործումը կրիպտո փոխանակման համար

Ստեղծեք առանձին խելացի պայմանագիր յուրաքանչյուր օգտագործողի համար

Յուրաքանչյուր օգտագործողի համար առանձին խելացի պայմանագիր տեղադրելը թույլ է տալիս խուսափել սերվերում դրամապանակների անձնական բանալիներ պահելուց: Փոխանակումը կկանչի այս խելացի պայմանագիրը՝ ժետոնները տաք դրամապանակ փոխանցելու համար:

Մենք նույնպես հրաժարվեցինք այս լուծումից, քանի որ օգտագործողին չի կարելի ցույց տալ իր դրամապանակի հասցեն՝ առանց խելացի պայմանագիր գործադրելու (սա իրականում հնարավոր է, բայց բավականին բարդ ձևով՝ այլ թերություններով, որոնք մենք այստեղ չենք քննարկելու): Բորսայում օգտատերը կարող է ստեղծել այնքան հաշիվներ, որքան իրեն պետք է, և յուրաքանչյուրին պետք է իր դրամապանակը: Սա նշանակում է, որ մենք պետք է գումար ծախսենք պայմանագրի գործարկման վրա՝ նույնիսկ վստահ չլինելով, որ օգտատերը կօգտագործի այս հաշիվը:

Opcode CREATE2

Նախորդ մեթոդի խնդիրը շտկելու համար մենք որոշեցինք օգտագործել CREATE2 opcode-ը: CREATE2-ը թույլ է տալիս նախապես որոշել հասցեն, որտեղ կտեղակայվի խելացի պայմանագիրը: Հասցեն հաշվարկվում է հետևյալ բանաձևով.

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


, Որտեղ:

  • հասցե — խելացի պայմանագրի հասցեն, որը կկանչի CREATE2
  • աղ - պատահական արժեք
  • init_code - խելացի պայմանագրային բայթկոդ տեղակայման համար

Սա ապահովում է, որ հասցեն, որը մենք տրամադրում ենք օգտագործողին, իրականում պարունակում է ցանկալի բայթ կոդը: Ավելին, այս խելացի պայմանագիրը կարող է գործարկվել, երբ մեզ անհրաժեշտ լինի: Օրինակ, երբ օգտատերը որոշում է առաջին անգամ օգտագործել իր դրամապանակը:
Ինչպես որոշել խելացի պայմանագրի հասցեն նախքան տեղակայումը. CREATE2-ի օգտագործումը կրիպտո փոխանակման համար
Ավելին, դուք կարող եք ամեն անգամ հաշվարկել խելացի պայմանագրի հասցեն՝ այն պահելու փոխարեն, քանի որ.

  • հասցե բանաձևում հաստատուն է, քանի որ սա մեր դրամապանակների գործարանի հասցեն է
  • աղ — user_id հեշ
  • init_code հաստատուն է, քանի որ մենք օգտագործում ենք նույն դրամապանակը

Ավելի շատ բարելավումներ

Նախորդ լուծումը դեռ ունի մեկ թերություն՝ խելացի պայմանագիրը գործարկելու համար պետք է վճարել: Այնուամենայնիվ, դուք կարող եք ազատվել դրանից: Դա անելու համար կարող եք զանգահարել գործառույթը փոխանցում ()եւ հետո ինքնաոչնչացում () դրամապանակի կոնստրուկտորում։ Իսկ հետո խելացի պայմանագրի տեղակայման համար նախատեսված գազը կվերադարձվի։

Հակառակ տարածված կարծիքի, դուք կարող եք մի քանի անգամ նույն հասցեում խելացի պայմանագիր գործարկել CREATE2 օպոդով: Դա պայմանավորված է նրանով, որ CREATE2-ը ստուգում է, որ նպատակային հասցեի ոչ միությունը զրոյական է (կոնստրուկտորի սկզբում նրան վերագրվում է «1» արժեքը): Այս դեպքում գործառույթը ինքնաոչնչացում () ամեն անգամ զրոյացնում է ոչ մեկ հասցեները: Այսպիսով, եթե դուք կրկին զանգահարեք CREATE2-ին նույն արգումենտներով, ապա nonce ստուգումը կանցնի:

Խնդրում ենք նկատի ունենալ, որ այս լուծումը նման է Ethereum հասցեի տարբերակին, բայց առանց անձնական բանալիներ պահելու անհրաժեշտության: Դրամապանակից տաք դրամապանակ գումար փոխանցելու արժեքը մոտավորապես հավասար է ֆունկցիայի կանչի արժեքին փոխանցում (), քանի որ մենք չենք վճարում խելացի պայմանագրի տեղակայման համար:

Վերջնական որոշում

Ինչպես որոշել խելացի պայմանագրի հասցեն նախքան տեղակայումը. CREATE2-ի օգտագործումը կրիպտո փոխանակման համար

Սկզբնապես պատրաստվել է.

  • միջոցով աղ ստանալու ֆունկցիա USER_ID
  • խելացի պայմանագիր, որը կկանչի CREATE2 օպերացիոն ծածկագիրը համապատասխան աղով (այսինքն՝ դրամապանակների գործարան)
  • դրամապանակի բայթկոդ, որը համապատասխանում է հետևյալ կոնստրուկտորի հետ պայմանագրին.

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


Յուրաքանչյուր նոր օգտվողի համար մենք ցույց ենք տալիս նրա դրամապանակի հասցեն հաշվարկով

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


Երբ օգտատերը նշաններ է փոխանցում համապատասխան դրամապանակի հասցեին, մեր ֆոնդը տեսնում է փոխանցման իրադարձություն պարամետրով _դեպի, հավասար է դրամապանակի հասցեին։ Այս պահին արդեն հնարավոր է մեծացնել օգտատիրոջ մնացորդը բորսայում նախքան դրամապանակը տեղակայելը:

Երբ դրամապանակի հասցեն կուտակում է բավարար թվով թոքեններ, մենք կարող ենք դրանք միանգամից փոխանցել hotwallet: Դա անելու համար backend-ը կանչում է խելացի պայմանագրային գործարանի ֆունկցիան, որն իրականացնում է հետևյալ գործողությունները.

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


Այսպիսով, կոչվում է դրամապանակի խելացի պայմանագրային կոնստրուկտոր, որն իր բոլոր նշանները փոխանցում է տաք դրամապանակի հասցեին և այնուհետև ինքնաոչնչանում է:

Ամբողջական կոդը կարելի է գտնել այստեղ. Խնդրում ենք նկատի ունենալ, որ սա մեր արտադրության կոդը չէ, քանի որ մենք որոշեցինք օպտիմիզացնել դրամապանակի բայթկոդը և այն գրել opcodes-ով:

Հեղինակ Պավել Կոնդրատենկով, Ethereum-ի մասնագետ

Source: www.habr.com

Добавить комментарий