WEB3DEV

Cover image for Como Automatizar Pausas em um Contrato Inteligente
Paulo Gio
Paulo Gio

Posted on • Atualizado em

Como Automatizar Pausas em um Contrato Inteligente

Trabalhando com o OpenZeppelin Defender

https://miro.medium.com/max/1100/0*g3kat9CDkyUU-qoW

Foto de Ivan Bandura no Unsplash

Um dos principais recursos do OpenZeppelin Defender é sua utilidade para monitoramento de segurança e automação geral. Este guia utiliza diversos componentes do Defender para automatizar a resposta a incidentes para um determinado conjunto de condições em um contrato ERC20.

Visão Geral

O OpenZeppelin Defender possui vários componentes principais de funcionalidade: Sentinel, Autotasks, Admin e Relayer. Cada componente serve como um importante bloco de construção para personalizar uma configuração de automação para o seu dapp ou protocolo.

Nesse projeto de sistema, um Sentinel (sentinela) monitora as transações no contrato e é configurado para disparar automaticamente um script Autotask (tarefa automatizada) no caso de uma grande transferência de tokens. O script Autotask envia uma transação de pausa para o contrato ERC20 por meio de um Relayer (retransmissor).

https://miro.medium.com/max/1100/0*uKkpfWITE0sS6YDN.webp

Configuração

Primeiro, inscreva-se no Defender e certifique-se de que o EOA usado para a implantação do contrato seja financiado com Goerli ETH (por meio de um faucet, ou torneira de tokens).

Faça o fork do repositório de demonstração.

Clone seu fork e instale as dependências:

$ git clone https://github.com/[GitHub username]/pause-guardian.git
$ cd pause-guardian
$ npm install
Enter fullscreen mode Exit fullscreen mode

Forneça as chaves de API necessárias no arquivo .env local. São esperados os seguintes valores:

PRIVATE_KEY: Para implantação do contrato na rede Goerli

API_KEY: Chave de API da equipe Defender

API_SECRET: Segredo da API da equipe Defender

Implantar o contrato ERC20

O Assistente de Contratos (Contracts Wizard) do OpenZeppelin possui uma API para facilitar a criação de contratos inteligentes. Gere um contrato ERC20 que seja Cunhável (Mintable), Pausável (Pausable) e que implementa um controle de acesso baseado em uma função, com 1 milhão de tokens pré-cunhados. O script pré-fornecido automatiza isso:

import { erc20 } from '@openzeppelin/wizard'const params = {
 name: 'ExampleToken',
 symbol: 'ETK',
 mintable: true,
 premint: '1000000',
 access: 'roles',
 pausable: true,
}

const contract = erc20.print(params)
Enter fullscreen mode Exit fullscreen mode

Execute $ npm run generate.

Em seguida, execute $ npm run deploy para compilar e implantar o contrato.

const adminClient = new AdminClient({
   apiKey: process.env.API_KEY,
   apiSecret: process.env.API_SECRET,
 })  

const contractDetails = {
   network: 'goerli',
   address: contract.address,
   name: NAME,
   abi: contractABI,
 }  

const newAdminContract = await adminClient.addContract(contractDetails)
Enter fullscreen mode Exit fullscreen mode

O script usa o admin-client (cliente-administrador) do Defender e carrega o contrato no painel do administrador imediatamente após a implantação.

Crie um Relayer e atribua a função de Pausa

Crie um Relayer para executar transações da blockchain através da API:

$ npm run relay
Enter fullscreen mode Exit fullscreen mode

Agora que você tem o Relayer, você precisa conceder a função apropriada a ele.

A interface web do Defender facilita o gerenciamento do controle de acesso. Por meio do painel do administrador, selecione o contrato ERC20 recém-criado e, em seguida, New Proposal → Modify Access (Nova proposta → Modificar acesso). Na próxima tela, selecione a função PAUSER no menu suspenso e forneça o endereço do Relayer que acabou de ser criado. Selecione EOA como estratégia de execução e selecione o endereço da conta utilizada para implantar o contrato. Atribua um título à proposta de acesso e execute-a.

​​https://miro.medium.com/max/1100/0*oTPBceRHnY2s9AQf.gif

Crie uma tarefa automatizada para enviar uma transação de pausa

Agora você tem um Relayer com o acesso apropriado para pausar o contrato. Está na hora de automatizar essa funcionalidade.

Crie uma Autotask que enviará uma transação de pausa para o contrato ERC20 implantado usando o Relayer.

$ npm run autotask
Enter fullscreen mode Exit fullscreen mode

O script cria uma nova Autotask no Defender e faz o upload do código da Autotask, fornecendo o ID do Relayer recém-criado para executar a transação usando o Relayer.

async function handler(event) {
 const provider = new DefenderRelayProvider(event)
 const signer = new DefenderRelaySigner(event, provider, { speed: 'fast' })  const erc20 = new ethers.Contract(ADDRESS, ABI, signer)  const isPaused = await erc20.paused()
 if (!isPaused) {
   const tx = await erc20.pause()
   console.log(tx)
 } else if (isPaused) {
   console.log('O contrato está pausado; fazendo nada')
 }
}
Enter fullscreen mode Exit fullscreen mode

Com a Autotask criada, o bloco de construção final é configurar um Sentinel para observar eventos na cadeia e acionar a Autotask.

Crie um Sentinel para acionar a Autotask

Sentinels podem observar uma ampla variedade de condições de contrato e enviar notificações ou disparar Autotasks quando acionados.

Execute $ npm run sentinel para criar um Sentinel que acione a Autotask se uma transferência de tokens de alto volume for detectada:

eventConditions: [
     {
       eventSignature: 'Transfer(address,address,uint256)',
       expression: 'value > 200000e18',
     },
   ],
Enter fullscreen mode Exit fullscreen mode

Teste a Automação de Pausa Automática

Agora que todos os blocos de construção foram assentados, o sistema está pronto para ser testado. Tente transferir uma quantidade de tokens superior a 200.000 do contrato para outra conta. O Sentinel irá detectar o evento de transferência (Transfer) de alto volume e acionará a Autotask, que enviará a transação de pausa por meio do Relayer e, assim, o contrato ERC20 será pausado. A tentativa de qualquer transferência de alto volume subseqüente, entretanto, falharia.

Recursos

Artigo original publicado por Stephen Lloyd Webber. Traduzido por Paulinho Giovannini.

Latest comments (0)