S-ar putea să fi întâlnit câteva sfaturi Solidity pentru a vă îmbunătăți abilitățile de codare, pentru a economisi puțin benzină, dar astăzi vreau să mă concentrez mai mult pe modul în care înțelegerea Mașinii Virtuale Ethereum vă poate economisi efectiv costurile de gaz pentru contractele inteligente.

Deoarece ne vom scufunda în Ethereum, voi lăsa aici fragmentul din Hârtia sa galbenă care specifică costurile de gaz ale codurilor operaționale, iar pe parcursul articolului ne vom referi la ele.



Sfat #1: Acces la rece VS acces cald

Gcodsload: 2100 gaz

Gwarmaccess: 100 gaz

Acolo avem primul nostru OPCODE, primul specifică cât costă accesarea unei variabile pentru prima dată (sau acces la rece), în timp ce al doilea specifică cât costă accesarea variabilei a doua oară și mai departe (acces cald ). După cum puteți vedea, diferența de preț este destul de mare, așa că înțelegerea acestui lucru poate face o mare diferență în costurile tranzacțiilor contractului dvs. inteligent. Să vedem un exemplu.





Memorarea în cache a datelor în interiorul unei funcții în Solidity poate duce la o utilizare mai mică a gazului, chiar dacă are nevoie de mai multe linii de cod. În acest caz, este prin schimbarea locației matricei și, în loc să o folosească din stocare și, prin urmare, accesarea la rece de fiecare dată în buclă, stochează matricea în memorie unde este mai ieftin să o accesați.

Sfat nr. 2: valori zero vs non-zero și rambursări de gaz

Gsset = 20.000 de gaz

Rsclear = {reducere la prețul de execuție}

Schimbarea unei valori de la 0 la 0 pe blockchain-ul Ethereum este costisitoare, așa cum vedem în prețul Gsset, dar schimbarea unei valori de la 0 la 0 vă poate oferi o rambursare a valorii gazului conform codului operațional Rsclear. Pentru a nu profita de rambursare, se stabilește că poți fi rambursat doar cu maximum 20% din costul total al tranzacției.

Puteți găsi un astfel de scenariu într-un scenariu foarte comun pe blockchain, care este actualizarea balanței adreselor din contractele inteligente. Să vedem un exemplu pentru fiecare:





  • În primul exemplu de contract ZeroToNonZero, de la zero la non-zero (5.000 de gaz*) + zero la non-zero (20.000 de gaz) = 25.000 de gaz

  • În al doilea exemplu de contract NonZeroToZero, De la zero la zero (5.000 de gaz*) + de la zero la zero (20.000 de gaz) — Rambursare (4.800 de gaz) = 21.200 de gaz

*2.100 (Gcolssload) + 2.900 (Gsreset) = 5.000 de gaz

Sfatul #3: Ordinea variabilelor de stare contează

Stocarea este ca o structură de date cheie-valoare care deține valorile variabilelor de stare ale unui contract inteligent Solidity.

Vă puteți gândi la stocare ca la o matrice care vă va ajuta să vizualizați acest lucru. Fiecare spațiu din această „matrice” de stocare se numește slot și deține 32 de octeți (256 de biți) de date și fiecare variabilă de stare declarată în contractul inteligent va ocupa un slot în funcție de poziția sa de declarare și de tipul său.

Nu toate tipurile de date iau toți cei 32 de octeți ai fiecărui slot, deoarece există unele tipuri de date (bool, uint8, adresa...) care iau mai puțin de atât.

Trucul aici este că, dacă două/trei sau mai multe variabile împreună au 32 de octeți sau mai puțin, compilatorul Solidity va încerca să le împacheteze într-un singur slot, dar aceste variabile trebuie definite una lângă cealaltă.





Aici folosim tipurile de date bool (1 octet), adresă (20 de octeți) și uint256 (32 de octeți). Deci, cunoscând dimensiunea acestor variabile, puteți înțelege cu ușurință că în primul exemplu din contractul TwoSlots, deoarece avem bool și adresa împreună (1 + 20 = 21 octeți, adică mai puțin de 32 octeți), acestea vor ocupa un singur slot. Pe contractul ThreeSlots, deoarece bool și uint256 nu pot fi în același slot (1 + 32 = 33 de octeți, care este mai mare decât capacitatea slotului), în total vom folosi trei sloturi.

Acum, de ce este asta atât de important?

SLOAD opcode costă 2100 de benzină și este folosit pentru a citi din sloturile de stocare, așa că, dacă puteți stoca variabilele în mai puține sloturi, veți ajunge să economisiți puțin combustibil.

Sfat #4: uint256 este mai ieftin decât uint8

Am aflat în sfatul#3că uint256 (256 de biți = 32 de octeți) ocupă singur un slot și am aflat, de asemenea, că uint8 este mai puțin de 32 de octeți. Deci, deși este destul de simplu că 8 biți sunt mai mici decât 256 de biți, cum de uint256 este mai ieftin?

Pentru a înțelege că este important să știți că, dacă o variabilă nu umple ea însăși întregul slot și dacă acest slot nu este umplut de nicio altă variabilă, EVM-ul va umple restul biților rămași cu „0”-uri. pentru a-l putea manipula.

Această adăugare „0” efectuată de EVM va costa gaz, ceea ce înseamnă că, pentru a economisi gazul tranzacției, este mai bine să utilizați uint256 în loc de uint8.

__________________

Sperăm că, în timp ce aflați despre aceste sfaturi pentru a reduce costurile cu gazul în contractele dvs. inteligente, ați învățat, de asemenea, puțin despre cum funcționează EVM.

__________________

Twitter @TheBlockChainer pentru a găsi mai multe actualizări zilnice despre Smart Contracts, Web3 Security, Solidity, Auditing smart contracts și multe altele.

__________________