WEB3DEV

Cover image for Contrato Inteligente de Bloqueio de Tempo em Solidity
Paulo Gio
Paulo Gio

Posted on

Contrato Inteligente de Bloqueio de Tempo em Solidity

Como sabemos, os contratos inteligentes são públicos e qualquer pessoa pode ver o código do seu contrato inteligente, por isso é necessário escrever código que seja compreensível para todos. Além disso, o seu contrato inteligente deve incluir lógicas que ganhem a confiança dos usuários do contrato inteligente. O bloqueio de tempo é uma das maneiras de ganhar a confiança dos usuários do seu contrato inteligente.

Em um contrato inteligente de bloqueio de tempo (Timelock Smart Contract), adicionamos a lógica no contrato que restringe o usuário, incluindo o proprietário do contrato inteligente, a esperar por um determinado período de tempo antes de realizar qualquer transação.

Um dos casos de uso do contrato de bloqueio de tempo é uma oferta inicial de moedas (ICO). E se, após uma ICO bem-sucedida, os funcionários da empresa ainda detiverem a maioria dos tokens e decidirem negociá-los imediatamente, então o preço do token irá cair e outros que investiram nele terão prejuízo. Para evitar essa situação, podemos usar o contrato de bloqueio de tempo. No contrato de bloqueio de tempo, os tokens ficarão bloqueados por um determinado período de tempo, para que ninguém possa negociar os tokens cedo e os investidores fiquem satisfeitos.

https://miro.medium.com/max/1100/1*JNK6p1v9OehZLzStN535Rw.webp

Vamos ver como podemos escrever um contrato inteligente de bloqueio de tempo em Solidity.

Primeiro, criamos um contrato inteligente de token ERC20. O endereço desse contrato inteligente será usado em nosso contrato inteligente de bloqueio de tempo.

pragma solidity ^0.8.17;

import '@openzeppelin/contracts/token/ERC20/ERC20.sol';

contract TimelockTokenDemo is ERC20 {
   constructor() ERC20("Timelock Token Demo", "TTD") {
       _mint(msg.sender, 10000 * 10 ** decimals());
   }
}
Enter fullscreen mode Exit fullscreen mode

Na primeira linha, definimos a versão do compilador que estamos usando, que é a versão mais recente. Em seguida, importamos o contrato ERC20.sol do openzeppelin e, depois disso, criamos um contrato inteligente e o batizamos de TimeLockTokenDemo, que é herdado do ERC20.

constructor() ERC20("Timelock Token Demo", "TTD") {
       _mint(msg.sender, 10000 * 10 ** decimals());
   }
Enter fullscreen mode Exit fullscreen mode

Então criamos um construtor que terá o nome de um token e um símbolo. O construtor tem a função _mint derivada do contrato inteligente ERC20, que cria o suprimento total de tokens.

Você pode criar o contrato inteligente acima usando este assistente do openzeppelin.

https://docs.openzeppelin.com/contracts/4.x/wizard

Agora vamos criar um contrato inteligente TimelockDemo no qual vemos a implementação do contrato inteligente de bloqueio de tempo.

pragma solidity ^0.8.17;

import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import "@openzeppelin/contracts/access/Ownable.sol";

contract TimelockDemo {

 uint public constant lockDuration = 10 days;
 uint public immutable endLocking;
 address public immutable owner;

 constructor() {
   owner = msg.sender;
   endLocking = block.timestamp + lockDuration;
 }

 modifier blockWithdraw() {
   require(block.timestamp >= endLocking, "Você não pode retirar o valor antes de 10 dias.");
   _;
 }

 function withdraw(address token, uint amount) external onlyOwner blockWithdraw {

   IERC20(token).transfer(owner, amount);

 }
}
Enter fullscreen mode Exit fullscreen mode

Vejamos linha por linha:

pragma solidity ^0.8.17;

import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import "@openzeppelin/contracts/access/Ownable.sol";

contract TimelockDemo {
Enter fullscreen mode Exit fullscreen mode

Primeiro, definimos a versão e depois importamos a interface IERC20.sol do openzeppelin. Em seguida, importamos o contrato inteligente Ownable que usaremos para restringir a função de retirada.

uint public constant lockDuration = 10 days;
 uint public immutable endLocking;
 address public immutable owner;

 constructor() {
   owner = msg.sender;
   endLocking = block.timestamp + lockDuration;
 }
Enter fullscreen mode Exit fullscreen mode

Dentro do contrato inteligente, temos três variáveis de estado: a primeira é a lockDuration, que é definida para 10 dias; em seguida, temos a endLocking e a owner. Veremos o uso dessas variáveis em seguida.

constructor() {
   owner = msg.sender;
   endLocking = block.timestamp + lockDuration;
 }

 modifier blockWithdraw() {
   require(block.timestamp >= endLocking, "Você não pode retirar o valor antes de 10 dias.");
   _;
 }

 function withdraw(address token, uint amount) external onlyOwner blockWithdraw {

   IERC20(token).transfer(owner, amount);

 }
}
Enter fullscreen mode Exit fullscreen mode

A função do construtor que só chamará no momento da criação do contrato inteligente tem uma configuração de proprietário na primeira linha.

owner = msg.sender;
Enter fullscreen mode Exit fullscreen mode

Esta linha define o proprietário deste contrato inteligente no momento da implantação do contrato inteligente.

endLocking = block.timestamp + lockDuration;
Enter fullscreen mode Exit fullscreen mode

Na próxima linha, definimos a variável endLocking, que contém o tempo de término da restrição de bloqueio de tempo. Usaremos uma variável global, que é block.timestamp e adicionaremos lockDuration a ela. A variável endLocking será usada para verificar o tempo de bloqueio da transação.

modifier blockWithdraw() {
   require(block.timestamp >= endLocking, "You can't withdraw amount before 10 days.");
   _;
 }
Enter fullscreen mode Exit fullscreen mode

Em seguida, criaremos uma função modificadora blockWithdraw que garantirá a funcionalidade de bloqueio de tempo na função de retirada. Usaremos este modificador na função de retirada. Essa restrição garantirá que o proprietário deste contrato inteligente não possa retirar tokens do contrato inteligente, aumentando assim a confiança dos investidores ou compradores no token.

function withdraw(address token, uint amount) external onlyOwner blockWithdraw {

   IERC20(token).transfer(owner, amount);

 }
Enter fullscreen mode Exit fullscreen mode

Na função withdraw, adicionaremos os modificadores onlyOwner e blockWithdraw: o primeiro garantirá que esta função será chamada apenas pelo proprietário deste contrato inteligente e o modificador blockWithdraw restringirá o proprietário a retirar tokens antes do período de tempo definido neste contrato inteligente em particular. Definimos 10 dias, portanto, o proprietário deverá esperar por dias após a implantação do contrato inteligente.

Conclusão

Neste artigo, aprendemos como criar um contrato inteligente de bloqueio de tempo e como ele pode ser útil para qualquer contrato inteligente a fim de conquistar a confiança de seus usuários.

Artigo publicado por Ismail. Traduzido por Paulinho Giovannini.

Latest comments (0)