Lição: 050: Emitindo Eventos
Nesta aula, vamos explorar uma das funcionalidades essenciais do Solidity — os eventos. Os eventos são fundamentais para registrar as atividades que ocorrem dentro dos contratos inteligentes. Eles ajudam ouvintes externos (como interfaces de usuário e aplicações descentralizadas) a reagir de forma eficiente às mudanças no estado do contrato.
O que são Eventos?
Os eventos permitem que os contratos inteligentes se comuniquem com o mundo exterior. Quando um evento é emitido, ele cria uma entrada de log na blockchain, que pode ser indexada para facilitar a busca. Isso significa que qualquer dApp pode escutar esses eventos sem precisar chamar diretamente as funções do contrato, economizando gás e melhorando a eficiência.
Definindo e Emitindo Eventos
Para definir um evento em Solidity, você utiliza a palavra-chave event
, seguida pelo nome do evento e seus parâmetros. Depois de definir um evento, você pode emiti-lo dentro de qualquer função do seu contrato usando a palavra-chave emit
.
Exemplo: Um Contrato de Votação Simples
Vamos criar um contrato de votação simples que emite eventos quando um eleitor registra um voto.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Votacao {
// Define um evento para registrar um voto
event VotoRegistrado(address indexed eleitor, uint candidatoId);
struct Candidato {
uint id;
string nome;
uint contadorVotos;
}
mapping(uint => Candidato) public candidatos;
mapping(address => bool) public eleitores;
uint public candidatosCount;
constructor() {
adicionarCandidato("Alice");
adicionarCandidato("Bob");
}
function adicionarCandidato(string memory nome) private {
candidatosCount++;
candidatos[candidatosCount] = Candidato(candidatosCount, nome, 0);
}
function votar(uint candidatoId) public {
require(!eleitores[msg.sender], "Você já votou.");
require(candidatoId > 0 && candidatoId <= candidatosCount, "ID de candidato inválido.");
// Registra o voto
eleitores[msg.sender] = true;
candidatos[candidatoId].contadorVotos++;
// Emite o evento VotoRegistrado
emit VotoRegistrado(msg.sender, candidatoId);
}
}
Análise do Código
-
Definição do Evento:
event VotoRegistrado(address indexed eleitor, uint candidatoId);
Definimos o evento
VotoRegistrado
, que irá registrar o endereço do eleitor e o ID do candidato para o qual ele votou. A palavra-chaveindexed
permite que o parâmetroeleitor
seja pesquisável nas consultas de log. -
Struct e Mapeamentos: Definimos uma struct
Candidato
para armazenar informações sobre cada candidato, e utilizamos dois mapeamentos:candidatos
para armazenar os dados dos candidatos pelo ID,eleitores
para acompanhar se um eleitor já votou.
-
Construtor: O construtor inicializa o contrato adicionando dois candidatos.
-
Função Votar:
- Verifica se o eleitor ainda não votou.
- Confirma que o ID do candidato é válido.
- Atualiza o mapeamento
eleitores
e incrementa ocontadorVotos
do candidato correspondente. - Por fim, emite o evento
VotoRegistrado
.
Escutando Eventos
Para escutar eventos emitidos a partir de um contrato inteligente, você geralmente usa uma biblioteca JavaScript como Web3.js ou Ethers.js na interface do seu dApp. Aqui está um exemplo simples usando Ethers.js:
const { ethers } = require("ethers");
// Supondo que você já tenha se conectado ao provedor e tenha a instância do contrato
const contratoVotacao = new ethers.Contract(enderecoContrato, abi, provider);
// Escutando o evento VotoRegistrado
contratoVotacao.on("VotoRegistrado", (eleitor, candidatoId) => {
console.log(`Eleitor: ${eleitor} votou no candidato ID: ${candidatoId}`);
});
Explicação do Código
- O método
on
permite que você se inscreva para o eventoVotoRegistrado
. Quando o evento é emitido, a função de retorno de chamada é acionada e fornece parâmetros, comoeleitor
ecandidatoId
.
Benefícios de Usar Eventos
- Eficiência: Eventos são mais baratos que operações de armazenamento em termos de taxas de gás.
- Alertas: Facilitam respostas em tempo real às ações do usuário.
- Transparência de Dados: Eventos fornecem um log das ações importantes realizadas no contrato.
Conclusão
Nesta aula, abordamos os fundamentos da emissão de eventos em Solidity. Os eventos são uma ferramenta poderosa que permite que seus contratos inteligentes se comuniquem com interfaces de usuário e agentes externos de forma fluida. Compreender como definir e emitir eventos pode aumentar significativamente a interatividade e a eficiência do seu dApp.
Nas próximas aulas, iremos aprofundar esses conceitos e explorar funcionalidades adicionais dentro do Solidity. Boa codificação!