Eu tenho revisado Solidity recentemente para consolidar os detalhes e estou escrevendo uma série de "WTF Introdução Simples à Solidity" para iniciantes (os programadores experientes podem procurar por outros tutoriais). Atualizo de 1 a 3 lições por semana.
Twitter: @0xAA_Science
Comunidade: Discord | Grupo no WeChat | Website WTF.academy
Todo o código e tutoriais estão disponíveis no Github: github.com/AmazingAng/WTF-Solidity
Nesta lição, usaremos uma transferência de tokens ERC20 como exemplo para apresentar os eventos (event) em Solidity.
Os eventos em Solidity são uma abstração dos logs na EVM e têm duas características principais:
- Responsividade: Os aplicativos (como o ethers.js) podem assinar e ouvir esses eventos através da interface RPC e responder a eles no frontend.
- Economia: Os eventos são uma forma econômica de armazenar dados na EVM, custando cerca de 2.000
gaspor evento. Em comparação, armazenar uma nova variável na cadeia custa pelo menos 20.000gas.
A declaração de um evento começa com a palavra-chave event, seguida pelo nome do evento e entre parênteses os tipos e nomes das variáveis que o evento registrará. Um exemplo é o evento Transfer do contrato de token ERC20:
event Transfer(address indexed from, address indexed to, uint256 value);Neste exemplo, o evento Transfer registra 3 variáveis: from, to e value, que correspondem ao endereço do remetente do token, ao endereço do destinatário e à quantidade transferida. As variáveis from e to têm a palavra-chave indexed antes delas, o que significa que serão armazenadas nos topics do log da máquina virtual Ethereum, facilitando pesquisas futuras.
Podemos emitir eventos dentro de funções. No exemplo abaixo, cada vez que a função _transfer() é chamada para realizar uma transferência, o evento Transfer é emitido e as variáveis correspondentes são registradas.
function _transfer(
address from,
address to,
uint256 amount
) external {
_balances[from] = 10000000; // Dá ao endereço de transferência algum saldo inicial
_balances[from] -= amount; // subtrai a quantidade transferida do endereço remetente
_balances[to] += amount; // adiciona a quantidade transferida ao endereço destinatário
// Emite o evento
emit Transfer(from, to, amount);
}A Máquina Virtual Ethereum (EVM) utiliza logs para armazenar eventos Solidity. Cada registro de log contém duas partes: os tópicos (topics) e os dados (data).
A primeira parte do log são os tópicos, que são um array usado para descrever o evento e não pode ter mais do que 4 elementos. O primeiro elemento é a assinatura do evento (hash). Para o evento Transfer mencionado acima, o hash do evento é:
keccak256("Transfer(address,address,uint256)")
//0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efAlém do hash do evento, os tópicos podem incluir até 3 parâmetros indexed, que são os endereços de transferência no caso do evento Transfer.
Os parâmetros não marcados como indexed serão armazenados na parte de dados (data) do log e correspondem aos "valores" do evento. Esses parâmetros não podem ser pesquisados diretamente, mas podem armazenar dados de qualquer tamanho. Portanto, a parte de dados no log pode ser usada para armazenar estruturas de dados complexas, como arrays e strings, que excedem 256 bits. Mesmo que esses dados sejam armazenados na parte de tópicos como um hash, o espaço consumido na armazenagem por dados na parte de dados é menor do que nos tópicos.
Vamos compilar e implantar o contrato Event.sol.
Depois, chamaremos a função _transfer.
Vamos tentar realizar uma transferência de 100 tokens na rede de testes Rinkeby usando a função _transfer(). Podemos consultar os detalhes do evento no Etherscan: link para a transação.
Clicando no botão Logs, podemos ver os detalhes do evento:
Os tópicos contêm três elementos, sendo o [0] o hash do evento, o 1 e o 2 são informações dos dois parâmetros marcados como indexed que definimos, ou seja, os endereços do remetente e do destinatário da transferência. Os dados contêm o restante, ou seja, a quantia da transferência.
Nesta lição, aprendemos como usar e consultar eventos em Solidity. Muitas ferramentas de análise blockchain, como a Nansen e a Dune Analysis, são baseadas em eventos.
