Solidity Cheat Sheet
Struttura del contratto
Ogni file inizia con una licenza e un pragma; il contratto è l'unità di deploy.
| Sintassi | Significato |
|---|---|
// SPDX-License-Identifier: MIT | Commento di licenza che il compilatore si aspetta alla riga 1 |
pragma solidity ^0.8.0; | Versione del compilatore per cui è scritto il file |
contract Counter { ... } | Dichiarare un contratto (stato + funzioni) |
constructor(uint start) { count = start; } | Viene eseguito una sola volta, al deploy |
import "./Token.sol"; | Importare un altro file |
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | Importare un pacchetto di libreria |
interface IToken { function balanceOf(address a) external view returns (uint); } | Dichiarare un'interfaccia (senza corpi) |
library Math { function min(uint a, uint b) internal pure returns (uint) { ... } } | Una libreria di funzioni riutilizzabili |
Tipi valore
Gli interi hanno dimensioni fisse e niente decimali; la 0.8 fa revert in caso di overflow.
| Tipo | Cosa contiene |
|---|---|
uint256 / uint | Intero senza segno, da 0 a 2^256 - 1 (uint è uint256) |
uint8, uint16, ... uint128 | Interi senza segno più piccoli, a passi di 8 bit |
int256 / int | Intero con segno (ammette i negativi) |
bool | true o false |
address | Indirizzo di 20 byte di un account o di un contratto |
address payable | Indirizzo che può ricevere Ether tramite transfer/send |
bytes32, bytes1... | Array di byte a dimensione fissa |
enum Status { Open, Closed } | Insieme di costanti con nome, memorizzato come uint8 |
1 ether, 1 gwei, 1 wei | Unità di Ether: 1 ether = 10^18 wei |
1 days, 2 hours, 30 minutes | Unità di tempo, in secondi |
Tipi riferimento e posizione dei dati
Array, stringhe, bytes, struct e mapping vivono in storage, memory o calldata.
| Sintassi | Significato |
|---|---|
string memory name | Stringa UTF-8 dinamica (una copia temporanea) |
bytes memory data | Array di byte dinamico |
uint[] public scores; | Array dinamico in storage |
uint[3] fixed; | Array a dimensione fissa di 3 |
uint[] memory tmp = new uint[](5); | Allocare un array in memory |
scores.push(42); | Aggiungere a un array in storage |
scores.pop(); | Rimuovere l'ultimo elemento |
scores.length | Numero di elementi |
storage | Persistente, on-chain, costoso da scrivere |
memory | Temporaneo, vive per una sola chiamata |
calldata | Input di sola lettura delle funzioni external, il più economico |
Mapping e struct
Un mapping è una tabella hash senza lunghezza e senza iterazione; una struct raggruppa campi.
| Sintassi | Significato |
|---|---|
mapping(address => uint) public balances; | Archivio chiave-valore, ogni chiave esiste (predefinito 0) |
balances[msg.sender] += 1; | Leggere/scrivere per chiave |
mapping(address => mapping(address => uint)) allowance; | Mapping annidato |
struct User { string name; uint age; bool active; } | Definire una struct |
User memory u = User("Ada", 36, true); | Creare una struct in memory |
User memory u = User({name: "Ada", age: 36, active: true}); | Creazione con campi nominati |
users[msg.sender] = u; | Salvare una struct in un mapping |
users[msg.sender].age = 37; | Aggiornare un campo in storage |
delete users[msg.sender]; | Riportare ai valori predefiniti |
Funzioni e visibilità
Ogni funzione dichiara chi può chiamarla e se legge o scrive lo stato.
| Sintassi | Significato |
|---|---|
function add(uint a, uint b) public pure returns (uint) { return a + b; } | Una funzione con parametri e un valore di ritorno |
public | Chiamabile da ovunque (dentro e fuori) |
external | Chiamabile solo dall'esterno del contratto |
internal | Questo contratto e i contratti che lo ereditano |
private | Solo questo contratto |
view | Legge lo stato, non lo scrive mai |
pure | Non legge alcuno stato |
payable | Può ricevere Ether con la chiamata |
returns (uint sum, bool ok) | Più valori di ritorno con nome |
(uint s, bool ok) = f(); | Destrutturare più valori di ritorno |
uint public count; | Una variabile di stato public riceve un getter automatico count() |
Modifier, costanti ed ereditarietà
Riusa i controlli con i modifier; fissa i valori con constant e immutable.
| Sintassi | Significato |
|---|---|
modifier onlyOwner() { require(msg.sender == owner, "Not owner"); _; } | Definire un modifier (_ = esegue il corpo della funzione) |
function withdraw() public onlyOwner { ... } | Applicare un modifier |
uint public constant MAX = 100; | Costante in fase di compilazione |
address public immutable owner; | Impostato una volta nel costruttore, poi fisso |
contract Token is ERC20, Ownable { ... } | Ereditare da altri contratti |
function f() public virtual { ... } | Permettere l'override |
function f() public override { ... } | Fare l'override di una funzione del genitore |
super.f(); | Chiamare l'implementazione del genitore |
abstract contract Base { function f() public virtual; } | Contratto con funzioni non implementate |
Controllo del flusso
Le solite istruzioni della famiglia C; niente switch, e i cicli costano gas a ogni iterazione.
| Sintassi | Significato |
|---|---|
if (x > 5) { ... } else if (x > 2) { ... } else { ... } | Rami condizionali |
for (uint i = 0; i < n; i++) { ... } | Ciclo con contatore |
while (x < 10) { x++; } | Ciclo finché una condizione è vera |
do { ... } while (cond); | Viene eseguito almeno una volta |
break; / continue; | Uscire dal ciclo / passare all'iterazione successiva |
x > 0 ? a : b | Espressione ternaria |
a / b | Divisione intera (scarta il resto) |
a % b | Resto |
a ** 2 | Elevamento a potenza |
unchecked { x++; } | Salta i controlli di overflow (risparmia gas, usalo con cautela) |
Errori: require, revert, assert
Un controllo fallito annulla l'intera transazione e rimborsa il gas non usato.
| Sintassi | Significato |
|---|---|
require(amount > 0, "Amount must be positive"); | Validare input o stato; revert con un messaggio |
revert("Not allowed"); | Interrompere senza condizioni |
error Insufficient(uint available, uint requested); | Dichiarare un errore personalizzato (più economico delle stringhe) |
revert Insufficient(balance, amount); | Revert con un errore personalizzato |
assert(total == a + b); | Verificare un invariante che non deve mai fallire |
try token.transfer(to, amt) returns (bool ok) { ... } catch { ... } | Gestire una chiamata esterna che fallisce |
Eventi
Gli eventi scrivono log a cui le app off-chain possono iscriversi; non sono leggibili dai contratti.
| Sintassi | Significato |
|---|---|
event Transfer(address indexed from, address indexed to, uint value); | Dichiarare un evento |
emit Transfer(msg.sender, to, amount); | Emetterlo |
indexed | Parametro filtrabile (fino a 3 per evento) |
event Log(string message); | Si può registrare qualsiasi tipo ABI |
Ether, indirizzi e variabili globali
Il contesto della transazione arriva da msg, block e tx.
| Sintassi | Significato |
|---|---|
msg.sender | Indirizzo che ha chiamato questa funzione |
msg.value | Wei inviati con la chiamata (richiede payable) |
block.timestamp | Orario del blocco corrente (secondi dall'epoch) |
block.number | Altezza del blocco corrente |
tx.origin | L'account esterno che ha avviato la tx (da evitare per l'autenticazione) |
address(this).balance | Saldo in Ether di questo contratto |
payable(to).transfer(1 ether); | Invia Ether, fa revert in caso di errore |
(bool ok, ) = to.call{value: amt}(""); | Invio di basso livello, restituisce un flag di successo |
receive() external payable {} | Viene eseguita con un semplice trasferimento di Ether |
fallback() external payable {} | Viene eseguita quando nessuna funzione corrisponde |
keccak256(abi.encodePacked(a, b)) | Calcolare l'hash di valori |
abi.encode(x), abi.decode(data, (uint)) | Codificare / decodificare dati ABI |
Tutta la sintassi Solidity che usi ogni giorno, in una sola pagina. Questa Solidity cheat sheet è un riferimento rapido per il linguaggio degli smart contract di Ethereum e di ogni chain EVM: dichiarare un contratto, scegliere i tipi, salvare dati in mapping e struct, scrivere funzioni con la visibilità e la mutabilità giuste, e proteggerle con require, modifier ed eventi.
La sintassi è quella di Solidity 0.8, che controlla l'overflow aritmetico per impostazione predefinita e funziona con Remix, Hardhat e Foundry. Copia ciò che ti serve o provalo dal vivo nel playground Solidity: scrivi un contratto, compilalo ed eseguilo su una EVM nel browser.
Solidity cheat sheet FAQ
Is this Solidity cheat sheet free?
Yes. This cheat sheet is free to use, with no sign-up required. Bookmark it and come back any time you need a quick reference.
Is this cheat sheet good for beginners?
Yes. It is organized by topic so you can find what you need at any level, and each entry links back to Coddy's free interactive Solidity course when you want to go deeper.