Como migrar projetos do Ethers v5 para Ethers v6

Cripto

Como migrar projetos do Ethers v5 para Ethers v6

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

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

Hoje no mercado de programação web3 existem duas bibliotecas que são muito utilizadas em projetos JavaScript, quer seja no frontend, seja no backend: a mais antiga Web3.js e a mais moderna EthersJS. E assim como tivemos uma grande evolução que quebrou muita coisa quando a Web3.js saiu da sua versão 1 para a v2, aconteceu o mesmo recentemente com a Ethers mudando da v5 para v6.

Escrevo este post da maneira que eu gostaria de ter encontrado na Internet quando precisei atualizar aplicações da Ethers 5 para Ethers 6 e espero que lhe ajude também. Algumas mudanças são sutis e possivelmente você já resolveu sozinho, outras são mais grosseiras mesmo e afetam principalmente usuários de TypeScript, que é mais sensível a estas mudanças de tipos. Não é para ser um post extenso e ao mesmo tempo ele deve ser atualizado ao longo do tempo, conforme vou aprendendo mais sobre EthersJS v6.

Se preferir, o vídeo abaixo possui praticamente o mesmo conteúdo.

Curso Node.js e MongoDB

Mudanças da v5 para v6

A maior parte das mudanças são simples, pois correspondem a mudanças na estrutura de pastas da biblioteca. De fato até a versão 5 eu sentia a biblioteca um tanto verbosa e com um uso excessivo da pasta utils, sendo esta uma das principais mudanças: não tem mais a pasta utils. Tudo que estava na utils agora está direto ethers.x. Ou seja:

O mesmo vale para os providers. Antes tínhamos de especificar o caminho passando por providers, agora não é mais necessário, chamamos os providers diretamente a partir do objeto ethers.

Falando em providers, outra mudança que me impactou foi a mudança de nome do Web3Provider para BrowserProvider. Confesso que ficou um excelente nome, já que ele serve justamente para integração com as carteiras de browser como metaMask (saiba mais sobre aqui), mas ainda assim é uma breaking change que afetou meus projetos aqui. Então se juntarmos a alteração anterior e essa, teremos:

Ainda no âmbito dos providers é a alteração da função provider.getSigner, usada para nos prepararmos para assinar transações para a blockchain. Antes, a função getSigner era sync, agora ela é async e retorna uma promise, então cuidado com isso pois sabemos que interfere bastante no fluxo de execução (saiba mais sobre async aqui).

Além disso, além dessa mudança para pegar o signer do provider, para quem usa TypeScript tivemos algumas mudanças de type definitions que afetam a integração com Smart Contracts. Como esse, do ABI de um contrato que antes era ContractInterface e agora é InterfaceAbi.

E certamente devem ter outros types que mudaram, esse é um dos que eu fui impactado em meus projetos.

Um último ponto que mudou drasticamente quebrando compatibilidade são as chamadas estáticas. Chamadas estáticas permitem enviar transações para a blockchain sem pagar pelos seus custos, mas também não sendo persistidas, como se fossem chamadas “fake” ou de teste. Veja o antes e depois das static calls no Ethers.

Além do próprio nome mudar de callStatic para staticCall, mudou o local onde ela deve ser chamada, de antes da função do contrato para depois da mesma.

Números Gigantes

Agora saindo dos providers, vamos falar de números gigantes ou Big Numbers/Big Ints. Antes a biblioteca ethers usava uma biblioteca de terceiros para representação de números gigantes no JavaScript (biblioteca BigNumber), algo extremamente necessário no contexto de criptomoedas onde é comum ter números astronômicos na faixa de 18 dígitos. Como JavaScript possui suporte a bigint nativamente desde a versão 2020 da linguagem, era uma questão de tempo até que as bibliotecas começassem a se adaptar e foi isso o que aconteceu com o Ethers na sua versão 6.

A primeira coisa que você deve fazer é, se estiver usando TypeScript, alterar no tsconfig.json para que a versão-alvo do Ecmascript (target) seja a es2020, que tem suporte a bigint. Isso vai te permitir, além de usar o tipo bigint, usar a notação 1n, onde 1 é o numeral e ‘n’ indica que este é um número gigante (bigint), sendo tratado em memória de maneira diferente ao number tradicional.

Agora as alterações de BigNumber para o novo padrão devem ser feitas da seguinte forma: primeiro, na tipagem via TS (types ou interfaces), quando você tinha um campo gigante usava BigNumber, agora deve usar BigNumberish, que oferece um suporte mais flexível, incluindo ao bigint nativo.

No entanto, uma vez que você use o novo tipo BigNumberish e abandone de vez a lib BigNumber usada na v5 em prol do bigint nativo da v6, você deverá mudar as funções de conversão que você usava, como por exemplo as que convertem para número gigante:

E o contrário também vale, quando você tem um BigNumberish e quer devolver para number (nos casos em que isso é possível, é claro):

E por enquanto estas são as alterações que tive de fazer em meus projetos e que resolvi compartilhar com vocês, para ajudá-los na atualização dos seus. Espero ter ajudado e até a próxima!

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 *