Како одредити адресу паметног уговора пре примене: коришћење ЦРЕАТЕ2 за крипто размену

Тема блокчејна никада не престаје да буде извор не само свих врста хипеа, већ и идеја које су веома вредне са технолошке тачке гледишта. Стога није заобишла ни становнике сунчаног града. Људи пажљиво гледају, проучавају, покушавају да пренесу своју стручност у традиционалној безбедности информација на блокчејн системе. За сада, то је тачно: један од развоја Ростелецом-Солар-а може да провери безбедност софтвера заснованог на блокчејну. И успут се појављују неке мисли о решавању примењених проблема блокчејн заједнице. Један од ових животних хакова – како да одредите адресу паметног уговора пре примене помоћу ЦРЕАТЕ2 – данас желим да поделим са вама испод реза.

Како одредити адресу паметног уговора пре примене: коришћење ЦРЕАТЕ2 за крипто размену
Опкод ЦРЕАТЕ2 је додат у Константинопољски хард форк 28. фебруара ове године. Како је наведено у ЕИП-у, овај опкод је уведен првенствено за државне канале. Међутим, користили смо га да решимо другачији проблем.

Постоје корисници са стањем на берзи. Сваком кориснику морамо да обезбедимо Етхереум адресу на коју свако може да пошаље токене и на тај начин допуни свој налог. Назовимо ове адресе „новчаници“. Када токени стигну у новчанике, морамо их послати у један новчаник (хотваллет).

У следећим одељцима анализирам опције за решавање овог проблема без ЦРЕАТЕ2 и говорим вам зашто смо их напустили. Ако вас занима само коначни резултат, можете га пронаћи у одељку „Коначно решење“.

Етхереум адресе

Најједноставније решење је генерисање нових Етхереум адреса за нове кориснике. Ове адресе ће бити новчаници. Да бисте пренели токене из новчаника у хотваллет, потребно је да потпишете трансакцију позивањем функције трансфер () са приватним кључем новчаника из позадине.

Овај приступ има следеће предности:

  • то је само
  • цена преноса токена из новчаника у хотваллет једнака је цени позива функције трансфер ()

Међутим, одлучили смо се против овог приступа јер има један велики недостатак: морате негде да похраните приватне кључеве. Не само да се могу изгубити, већ морате пажљиво управљати приступом овим кључевима. Ако је бар један од њих компромитован, токени одређеног корисника неће стићи до врућег новчаника.

Како одредити адресу паметног уговора пре примене: коришћење ЦРЕАТЕ2 за крипто размену

Направите посебан паметни уговор за сваког корисника

Примена засебног паметног уговора за сваког корисника омогућава вам да избегнете чување приватних кључева за новчанике на серверу. Размена ће позвати овај паметни уговор да пренесе токене на хотваллет.

Одустали смо и од овог решења, пошто кориснику не може бити приказана његова адреса новчаника без примене паметног уговора (ово је заправо могуће, али на прилично сложен начин са другим недостацима о којима овде нећемо говорити). На берзи корисник може да креира онолико налога колико му је потребно, а сваком је потребан сопствени новчаник. То значи да морамо да потрошимо новац на постављање уговора, а да нисмо сигурни да ће корисник користити овај налог.

Опцоде ЦРЕАТЕ2

Да бисмо решили проблем претходне методе, одлучили смо да користимо ЦРЕАТЕ2 опцоде. ЦРЕАТЕ2 вам омогућава да унапред одредите адресу на којој ће паметни уговор бити распоређен. Адреса се израчунава помоћу следеће формуле:

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


, где:

  • адреса — адресу паметног уговора који ће звати ЦРЕАТЕ2
  • со - случајна вредност
  • инит_цоде — бајт код паметног уговора за примену

Ово осигурава да адреса коју пружамо кориснику заправо садржи жељени бајт код. Штавише, овај паметни уговор се може применити кад год нам затреба. На пример, када корисник одлучи да користи свој новчаник први пут.
Како одредити адресу паметног уговора пре примене: коришћење ЦРЕАТЕ2 за крипто размену
Штавише, можете израчунати адресу паметног уговора сваки пут уместо да је чувате јер:

  • адреса у формули је константна, пошто је ово адреса наше фабрике новчаника
  • со — хеш ИД корисника
  • инит_цоде је константан јер користимо исти новчаник

Још побољшања

Претходно решење и даље има један недостатак: морате да платите да бисте применили паметни уговор. Међутим, можете га се ослободити. Да бисте то урадили, можете позвати функцију трансфер (), и онда самодеструкција() у конструктору новчаника. А онда ће гас за примену паметног уговора бити враћен.

Супротно популарном веровању, можете применити паметни уговор на исту адресу више пута са ЦРЕАТЕ2 опкодом. То је зато што ЦРЕАТЕ2 проверава да ли је нонце циљне адресе нула (додељује му се вредност "1" на почетку конструктора). У овом случају, функција самодеструкција() ресетује нонце адресе сваки пут. Дакле, ако поново позовете ЦРЕАТЕ2 са истим аргументима, једнократна провера ће проћи.

Имајте на уму да је ово решење слично опцији Етхереум адресе, али без потребе за чувањем приватних кључева. Цена преноса новца из новчаника у хотваллет је приближно једнака цени позива функције трансфер (), пошто не плаћамо примену паметног уговора.

Коначна одлука

Како одредити адресу паметног уговора пре примене: коришћење ЦРЕАТЕ2 за крипто размену

Оригинално припремио:

  • функција за добијање соли усер_ид
  • паметан уговор који ће позвати ЦРЕАТЕ2 опцоде са одговарајућом соли (тј. фабрика новчаника)
  • бајт код новчаника који одговара уговору са следећим конструктором:

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:]


Када корисник пренесе токене на одговарајућу адресу новчаника, наш бацкенд види Трансфер догађај са параметром _до, једнако адреси новчаника. У овом тренутку, већ је могуће повећати стање корисника на берзи пре него што примените новчаник.

Када адреса новчаника акумулира довољан број токена, можемо их све одједном пренети у хотваллет. Да би то урадио, позадински део позива функцију фабрике паметних уговора, која обавља следеће радње:

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


Тако се позива конструктор паметног уговора новчаника, који преноси све своје токене на адресу хотваллет-а и затим се самоуништава.

Комплетан код се може наћи овде. Имајте на уму да ово није наш производни код, јер смо одлучили да оптимизујемо бајт код новчаника и записали га у кодовима операција.

Аутор Павел Кондратенков, специјалиста Етхереум

Извор: ввв.хабр.цом

Додај коментар