Lição: 125: Implementando um Contrato de Crowdsale Simples
Nesta aula, iremos aprender como implementar um contrato de crowdsale simples usando a linguagem de programação Solidity. Um crowdsale é um método de arrecadação de fundos onde um projeto vende tokens em troca de criptomoeda. Esta implementação cobrirá os conceitos básicos de crowdsales, incluindo precificação, distribuição de tokens e gerenciamento de contribuições.
Pré-requisitos
Antes de mergulhar no código, certifique-se de estar familiarizado com:
- Entendimento básico do Ethereum e contratos inteligentes.
- Familiaridade com a sintaxe do Solidity.
- Um ambiente de desenvolvimento configurado (como Remix, Truffle ou Hardhat).
Passo 1: Configurando o Contrato de Token ERC20
Primeiro, vamos criar um token ERC20 simples que nosso contrato de crowdsale usará. Aqui está uma implementação básica:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
contract SimpleToken is ERC20 {
constructor(uint256 initialSupply) ERC20("SimpleToken", "STK") {
_mint(msg.sender, initialSupply);
}
}
Explicação
- Importamos o contrato
ERC20
da OpenZeppelin. - O contrato
SimpleToken
herda do contrato ERC20 e mint um suprimento inicial de tokens para o endereço do desenvolvedor.
Passo 2: Criando o Contrato de Crowdsale
Em seguida, implementaremos o contrato de crowdsale, que gerenciará a venda dos tokens:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract SimpleCrowdsale is Ownable {
IERC20 public token;
uint256 public rate; // número de tokens por um wei
address payable public wallet; // endereço para receber fundos
uint256 public raisedAmount; // total de fundos arrecadados
uint256 public openingTime; // hora de início do crowdsale
uint256 public closingTime; // hora de encerramento do crowdsale
modifier onlyWhileOpen {
require(block.timestamp >= openingTime && block.timestamp <= closingTime, "Crowdsale não está aberto");
_;
}
constructor(
uint256 _rate,
address payable _wallet,
IERC20 _token,
uint256 _openingTime,
uint256 _closingTime
) {
require(_rate > 0, "A taxa deve ser maior que 0");
require(_wallet != address(0), "O endereço da carteira não pode ser zero");
require(address(_token) != address(0), "O token não pode ser zero");
require(_openingTime < _closingTime, "Horários de abertura e fechamento inválidos");
rate = _rate;
wallet = _wallet;
token = _token;
openingTime = _openingTime;
closingTime = _closingTime;
}
function buyTokens() public payable onlyWhileOpen {
uint256 weiAmount = msg.value;
require(weiAmount > 0, "Você precisa enviar algum Ether");
uint256 tokens = weiAmount * rate;
raisedAmount += weiAmount;
token.transfer(msg.sender, tokens);
wallet.transfer(msg.value);
}
function getRaisedAmount() public view returns (uint256) {
return raisedAmount;
}
function hasEnded() public view returns (bool) {
return block.timestamp > closingTime;
}
function withdrawUnsoldTokens() public onlyOwner {
require(hasEnded(), "Crowdsale ainda não terminou");
uint256 unsoldTokens = token.balanceOf(address(this));
token.transfer(wallet, unsoldTokens);
}
}
Explicação
- O contrato
SimpleCrowdsale
gerencia a venda dos tokens. - Ele aceita diversos parâmetros como
rate
,wallet
,token
,openingTime
eclosingTime
no construtor. - O modificador
onlyWhileOpen
garante que a compra de tokens só possa ocorrer durante o período permitido. - A função
buyTokens
permite que usuários comprem tokens enviando Ether. A função calcula o número de tokens com base na taxa e os transfere para o comprador. Ela também envia o Ether recebido para a carteira especificada. - A função
getRaisedAmount
permite verificar o total arrecadado. - A função
hasEnded
verifica se o crowdsale já acabou. - A função
withdrawUnsoldTokens
permite ao proprietário do contrato retirar quaisquer tokens não vendidos após o término do crowdsale.
Passo 3: Implantação
Você pode implantar os contratos SimpleToken
e SimpleCrowdsale
usando o Remix ou qualquer framework de desenvolvimento Solidity.
- Implemente o contrato
SimpleToken
com um suprimento inicial, por exemplo,1000000
. - Anote o endereço do token.
- Implemente o contrato
SimpleCrowdsale
usando o endereço do token acima, defina a taxa (por exemplo,100
tokens por Wei) e configure o endereço da carteira, horário de abertura e horário de fechamento.
Conclusão
Nesta aula, implementamos um contrato de crowdsale simples junto com um token ERC20 básico. Aprendemos como gerenciar vendas de tokens, lidar com contribuições e transferir tokens para os compradores. Este é um passo fundamental na criação de aplicações descentralizadas (dApps) na blockchain do Ethereum.
Experimente o código, tente modificar os parâmetros e explore recursos mais avançados, como lista de permissões, diferentes estratégias de precificação ou limites flexíveis. Boa codificação!