WEB3DEV

Cover image for Iniciante em Web3: Como usar o Foundry para testar um contrato ERC20 com Fuzzing
Diogo Jorge
Diogo Jorge

Posted on • Atualizado em

Iniciante em Web3: Como usar o Foundry para testar um contrato ERC20 com Fuzzing

Este artigo foi escrito por Pari Tomar, e traduzido por Diogo Jorge. O artigo original pode ser encontrado aqui

Contexto

Se você é novo no mundo da web3 e do desenvolvimento de contratos inteligentes, está com sorte. Comparado com alguns anos atrás, desenvolver um Contrato Inteligente é muito mais fácil. Até recentemente, a única ferramenta disponível para desenvolver o Contrato Inteligente era o Truffle . Posteriormente surgiu a famosa ferramenta Builder que hoje é conhecida como Hardhat ( link para seu rebranding).

Apenas algumas semanas atrás, fizemos um artigo comparando Hardhat e Truffle e o que você pode usar hoje para desenvolver Contratos Inteligentes com mais rapidez e eficiência: Hardhat ou Truffle? Como um desenvolvedor de blockchain iniciante, qual devo escolher.

Surge uma nova ferramenta: Foundry

Depois de lançar o artigo acima mencionado, grande parte do nosso público se aproximou de nós solicitando que também abordássemos o Foundry. O Foundry como uma ferramenta para o desenvolvimento de contratos inteligentes é nova no cenário, e foi introduzida apenas em dezembro de 2021. Embora o Foundry tenha apenas 6 meses, ele ganhou muito reconhecimento como uma das ferramentas mais rápidas para testar contratos inteligentes.

O foco deste artigo

Este artigo não trata dos benefícios de usar o Foundry, para isso você pode consultar este artigo: Apresentando a caixa de ferramentas de desenvolvimento Foundry Ethereum ; o foco deste artigo está em:

  1. Como você pode usar o Foundry para testar um contrato inteligente ERC20 padrão e
  2. Como você pode implantar contratos inteligentes ERC20 em uma rede de testes usando o Foundry.

Nota de agradecimento

Antes de nos aprofundar no Foundry, gostaríamos de estender uma enorme nota de agradecimento ao nosso autor convidado: Akshay (acessível no Twitter , LinkedIn e Medium ), sem cujos excelentes esforços isso não teria sido possível. Ele é a figura central por trás de tudo o que documentamos abaixo.

Instalação

Para usuários de Linux e Mac , basta executar o seguinte comando

curl -L https://foundry.paradigm.xyz | bash

Em seguida, execute o comando foundryup para instalar o Foundry em seu sistema local.

Isso instalará foundryup, a ferramenta que o ajudará a instalar forge (forja), cast (fundição), e anvil (bigorna): os três pilares da fundição para o desenvolvimento completo de contratos inteligentes.

Embora cada uma dessas 3 ferramentas sejam independentes, com toda a honestidade, você usará todas essas 3 juntas para desenvolver seus contratos inteligentes e testá-los com mais rapidez e eficiência.

Para o software operacional Windows, a instalação é um pouco diferente. Siga os seguintes passos:

  1. Baixe Rust:- https://www.rust-lang.org/tools/install
  2. Execute o arquivo exe baixado
  3. Escolha 1 instalação padrão

Seu terminal do Windows deve ficar assim:

Image description

Posteriormente, execute o seguinte:

load install --git https://github.com/foundry-rs/foundry foundry-cli anvil --bins --locked

Observe que o Microsoft Visual Studio deve ser instalado em seu Windows antes de executar o comando acima.

Codificação, Codificação e Codificação 💻

Sem perda de tempo, vamos entrar na codificação. Agora, nosso objetivo é focar nos pontos fortes de teste “fuzzing” do Foundry e, portanto, para esse fim, escolhemos um exemplo de contrato inteligente de um token ERC20.

Passo 1: Crie uma pasta com qualquer nome que você preferir ou nossa sugestão: foundryFirstSteps onde você preferir em seu laptop/desktop/fera de codificação ;)

Etapa 2: Abra o terminal, cd para foundryFirstSteps e execute o seguinte comando:

forge init

Você deve ver algo assim na sua tela:

Image description

Etapa 3: Abra esta pasta no VSCode ou em seu editor de código preferido. A estrutura de diretórios desta pasta deve se parecer com isto:

Image description

Um rápido resumo da estrutura de diretórios:

  1. A pasta lib é como a usina de fundição. Esta é a pasta mais importante que você precisa em seu projeto.

Você é mais do que bem-vindo para fazer um tour por esta pasta em particular, no entanto, recomendamos que você não brinque muito com ela, pois você não sabe o que pode danificar e isso afetará toda a nossa experiência de codificação.

2.Fora isso você tem 2 pastas principais , uma sendo source ou src e a outra sendo scripts . Vamos realizar o desenvolvimento do contrato inteligente na pasta src.

Etapa 3: crie um novo arquivo de contrato inteligente na pasta src com o nome: MyToken.sol e copie o seguinte no arquivo:

// SPDX-License-Identifier: 
UNLICENSED pragma solidity ^0.8.13;

import "openzeppelin/contracts/token/ERC20/ERC20.sol";

contract MyToken é ERC20{

   construtor (string memory _name, string memory _symbol) ERC20 (_name,_symbol){
   }

   function mint(address to, uint256 amount) public virtual {
       _mint(to,amount);
   }

   function burn(address form, quantidade uint) public virtual {
       _burn(form, amount);
   }
}
Enter fullscreen mode Exit fullscreen mode

Como você notará, este é um contrato inteligente ERC20 bem comum e não há nada muito elaborado neste contrato.

Etapa 4: Para instalar o openzeppelin-contracts em nosso repositório de fundição [já que este não é o método node_modules], você precisará executar o seguinte comando:

forge install openzeppelin/openzepplin-contracts

Além disso, você terá que criar um arquivo com o nome remappings.txt e depois em remappings.txt, colocar esta linha

ds-test/=lib/forge-std/lib/ds-test/src/
forge-std/=lib/forge-std/src/
openzeppelin-contracts/=lib/openzeppelin-contracts/

Isso diz ao Forge: “Ei, sempre que você clicar em openzepplin/, procure em lib/openzeppelin-contracts/.”

Etapa 5: testes (o núcleo de todo este artigo)

  • Na sua pasta de teste já existe um arquivo com o nome Contract.t.sol; você pode excluí-lo ou excluir seu conteúdo e renomeá-lo para MyToken.t.sol; porque vamos criar nosso próprio arquivo de teste e executar esses testes.
  • Agora, vamos passar por todos os itens de teste, um a um, para que você tenha o melhor domínio sobre eles:
  • Configuração:

Image description

  • Importando o arquivo mais importante da pasta lib: Test.sol. Este arquivo será o canivete suíço que executará os testes que iremos codificar. É extremamente importante que você importe esse arquivo corretamente. Qualquer erro na importação deste arquivo fará com que nossos testes não funcionem.
  • Em seguida, estaremos importando nosso contrato MyToken.sol; ou qualquer que seja o nome do arquivo que você tenha escolhido para o seu contrato.

Algumas configurações básicas de variáveis:

  1. Endereço alice e Endereço bob . Como você notará, estamos chamando uma função VM para o propósito desta definição.
  2. VM é importada de VM.sol; através do Test.sol e sua importação Script.sol
  3. O nome deve ser um brinde: é a sigla para Virtual Machine.sol;
  4. Agora, se você seguir a função addr, perceberá algo muito, muito importante. Esta função retorna o endereço de um determinado conjunto de chaves privadas.

Alerta de Aprendizagem!!!

A opção de definir um signatário ou um endereço através de chave privada no Hardhat é configurada através do hardhat.config.js; O Foundry não tem nenhum foundry.config.ts. Portanto, a capacidade de criar um signatário e fazer transações de um determinado endereço é configurada diretamente no arquivo de teste.

Seguindo a definição dos signatários, temos a configuração que irá implantar o contrato com o nome e símbolo de nossa escolha e então testar se o nome e símbolo estão configurados corretamente.

  • Testes básicos:

Image description

Não vamos perder seu tempo explicando os testes acima. Os testes acima são bastante simples e autoexplicativos.

Como você deve ter notado, usamos 'assertTrue' e 'assertEq' alternadamente. Aqui está um guia rápido para o que é o que.

assertTrue -> use isso quando sua função de teste retornar um valor bool

assertEq -> Use isso quando sua função de teste retornar uint,address,string

Execute os testes usando o comandoforge test

Se você receber alguma mensagem de erro, tente executar o comando RUST_BACKTRACE=1 forge test para definir a variável de ambiente Rust backtrace como false.

Portanto, sua saída deve ser semelhante a:

Image description

  • Testes de nível avançado:

Image description

Prank: Sem julgar a escolha da palavra aqui, segue o que ela significa:

  1. vm.prank(endereço) → isso garantirá que a chamada feita logo após essa linha seja feita de um endereço específico; isso é bastante semelhante ao Hardhat onde fazemos uma chamada de contrato inteligente usando a função.connect(address)
  2. vm.startPrank(address) → [semelhante ao vm.prank acima] nesta função todas as chamadas que fiz após esta linha serão feitas a partir desse endereço específico, a menos quevm.StopPrank seja chamado

Em palavras simples, podemos alterar arbitrariamente o valor do msg.sender via Prank, startPrank e stopPrank.

  • Testes de falha:

Image description

Novamente, não vamos perder seu tempo explicando também os testes acima; pois estes são muito simples e auto-explicativos. A única coisa única acima é que esses testes verificarão e confirmarão que a transação de blockchain para as funções testadas está falhando e não sendo bem-sucedida.

Teste de Fuzz

Como mencionado acima, uma das maiores vantagens de usar o Foundry para desenvolvimento de contratos inteligentes é o recurso de teste Fuzz que é construído dentro do Foundry. Agora, lembre-se de que não é que o teste do Fuzz não possa ser realizado durante o desenvolvimento de contrato inteligente por meio do Truffle ou do Hardhat; a única coisa é que ele não está embutido como um recurso nessas ferramentas e também que é difícil obter fuzzing para testar contratos inteligentes usando JS (JavaScript). Aprendendo com o Foundry, alguns usuários do Hardhat solicitaram que a Hardhat org analisasse esse recurso: https://github.com/NomicFoundation/hardhat/issues/2136

Image description

Acima está uma amostra do teste fuzz que fizemos no contrato de teste.

Em programação e desenvolvimento de software, fuzzing ou teste fuzz é uma técnica de teste de software automatizada que envolve o fornecimento de dados inválidos, inesperados ou aleatórios como entradas para um programa de computador.

Fonte: Wikipédia

Em uma simples leitura do referido acima, você perceberá que os testes acima são voltados para a inserção de valores aleatórios em nossos testes. Esses testes são para descobrir os casos extremos nos testes.

Por padrão, o fuzzing executará cada caso de teste 256 vezes com entradas aleatórias. Se você quiser aumentar as execuções, basta adicionar fuzz_runs = <inputNumber> em foundry.toml.

Todo o código acima está aqui: Link para o GitHub. ☁️ 💻 🔗

Você é mais do que bem-vindo para usar a base de código existente. Infelizmente, o Foundry ainda está em desenvolvimento e, portanto, é provável que você tenha contra-tempos. Mas não se preocupe, estamos a apenas um tweet de distância, marque-nos em @uv_labs e trabalharemos com você para resolver o ocorrido.

Se você gosta do nosso trabalho, por favor: (a) siga nossa publicação: https://medium.com/uv-labs e (b) nos dê uma estrela 🙏.

Autores (aberto a comentários): 👇

Amateur-Dev , Akshay Tarpara e Pari Tomar

Latest comments (0)