Como monitorar eventos da blockchain com Node.js e EthersJS

Node.js

Como monitorar eventos da blockchain com Node.js e EthersJS

Luiz Duarte
Escrito por Luiz Duarte em 06/02/2023
Junte-se a mais de 34 mil devs

Entre para minha lista e receba conteúdos exclusivos e com prioridade

Muitas vezes em aplicações web nós enviamos uma requisição para um servidor e ela levará um tempo considerável para ser processada. Quando não sabemos quanto é esse tempo e não podemos manter a conexão ativa até receber uma resposta sob risco de timeout temos de pensar em alternativas. A alternativa mais simples e ineficiente é fazer “pulling”, uma técnica que consiste em criar um timer e ficar fazendo requisições ao servidor pedindo por atualizações. A melhor alternativa é buscar ser avisado pelo servidor de algum forma quando o processamento acabar, geralmente envolvendo websockets ou webhooks.

Na programação para blockchain temos este mesmo problema elevado à enésima potência uma vez que o processamento em nós da rede é caro e geralmente lento, ao menos nas redes mais famosas como a Ethereum. Mesmo que esteja usando uma rede mais barata como a BNB Smart Chain (BSC) ou Polygon, ainda enfrentará esse dilema de como saber que um processamento terminou sem ficar consultando várias vezes a blockchain?

Neste universo em específico a solução é monitorar/escutar por eventos específicos nos smart contracts aguardando por novidades e é isso que vamos explorar no tutorial de hoje, usando a biblioteca EthersJS e a tecnologia Node.js. Caso queira ver o mesmo tutorial, mas com a lib web3.js, use este link.

Curso Web3 para Iniciantes

#1 – Eventos em Solidity

O primeiro ponto é entender como os eventos em Solidity funcionam, assumindo aqui que você estará trabalhando com blockchains baseadas em Ethereum/EVM. Quando estamos programando nossos smart contracts nós podemos usar um keyword event para declarar um evento, como abaixo retirado de um contrato de token ERC-20.

Este evento Transfer é declarado no contrato e indica que ele pode ser monitorado/escutado por alguém conectado à blockchain. Agora para que o evento aconteça de fato, seja disparado, o programador do smart contract deve usar a keyword emit em alguma função do contrato, como abaixo, retirado do mesmo contrato ERC-20.

Assim, quando chamamos emit Transfer, nós enviamos um registro de evento para a blockchain que será incluído junto aos logs do bloco minerado e qualquer sistema que esteja monitorando este evento em específico será avisado, como uma carteira de criptomoedas por exemplo.

Um último ponto ainda sobre eventos no Solidity é que você pode querer escutar os eventos de uma carteira específica, ao invés de ficar escutando qualquer transferência que acontecer. Isso é possível através do uso da keyword indexed como mostrado acima, onde tanto o from quanto o to podem ser usados como filtro no monitoramento para receber apenas eventos de um from ou de um to específicos. Importante frisar que o uso da keyword indexed aumenta o custo de gás das transações que emitirem este evento, além do que existe um limite de até 3 variáveis indexed por evento apenas, então use com parcimônia.

Apesar do exemplo acima ser bem comum, envolvendo tokens e transferências, você pode criar o evento que quiser para qualquer finalidade. Por exemplo, se tiver um smart contract de uma dex (exchange descentralizada), você pode querer ter um evento para quando um trade é realizado entre dois traders, como abaixo.

Repare que este evento não tem nada a ver com o anterior, seus campos são completamente diferentes. E aí, na função que faz o trade acontecer de fato, você emite este evento para avisar quem quer que esteja monitorando este evento neste contrato.

Dito isso, agora que você entendeu como os eventos são declarados e emitidos nos contratos é hora de entender como monitoramos eles em nossas aplicações web.

#2 – Monitorando eventos no backend

Existem duas bibliotecas para criar aplicações Web3 no mercado que realmente valem a pena ser citadas: a Web3.js e a EthersJS. Neste tutorial usarei a segunda por ser mais moderna.

Para nosso exemplo de aplicação web frontend eu usarei Node.js, que é uma tecnologia muito usada em backend para Web3. Mesmo sem conhecimento algum de Node.js você pode criar um projeto simples usando o comando abaixo na sua máquina, dentro de uma pasta criada para guardar o projeto (a minha chamei de nodejs-event-ethers).

Depois, entre na pasta do projeto e vamos instalar as bibliotecas EthersJS e dotenv que vamos usar.

Agora com tudo preparado, vamos criar uma funcionalidade no backend (crie um arquivo index.js) que espera pelo evento de transferência de um token. Para que você consiga simular esse teste é importante que você já tenha publicado um contrato seu na blockchain, a fim de poder interagir com ele de forma a causar o disparo do evento que estará monitorando. Eu estarei usando este contrato de token ERC-20 que publiquei na BSC Testnet.

Importe a biblioteca Ethers no topo do arquivo index.js junto do carregamento do dotenv (que vamos configurar logo mais).

Para receber eventos da blockchain é importante que você tenha uma conexão de websockets com um full node. Felizmente hoje é dia é muito fácil conseguir acesso a um usando provedores de blockchain as a service como Infura, Moralis, Ankr, Quicknode e outros que fornecem um acesso limitado gratuito aos mesmos. No meu caso que tenho o contrato publicado na BSC Testnet  vou usar a Quicknode neste exemplo que é um dos provedores que fornecem nós para BSC. Se vai publicar na Ethereum ou Sepolia, pode usar a Infura por exemplo. Apenas crie uma conta no provedor da sua preferência e use o nó gratuito para obter a URL do servidor de websockets que será necessário mais abaixo.

Essa URL, bem como o endereço do seu contrato na blockchain devem ser colocados por segurança em um arquivo .env na raiz do seu projeto, que não deve ser versionado, como abaixo.

Com as importações realizadas e variáveis de ambiente posicionadas, vamos escrever a função dentro do index.js que fará o monitoramento e tratamento do evento depois de recebido.

Começamos a função carregando um objeto WebSocketProvider com a URL do servidor de websockets. Depois declaramos um objeto de filtro que é a parte mais importante do listening de eventos. Nele definimos o endereço do contrato a ser monitorado (address) e os tópicos que queremos escutar, sendo que devem ser passados no formato Evento(params) sem qualquer espaço pois a função ethers.utils.id vai converter a string para o identificador único do evento.

Uma vez configurado esse filtro, usamos o mesmo para configurar o gatilho com a função on, que irá disparar a função de callback passada como segundo parâmetro toda vez que as condições do filtro forem atingidas.

Agora rode a sua aplicação com ‘node index.js’ e conseguirá testar facilmente desde que consiga simular a situação que emitirá o evento. Com isso finalizamos nosso exemplo de backend.

E com isso finalizamos o nosso tutorial de como monitorar eventos da blockchain com Web3.js, espero que tenha lhe ajudado!

TAGS:

Olá, tudo bem?

O que você achou deste conteúdo? Conte nos comentários.

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *