Potresti esserti imbattuto in alcuni suggerimenti di Solidity per migliorare le tue capacità di programmazione al fine di risparmiare un po' di gas, ma oggi voglio concentrarmi maggiormente su come comprendere la macchina virtuale di Ethereum può effettivamente farti risparmiare sui costi del gas sui tuoi contratti intelligenti.

Dato che ci tufferemo in Ethereum, lascerò qui lo snippet del suo Yellow Paper che specifica i costi del gas degli opcode, e durante l'articolo faremo riferimento ad essi.



Suggerimento n. 1: accesso freddo VS accesso caldo

Carico freddo: 2100 gas

Accesso Gwarm: 100 gas

Lì abbiamo i nostri primi OPCODES, il primo specifica quanto costa accedere a una variabile per la prima volta (o accesso a freddo) mentre il secondo specifica quanto costa accedere alla variabile una seconda volta e oltre (accesso a caldo ). Come puoi vedere, la differenza di prezzo è piuttosto grande, quindi comprenderlo può fare una grande differenza nei costi delle transazioni del tuo contratto intelligente. Vediamo un esempio.





La memorizzazione nella cache dei dati all'interno di una funzione in Solidity può comportare un minore utilizzo di gas, anche se richiede più righe di codice. In questo caso, si cambia la posizione dell'array e invece di utilizzarlo dallo spazio di archiviazione e quindi accedervi a freddo ogni volta nel ciclo, archivia l'array in memoria dove è più economico accedervi.

Suggerimento n. 2: valori zero o diversi da zero e rimborsi del gas

Gsset = 20.000 gas

Rsclear = {sconto sul prezzo di esecuzione}

Cambiare un valore da 0 a diverso da zero sulla blockchain di Ethereum è costoso, come vediamo nel prezzo di Gsset, ma cambiare un valore da diverso da zero a 0 può darti un rimborso in valore di gas secondo il codice operativo Rsclear. Per non usufruire del rimborso è stabilito che potrai essere rimborsato solo fino ad un massimo del 20% del costo totale della transazione.

Puoi trovare uno scenario del genere in uno scenario molto comune sulla blockchain, che sta aggiornando il saldo degli indirizzi nei contratti intelligenti. Vediamo un esempio di ciascuno:





  • Nel primo esempio contratto ZeroToNonZero, da diverso a zero a diverso da zero (5.000 gas*) + da zero a diverso da zero (20.000 gas) = ​​25.000 gas

  • Nel secondo esempio di contratto NonZeroToZero, da diverso a zero a zero (5.000 gas*) + da zero a diverso da zero (20.000 gas) — Rimborso (4.800 gas) = ​​21.200 gas

*2.100 (Gcolssload) + 2.900 (Gsreset) = 5.000 gas

Suggerimento n. 3: l'ordine delle variabili di stato è importante

Lo spazio di archiviazione è come una struttura di dati chiave-valore che contiene i valori delle variabili di stato di uno smart contract Solidity.

Puoi pensare allo storage come a un array che ti aiuterà a visualizzarlo. Ogni spazio in questo “array” di archiviazione è chiamato slot e contiene 32 byte (256 bit) di dati e ciascuna variabile di stato dichiarata nel contratto intelligente occuperà uno slot a seconda della sua posizione di dichiarazione e del suo tipo.

Non tutti i tipi di dati occupano tutti i 32 byte di ciascuno slot poiché esistono alcuni tipi di dati (bool, uint8, indirizzo...) che ne richiedono meno.

Il trucco qui è che se due/tre o più variabili insieme misurano 32 byte o meno, il compilatore di Solidity proverà a comprimerle insieme in un unico slot, ma queste variabili devono essere definite una accanto all'altra.





Qui utilizziamo i tipi di dati bool (1 byte), indirizzo (20 byte) e uint256 (32 byte). Quindi, conoscendo la dimensione di queste variabili puoi facilmente capire che nel primo esempio nel contratto TwoSlots poiché abbiamo bool e indirizzo insieme (1 + 20 = 21 byte, che è meno di 32 byte) occuperanno uno slot. Nel contratto ThreeSlots poiché bool e uint256 non possono trovarsi nello stesso slot (1 + 32 = 33 byte, che è maggiore della capacità dello slot) in totale utilizzeremo tre slot.

Ora, perché è così importante?

Il codice operativo SLOAD costa 2100 gas e viene utilizzato per leggere dagli slot di archiviazione, quindi se puoi memorizzare le variabili in meno slot, finirai per risparmiare un po' di gas.

Suggerimento n. 4: uint256 è più economico di uint8

Abbiamo appreso nel suggerimento n. 3 che uint256 (256 bit = 32 byte) occupa da solo uno slot e abbiamo anche appreso che uint8 è inferiore a 32 byte. Quindi, anche se è abbastanza semplice che 8 bit siano inferiori a 256 bit, come mai uint256 è più economico?

Per capirlo è importante sapere che se una variabile non riempie da sola l'intero slot e se questo slot non è riempito da nessun'altra variabile, l'EVM riempirà il resto dei bit rimanenti con "0" per poterlo manipolare.

Questa aggiunta "0" eseguita dall'EVM costerà gas, il che significa che per risparmiare gas di transazione è meglio utilizzare uint256 invece di uint8.

__________________

Si spera che, scoprendo questi suggerimenti per ridurre i costi del gas nei tuoi contratti intelligenti, tu abbia imparato anche un po’ di come funziona l’EVM.

__________________

Twitter @TheBlockChainer per trovare ulteriori aggiornamenti giornalieri su contratti intelligenti, sicurezza Web3, solidità, controllo dei contratti intelligenti e altro ancora.

__________________