Cheat Sheet de Solidity
Estrutura de um contrato
Todo arquivo começa com uma licença e um pragma; o contrato é a unidade de deploy.
| Sintaxe | Significado |
|---|---|
// SPDX-License-Identifier: MIT | Comentário de licença que o compilador espera na linha 1 |
pragma solidity ^0.8.0; | Versão do compilador para a qual o arquivo foi escrito |
contract Counter { ... } | Declarar um contrato (estado + funções) |
constructor(uint start) { count = start; } | Executa uma única vez, no deploy |
import "./Token.sol"; | Importar outro arquivo |
import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; | Importar um pacote de biblioteca |
interface IToken { function balanceOf(address a) external view returns (uint); } | Declarar uma interface (sem corpos) |
library Math { function min(uint a, uint b) internal pure returns (uint) { ... } } | Uma biblioteca de funções reutilizáveis |
Tipos de valor
Os inteiros têm tamanho fixo e não têm decimais; o 0.8 reverte em caso de overflow.
| Tipo | O que armazena |
|---|---|
uint256 / uint | Inteiro sem sinal, de 0 a 2^256 - 1 (uint é uint256) |
uint8, uint16, ... uint128 | Inteiros sem sinal menores, em passos de 8 bits |
int256 / int | Inteiro com sinal (permite negativos) |
bool | true ou false |
address | Endereço de conta ou contrato de 20 bytes |
address payable | Endereço que pode receber Ether via transfer/send |
bytes32, bytes1... | Arrays de bytes de tamanho fixo |
enum Status { Open, Closed } | Conjunto nomeado de constantes, armazenado como uint8 |
1 ether, 1 gwei, 1 wei | Unidades de Ether: 1 ether = 10^18 wei |
1 days, 2 hours, 30 minutes | Unidades de tempo, em segundos |
Tipos de referência e localização de dados
Arrays, strings, bytes, structs e mappings vivem em storage, memory ou calldata.
| Sintaxe | Significado |
|---|---|
string memory name | String UTF-8 dinâmica (uma cópia temporária) |
bytes memory data | Array de bytes dinâmico |
uint[] public scores; | Array dinâmico em storage |
uint[3] fixed; | Array de tamanho fixo com 3 elementos |
uint[] memory tmp = new uint[](5); | Alocar um array em memory |
scores.push(42); | Acrescentar ao final de um array em storage |
scores.pop(); | Remover o último elemento |
scores.length | Número de elementos |
storage | Persistente, on-chain, caro para escrever |
memory | Temporário, vive durante uma chamada |
calldata | Entrada somente leitura de função external, a mais barata |
Mappings e structs
Um mapping é uma tabela hash sem tamanho e sem iteração; um struct agrupa campos.
| Sintaxe | Significado |
|---|---|
mapping(address => uint) public balances; | Armazenamento chave-valor; toda chave existe (padrão 0) |
balances[msg.sender] += 1; | Ler/escrever por chave |
mapping(address => mapping(address => uint)) allowance; | Mapping aninhado |
struct User { string name; uint age; bool active; } | Definir um struct |
User memory u = User("Ada", 36, true); | Criar um struct em memory |
User memory u = User({name: "Ada", age: 36, active: true}); | Criação com campos nomeados |
users[msg.sender] = u; | Guardar um struct em um mapping |
users[msg.sender].age = 37; | Atualizar um campo em storage |
delete users[msg.sender]; | Redefinir para os valores padrão |
Funções e visibilidade
Toda função declara quem pode chamá-la e se lê ou escreve o estado.
| Sintaxe | Significado |
|---|---|
function add(uint a, uint b) public pure returns (uint) { return a + b; } | Uma função com parâmetros e valor de retorno |
public | Chamável de qualquer lugar (dentro e fora) |
external | Chamável apenas de fora do contrato |
internal | Este contrato e os contratos que herdam dele |
private | Somente este contrato |
view | Lê o estado, nunca o escreve |
pure | Não lê estado nenhum |
payable | Pode receber Ether com a chamada |
returns (uint sum, bool ok) | Vários valores de retorno nomeados |
(uint s, bool ok) = f(); | Desestruturar vários retornos |
uint public count; | Variável de estado pública ganha um getter automático count() |
Modifiers, constantes e herança
Reutilize verificações com modifiers; fixe valores com constant e immutable.
| Sintaxe | Significado |
|---|---|
modifier onlyOwner() { require(msg.sender == owner, "Not owner"); _; } | Definir um modifier (_ = executar o corpo da função) |
function withdraw() public onlyOwner { ... } | Aplicar um modifier |
uint public constant MAX = 100; | Constante em tempo de compilação |
address public immutable owner; | Definido uma vez no constructor e depois fixo |
contract Token is ERC20, Ownable { ... } | Herdar de outros contratos |
function f() public virtual { ... } | Permitir sobrescrita |
function f() public override { ... } | Sobrescrever uma função do pai |
super.f(); | Chamar a implementação do pai |
abstract contract Base { function f() public virtual; } | Contrato com funções não implementadas |
Controle de fluxo
As instruções habituais da família C; não há switch, e loops custam gas por iteração.
| Sintaxe | Significado |
|---|---|
if (x > 5) { ... } else if (x > 2) { ... } else { ... } | Ramificações condicionais |
for (uint i = 0; i < n; i++) { ... } | Loop com contador |
while (x < 10) { x++; } | Repetir enquanto uma condição for verdadeira |
do { ... } while (cond); | Executa pelo menos uma vez |
break; / continue; | Sair do loop / pular para a próxima iteração |
x > 0 ? a : b | Expressão ternária |
a / b | Divisão inteira (descarta o resto) |
a % b | Resto |
a ** 2 | Exponenciação |
unchecked { x++; } | Pular as verificações de overflow (economiza gas, use com cuidado) |
Erros: require, revert, assert
Uma verificação que falha desfaz a transação inteira e devolve o gas não usado.
| Sintaxe | Significado |
|---|---|
require(amount > 0, "Amount must be positive"); | Validar entrada ou estado; reverter com uma mensagem |
revert("Not allowed"); | Abortar incondicionalmente |
error Insufficient(uint available, uint requested); | Declarar um erro personalizado (mais barato que strings) |
revert Insufficient(balance, amount); | Reverter com um erro personalizado |
assert(total == a + b); | Verificar um invariante que nunca deve falhar |
try token.transfer(to, amt) returns (bool ok) { ... } catch { ... } | Tratar uma chamada externa que falha |
Eventos
Eventos gravam logs que apps off-chain podem assinar; não são legíveis a partir de contratos.
| Sintaxe | Significado |
|---|---|
event Transfer(address indexed from, address indexed to, uint value); | Declarar um evento |
emit Transfer(msg.sender, to, amount); | Emiti-lo |
indexed | Parâmetro filtrável (até 3 por evento) |
event Log(string message); | Qualquer tipo ABI pode ser registrado em log |
Ether, endereços e variáveis globais
O contexto da transação vem de msg, block e tx.
| Sintaxe | Significado |
|---|---|
msg.sender | Endereço que chamou esta função |
msg.value | Wei enviados com a chamada (exige payable) |
block.timestamp | Hora do bloco atual (segundos desde a epoch) |
block.number | Altura do bloco atual |
tx.origin | A conta externa (EOA) que iniciou a tx (evite para autenticação) |
address(this).balance | Saldo em Ether deste contrato |
payable(to).transfer(1 ether); | Enviar Ether; reverte em caso de falha |
(bool ok, ) = to.call{value: amt}(""); | Envio de baixo nível; retorna um indicador de sucesso |
receive() external payable {} | Executa em uma transferência simples de Ether |
fallback() external payable {} | Executa quando nenhuma função corresponde |
keccak256(abi.encodePacked(a, b)) | Calcular o hash de valores |
abi.encode(x), abi.decode(data, (uint)) | Codificar / decodificar dados ABI |
Toda a sintaxe de Solidity que você usa no dia a dia, em uma só página. Esta cheat sheet de Solidity é uma referência rápida da linguagem de smart contracts da Ethereum e de todas as chains EVM: declarar um contrato, escolher tipos, guardar dados em mappings e structs, escrever funções com a visibilidade e a mutabilidade certas, e protegê-las com require, modifiers e eventos.
A sintaxe aqui é a do Solidity 0.8, que verifica overflow aritmético por padrão e funciona com Remix, Hardhat e Foundry. Copie o que precisar ou teste ao vivo no playground de Solidity: escreva um contrato, compile e execute em uma EVM no seu navegador.