Kiel determini la adreson de inteligenta kontrakto antaŭ deplojo: uzante CREATE2 por kripta interŝanĝo

La temo de blokĉeno neniam ĉesas esti fonto de ne nur ĉiaj hype, sed ankaŭ ideoj, kiuj estas tre valoraj el teknologia vidpunkto. Tial ĝi ne preteriris la loĝantojn de la suna urbo. Homoj rigardas atente, studas, provas transdoni sian kompetentecon en tradicia informa sekureco al blokĉenaj sistemoj. Ĝis nun, ĝi estas ĝusta: unu el la evoluoj de Rostelecom-Solar povas kontroli la sekurecon de programaro bazita en blokĉeno. Kaj survoje aperas iuj pensoj pri solvado de aplikataj problemoj de la blokĉena komunumo. Unu el ĉi tiuj vivhakoj - kiel determini la adreson de inteligenta kontrakto antaŭ deplojo uzante CREATE2 - hodiaŭ mi volas dividi kun vi sub la tranĉo.

Kiel determini la adreson de inteligenta kontrakto antaŭ deplojo: uzante CREATE2 por kripta interŝanĝo
La opkodo CREATE2 estis aldonita en la malmola forko de Konstantinopolo la 28-an de februaro ĉi-jare. Kiel deklarite en la EIP, tiu opkodo estis lanĉita ĉefe por ŝtatkanaloj. Tamen ni uzis ĝin por solvi malsaman problemon.

Estas uzantoj kun saldo en la interŝanĝo. Ni devas provizi al ĉiu uzanto adreson de Ethereum, al kiu iu ajn povas sendi ĵetonojn, tiel replenigante sian konton. Ni nomu ĉi tiujn adresojn "monujoj". Kiam ĵetonoj alvenas en monujojn, ni devas sendi ilin al ununura monujo (hotmonujo).

En la sekvaj sekcioj, mi analizas eblojn por solvi ĉi tiun problemon sen CREATE2 kaj diras al vi kial ni forlasis ilin. Se vi nur interesiĝas pri la fina rezulto, vi povas trovi ĝin en la sekcio "Fina Solvo".

Ethereum-adresoj

La plej simpla solvo estas generi novajn Ethereum-adresojn por novaj uzantoj. Ĉi tiuj adresoj estos la monujoj. Por translokigi ĵetonojn de monujo al hotmonujo, vi devas subskribi la transakcion vokante la funkcion translokigo () kun la privata ŝlosilo de la monujo de la backend.

Ĉi tiu aliro havas la sekvajn avantaĝojn:

  • ĝi estas simpla
  • la kosto de translokado de ĵetonoj de monujo al hotmonujo estas egala al la kosto de funkciovoko translokigo ()

Tamen, ni decidis kontraŭ ĉi tiu aliro ĉar ĝi havas unu gravan malavantaĝon: vi devas stoki la privatajn ŝlosilojn ie. Ne nur ili povas esti perditaj, sed vi ankaŭ devas zorge administri aliron al ĉi tiuj ŝlosiloj. Se almenaŭ unu el ili estas kompromitita, tiam la ĵetonoj de aparta uzanto ne atingos la varman monujon.

Kiel determini la adreson de inteligenta kontrakto antaŭ deplojo: uzante CREATE2 por kripta interŝanĝo

Kreu apartan inteligentan kontrakton por ĉiu uzanto

Deploji apartan inteligentan kontrakton por ĉiu uzanto ebligas vin eviti stoki privatajn ŝlosilojn por monujoj sur la servilo. La interŝanĝo nomos ĉi tiun inteligentan kontrakton por translokigi la ĵetonojn al la hotmonujo.

Ni ankaŭ forlasis ĉi tiun solvon, ĉar oni ne povas montri al la uzanto sian monujo-adreson sen deploji inteligentan kontrakton (tio efektive eblas, sed en sufiĉe kompleksa maniero kun aliaj malavantaĝoj, kiujn ni ne diskutos ĉi tie). En la interŝanĝo, uzanto povas krei tiom da kontoj kiom li bezonas, kaj ĉiu bezonas sian propran monujon. Ĉi tio signifas, ke ni devas elspezi monon por disfaldi kontrakton sen eĉ esti certa, ke la uzanto uzos ĉi tiun konton.

Opcode CREATE2

Por solvi la problemon de la antaŭa metodo, ni decidis uzi la opkodon CREATE2. CREATE2 permesas vin antaŭdetermini la adreson kie la inteligenta kontrakto estos deplojita. La adreso estas kalkulita per la sekva formulo:

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


, kie:

  • adreso — la adreso de la inteligenta kontrakto, kiu nomos CREATE2
  • salo - hazarda valoro
  • init_code - inteligenta kontrakto bajtkodo por deplojo

Ĉi tio certigas, ke la adreso, kiun ni provizas al la uzanto, efektive enhavas la deziratan bajtkodon. Plie, ĉi tiu inteligenta kontrakto povas esti deplojita kiam ajn ni bezonas. Ekzemple, kiam uzanto decidas uzi sian monujon por la unua fojo.
Kiel determini la adreson de inteligenta kontrakto antaŭ deplojo: uzante CREATE2 por kripta interŝanĝo
Plie, vi povas kalkuli la inteligentan kontrakton-adreson ĉiufoje anstataŭ konservi ĝin ĉar:

  • adreso en la formulo estas konstanta, ĉar ĉi tiu estas la adreso de nia monujo-fabriko
  • salo — user_id hash
  • init_code estas konstanta ĉar ni uzas la saman monujon

Pli da plibonigoj

La antaŭa solvo ankoraŭ havas unu malavantaĝon: vi devas pagi por disfaldi la inteligentan kontrakton. Tamen vi povas forigi ĝin. Por fari tion vi povas voki la funkcion translokigo (), kaj tiam memdetruo () en la monujo konstrukciisto. Kaj tiam la gaso por disfaldi la inteligentan kontrakton estos redonita.

Kontraŭe al populara kredo, vi povas deploji inteligentan kontrakton al la sama adreso plurfoje kun la opkodo CREATE2. Ĉi tio estas ĉar CREATE2 kontrolas ke la nonce de la cela adreso estas nulo (al ĝi estas atribuita la valoro "1" komence de la konstrukciisto). En ĉi tiu kazo, la funkcio memdetruo () restarigas nonce adresojn ĉiufoje. Do se vi vokas CREATE2 denove kun la samaj argumentoj, la nonce-kontrolo pasos.

Bonvolu noti, ke ĉi tiu solvo similas al la opcio de adreso de Ethereum, sed sen neceso konservi privatajn ŝlosilojn. La kosto de translokado de mono de monujo al hotmonujo estas proksimume egala al la kosto de vokado de funkcio translokigo (), ĉar ni ne pagas por inteligenta kontrakto-deplojo.

Fina decido

Kiel determini la adreson de inteligenta kontrakto antaŭ deplojo: uzante CREATE2 por kripta interŝanĝo

Origine preparite de:

  • funkcio akiri salon per uzanto_id
  • inteligenta kontrakto, kiu nomos la opkodon CREATE2 kun la taŭga salo (t.e. monujo-fabriko)
  • monujo-bajtokodo responda al la kontrakto kun la sekva konstrukciisto:

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


Por ĉiu nova uzanto ni montras sian monujon per kalkulo

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


Kiam uzanto transdonas ĵetonojn al la responda monujo-adreso, nia backend vidas Translokigan eventon kun la parametro _al, egala al la monujo-adreso. Je ĉi tiu punkto, jam eblas pliigi la ekvilibron de la uzanto sur la interŝanĝo antaŭ deploji la monujon.

Kiam monujo-adreso amasigas sufiĉan nombron da ĵetonoj, ni povas transdoni ilin ĉiujn samtempe al hotwallet. Por fari tion, la backend nomas la inteligentan kontrakton fabrikan funkcion, kiu faras la jenajn agojn:

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


Tiel, la monujo inteligenta kontrakto-konstruanto estas vokita, kiu transdonas ĉiujn siajn ĵetonojn al la hotwallet-adreso kaj poste memdetruas.

La plena kodo troveblas tie. Bonvolu noti, ke ĉi tio ne estas nia produktkodo, ĉar ni decidis optimumigi la monujon bajtokodon kaj skribis ĝin en opkodoj.

Aŭtoro Pavel Kondratenkov, Ethereum-specialisto

fonto: www.habr.com

Aldoni komenton