SwiftHTML & CSSSolidityDesenvolvimento de JogosSolana/Rust
17.11.2024

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

  1. 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-chave indexed permite que o parâmetro eleitor seja pesquisável nas consultas de log.

  2. 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.
  3. Construtor: O construtor inicializa o contrato adicionando dois candidatos.

  4. 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 o contadorVotos 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 evento VotoRegistrado. Quando o evento é emitido, a função de retorno de chamada é acionada e fornece parâmetros, como eleitor e candidatoId.

Benefícios de Usar Eventos

  1. Eficiência: Eventos são mais baratos que operações de armazenamento em termos de taxas de gás.
  2. Alertas: Facilitam respostas em tempo real às ações do usuário.
  3. 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!

Video

Did you like this article? Rate it from 1 to 5:

Thank you for voting!