Como migrar projetos Truffle para HardHat

Cripto

Como migrar projetos Truffle para HardHat

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

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

Atualizado em 28/03/24!

No dia 21 de setembro de 2023 a ConsenSys, empresa responsável por produtos e serviços web3 como MetaMask, Infura e Truffle anunciou que estará encerrando o desenvolvimento e suporte deste último até o final deste ano (leia aqui). Já fazia algum tempo que a suíte Truffle vinha perdendo adesão na comunidade em virtude do crescimento e vantagens significativas do seu maior concorrente, HardHat. E é justamente essa a recomendação da ConsenSys para todos que ainda possuem projetos Truffle, que sejam migrados para HardHat até o final do período do suporte.

Então se esse é o seu caso, esse tutorial vai te ajudar nessa migração.

Usarei como exemplo fontes de projetos Truffle que eu ensinei a desenvolver aqui mesmo no blog e que você encontra abaixo.

Você não precisa ter feito nenhum desses tutoriais para conseguir acompanhar o que vou ensinar, mas deve conhecer o básico de Truffle e de HardHat, sendo que este último eu ensino neste tutorial.

Se preferir, pode assistir ao vídeo abaixo ao invés de ler o artigo, com exceção a parte de deploy, que neste artigo está mais atualizado (o HardHat mudou recentemente).

Vamos lá!

Truffle x HardHat

A primeira coisa que você precisa entender são as principais diferenças entre Truffle x HardHat. Entendendo essas diferenças você vai perceber os gaps que terá de estudar e a necessidade de alterações nos códigos mais gritantes.

Em termos do smart contract em si, é importantíssimo se tranquilizar pois nada muda, já que ambas trabalha com Solidity. Um problema a menos aqui nas suas migrações. O mesmo vale para ambiente de desenvolvimento, já que ambas são toolkits para Node.js. A única dica é que se você usa as extensões Truffle ou Solidity (Juan Blanco) no VS Code, eu recomendo que troque para a extensão da própria HardHat (NomicLabs).

A primeira grande diferença que você tem de entender é que Truffle era um toolkit focado em JS, enquanto que HardHat foca-se em TypeScript. Isso significa que se você ainda não aprendeu TypeScript que deve fazê-lo o quanto antes, não apenas pela exigência do HardHat em si mas pelo mercado como um todo, que cada vez mais usa esse superset. Você pode aprender sobre TS nesta série de tutoriais aqui do blog.

A segunda grande diferença é que Truffle usa como lib web3 a Web3.js, enquanto que HardHat usa a EthersJS. A Web3.js já foi líder incontestável de mercado, mas isso foi há algum tempo. A EthersJS a cada versão tem se mostrado uma lib mais madura, elegante e também muito mais focada em TypeScript, o que nos leva de volta ao ponto citado anteriormente. Essa diferença talvez seja a mais significativa de todas, já que isso impacta todo o resto. Você pode aprender sobre EthersJS neste e em outros tutoriais aqui do blog.

Uma terceira diferença, não tão significativa mas que impacta especialmente nos testes é que o Truffle/Web3.js (nas últimas versões) usam a lib BN.js para números gigantes, que aliás são muito comuns em contratos blockchain, enquanto que o HardHat/Ethers nas versões mais recentes (Ethers 6+) usam o tipo BigInt nativo do ECMAScript 2020 suportado pelo TypeScript, o que garante economia no tamanho da lib, maior compatibilidade com outras libs TS e menor curva de aprendizado em seu uso.

Depois desses dois pontos divergentes, todo o resto das diferenças é mais cosmético e os exemplos de código a seguir, embora não cubram 100% dos casos, vão te dar fôlego para migrar a maior parte dos projetos.

Curso Node.js e MongoDB

Migrando os Testes do Truffle para HardHat

Ambos toolkits utilizam o Jest como framework de testes, mas com variações no plugin de asserções, o que nos leva a lógicas de completamente iguais na forma de dividir e codificar os testes, mas “expects” diferentes. Além disso, as diferenças entre Web3.js e EthersJS também se fazem notar por aqui. Para não ficar apenas na teoria, vamos começar apresentando o contrato que vou usar como case de estudo, neste caso um CRUD de livros abaixo, sendo que omiti o conteúdo das funções pois são irrelevantes do ponto de vista deste estudo.

Em Truffle, os testes para este contrato seriam:

Vejamos como ficavam os testes com Truffle, inicialmente apenas a preparação dos testes, para comparamos por partes.

Repare como usamos artifacts.require para carregar o contrato e antes de cada teste (beforeEach) nós usamos a função new para criar uma cópia “nova” dele. Agora veja a lógica semelhante usando HardHat.

À primeira vista, pode parecer que o HardHat é mais trabalhoso ou mais complexo, visto que a quantidade de código é maior, certo?

O que acontece aqui é que no Truffle temos muitas coisas implícitas como a variável contract, o deploy do contrato, várias libs e outros. Enquanto no HardHat nós temos um controle maior de todo o processo através do conceito de fixtures, que são funções para deploy que você configura para os testes, como se fossem presets. Essa função de fixture roda apenas uma vez e depois seu resultado é carregado “limpo” no início de cada teste (loadFixture, veremos mais adiante), servindo não apenas para inicializar o contrato rapidamente como para obter carteiras de teste e outras questões.

Já o teste em si, não é tão diferente assim, apenas a asserção mesmo, onde o assert do Truffle:

Vira expect no HardHat (repare que sem o beforeEach, temos de chamar o loadFixture no início de cada teste):

Agora mais um teste, desta vez de obtenção de um livro já salvo no smart contract. Primeiro em Truffle:

E depois em HardHat:

Repare como é praticamente a mesma coisa, o que muda é que na versão Truffle o carregamento do contrato ficou lá no beforeEach.

Mais um, agora o teste de edição em Truffle

E em HardHat. Aqui existe uma leve variação mas por decisão do programador em separar melhor as duas asserções, pois poderia ter sido testada apenas em uma linha também.

E por fim, o último teste, de exclusão, no Truffle.

E no HardHat. Aqui notamos mais um ponto diferente em virtude das abordagens de cada lib para impersonalização de chamadas à blockchain. Enquanto que na Web3.js nós temos um array implícito de accounts com contas de teste, no HardHat essas contas são provenientes da fixture também, recebendo variáveis para cada uma. E aqui também podemos notar a diferença no tratamento de números gigantes, onde a BN.js do Truffle não é tratada nativamente no JS, mas os números gigantes do HardHat são nativos do TS.

Existem mais diferenças do que essas, mas já dá pra ter uma ideia. Um bom ponto de partida é você explorar a página de testes do HardHat onde eles descrevem algumas funcionalidades muito bacanas como auditoria de cobertura de código, auditoria de consumo de gás, avanço da blockchain no tempo (para testes time-based) e muito mais.

Curso Beholder
Curso Beholder

Migrando o Deploy do Truffle para HardHat

Agora vamos falar de deploy, que é um elemento onipresente em todos projetos de smart contracts.

Na pasta migrations do Truffle encontramos algo como abaixo, para o mesmo contrato de CRUD de livros que mostrei acima.

Enquanto que em HardHat nós temos a pasta ignition/modules:

À primeira vista, a função de deploy do Truffle é mais simples e de fato ela é. No caso do HardHat ele usa uma feature chamada Ignition, que é uma forma declarativa de realizar o deploy, baseada na instanciação e manipulação de contratos.

Lembrando que, para que um deploy em Truffle funcione, é necessário configurar no truffle-config.js o compilador, a rede (que depende de plugin de terceiros) e a verificação do contrato (que também depende de outro plugin). Exemplo abaixo:

Olhe como fica a mesma configuração no arquivo hardhat.config.ts do HardHat:

Nesse ponto o HardHat é mais enxuto uma vez que não depende de plugins adicionais a serem instalados para tarefas como deploy e verificação de contrato.

Fugindo um pouco do código e indo para ambiente, se você estava acostumado a usar o Ganache como blockchain de testes/desenvolvimento, recomendo já ir se acostumando mais com a HardHat Network, que abordo neste post.

E estes foram os principais pontos que você precisa saber para migrar um projeto de smart contract Truffle para HardHat. Salvo funcionalidades bem específicas, ambos toolkits são bem parecidos, ficando as maiores diferenças por conta de JS x TS e Web3.js x EthersJS mesmo.

Um ponto importante, digno de ser citado, é que independente da “morte” do Truffle em alguns meses, a lib Web3.js segue forte e sendo interessante de ser estudada, principalmente para projetos de dapps (frontend). Isso se deve principalmente ao fato de que ela não é desenvolvida pela ConsenSys, mas pela ChainSafe

Um abraço 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 *