Neste artigo, aprenderemos como construir nossa própria carteira Multisig básica. Vamos aprender sobre o Hardhat e testar um contrato inteligente usando o Hardhat.
Este será um artigo mais extenso, por isso é recomendado que você reserve um tempo e siga este tutorial para obter o máximo dele. Em caso de dúvidas, sinta-se à vontade para entrar em contato comigo.
O que é uma carteira Multisig?
Você pode pensar em uma carteira Multisig como uma conta bancária conjunta, onde as assinaturas de várias partes são necessárias para iniciar uma transação a partir da conta. Da mesma forma, uma carteira Multisig é uma carteira baseada em contrato inteligente mantida por várias contas diferentes. Essas contas são conhecidas como proprietários ou administradores da carteira Multisig.
Ciclo de Vida da Transação
- Cada transação da carteira Multisig passa por um ciclo de vida específico, ou seja, ela passa por certas etapas.
- Para iniciar o ciclo, um dos administradores submeterá (
Submit
) essa transação para a fila de transações da carteira. - Depois disso, outros administradores aprovarão (
Approve
) essa transação se concordarem com ela. - Os administradores também podem revogar (
Revoke
) sua aprovação antes que a transação seja executada. - Uma vez que uma transação recebe as aprovações mínimas necessárias dos administradores, qualquer um dos administradores pode então executar (
Execute
) essa transação.
Chega de teoria, agora vamos nos aprofundar na construção de nossa própria implementação de uma carteira Multisig. Nós usaremos o hardhat e o typescript nesse processo. Primeiro, vamos configurar um projeto básico de partida com o hardhat e o typescript. Felizmente, grande parte deste passo é automatizada com o script inicializador do hardhat. Em seguida, escreveremos os contratos inteligentes IMultisigCore
e MultisigCore
. Esses contratos terão as funcionalidades principais da carteira Multisig mencionadas acima no artigo. Outros contratos herdarão o MultisigCore
para adicionar funcionalidades principais à implementação de suas carteiras Multisig. Também herdaremos este contrato em nossa carteira Multisig
para seguir o mesmo padrão.
Configuração do Hardhat
Vamos começar com a configuração do projeto inicial do hardhat. Navegue até a pasta onde você deseja criar este projeto. Em seguida, digite o seguinte comando: yarn init
e siga as instruções, pressione enter para manter os valores padrão. Isso criará um arquivo package.json
, ou seja, criará um projeto node neste diretório. Agora, para instalar o hardhat como uma das dependências de desenvolvimento, execute o comando: yarn add --dev hardhat
. Usamos o sinalizador --dev
porque o hardhat é uma dependência de desenvolvimento. Após a execução bem-sucedida do comando acima, você verá o hardhat adicionado como uma das devDependencies no package.json
. Agora, para executar o comando do hardhat, execute: yarn hardhat. Quando você executar esse comando pela primeira vez, será exibida uma mensagem de boas-vindas. Escolha Create a TypeScript project
com as teclas de seta e pressione enter para manter os valores padrão. Ele instalará algumas outras dependências para facilitar o trabalho com tipos no TypeScript, etc. Uma vez concluído, você verá que o script criou um código modelo com TypeScript. Você terá Lock.sol
, Lock.ts
nos diretórios contracts
, test
e deploy.ts
no diretório scripts
. Você pode excluir com segurança esses arquivos, pois na próxima seção estaremos escrevendo nossos próprios arquivos de contrato.
Interface IMultisigCore
Agora que concluímos a configuração básica do ambiente, vamos começar a construir nossa biblioteca de carteira Multisig do zero. Na pasta contracts
do nosso projeto, crie uma subpasta chamada MultisigLib
. Todo o código deste projeto está disponível no link do repositório no final. Agora, vamos criar uma interface IMultisigCore
para nosso contrato de biblioteca central Multisig. Este arquivo de interface terá declarações para os erros e eventos emitidos pelo nosso contrato Multisig. Você pode ver no trecho de código abaixo que nosso contrato emitirá 5 eventos: Deposit
, Submit
, Approve
, Revoke
e Execute
. Leia os comentários no código para entender mais sobre esses eventos.
O Solidity suporta erros personalizados desde a versão 0.8.4. Abaixo está um trecho de código contendo os erros personalizados lançados pelo núcleo Multisig em diferentes pontos. Você pode ler os comentários para entender quando revertemos com um erro específico.
Isso conclui a interface IMultisigCore
que descreve os eventos emitidos e os erros lançados pelo contrato MultisigCore
.
Contrato MultisigCore
Agora, vamos dar uma olhada no contrato MultisigCore
, onde toda a mágica Multisig acontece. Vamos começar com a struct
de transação e outras declarações de variáveis de estado.
Como você pode ver no trecho de código acima, a transação tem quatro atributos: endereço to
, value
, data
e um booleano isExecuted
. Além disso, temos uma matriz de administradores (admins) de endereços, um mapeamento isAdmin
para verificar rapidamente se o endereço fornecido é um administrador ou não. Temos um mapeamento semelhante isApprover
para verificar se, para uma transação dada, um administrador dado foi aprovado ou não. Também temos minApprovals
, que é o número mínimo de aprovações necessárias para executar qualquer transação. availableBalance
é o saldo disponível da Multisig para gastar em transações. Em seguida, vamos analisar alguns modificadores de função no contrato.
onlyAdmin
permite que apenas os administradores chamem a função. notExecuted
verifica e permite a chamada da função se a transação fornecida ainda não tiver sido executada, de maneira semelhante, notApproved
verifica e permite a chamada da função apenas se a transação fornecida ainda não foi aprovada pelo chamador, ou seja, reverte se já aprovada pelo chamador. isApproved
é o inverso do modificador notApproved
. Agora, vamos analisar o construtor e outras funções do contrato onde estes modificadores são usados.
No construtor deste contrato, definimos os admins
(administradores) e minApprovals
e atualizamos o mapeamento isAdmin
para todos os administradores fornecidos. Na função _submit
, adicionamos novas transações à matriz de transações, atualizamos availableBalance
e emitimos o evento Submit
. Nas funções _approve
e _revoke
, atualizamos o mapeamento isApprover
e emitimos os eventos Approve
ou Revoke
, conforme o caso. Na função _execute
, verificamos a contagem de aprovações para a transação e, se tivermos as aprovações mínimas necessárias, atualizamos a transação no armazenamento e executamos a transação com as seguintes linhas de código.
Com txn.to.call{value: txn.value}(txn.data)
, estamos passando o valor e os dados da transação na chamada ao endereço em txn.to
. Isso é tudo para o contrato MultisigCore
, é isso que é necessário para criar uma carteira multi-sig.
Contrato de Carteira Multisig
Na última seção, escrevemos os contratos da MultisigLib
, ou seja, MultisigLib/IMultisigCore
e MultisigLib/MultisigCore
. Nesta seção, usaremos esse contrato para construir nossa carteira multisig. Na pasta contracts
, ou seja, fora da pasta MultisigLib
, crie um novo arquivo chamado Multisig.sol
.
Como você pode ver acima, as funções submit
, approve
, revoke
e execute
, além do construtor deste contrato, são bastante simples. A única novidade neste contrato são as funções receive
e fallback
, que permitem que este contrato receba fundos mesmo sem chamar nenhuma função.
Script de Implantação
A seguir, escreveremos o script de implantação para implantar este contrato Multisig. Este script é semelhante ao script padrão do início do hardhat. Abaixo estão os conteúdos do script deploy.ts
.
Testando o contrato da carteira Multisig
Agora temos um contrato de carteira Multisig e testaremos as funcionalidades desse contrato. O Hardhat usa o Mocha e o Chai para testar contratos inteligentes. Todos esses testes seguem o formato describe-it de escrever testes.
Um bloco describe
pode ter outras descrições aninhadas dentro dele. Isso nos permite descrever nosso contrato com esses describe
e describe
aninhados que testam diferentes partes do contrato.
Fixtures e loadFixture
O Hardhat permite fixtures, que é uma maneira de ter vários testes com as mesmas condições iniciais. A fixture é basicamente uma maneira de restaurar a rede para um determinado estado. Da primeira vez que a loadFixture
é chamada com uma função, ela executa a função e, toda vez que é chamada, o Hardhat redefine a rede para o estado em que estava na primeira execução da função. Isso nos permite ter as mesmas condições iniciais para nossos testes. Para nossos testes, usaremos principalmente três fixtures: deployMultisigFixture
, depositFixture
e submitFixture
, sendo que cada uma delas é baseada na anterior. Você pode ver o trecho de código abaixo.
A deployMultisigFixture
, como o nome sugere, é a fixture de implantação, ela fornece o contrato implantado, a fábrica de contratos e outros parâmetros de implantação. A depositFixture
é baseada na deployMultisigFixture
, onde os três administradores transferem um ether para o contrato Multisig. A submitFixture é baseada na
depositFixture`, onde cada um dos três administradores enviam uma transação cada um.
Acima está o trecho de código dos testes para a funcionalidade execute
; todos os outros testes são escritos de maneira semelhante. Você pode encontrar e ler todos os testes no arquivo Multisig.test.ts
no diretório de testes no repositório associado a esta postagem. Isso conclui a postagem, obrigado por ler até o final, espero que tenha aprendido algo com isso.
Repositório: ts-multisig
https://github.com/BuildBearLabs/Tutorials
Autor: Nisarg Chaudhari (@nisargsc)
Sobre o BuildBear:
O BuildBear é uma plataforma para testar dApps em grande escala, para equipes. Ele fornece aos usuários sua própria Testnet privada para testar seus contratos inteligentes e dApps, que podem ser bifurcados de qualquer cadeia EVM. Ele também fornece uma Torneira (Faucet), Explorador (Explorer) e RPC para fins de teste.
O BuildBear tem como objetivo construir um ecossistema de ferramentas para testar dApps em grande escala para as equipes.
Esse artigo é uma tradução feita por @bananlabs. Você pode encontrar o artigo original aqui
Latest comments (0)