Uma das coisas mais comuns para dar segurança aos investidores e usuários de protocolos na blockchain é a verificação de contratos. Basicamente a verificação é o processo de, através de um explorador de blocos, expor o código fonte do contrato para análise de terceiros, no melhor estilo open-source. Ou seja, qualquer pessoa do mundo poderá olhar o seu código, entender como ele funciona e verificar se possui algo malicioso ou não.
Além disso, ao ter o seu contrato verificado em block explorers como a EtherScan (e derivadas), você tem acesso a uma interface gráfica que permite usar o contrato ali mesmo, no próprio block explorer, o que é muito útil principalmente na etapa de desenvolvimento, quando estamos fazendo o primeiro deploy fora do ambiente local e colocando em uma testnet.
Sendo assim, nesse tutorial eu vou mostrar como fazer a verificação de um contrato no block explorer EtherScan (mas também funciona para derivados) que você acabou de fazer deploy, utilizando o toolkit HardHat, um dos mais populares para projetos de smart contracts atualmente. Caso nunca tenha usado HardHat antes, neste tutorial eu começo a ensinar sobre ele.
Se preferir, pode assistir ao vídeo abaixo ao invés de ler.
Vamos lá!
#1 – Verificando contrato em rede suportada
Primeiro eu quero falar do processo mais simples possível, que é verificar um smart contract que esteja provisionado em uma blockchain nativamente suportada pelo HardHat. O comando abaixo lista quais elas são, se a sua não estiver na lista, pule para a parte 2 deste tutorial, mais abaixo.
1 2 3 |
npx hardhat verify --list-networks |
No meu caso eu usarei a testnet da rede BSC (BNB Smart Chain) pois ela fornece full node público, o que facilita nosso setup, além de possuir taxas baixas, mas o processo é o mesmo em todas redes suportadas. Para não deixar seu projeto fixado para esta única rede, minha recomendação é que instale o pacote DotEnv:
1 2 3 |
npm install dotenv |
E crie um arquivo .env na raiz do seu projeto HardHat, a fim de configurarmos as variáveis de ambiente que apontem para a rede em questão. Abaixo, configurações para ree BSC Testnet, configure de acordo com sua rede (várias redes listadas aqui).
1 2 3 4 5 6 |
SECRET=<12 palavras> RPC_URL=https://data-seed-prebsc-1-s1.binance.org:8545/ CHAIN_ID=97 API_KEY=<explicarei depois> |
Agora vá no seu hardhat.config.ts, importe o pacote dotenv e use das variáveis dele para configurar sua rede (se você já fez o deploy via HardHat, talvez não tenha apenas a parte etherscan no final):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
import { HardhatUserConfig } from "hardhat/config"; import "@nomicfoundation/hardhat-toolbox"; import dotenv from "dotenv"; dotenv.config(); const config: HardhatUserConfig = { solidity: "0.8.24", networks: { bsctest: { url: process.env.RPC_URL, chainId: parseInt(`${process.env.CHAIN_ID}`), accounts: { mnemonic: process.env.SECRET } } }, etherscan: { apiKey: process.env.API_KEY } }; export default config; |
Repare que temos 3 configurações aqui: solidity, networks e etherscan. A primeira diz respeito à compilação. A segunda diz respeito às redes configuradas para o seu projeto e a última é que mais nos importa aqui, pois diz respeito à verificação do contrato. Apesar do nome da propriedade ser etherscan, ela funciona para qualquer block explorer baseado em EtherScan (como o BSCScan e outros), então não dê bola para o nome.
Para verificar seu contrato em uma rede suportada, a única coisa que irá precisar nessa configuração etherscan é a API Key do block explorer, que deverá ser configurada no .env. Para obter uma é simples e gratuito: vá no block explorer, crie uma conta nele e dentro da conta crie uma API Key. Apenas atente-se de fazer esse processo no site de produção do block explorer, não pode ser nas versões testnet. Por exemplo, no meu caso, independente se fiz deploy na BSC Testnet ou Mainnet, a chave de API deve ser obtida em bscscan.com (mainnet). De posse dessa Api Key, vá no seu .env e adicione essa chave lá, na respectiva variável.
Com tudo devidamente configurado agora você pode ir no terminal e rodar o script de verificação, usando o endereço do contrato que acabou de fazer o deploy (sem <…>). Repare como o nome da minha rede é bsctest, pois assim defini no hardhat.config.ts, talvez a sua tenha outro nome.
1 2 3 |
npx hardhat verify --network bsctest <contrato> |
Depois de algum tempo que pode demorar dado o tamanho do seu contrato e o congestionamento da rede, ele irá aparecer como verificado no site da BSC Scan, com um ícone de check verde ao lado da aba contract, como na imagem abaixo. Tudo estando certo a sua aba Contract da tela do contrato agora irá lhe fornecer as opções de “Read Contract” e “Write Contract”, respectivamente as operações públicas possíveis de leitura e de escrita, este último incorrendo em taxas de rede (gas fee). Atenção ao link de Reset no canto direito, ele é importante para atualizar a página pois ela não o faz automaticamente.
Para as operações de escrita você precisará pagar as taxas de rede e para isso precisará de uma carteira, certo? O site BSC Scan (e derivados) também se integra com a MetaMask, basta clicar no link “Connect to Web3” que fica com uma bolinha vermelha na esquerda, até que a conexão seja feita e você autorize o dapp BSC Scan na sua carteira quando solicitado.
Você então pode usar os botões azuis fornecidos para invocar as propriedades e funções públicas do contrato, fazendo seus testes em produção. Caso queira ver como ficou o meu, confira neste link. Mais tarde, você pode fazer testes usando algum dapp criado por você, como os que eu ensino a criar neste tutorial aqui pegando o ABI gerado no BSC Scan.
#2 – Verificação em redes não suportadas: SnowTrace
Se você tiver um erro no momento da verificação em virtude da falta de suporte à rede que você usou, pode ser necessário a configuração manual da sua rede no HardHat Config. Uma rede popular não suportada na data que escrevo este tutorial é a Avalanche SnowTrace.
Depois que tiver feito o deploy na Avax, você deve configurar a private key da sua wallet (tem de ser a private key da carteira que fez o deploy e não pode ser a frase mnemônica) como uma variável de ambiente do sistema operacional. Para isso você pode usar um dos dois comandos abaixo, conforme seu sistema operacional:
1 2 3 4 5 6 7 |
//windows SET PRIVATE_KEY=xxxx //unix/linux/mac export PRIVATE_KEY=xxxx |
Depois, você deve configurar o seu hardhat.config.ts para o SnowTrace, como abaixo. Repare como uso uma sessão nova da configuração etherscan, chamada customChains, que serve justamente para adicionar suporte a redes nativamente não suportadas:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
import { HardhatUserConfig } from "hardhat/config"; import "@nomicfoundation/hardhat-toolbox"; import dotenv from 'dotenv'; dotenv.config(); const config: HardhatUserConfig = { solidity: "0.8.24", networks: { avaxtest: { url: 'https://api.avax-test.network/ext/bc/C/rpc', accounts: [`${process.env.PRIVATE_KEY}`] }, }, etherscan: { apiKey: { snowtrace: "snowtrace", // deixe qualquer coisa, não é usado }, customChains: [ { network: "snowtrace", chainId: 43113, urls: { apiURL: "https://api.routescan.io/v2/network/testnet/evm/43113/etherscan", browserURL: "https://testnet.snowtrace.io" } } ] }, sourcify: { enabled: false } }; export default config; |
Note que a configuração acima é para Testnet. Se quiser as configs de produção da Avax, pegue na documentação oficial.
Agora basta rodar o comando de verificação normalmente, como abaixo.
1 2 3 |
npx hardhat verify <contract address> --network avaxtest |
Pronto, contrato verificado!
#2 – Verificação em redes não suportadas: Amoy e outras redes
Se você tiver um erro no momento da verificação em virtude da falta de suporte à rede que você usou, pode ser necessário a configuração manual da sua rede no HardHat Config. Uma rede popular não suportada na data que escrevo este tutorial é a Polygon Amoy.
Depois que tiver feito o deploy na Amoy você deve configurar o seu hardhat.config.ts para a Amoy, como abaixo. Repare como uso uma sessão nova da configuração etherscan, chamada customChains, que serve justamente para adicionar suporte a redes nativamente não suportadas:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
import dotenv from "dotenv"; dotenv.config(); import { HardhatUserConfig } from "hardhat/config"; import "@nomicfoundation/hardhat-toolbox"; const config: HardhatUserConfig = { solidity: "0.8.24", networks: { amoy: { url: process.env.RPC_URL, chainId: parseInt(`${process.env.CHAIN_ID}`), accounts: { mnemonic: process.env.SECRET } } }, etherscan: { apiKey: { amoy: `${process.env.API_KEY}` }, customChains: [ { network: "amoy", chainId: parseInt(`${process.env.CHAIN_ID}`), urls: { apiURL: "https://api-amoy.polygonscan.com/", browserURL: "https://amoy.polygonscan.com" } } ] } }; export default config; |
Note que a configuração acima é para Testnet. Agora basta rodar o comando de verificação normalmente, como abaixo.
1 2 3 |
npx hardhat verify <contract address> --network amoy |
Pronto, contrato verificado!
Olá, tudo bem?
O que você achou deste conteúdo? Conte nos comentários.