WEB3DEV

Cover image for Como Usar o Dapptools | Código Como MakerDAO
Panegali
Panegali

Posted on • Atualizado em

Como Usar o Dapptools | Código Como MakerDAO

Aprenda a usar o Dapptools, a estrutura de implantação de contrato inteligente para desenvolvedores web3 que amam Bash e a linha de comando. Analisamos o aprendizado desta estrutura de implantação de blockchain de ponta a ponta.

1 dapp.tools

MakerDAO é um dos maiores protocolos DeFi existentes, sendo a stablecoin DAI uma das mais utilizadas na indústria. Sua equipe usa um framework especial chamado dapptools para criar, implantar, testar e interagir com seus contratos inteligentes.

Criado pela equipe do Dapphub, o framework dapptools é uma ferramenta minimalista amigável ao bash que qualquer usuário avançado do Linux facilmente se apaixonará, e muitos já o fizeram.

2 Transmissions11 exclamando entusiasmo ao dapptools

Também é incrivelmente amigável para iniciantes, portanto, se esta é sua primeira olhada em um framework de implantação, você veio ao lugar certo. Neste artigo, vamos mostrar como fazer o seguinte com o dapptools:

  1. Escrever e compilar contratos
  2. Contratos de teste com solidity e fuzzing
  3. Implantar contratos
  4. Interagir com contratos implantados

Vamos usar nosso dapptools-demo que configuramos para aprender sobre isso. Sinta-se livre para pular lá para entrar. Se você quiser, você também pode conferir a ferramenta Foundry, que é uma reescrita do dapptools, mas escrita em rust pela equipe Paradigm.

Para um repositório mais completo, com mais código e bons exemplos, confira o dapptools-starter-kit, ele inclui exemplos de código usando a Chainlink!

Se você quiser apenas clonar o repositório para começar a usar ele, sinta-se à vontade para acompanhar o readme no repositório!

O vídeo sobre tudo isso será lançado em breve:

https://youtu.be/ZurrDzuurQs
Vídeo do Dapptools


Sumário

1 . Configurar

2 . Ambiente

3 . Requerimentos de instalação

4 . Crie um projeto local dapptools

5 . Executar testes

6 . Fuzzing

7 . Importação do Openzeppelin e contratos externos

8 . O Contrato NFT

9 . Remapeamentos

10 . Implantando em uma rede de teste

11 . Definir uma variável de ambiente

12 . Criar um remetente padrão

13 . Adicione sua chave privada

14 . Atualize seu Makefile

15 . Implemente o contrato

16 . Interagindo com contratos

17 . Verifique seu contrato no Etherscan

18 . E finalmente

19 . Recursos


Configurar

Ambiente

Primeiro, você precisará de um editor de código, sou um grande fã do VSCode. Se você estiver no Windows, precisará baixar o WSL, pois executaremos vários comandos do Windows.

Uma vez que você estiver usando o VSCode, abra um terminal para executar comandos para instalação, ou de qualquer maneira que você normalmente executa comandos de shell.

Requerimentos de instalação

  1. Git
  2. Make
  3. Dapptools

Primeiro, você precisará instalar o git, siga este link para instalá-lo. Você saberá que fez certo se puder executar:

git --version 
Enter fullscreen mode Exit fullscreen mode

Em seguida, você precisará ter certeza de ter o make instalado. A maioria dos computadores já vem com ele instalado, mas se não, confira estas perguntas sobre o assunto na rede Stack Exchange.

Em seguida, instale o dapptools. Certifique-se de ir para a documentação oficial para instalar, mas será algo como executar isto:

# usuário deve estar em sudoers
curl -L https://nixos.org/nix/install | sh

# Execute isso ou faça login novamente para usar o Nix
. "$HOME/.nix-profile/etc/profile.d/nix.sh"
curl https://dapp.tools/install | sh
Enter fullscreen mode Exit fullscreen mode

E você deve ter dapp, seth, ethsign, hevme alguns outros comandos que você pode executar agora!

Estas instruções só funcionam para sistemas baseados em Unix (por exemplo, MacOS)

Crie um projeto local dapptools

Para criar uma nova pasta, execute o seguinte:

dapp init
Enter fullscreen mode Exit fullscreen mode

Isso lhe dará um layout de arquivo básico que deve se parecer com isso:

.
├── Makefile
├── lib
   └── ds-test
       ├── LICENSE
       ├── Makefile
       ├── default.nix
       ├── demo
          └── demo.sol
       └── src
           └── test.sol
├── out
   └── dapp.sol.json
└── src
   ├── DapptoolsDemo.sol
   └── DapptoolsDemo.t.sol
Enter fullscreen mode Exit fullscreen mode

Makefile: Onde você coloca seus “scripts”. O Dapptools é baseado em linha de comando, e nosso makefile nos ajuda a executar comandos grandes com poucos caracteres.

lib: esta pasta é para dependências externas, como o Openzeppelin ou o ds-test.

out: para onde vai o seu código compilado. Semelhante à pasta build em brownie ou à pasta artifacts no hardhat.

src: é aqui que estão seus contratos inteligentes. Semelhante à pasta contracts em brownie e hardhat.

Executar testes

Para executar testes, você só precisará executar:

dapp test
Enter fullscreen mode Exit fullscreen mode

e você verá uma saída como:

Running 2 tests for src/DapptoolsDemo.t.sol:DapptoolsDemoTest
[PASS] test_basic_sanity() (gas: 190)
[PASS] testFail_basic_sanity() (gas: 2355)
Enter fullscreen mode Exit fullscreen mode

Fuzzing

Dapptools vem incorporado com ênfase em fuzzing. Uma ferramenta incrivelmente poderosa para testar nossos contratos com dados aleatórios.

Vamos atualizar nosso DapptoolsDemo.sol com uma função chamada play. Aqui está como nosso novo arquivo deve ficar:

// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.6;
contract DapptoolsDemo {
function play(uint8 password) public pure returns(bool){
       if(password == 55){
           return false;
       }
       return true;
   }
}
Enter fullscreen mode Exit fullscreen mode

E vamos adicionar um novo teste em nosso DappToolsDemo.t.sol que é compatível com fuzzing chamado test_basic_fuzzing. O arquivo então ficará assim:

// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.6;
import "ds-test/test.sol";
import "./DapptoolsDemo.sol";
contract DapptoolsDemoTest is DSTest {
   DapptoolsDemo demo;
function setUp() public {
       demo = new DapptoolsDemo();
   }
function testFail_basic_sanity() public {
       assertTrue(false);
   }
function test_basic_sanity() public {
       assertTrue(true);
   }
function test_basic_fuzzing(uint8 value) public {
       bool response = demo.play(value);
       assertTrue(response);
   }
}
Enter fullscreen mode Exit fullscreen mode

Agora podemos fornecer dados aleatórios ao nosso contrato e esperamos que ele dê um erro se nosso código fornecer o número 55. Vamos executar nossos testes agora com o sinalizador fuzzing:

dapp test  fuzz-runs 1000
Enter fullscreen mode Exit fullscreen mode

E veremos uma saída como:

+ dapp clean
+ rm -rf out
Executando 3 testes para src/DapptoolsDemo.t.sol:DapptoolsDemoTest
[PASS] test_basic_sanity() (gas: 190)
[PASS] testFail_basic_sanity() (gas: 2355)
[FAIL] test_basic_fuzzing(uint8). Counterexample: (55)
Run:
dapp test --replay '("test_basic_fuzzing(uint8)","0x0000000000000000000000000000000000000000000000000000000000000037")'
para testar este case novamente, ou 
depuração do dapp --replay '("test_basic_fuzzing(uint8)","0x0000000000000000000000000000000000000000000000000000000000000037")'
para depurá-lo.

Falha:

 Erro: Asserção falhada
Enter fullscreen mode Exit fullscreen mode

E nossos testes fuzzing detectaram o outlier! Corri 1000 trilhas diferentes para o nosso teste test_basic_fuzzing e encontrei o outlier 55. Isso é incrivelmente importante para encontrar os casos de uso aleatórios que quebram seus contratos nos quais você pode não ter pensado.

Importação do Openzeppelin e contratos externos

Digamos que queremos criar um NFT usando o padrão Openzeppelin. Para instalar contratos ou pacotes externos, podemos usar o comando dapp install. Precisamos nomear a organização do repositório GitHub e o nome do repositório a ser instalado.

Primeiro, precisamos confirmar nossas alterações até agora! O Dapptools traz pacotes externos como git submodules, então precisamos confirmar primeiro.

Execute:

git add .
git commit -m 'initial commit'
Enter fullscreen mode Exit fullscreen mode

Então, podemos instalar nossos pacotes externos. Por exemplo, para OpenZeppelin, usaríamos:

dapp install OpenZeppelin/openzeppelin-contracts
Enter fullscreen mode Exit fullscreen mode

Você deve ver uma nova pasta em sua pasta lib agora rotulada como openzeppelin-contracts.

O Contrato NFT

Crie um novo arquivo na pasta src chamado NFT.sol. E adicione este código:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
contract NFT is ERC721 {
   uint256 public tokenCounter;
   constructor () ERC721 ("NFT", "NFT"){
       tokenCounter = 0;
   }
function createCollectible() public returns (uint256) {
       uint256 newItemId = tokenCounter;
       _safeMint(msg.sender, newItemId);
       tokenCounter = tokenCounter + 1;
       return newItemId;
   }
}
Enter fullscreen mode Exit fullscreen mode

Se você tentar dapp build agora, você receberá um grande erro!

Remapeamentos

Precisamos informar ao dapptools que import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; está apontando para nossa pasta lib. Então criamos um arquivo chamado remappings.txt e adicionamos:

@openzeppelin/=lib/openzeppelin-contracts/
ds-test/=lib/ds-test/src/
Enter fullscreen mode Exit fullscreen mode

Em seguida, criamos um arquivo chamado .dapprc adicionamos a seguinte linha:

export DAPP_REMAPPINGS=$(cat remappings.txt)
Enter fullscreen mode Exit fullscreen mode

O Dapptools procura em nosso .dapprc por diferentes variáveis ​​de configuração, como hardhat.config.js no hardhat. Neste arquivo de configuração, dizemos a ele para ler a saída remappings.txt e usá-la como “remapeamentos”. Remapeamentos são como informamos nossas importações em solidity de onde devemos importar os arquivos. Por exemplo em nosso remapping.txt vemos:

@openzeppelin/=lib/openzeppelin-contracts/
Enter fullscreen mode Exit fullscreen mode

Isso significa que estamos dizendo ao dapptools que quando ele compila um arquivo e vê @openzeppelin/ em uma instrução de importação, ele deve procurar arquivos em lib/openzeppelin-contracts/. Então se fizermos

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
Enter fullscreen mode Exit fullscreen mode

Estamos realmente dizendo:

import "lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol";
Enter fullscreen mode Exit fullscreen mode

Então, para não compilarmos toda a biblioteca, precisamos adicionar o seguinte ao nosso arquivo .dapprc:

export DAPP_LINK_TEST_LIBRARIES=0
Enter fullscreen mode Exit fullscreen mode

Isto diz ao dapptools para não compilar tudo em lib quando executamos testes.

Implantando em uma rede de teste

Nota: Se você deseja configurar sua própria rede local, você pode executar dapp testnet.

Adicione .env ao seu arquivo .gitignore.

Se você ainda não tiver um, crie um arquivo .gitignore e apenas anexe esta linha dentro dele:

.env
Enter fullscreen mode Exit fullscreen mode

Por favor faça isso. Não vamos empurrar sua chave privada para git com este passo a passo (yee!), mas queremos adquirir o hábito de adicionar isto ao nosso .gitignore sempre! Isso ajudará a protegê-lo contra o envio acidental de variáveis ​​de ambiente para um repositório git público. Você ainda pode forçá-los, então tenha cuidado!

Definir uma variável de ambiente

Para implantar em uma rede de teste, precisamos de um nó blockchain. Uma escolha fantástica é o projeto Alchemy. Você pode obter um endpoint HTTP de rede de teste gratuito. Basta se inscrever para um projeto gratuito e clicar em view key (ou qualquer que seja o texto no momento) e você terá um endpoint HTTP!

Você pode escolher sua rede de teste e vai querer ficar bom em trabalhar com diferentes redes de teste. Eu escolheria um dos Faucets Chainlink, onde você pode obter a rede de teste LINK e ETH. Kovan ou Rinkeby serão ótimas escolhas, então qualquer uma funciona.

Se ainda não o fez, crie um arquivo .env e, em seguida, adicione seu endpoint ao arquivo .env. Será algo como:

export ETH_RPC_URL=http://alchemy.io/adfsasdfasdf
Enter fullscreen mode Exit fullscreen mode

Criar um remetente padrão

Obtenha uma carteira eth se ainda não tiver. Você pode ver instruções mais detalhadas para configurar uma Metamask aqui. Mas, idealmente, você obtém uma Metamask e, em seguida, obtém algum ETH da rede de teste das Faucets Chainlink. Em seguida, mude para a rede de teste com a qual está trabalhando. Sua metamask deve ser algo como:

mm Metamask

Uma vez que você tenha uma carteira, defina o endereço dessa carteira como uma variável de ambiente ETH_FROM.

export ETH_FROM=YOUR_ETH_WALLET_ADDRESS
Enter fullscreen mode Exit fullscreen mode

Além disso, se estiver usando o Kovan, financie sua carteira com ETH da rede de teste.

Adicione sua chave privada

NOTA: RECOMENDO ALTAMENTE O USO DE UMA METAMASK QUE NÃO TENHA DINHEIRO DE VERDADE PARA DESENVOLVIMENTO.

Se você enviar sua chave privada para um repositório público com dinheiro real, as pessoas podem roubar seus fundos.

Portanto, se você acabou de criar sua Metamask e está trabalhando apenas com fundos da rede de teste, está seguro.

O Dapptools vem com uma ferramenta chamada ethsign, e é aqui que vamos armazenar e criptografar nossa chave. Para adicionar nossa chave privada (necessária para enviar transações) pegue a chave privada da sua carteira e execute:

ethsign import
Enter fullscreen mode Exit fullscreen mode

Em seguida, ele solicitará que você adicione sua chave privada e, em seguida, uma senha para criptografá-la. Isso criptografa sua chave privada em ethsign. Você precisará da sua senha sempre que quiser enviar uma transação para o futuro. Se você executar o comando ethsign ls e receber uma resposta como:

0x3DF02ac6fEe39B79654AA81C6573732439e73A81 keystore
Enter fullscreen mode Exit fullscreen mode

Você fez certo.

Atualize seu Makefile

O comando que podemos usar para implantar nossos contratos é dapp create DapptoolsDemo e depois alguns sinalizadores para adicionar variáveis ​​de ambiente. Para facilitar nossas vidas, podemos adicionar nosso comando de implantação a um Makefile, e apenas dizer ao Makefile para usar nossas variáveis ​​de ambiente.

Adicione o seguinte ao nosso Makefile

-include .env
Enter fullscreen mode Exit fullscreen mode

Implemente o contrato

Em nosso Makefile, temos um comando chamado deploy, que será executado dapp create DapptoolsDemo e incluirá nossas variáveis ​​de ambiente. Para executá-lo, basta executar:

make deploy
Enter fullscreen mode Exit fullscreen mode

E você será solicitado a fornecer sua senha. Uma vez bem-sucedido, ele implantará seu contrato!

criar dapp DapptoolsDemo
++ seth send --create 608060405234801561001057600080fd5b50610158806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c806353a04b0514610030575b600080fd5b61004a60048036038101906100459190610096565b610060565b60405161005791906100d2565b60405180910390f35b600060378260ff161415610077576000905061007c565b600190505b919050565b6000813590506100908161010b565b92915050565b6000602082840312156100ac576100ab610106565b5b60006100ba84828501610081565b91505092915050565b6100cc816100ed565b82525050565b60006020820190506100e760008301846100c3565b92915050565b60008115159050919050565b600060ff82169050919050565b600080fd5b610114816100f9565b811461011f57600080fd5b5056fea264697066735822122004d7143940853a7650f1383002b6ba56991e7a5c7d763e755774a149ca0465e364736f6c63430008060033 'DapptoolsDemo()'
seth-send: warning: `ETH_GAS' não definido; utilizando a quantidade de gás padrão
Senha de conta Ethereum (não refletida): seth-send: 
Transação publicada com 376 bytes de calldata.
seth-send: 0xeb871eee1fa31c34583b63002e2b16a0252410b5615623fd254b1f90b67369d4
seth-send: Aguardando o recebimento da transação........
seth-send: Transação incluída no bloco 29253678.
0xC5a62934B912c3B1948Ab0f309e31a9b8Ed08dd1
Enter fullscreen mode Exit fullscreen mode

E você deve ser capaz de ver o endereço final dado no Etherscan.

Interagindo com contratos

Para interagir com contratos implantados, podemos usar seth call e seth send. Eles são um pouco diferentes:

  • seth call: só lerá dados da blockchain. Não vai “gastar” nenhum gás.
  • seth send: Isso enviará uma transação para a blockchain, potencialmente modificará o estado do blockchain e gastará gás.

Para ler dados da blockchain, poderíamos fazer algo como:

ETH_RPC_URL=<YOUR_RPC_URL> seth call <YOUR_DEPLOYED_CONTRACT> "FUNCTION_NAME()" <ARGUMENTS_SEPARATED_BY_SPACE>
Enter fullscreen mode Exit fullscreen mode

Como:

ETH_RPC_URL=<YOUR_RPC_URL> seth call 0x12345 "play(uint8)" 55
Enter fullscreen mode Exit fullscreen mode

Para o qual você terá que 0x0000000000000000000000000000000000000000000000000000000000000000significa falso, já que essa resposta é igual a 0 e, embool`, 0 significa falso.

Para escrever dados na blockchain, poderíamos fazer algo como:


ETH_RPC_URL=<YOUR_RPC_URL> ETH_FROM=<YOUR_FROM_ADDRESS> seth send <YOUR_DEPLOYED_CONTRACT> "FUNCTION_NAME()" <ARGUMENTS_SEPARATED_BY_SPACE>

Não implantamos um contrato que tenha um ótimo exemplo para fazer isso, mas digamos que a função play foi capaz de modificar o estado da blockchain, que ficaria assim:


ETH_RPC_URL=<YOUR_RPC_URL> ETH_FROM=<YOUR_FROM_ADDRESS> seth send 0x12345 "play(uint8)" 55

Verifique seu contrato no Etherscan

Depois de implantar um contrato no etherscan, você pode verificá-lo:

  1. Obtendo uma chave de API Etherscan.

  2. Em seguida, executando

solidity
ETHERSCAN_API_KEY=<api-key> dapp verify-contract <contract_directory>/<contract>:<contract_name> <contract_address>

Por exemplo:

solidity
ETHERSCAN_API_KEY=123456765 dapp verify-contract ./src/DapptoolsDemo.sol:DapptoolsDemo 0x23456534212536435424

E finalmente

  1. Adicione cache ao seu .gitignore

  2. Adicione update:; dapp update no topo do seu Makefile. Isso atualizará e baixará os arquivos em .gitmodules e lib quando você executar o make.

  3. Adicione uma LICENSE. Você pode simplesmente copiar uma do nosso repositório se não souber como!

E pronto!

Recursos

Se você gostou, considere doar!

Endereço da carteira ETH: 0x9680201d9c93d65a3603d2088d125e955c73BD65


Este artigo foi escrito por Patrick Collins. A versão original pode ser encontrada aqui. Traduzido e adaptado por Marcelo Panegali.

Top comments (0)