O desenvolvimento de smart contracts requer um controle de qualidade muito apurado, mais que o normal na indústria de software. Isso devido a inúmeras razões mas posso citar duas principais: a primeira porque na imensa maioria dos casos os smart contracts lidam com dinheiro de outras pessoas, trazendo uma semelhança com a área financeira, onde atuei por vários anos, e segundo porque os smart contracts são imutáveis, ou seja, depois que colocar em produção, não tem como modificar nada no código deles.
Assim, não é incomum que o pipeline de desenvolvimento e testes envolva diversas iterações ou etapas de testes, que começam com a escrita e execução dos testes unitários, tarefa que toolkits como Truffle e HardHat (clique nos links para ver os tutoriais) nos ajudam bastante pois eles são integrados ao framework de testes Mocha. Mas esta é apenas a primeira etapa dos testes. Assim que todos os testes unitários do seu smart contract estejam passando, é hora de fazermos deploy dele em uma blockchain de teste e testarmos nela, para ter algo mais próximo do ambiente real onde o contrato irá operar.
Atualmente todas as redes blockchain possuem nós de teste que os desenvolvedores podem usar para subir os seus contratos e fazerem testes, como se fossem ambientes de homologação. No entanto, assim como outros ambientes de homologação nós não temos muita gestão sobre o ambiente e suas configurações, nos deixando bem limitados durante testes mais exploratórios importantes durante o desenvolvimento. Fora que ficar toda hora subindo o seu contrato para uma testnet é lento e lhe consome recursos, mesmo que sejam moedas fakes.
Por isso, é imprescindível em projetos mais importantes, que não sejam apenas didáticos, que você tenha uma rede própria, de preferência local, para testar seu projeto. Isso é possível rodando um nó na sua máquina, seja com as ferramentas oficiais para full nodes reais como o Geth, ou com implementações mais simplificadas e voltadas apenas para simulação como o Ganache, que vamos estudar hoje ou a HardHat Network, vista nesse outro post.
#1 – O Ganache
O Ganache, segundo seu próprio site oficial, serve para rapidamente subir uma blockchain Ethereum pessoal que você pode usar para rodar testar, executar comandos e inspecionar o estado enquanto controla como ela opera. No link que forneci antes você consegue baixar a última versão do Ganache para o seu sistema operacional e facilmente colocar ele para funcionar já que a instalação é bem direta e exige apenas que avance até o final.
Antes de você avançar, talvez tenha reparado na URL dele que o Ganache faz parte da suíte de ferramentas do Truffle, projeto da ConsenSys, famosa empresa do mundo blockchain responsável por produtos de sucesso como MetaMask e Infura. No entanto, o Ganache é um software independente e gratuito, você não precisa estar usando outros produtos e projetos da mesma empresa, embora ele funcione muito melhor em projetos Truffle. Assim, certifique-se de baixá-lo do site oficial e instale-o apenas avançando até o final.
Quando executá-lo a primeira vez, você irá se deparar com a tela inicial que lhe questiona se você quer inicializar rapidamente um novo nó, com as configurações default, ou se deseja inicializar personalizando as configurações. Recomendo a primeira opção.
Assim que ele terminar a criação da sua blockchain Etehereum pessoal, você terá acesso a uma tela similar a essa abaixo, que vamos explorar brevemente juntos.
O Ganache tem como principal funcionalidade simular uma blockchain Ethereum na sua máquina e permitir a exploração e customização da mesma. Então logo de cara você tem acesso a algumas áreas como accounts, blocks, transactions, etc que são justamente funcionalidades idênticas às que você encontra em exploradores de blocos como EtherScan e BSCScan. Mais do que isso, essa rede criada no Ganache já vem como dezenas de contas pré-criadas, com 100 Ether de saldo em cada uma, facilitando muito na hora dos testes, basta escolher uma na área de accounts e usar, sendo que no ícone da chave, bem à direita, você tem acesso à private key de cada uma delas e no topo a frase mnemônica fica sendo exposta.
Outro ponto forte do Ganache é que a mineração de blocos é automática. Então se você enviar uma transação para ele, o resultado será praticamente instantâneo, lhe poupando muito tempo nos testes (15-30 segundos por transação). Por padrão você vai ter o bloco gênese e os demais serão minerados conforme a necessidade, sem qualquer intervenção sua.
Enfim, para todos efeitos o Ganache irá agir como sendo uma rede Ethereum, inclusive permitindo o deploy de smart contracts.
#2 – Deploy de Smart Contract
Para fazer deploy de um smart contract no Ganache você deve enviar uma transação de criação do mesmo, depois de codificá-lo, algo bem simples de fazer usando toolkits como Truffle e HardHat (tutorial de deploy nos links deles). No caso do Truffle por exemplo, basta incluir no truffle-config.js uma nova network apontada para o Ganache, como abaixo (os dados você pega na interface do Ganache).
1 2 3 4 5 6 7 8 9 |
networks: { ganache: { host: "127.0.0.1", port: 7545, network_id: "5777" } }, |
Depois que o truffle-config.js estiver devidamente configurado, hora de revisar a migration do seu contrato e rodar o comando de migração escolhendo a network correta.
1 2 3 |
truffle migrate --network ganache |
Assim, seu contrato terá o deploy realizado no Ganache, sendo facilmente observado na aba de Blocks, acessando o novo bloco minerado e vendo a transação de criação de contrato lá.
Uma coisa bacana que tem no Ganache é a capacidade de inspecionar o estado do contrato, na aba Contracts. Vá até lá e vincule o arquivo truffle-config.js do seu projeto Truffle e verá que você consegue ver todos os estados do contrato assim que ele já tiver sido feito o deploy. Infelizmente não tem como interagir com o contrato nesta tela, assim como fazemos no EtherScan e BSCScan, mas imagino que no futuro eles irão evoluir neste sentido.
Por enquanto, para que possamos interagir com contratos ou mesmo com as configurações da rede do Ganache, temos de fazer isso via JSON RPC ou ferramentas que usem este protocolo.
#3 – JSON RPC
Se você olhar logo abaixo das categorias do topo verá um resumo do estado da blockchain, incluindo bloco atual, preço do gás, versão da rede, id da rede e algo importantíssimo que é o endereço do RPC Server. Isso porque o Ganache seria praticamente inútil se não tivesse implementado as APIs no padrão JSON RPC, que é o padrão usado pelos nós Ethereum reais.
É através de chamadas JSON RPC que toda a comunicação com o Ganache irá acontecer e antes de fazermos isso usando ferramentas mais amigáveis, convém uma rápida prática usando JSON RPC diretamente. Isso é possível usando o playground Open RPC neste link. Este site funciona como se fosse um Postman, simulando requests e exibindo responses, mas focado no mundo JSON RPC. Assim, podemos facilmente testar qualquer rede bastando colar o endereço do RPC Server dela na aba de testes, como abaixo, onde colei o endereço do meu Ganache.
Para abrir essa aba de testes, selecione um dos muitos métodos RPC na listagem da direita, como o eth_gasPrice, que é bem simples de usar e use o botão “Try It Now”. Na aba de testes, você tem à esquerda o payload da request e no lado direito, a resposta da sua requisição. A fim de exemplo, cole a URL do seu servidor RPC do Ganache (geralmente HTTP://127.0.0.1:7545) e no lado esquerdo revise se a chamada do gasPrice está como abaixo.
1 2 3 4 5 6 7 8 |
{ "jsonrpc": "2.0", "method": "eth_gasPrice", "params": [], "id": 0 } |
Esta é uma função bem simples que não espera parâmetros e retorna o preço do gás atualmente na rede, como abaixo.
1 2 3 4 5 6 7 |
{ "jsonrpc": "2.0", "result": "0x4a817c800", "id": 0 } |
Repare que o valor parece incompreensível, isso porque ele está em hexadecimal. Para trazê-lo para o padrão decimal que estamos acostumados, copie o valor do result e cole-o em algum site que converta hexadecimal para decimal e terá o resultado do gás price em wei, a menor fração do Ethereum. Se quiser converter de Wei para Ether ou GWei, use algum site que converta Wei para Ether.
Outra chamada simples de fazer via JSON RPC e que ajuda a mostrar o funcionamento do Ganache é a eth_getBalance, que serve para retornar o saldo de uma conta da sua rede. Diferente do eth_gasPrice, esta chamada exige a passagem de parâmetros no array params, sendo o primeiro o endereço da conta e o segundo qual bloco será usado como referência (latest significa o último). Copie um endereço de conta do seu Ganache para colocar no lugar do meu abaixo.
1 2 3 4 5 6 7 8 9 10 11 |
{ "jsonrpc": "2.0", "method": "eth_getBalance", "params": [ "0x5002f43d58F4cF76F4d659DD055110149a3beBf2", "latest" ], "id": 0 } |
Como resultado você terá o saldo desta conta, em hexadecimal. Pode converter para decimal e terá o valor em wei.
1 2 3 4 5 6 7 |
{ "jsonrpc": "2.0", "result": "0x56b616246e66b3800", "id": 0 } |
Nos dois exemplos acima nós fizemos calls para a blockchain do Ganache, que são chamadas somente de leitura. Embora seja perfeitamente possível fazer transactions usando JSON RPC e invocação de contratos, é um processo extremamente trabalhoso e inviável de fazermos desta forma. Para usar de fato o Ganache em nossos testes geralmente não o fazemos via JSON RPC, mas sim via alguma carteira cripto, como MetaMask, ou via Truffle Console, que usam por sua vez o JSON RPC por “baixo dos panos”.
#4 – Carteira de Criptomoedas
Uma vez que o Ganache simula uma rede Ethereum perfeitamente, é possível usar qualquer carteira compatível com Ethereum com ele, como a MetaMask por exemplo. Em outra oportunidade eu já falei bastante sobre MetaMask e ensinei como criar uma gratuitamente. Assista ao vídeo abaixo caso queira aprender.
Após criar a sua MetaMask você pode apontar ela para a rede que quiser, desde que seja compatível com Ethereum. Assim, para apontarmos a nossa MetaMask para nosso Ganache, abra a sua MetaMask e acesse a área de redes no menu superior, que por padrão estará apontado para Mainnet Ethereum. Selecione a opção “adicionar rede” nesse menu.
Vai se abrir uma tela com várias opções de rede, mas Ganache não estará na lista, então use a última opção “Add a network manually”. Agora sim, você poderá preencher o formulário com os dados do seu Ganache, como abaixo.
- Nome da Rede: Ganache
- Novo URL do RPC: HTTP://127.0.0.1:7545
- ID da Cadeia: 1337
- Símbolo da Moeda: ETH
Agora que você tem a rede do Ganache cadastrada na sua MetaMask, você pode selecionar ela no menu superior de redes, o que será um pouco decepcionante já que vai aparecer que você possui 0 ETH na conta.
Para que você possa usar uma das contas criadas pelo Ganache na MetaMask, basta selecionar a account que quiser no Ganache e ir na opção de chaves que fica à direita, copiando a chave privada. Agora volte à MetaMask, clique no ícone da sua conta na direita e depois em “Importar Conta”, sendo que basta informar a sua Private Key da account do Ganache para que sua conta seja adicionada à MetaMask e com isso consiga ver seu saldo e interagir com qualquer dapp que esteja usando o seu Ganache como blockchain usando sua carteira.
Este é um jeito especialmente útil de fazer seus testes se estiver testando um dapp, que possua frontend se comunicando com smart contracts que estejam no seu Ganache.
No entanto, se você tem apenas o contrato, o caminho é usar o Truffle Console.
#5 – Truffle Console
E por fim, outra opção que você tem de se comunicar com contratos provisionados no Ganache é usando um CLI chamado Truffle Console. Quando você instala o Truffle globalmente na sua máquina você passa a ter o comando abaixo disponível, que abre um REPL JavaScript com a biblioteca web3.js disponível na memória e recursos demais recursos do Truffle.
Rode o comando abaixo na pasta do projeto Truffle para iniciar o Truffle Console.
1 2 3 |
truffle console |
Uma vez com o Truffle Console iniciado, você pode carregar a instância do seu contrato instalado na blockchain com o comando abaixo, como se estivesse programando JS no console. Obviamente troque “SeuContrato” pelo nome do seu smart contract.
1 2 3 |
let contract = await SeuContrato.deployed(); |
Agora, a partir da linha seguinte você pode usar qualquer função do seu contrato apenas chamando a mesma, como faria em um dapp. Apenas atente ao fato de que todas funções são async e que deve usar await para pegar o retorno delas de maneira apropriada. Esta instância é a mesma que está provisionada no Ganache, então se fizer chamadas a funções que sejam transações, elas serão enviadas ao Ganache e irão alterar o estado do mesmo, o que é excelente para testes manuais de contratos em ambiente local.
No exemplo abaixo, chamo uma função count que existe no meu contrato.
1 2 3 |
const qty = await SeuContrato.count(); |
E com isso abordamos as principais funcionalidades e formas de interagir com o Ganache, tanto para o deploy quanto para os testes de smart contracts usando esta incrível ferramenta.
Até a próxima!
Olá, tudo bem?
O que você achou deste conteúdo? Conte nos comentários.