Recentemente escrevi alguns tutoriais sobre como criar Smart Contracts usando a linguagem Solidity e a suíte HardHat, você confere um olá mundo neste link e um CRUD neste link. Uma coisa que não ensinei na ocasião é que é extremamente importante é o processo de deploy do seu smart contract na blockchain e este é o objetivo do tutorial de hoje.
O processo de fazer deploy consiste da compilação do seu contrato em bytecodes que possam ser interpretados pela EVM (Ethereum Virtual Machine) e envio esses bytecodes para um provedor distribuir aos nós da rede. Durante os tutoriais anteriores testamos tudo usando testes unitários automatizados e deploy em uma rede interna do HardHat, de testes. Agora, para enviar a um nó de blockchain existem várias formas mas a que escolhi para este tutorial aqui é usando a carteira de criptomoedas MetaMask.
Se preferir, pode assistir ao vídeo abaixo ao invés de ler.
Atenção: esse tutorial utiliza HardHat Ignition para o deploy. Se estiver procurando aprender a usar scripts HardHat, use este outro tutorial.
#1 – Preparando a Carteira
Já falei extensivamente da MetaMask, a principal carteira cripto de browser do mundo, tanto aqui no blog quanto no meu canal, sendo que se você não possui uma ainda, use o vídeo abaixo para aprender como criar e configurar a sua, é gratuita.
Usaremos a MetaMask para o pagamento da taxa de rede (gas fee) necessária ao deploy e envio dos bytecodes para o provider dela, que distribuirá nosso código pela rede. Um ponto importante a considerar é em qual rede você fará o seu deploy. Eu usarei aqui a Sepolia, que é uma rede de testes da Ethereum. Isso porque ela já vem configurada na MetaMask, bastando apenas habilitar as redes de teste em Settings > Advanced, como mostra a imagem abaixo.
Para poder fazer o deploy temos de ter saldo para pagar as taxas. Você consegue obter saldo de teste para Sepolia neste Faucet PoW. Só colocar o endereço da sua carteira e mandar rodar por alguns minutos. Enquanto isso, certifique-se de deixar a rede de testes selecionada como principal na sua MetaMask (repare no canto superior esquerdo da sua carteira) para que nosso desenvolvimento seja realizado em cima dela a fim de não gastarmos fundos com os testes. Em seguida copie o endereço da sua carteira de testes, que fica logo abaixo do nome da sua conta.
Agora com saldo na carteira e ela apontada para a Sepolia, podemos avançar para o deploy em si.
#2 – Fazendo o Deploy
Uma vez que sua carteira esteja devidamente configurada no seu browser, volte ao VS Code para fazermos o deploy. Você vai precisar da frase mnemônica da sua carteira MetaMask, a fim de que o deploy seja todo automatizado usando HardHat. Esta frase são aqueles famosas 12 palavras secretas que você recebe quando cria a sua carteira e muito cuidado com ela pois quem a tiver tem controle total sobre sua carteira.
Vamos salvar estas palavras em um arquivo .env na raiz do projeto com duas variáveis SECRET e RPC_NODE, sendo que este arquivo não deve ser versionado então é de bom tom colocá-lo no .gitignore caso esteja usando Git. Para que possamos usar arquivos .env para configurações do projeto instale a dependência do DotEnv no projeto.
1 2 3 |
npm i dotenv |
Crie o arquivo .env, preencha a variável SECRET com sua frase mnemônica e para a variável RPC_NODE precisamos de um endereço público da rede Sepolia. Você pode obter um gratuitamente se cadastrando na Infura.io, um serviço de blockchain em nuvem da mesma empresa criadora da MetaMask, a Consensys. Após terminar e validar seu cadastro (não é necessário cartão de crédito), pegue a URL do nó Sepolia e coloque no seu .env.
Agora é importante você entender que o script que vai fazer o deploy do seu contrato na blockchain é o BookDatabase.ts que deve existir na pasta ignition/modules. Crie ele se não existir e coloque o seguinte conteúdo que vou explicar na sequência.
1 2 3 4 5 6 7 8 9 10 11 12 |
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; const BookDatabaseModule = buildModule("BookDatabaseModule", (m) => { const contract = m.contract("BookDatabase"); return { contract }; }); export default BookDatabaseModule; |
Esse script importa a função buildModule do HardHat Ignition, que é o utilitário de deploy do HardHat. Com essa função, passamos o nome do nosso módulo de deploy (m) e utilizamos dele para instanciar um contrato (contract) passando o nome do contrato Solidity que está na pasta contracts, retornando o mesmo após finalizar o processo.
Agora, vamos nos focar no seu hardhat.config.ts. Por padrão estávamos usando uma rede default de teste e agora devemos apontar para a rede onde faremos o deploy, configurando corretamente os dados do nosso nó RPC, que obtivemos na Infura. Os demais dados você pode pegar abaixo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import { HardhatUserConfig } from "hardhat/config"; import "@nomicfoundation/hardhat-toolbox"; import dotenv from 'dotenv'; dotenv.config(); const config: HardhatUserConfig = { solidity: "0.8.24", networks: { sepolia: { url: process.env.RPC_NODE, chainId: 11155111, accounts: { mnemonic: process.env.SECRET } } } }; export default config; |
Repare que o .env está sendo carregado logo no início para que process.env.SECRET possa ser chamado mais tarde. Repare também no ChainID, que é específico para Sepolia. Se quiser, pode colocar o Chain Id da rede no .env também, a fim de não deixar nenhuma configuração diretamente no código.
Com isso, estamos com tudo configurado para o deploy e para fazê-lo de fato, basta rodar o comando abaixo do HardHat em nosso projeto.
1 2 3 |
npx hardhat ignition deploy ignition/modules/BookDatabase.ts --network sepolia |
Este comando vai compilar o seu script definido no ignition/modules/BookDatabase.ts, vai assinar a transação usando sua carteira MetaMask e vai enviar os bytecodes nessa transação para a blockchain configurada no hardhat.config.ts. Ao término de todo o processo, você terá as informações do deploy bem sucedido, como abaixo.
Para conferir se a transação foi um sucesso basta você pegar o hash que recebeu e ir conferir no site da sepolia.etherscan.io. Colando o endereço/hash do seu contrato você verá se o deploy dele já foi finalizado e todos os detalhes das transações que já aconteceram com esse contrato.
Quando a transação de deploy estiver marcada como concluída/bem sucedida o seu contrato já está live na blockchain, ou seja, pode ser usado normal e publicamente por qualquer pessoa que possua o endereço dele, invocando todas as funções e propriedades públicas do mesmo.
Você vai notar que na pasta ignition foi criada uma pasta deployments também. Certifique-se de colocar ela também no gitignore pois não é necessário versioná-la.
Bônus: Contratos com Dependências
Mas e se o seu contrato possui dependências, ou seja, outros contratos que você precisa fazer deploy em determinada ordem? Isso é perfeitamente possível de fazer com HardHat Ignition também, como abaixo, onde faço deploy de um contrato Condominium e depois de um CondominiumAdapter, que precisa do primeiro.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules"; const CondominiumModule = buildModule("CondominiumModule", (m) => { const condominium = m.contract("Condominium"); const adapter = m.contract("CondominiumAdapter", [], { after: [condominium], }); m.call(adapter, "upgrade", [condominium]); return { condominium, adapter }; }); export default CondominiumModule; |
E de quebra, repare como ainda chamo uma função do adapter com o comando call do módulo (m), passando o objeto que eu quero chamar a função, o nome da função e o array de parâmetros dela (aqui eu passei um objeto de contrato que será resolvido como um endereço).
Um próximo passo possível é você verificar o seu contrato no block explorer, o que ensino neste tutorial.
Até a próxima!
Olá, tudo bem?
O que você achou deste conteúdo? Conte nos comentários.