Text original:《Vanity Addresses》de foobar
Compilare: terci peste noapte, calea DeFi
160 de milioane de dolari americani au dispărut, iar Wintermute a pierdut fondurile. Wintermute este unul dintre cele mai astute fonduri de piață din industrie lipseau 9 fonduri. Deci, ce a dus la furtul Wintermute? Acest lucru este cauzat de aleatoritatea slabă într-un generator de adrese de vanity. Hackerii Black Hat forțează brutal perechea cheie privată și adresă publică de la zero, iar apoi o cantitate mare de active cripto sunt transferate.
Există, de asemenea, o poveste despre piratarea Finanțelor indexate, unde li s-au furat 16 milioane de dolari în octombrie 2021, iar fondurile furate au fost apoi mutate la adrese care încep cu 0xba5ed... . Ceea ce nu știau ei era că adresa de vanitate a fost afectată și de vulnerabilitatea proastă de aleatorie care a afectat Wintermute, iar în septembrie 2022, toți banii au fost furați din nou, mergând la o altă adresă de portofel piratată. Hoții sunt nemilos.
Deci, ce probleme au întâmpinat acești dezvoltatori talentați și ce putem învăța din ei?
În stânga este adresa normală folosită pentru contractul WETH. În dreapta este o adresă frumoasă cu 14 zerouri de început pentru optimizarea robotului MEV. Cel mai obișnuit tip de adresă vanity este una cu multe zerouri la început.
În primul rând, ce este o adresă de vanitate (cunoscută și ca adresă de vanitate)? O adresă de vanitate se referă la o adresă publică pe care un utilizator o creează în mod deliberat pentru a o asocia cu portofelul sau cu contractul inteligent. Poate începe cu 0x0000000, poate începe cu 0xdeadbeef, poate este o altă adresă obișnuită. Există mai multe motive pentru popularitatea lor:
1. Optimizarea gazului: Wintermute a economisit 15.000 USD utilizând o adresă EOA cu mai multe zerouri la început. Sună prostesc Mulți oameni sunt de acord, dar așa funcționează EVM-ul Dacă aveți multe zerouri în adresa dvs., taxa de tranzacție poate scădea. Deci, dacă utilizați o adresă de contract inteligentă cu multe zerouri, atunci când utilizatorii interacționează cu ea, vor fi fericiți, deoarece îi economisește bani.
Cartea galbenă Ethereum descrie modul în care adresele zero de vârf pot permite gaz mai ieftin
2. Marca de acord. Știți că contractul Token de 1 inch începe cu 0x111111111...?
Contract de jetoane de 1 inch
3. Repetabilitate multi-catenă. În opinia mea, aceasta este o prioritate de top și de ce fiecare protocol ar trebui să folosească o adresă vanity pentru implementarea lor. Aplicația dvs. poate trăi pe 15 lanțuri EVM diferite și poate avea aceeași adresă peste tot! Nu ar fi acest lucru mai ușor pentru dezvoltatori și utilizatori?
Deci, când este sigură o adresă destul de bună?
Există două tipuri de adrese Ethereum: conturi deținute extern (EOA) și conturi cu contracte inteligente. Dacă ați folosit un portofel precum MetaMask, fiecare adresă din acesta este un EOA, care este folosit pentru a semna mesaje și a procesa tranzacții. Comparați acest lucru cu un cont de contract inteligent, cum ar fi contractul Uniswap, cu care oamenii pot interacționa, dar nu poate lua propriile acțiuni fără a fi declanșat. Pentru a rezuma, este foarte simplu. Adresele cu numere bune nu sunt sigure pentru conturile EOA, dar sunt sigure pentru conturile cu contracte inteligente.
Deci de ce este așa? Vom explica acest lucru mai detaliat mai jos, dar depinde de modul în care este generată adresa vanity. Pentru conturile EOA, parcurgeți milioane de chei private până când găsiți una care corespunde unei adrese publice cu aspect frumos. Cu toate acestea, cheia privată controlează fondurile dintr-un cont EOA, așa că dacă aleatorietatea pe care o folosești pentru a traversa cheia privată este compromisă, întregul tău cont este distrus. Pe de altă parte, crearea adreselor de vanitate de contracte inteligente necesită doar traversarea semințelor publice, care nu acordă niciun drept administrativ contractului inteligent.
Acesta este motivul pentru care Wintermute a eșuat și OpenSea a reușit - generarea de chei private în memoria nesigură cu software nesigur este proastă. Dar generarea de semințe publice în acest fel este destul de drăguță! Prin urmare, o adresă bună EOA este un drum către faliment, în timp ce o adresă bună de contract inteligent este un drum către succes.
De ce protocolul necesită o adresă frumoasă?
Documentare mai simplă! Puteți indica o adresă de contract pe toate lanțurile;
Verificabil de utilizator! Aceeași adresă de contract va apărea numai dacă și numai dacă bytecode este corelat octet cu octet;
Dezvoltatorii pot verifica! Deoarece adrese de contract identice apar numai în cazul unei potriviri exacte, puteți observa mici modificări dificile în scriptul de implementare;
Integrare mai ușoară! Alte protocoale pot codifica adresa contractului dvs. în codul lor cu mai multe lanțuri, fără a fi nevoie să utilizați instrucțiunile if bazate pe chainId.
NOTĂ: Suntem pe cale să studiem un manual de instrucțiuni detaliat. Punând toate piesele împreună pentru prima dată, ne scufundăm mai adânc în spațiul tehnic, iar publicul țintă este dezvoltatorii de contracte inteligente cu experiență în implementarea contractelor inteligente în lanț. Dacă ești interesat, continuă să citești, dar dacă nu este pentru tine, nu-ți face griji să ții pasul Există o provocare tehnică suplimentară la sfârșit (cu recompense).
Contract inteligent adresa frumoasa
Există o modalitate de a genera adrese smart contract care sunt 100% sigure, indiferent de software-ul pe care îl utilizați, nu contează dacă tehnologia iterativă este scursă public. Se numește „metoda CREATE2 din fabrică” și nu numai că oferă o adresă drăguță, ci este și o modalitate sigură de a vă asigura că aveți aceeași adresă de implementare a contractului pe mai multe lanțuri. De asemenea, le permite altora să implementeze codul fără încredere în numele dvs., fără nicio partajare a cheii private sau presupuneri nonce.
În primul rând, o privire de ansamblu rapidă asupra modului de a alege o adresă de contract inteligent. Există două opțiuni de implementare, CREATE și CREATE2. Când implementați un contract inteligent direct de la EOA, procesul implicit este CREATE. Adresa este determinată prin hashing adresa creatorului contractului cu creatorul contractului nonce. Acest nonce se referă la câte tranzacții a trimis o adresă, astfel încât un nou portofel începe de la 0 și este incrementat cu 1 de fiecare dată când este trimisă o nouă tranzacție. Iată formula magică pentru adresa de contract inteligent implementată de CREATE:
noua_adresa = hash(expeditor, nonce)
Mai puțin obișnuită, dar mai interesantă, este adresa de contract inteligent implementată folosind CREATE2 și iată formula sa:
adresă_nouă = hash(0xFF, expeditor, sare, cod octet)
Primul pare mai simplu, nu? Cu toate acestea, să dăm un exemplu în care această simplitate poate fi dăunătoare în comparație cu procesul mai robust CREATE2.
Airy Alice: Există o problemă cu mai multe lanțuri
Imaginați-vă că un dezvoltator cripto pe nume Alice creează două contracte inteligente: o furcă Uniswap numită GriddleSwap și un proiect NFT numit ph00ts. Toate sunt primitive independente imuabile, ceea ce înseamnă că nu există dependențe externe sau riscuri de punte încrucișată. Alice implementează GriddleSwap în Ethereum folosind nonce 0, apoi implementează ph00ts în Ethereum folosind nonce 1. Din păcate, Alice are o perioadă scurtă de atenție și a fost distrasă de pe crypto Twitter pentru câteva minute înainte de a-și desfășura munca pe Binance Smart Chain (BSC), a doua cea mai mare platformă de contracte inteligente.
Hopa, s-a încurcat ordinea de implementare!
Dar așteaptă, ea a încurcat ordinea de desfășurare și a instalat ph00ts înainte de GriddleSwap. Deoarece adresa contractului inteligent se bazează doar pe adresa creatorului, iar în blockchain-ul implementat, Ethereum gridleswap are exact aceeași adresă ca BSC ph00ts Pentru a înrăutăți lucrurile, adresa Ethereum ph00ts este aceeași cu adresa BSC GriddleSwap! A crede că utilizatorii finali vor fi confuzi este o subestimare. De fapt, poate fi abuzat de implementatorii rău intenționați pentru a păcăli oamenii să creadă că comportamentul contractual pe lanț este același - ceea ce este o presupunere corectă, având în vedere aceeași adresă!
Atentă Alice: Vor mai fi probleme
Chiar dacă Alice este atentă la desfășurare și nu amestecă niciodată ordinea non-urilor, există și alte probleme. Dacă Alice se implementează corect în Ethereum și BSC, dar apoi face o tranzacție fără legătură pe Polygon, nonce 0 a fost epuizat. Ea nu poate implementa niciodată GriddleSwap acolo, deoarece nonce-ul ei a fost incrementat. Prin urmare, cheile private ale implementatorului trebuie protejate cu orice preț. Dacă Alice o scurge, un sabotor rău intenționat poate face tranzacții fără legătură. Dacă Alice îl pierde, va pierde și capacitatea de a se desfășura la acea adresă din nou pe un lanț nou. Aceasta este o vulnerabilitate permanentă care se bazează pe un individ onest pentru a proteja cheia privată. Dacă nici măcar dezvoltatorii de bază Bitcoin nu o pot face, cum o putem face noi ceilalți?
Soluție: CREATE2
Din fericire, există o modalitate mai bună de a obține adrese consecvente în lanțuri – una care nu se bazează pe chei private secrete, nu se bazează pe un singur implementator și este rezistentă la erorile implementatorului pe parcurs. Amintiți-vă formula pentru găsirea adresei unui contract inteligent implementat folosind CREATE2:
adresă_nouă = hash(0xFF, expeditor, sare, cod octet)
Primul parametru 0xFF este o valoare constantă care poate fi ignorată. Cel de-al doilea parametru (adresa expeditorului) poate fi consecvent prin selectarea implementării 0x0000000000FFe8B47B3e2130213B802212439497 a lui z0age în majoritatea lanțurilor EVM. Al treilea parametru este o sare selectată de utilizator, pe care o putem folosi pentru a găsi o adresă bună și apoi o păstrăm neschimbată pe lanț. Al patrulea este codul octet al contractului, care servește ca o verificare utilă pentru a ne asigura că implementăm exact aceeași funcționalitate în lanț. Toți cei patru parametri pot rămâne aceiași, indiferent de ceea ce face un singur implementator.
De ce este mai bine, spre deosebire de cheia privată, sarea selectată de către implementator poate fi făcută publică. Deoarece nu leagă nicio informație secretă, oricine poate implementa contractul în noul lanț fără a dezvălui sau a partaja cheia privată. Parametrul bytecode asigură, de asemenea, că aceste noi implementări fără permisiune vor avea aceeași adresă dacă și numai dacă bytecode este același. Ca rezultat, utilizatorii finali obțin garanții mai puternice fără a fi nevoiți să facă diferențe detaliate de cod.
Pentru o privire de ansamblu mai aprofundată, consultați articolul științific popular al lui OpenZeppelin.
Creează-ți propria adresă frumoasă
Crezi că Proof of Work (PoW) va fi inutilă după fuziunea Ethereum? Mai gandeste-te! Aceleași capabilități GPU care ajută la găsirea de preimagini hash cu un număr mare de zerouri de început pentru blocurile Bitcoin sunt, de asemenea, excelente la găsirea de preimagini de hash cu un număr mare de zerouri de început pentru contractele inteligente EVM. z0age de la OpenSea (mulțumită explicației sale pentru această postare) a găsit o configurare simplă pentru a vă crea propria adresă de vanitate.
1. Utilizați vast.ai pentru a lansa un exemplu de exemplu de GPU, care încearcă de aproximativ 2 miliarde de ori pe secundă și costă aproximativ 25 de cenți/oră:
Imagine:nvidia / opencl
GPU: 1x RTX 3090
Spațiu pe disc necesar pentru a fi alocat: 1,83 GB
2. SSH și instalați rust + create2crunch
sudo apt install build-essential -y; curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y; sursa „$HOME/.cargo/env”; git clone https://github.com/0age/create2crunch && cd create2crunch; sed -i 's/0x4/0x40/g' src/lib.rs
3. Rulați o căutare de semințe. Pentru variabilele de mediu, INIT_CODE_HASH este keccak256 al codului de creare a contractului. O imprimare a unui test de turnătorie eșantion poate fi găsită aici - asigurați-vă că o verificați înainte de a consuma cantități mari de resurse de calcul! LEADING ar trebui să fie numărul de zero octeți de început pe care doriți, iar TOTAL ar trebui să fie numărul total de zero octeți pe care îi doriți în adresa contractului.
export FACTORY="0x0000000000ffe8b47b3e2130213b802212439497"; export CALLER="0x0000000000000000000000000000000000000000"; export INIT_CODE_HASH="0xabc...def"; export LEADING=5; export TOTAL=7; rulare cargo --lansare $FACTORY $CALLER $INIT_CODE_HASH 0 $LEADING $TOTAL
Când z0age și-a lansat pentru prima dată repo, a fost capabil să ruleze 1,9 miliarde de încercări pe secundă pe hardware-ul vastAI menționat mai sus. De atunci, vectorizarea a luat-o razna pe unele nuclee OpenGL și am observat 2,15 miliarde de încercări pe secundă. Aceasta înseamnă că găsirea unei adrese cu 5 octeți inițiali zero ar dura 256^5/(2150000000 * 60) ~= 8 minute, iar găsirea unei adrese cu 6 octeți zero inițiali ar dura 256^6/(2150000000 * 3600) ~ = 36 ore. O adresă de 7 octeți de început durează 256^7/(2150000000 * 86400) ~= 387 de zile. Rețineți că un octet este egal cu două caractere hexazecimale, deci o adresă de 5 octeți de început va avea 10 zerouri. Desigur, această căutare poate fi pe deplin paralelizată, iar probabilitatea reală de succes în timp va urma o distribuție Poisson.
Implementați fabrica CREATE2
Este posibil ca cititorii pricepuți să fi observat că Fabrica CREATE2 există deja la 0x0000000000FFe8B47B3e2130213B802212439497 pe toate lanțurile. Este un pic o problemă de găină și ou, cum depinde implementarea consecventă a adresei de implementarea consecventă a adresei?
Când am aflat pentru prima dată despre această abordare, am crezut că este doar o cheie privată deținută de cineva mai inteligent decât mine (scenariul „observanta Alice” de mai sus). Dar, de fapt, este mult mai robustă decât atât, Abordarea „tranzacțiilor fără cheie” a fondatorului ENS, Nick Johnson, exploatează faptul că puteți recupera adresa publică din orice semnătură a tranzacției fără a cunoaște cheia privată corespunzătoare care a semnat-o. Prin urmare, este posibil să se creeze o tranzacție („deploy a create2 factory”) și apoi să se inventeze o semnătură falsificată pentru aceasta, de exemplu o semnătură formată doar din 2. Cheia privată pentru această semnătură falsificată există, dar nimeni nu știe ce este. Dar putem recupera adresa publică corespunzătoare „semnăturii fără cheie”, să îi trimitem niște ETH și apoi să trimitem tranzacția semnată la mempool. În ciuda obscurității acestei metode, este o tranzacție validă și, de fapt, singura tranzacție validă care poate fi trimisă de la această adresă publică.
Rezultatul? Oricine poate implementa o fabrică într-un lanț nou fără nicio informație proprietară, prevenind în același timp actorii rău intenționați să provoace daune. Crearea unui EOA cu un singur scop care poate implementa o singură tranzacție este o tehnică foarte inteligentă.
Adrese și contracte specifice create în timpul tranzacțiilor fără cheie
Acest lucru poate fi realizat cu trei comenzi simple "forge cast". Codul de octet este prea lung pentru a fi copiat aici, dar puteți urma instrucțiunile de la https://github.com/ProjectOpenSea/seaport/blob/main/docs/Deployment.md fără permisiune pe orice lanț la alegere. Implementați cu ușurință CREATE2 Factory!
Desigur, dacă a fost deja implementat, nu este nevoie să îl implementați din nou.
Notă secundară: cerințele EIP-155 sunt teribile
O scurtă încercare de a-mi susține aventurile de guvernare L1, nu ezitați să treceți mai departe. EIP-155 este o propunere înaintată de Vitalik în 2016, care introduce conceptul de „ID de lanț” pentru a preveni atacurile de reluare. Fiecare lanț va avea propriul său identificator unic - 1 pentru Ethereum, 56 pentru BSC și 137 pentru Polygon - care va fi inclus în tranzacțiile semnate pentru a preveni atacurile de reluare, care a fost adoptat rapid de Ethereum, iar toate celelalte lanțuri EVM au urmat această propunere. Acest lucru este grozav, dar problema apare atunci când sunt selectate câteva lanțuri, cum ar fi Evmos, care a decis recent să interzică în mod explicit tranzacțiile înainte de EIP-155 , ceea ce, din motive ciudate, previne o eroare operațională în care Optimism a trimis 20 de milioane de jetoane OP către un multisig (da, ei din nou) adresa că Wintermute nu există, pretinde că o deține, dar nu a fost niciodată inițializată. Cu toate acestea, dezactivarea tranzacțiilor înainte de 155 ar distruge semnificativ un întreg set de implementări încrucișate, cum ar fi fabrica CREATE2 și proiecte de conducere precum Seaport. Aceste propuneri de guvernanță ar trebui să fie anulate imediat, iar detaliile de protecție ca acesta ar trebui să provină din portofel, mai degrabă decât din stratul de consens. Dacă multi-lanțul este viitorul, atunci aceste restricții inutile vor fi un obstacol imens pentru implementarea proiectelor de top pe blockchain-ul tău.
Lucruri distractive: distribuirea recompenselor
Astăzi https://delegate.cash este implementat pe 7 lanțuri EVM diferite (Ethereum, Polygon, Optimism, Celo, Avalanche, Fantom și Arbitrum) și 7 rețele de testare corespunzătoare acestor lanțuri. Adresa contractului pentru toate acestea este aceeași: 0x00000000000076A84feF008CDAbe6409d2FE638B.
Deci este suficient? Nu, avem nevoie de mai multe lanțuri. Deoarece delegatecash este o primitivă independentă cu zero dependențe, aceasta înseamnă că riscul de lanțuri multiple este efectiv zero. Acesta este un beneficiu pur! Prin urmare, pentru primii 5 oameni care vor implementa și vor verifica contractul inteligent delegatecash către noul lanț și testnet corespunzător, voi acorda un bonus de 100 USDC!
Trebuie să utilizați scriptul de implementare din depozitul open source aici. Acest lucru poate necesita implementarea fabricii CREATE2 dacă nu există și nu uitați de verificarea Etherscan! Desfășurare fericită și bucurați-vă de învățare experiențială!
