Quanto mais desenvolvimento de contrato inteligente tivermos, maior será a necessidade de ter kits de ferramentas de desenvolvimento que possam ajudar os desenvolvedores a implementar, testar e implantar com facilidade e rapidez. No que diz respeito aos kits de ferramentas de desenvolvimento de blockchain, muitas vezes ouvimos falar de Truffle e Hardhat, no entanto, a Opensea acaba de lançar uma nova versão de seu contrato inteligente chamado seaport, que é inicializado usando o Foundry.
O que é exatamente Foundry?
Foundry é um kit de ferramentas de desenvolvimento de contrato inteligente que gerencia suas dependências, compila seu projeto, executa testes, implementa e permite que você interaja com a cadeia a partir da linha de comando.
O Foundry é rápido em comparação com outros kits de ferramentas de desenvolvimento de contratos inteligentes, pois é escrito em Rust. O recurso mais interessante do Foundry é, na verdade, sua capacidade de permitir que os desenvolvedores implementem seus testes no Solidity e é altamente personalizável.
Instalação
Se você estiver usando Linux ou macOS, execute o seguinte comando:
curl -L <https://foundry.paradigm.xyz> | bash
Isso fará o download do foundryup. Em seguida, instale o Foundry executando:
foundryup
Se você usa o Windows, precisa compilar a partir do código-fonte para obter o Foundry.
Baixe e execute rustup-init de rustup.rs. Ele iniciará a instalação em um console.
Depois disso, execute o seguinte para criar o Foundry a partir da fonte:
cargo install --git <https://github.com/foundry-rs/foundry> foundry-cli anvil --bins --locked
Inicialização do projeto
Com o Foundry instalado, podemos criar nosso projeto executando este comando no diretório preferencial onde precisamos manter o projeto:
forge init foundry-project
Após rodar o comando acima, deverá gerar um projeto com a seguinte estrutura:
foundry-project
├─ lib
│ └─ forge.std
├─ src
│ └─ Contract.sol
├─ script
│ └─ Contract.s.sol
├─ test
│ └─ Contrat.t.sol
└─ foundry.toml
Como podemos ver, o projeto é gerado com alguns diretórios, o diretório lib contém todas as dependências necessárias para o projeto, é semelhante a um node_modules. O diretório src mantém a implementação do contrato inteligente, o script armazena scripts de solidity que podem ser usados para a implantação, o diretório test contém todos os arquivos de teste e, por último, o arquivo foundry.toml é usado para manter a configuração do projeto.
Implementação do projeto
Vamos implementar um contrato inteligente básico, pois este tutorial se trata de uma introdução. Então vamos criar o arquivo Counter.sol dentro da pasta src e adicionar os seguintes códigos:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
contract Counter {
address owner;
int private count;
constructor (int _count){
owner = msg.sender;
count = _count;
}
function getCount () public view returns (int) {
return count;
}
function incrementCount () public {
require(msg.sender == owner, "Unauthorized");
count++;
}
function decrementCount () public {
require(msg.sender == owner, "Unauthorized");
count--;
}
}
Neste trecho de código, basicamente implementamos o contrato de contador que contém um construtor que inicializa owner & count e também possui três funções para obter, incrementar e decrementar o contador, no qual apenas o proprietário pode incrementar ou decrementar.
O projeto pode ser construído para gerar a ABI usando o seguinte comando:
forge build
Implementação do teste
Vamos criar o arquivo de teste chamado Counter.t.sol no diretório test com os seguintes casos de teste:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import "forge-std/Test.sol";
import "src/Counter.sol";
contract CounterTest is Test {
Counter counter;
function setUp() public {
counter = new Counter(2);
}
function testGetCount() public {
int value = counter.getCount();
assertEq(value, 2);
}
function testIncrementCount() public {
counter.incrementCount();
int value = counter.getCount();
assertEq(value, 3);
}
function testIncrementCountFail() public {
vm.prank(address(0));
vm.expectRevert("Unauthorized");
counter.incrementCount();
}
function testDecrementCount() public {
counter.decrementCount();
int value = counter.getCount();
assertEq(value, 1);
}
function testDecrementCountFail() public {
vm.prank(address(0));
vm.expectRevert("Unauthorized");
counter.decrementCount();
}
}
Antes de tudo estamos importando o forge-std.Test.sol que encapsula um conjunto de funções utilitárias necessárias para escrever o teste e fizemos o mesmo com o Counter.sol que é o contrato inteligente que está sendo testado.
Em seguida, estamos configurando nosso teste inicializando nosso contrato inteligente de contador com 2 como valor padrão. Estamos aproveitando a função AssertEq vinda do forge-std.Test.sol para comparar se o valor retornado após a chamada da função getCount é igual ao passado durante a inicialização.
Você pode ver no cenário de falha do teste, estamos usando novas palavras-chave como vm.prank e vm.expectRevert, essas funções referem-se a códigos de trapaça no Foundry, eles são usados para manipular o ambiente de teste para obter situações da vida real.
A função vm.prank() é usada para definir msg.sender para o endereço especificado para a próxima chamada. Estamos literalmente usando isso aqui para mudar o proprietário. E a vm.expectRevert ajuda a interceptar uma situação de falha, passando a mensagem de erro exata.
Depois de executar o comando forge test, você poderá obter o seguinte resultado:
Implantação do Projeto
Para implantar nosso contrato inteligente, precisamos renomear Contract.s.sol para Counter.s.sol e adicionar o conteúdo abaixo:
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import "forge-std/Script.sol";
import { Counter } from "src/Counter.sol";
contract CounterScript is Script {
function run() public {
vm.startBroadcast();
new Counter(2);
vm.stopBroadcast();
}
}
O script possui a função run que será chamada para executar a implantação. A vm.startBroadcast cria transações que podem ser assinadas e enviadas posteriormente na cadeia e a vm.stopBroadcast interrompe a coleta de transações para transmissão posterior na cadeia.
Antes de executar o script que irá implantar nosso contrato inteligente na testnet BSC, vamos adicionar o arquivo .env no diretório raiz do projeto, contendo as seguintes chaves:
BSC_RPC=https://data-seed-prebsc-1-s2.binance.org:8545
PRIVATE_KEY=A chave privada de sua carteira
Agora podemos executar o seguinte comando para dar acesso shell às nossas variáveis env:
Em seguida, executamos o comando de implantação
forge create --rpc-url $BSC_RPC --private-key $PRIVATE_KEY script/Counter.s.sol:CounterScript
Em caso de implantação bem-sucedida, você deve obter a seguinte saída no terminal:
Conclusão
O framework Foundry ainda pode ser uma novidade no espaço web 3, porém já chamou a atenção de grandes empresas como a Opensea por todas as vantagens que oferece, a começar pela velocidade, customização e capacidade de escrever testes em Solidity. Será exagero afirmar que superará outras ferramentas de desenvolvimento de contatos inteligentes, mas vale a pena ficar de olho no seu desenvolvimento.
Este tutorial cobre apenas os fundamentos. Para saber mais sobre o Foundry, acesse a documentação oficial.
Esse artigo é uma tradução feita por @bananlabs. Você pode encontrar o artigo original aqui





Oldest comments (0)