Pular para o conteúdo principal

Transferências e aprovação de tokens ERC-20 a partir de um contrato inteligente em Solidity

contratos inteligentes
tokens
Solidity
erc-20
Intermediário
jdourlens
7 de abril de 2020
7 minutos de leitura

No tutorial anterior, estudamos a anatomia de um token ERC-20 em Solidity na blockchain Ethereum. Neste artigo, veremos como podemos usar um contrato inteligente para interagir com um token usando a linguagem Solidity.

Para este contrato inteligente, criaremos uma exchange descentralizada (DEX) fictícia real onde um usuário pode trocar ether pelo nosso token ERC-20 recém-implantado.

Para este tutorial, usaremos o código que escrevemos no tutorial anterior como base. Nossa DEX instanciará uma instância do contrato em seu construtor e executará as operações de:

  • troca de tokens por ether
  • troca de ether por tokens

Começaremos o código da nossa exchange descentralizada adicionando nossa base de código ERC-20 simples:

Nosso novo contrato inteligente de DEX implantará o ERC-20 e obterá todo o suprimento:

Então agora temos nossa DEX e ela tem toda a reserva de tokens disponível. O contrato tem duas funções:

  • buy: O usuário pode enviar ether e obter tokens em troca
  • sell: O usuário pode decidir enviar tokens para receber ether de volta

A função de compra

Vamos codificar a função de compra. Primeiro, precisaremos verificar a quantidade de ether que a mensagem contém e verificar se o contrato possui tokens suficientes e se a mensagem tem algum ether nela. Se o contrato possuir tokens suficientes, ele enviará o número de tokens ao usuário e emitirá o evento Bought.

Observe que, se chamarmos a função de exigir (require) no caso de um erro, o ether enviado será diretamente revertido e devolvido ao usuário.

Para manter as coisas simples, apenas fazemos a troca de 1 token por 1 Wei.

function buy() payable public {
    uint256 amountTobuy = msg.value;
    uint256 dexBalance = token.balanceOf(address(this));
    require(amountTobuy > 0, "You need to send some ether");
    require(amountTobuy <= dexBalance, "Not enough tokens in the reserve");
    token.transfer(msg.sender, amountTobuy);
    emit Bought(amountTobuy);
}

No caso em que a compra for bem-sucedida, devemos ver dois eventos na transação: O evento Transfer do token e o evento Bought.

Two events in the transaction: Transfer and Bought

A função de venda

A função responsável pela venda primeiro exigirá que o usuário tenha aprovado o valor chamando a função de aprovar (approve) de antemão. Aprovar a transferência exige que o token ERC20Basic instanciado pela DEX seja chamado pelo usuário. Isso pode ser alcançado chamando primeiro a função token() do contrato da DEX para recuperar o endereço onde a DEX implantou o contrato ERC20Basic chamado token. Em seguida, criamos uma instância desse contrato em nossa sessão e chamamos sua função approve. Depois, somos capazes de chamar a função sell da DEX e fazer a troca (swap) de nossos tokens de volta por ether. Por exemplo, é assim que isso se parece em uma sessão interativa do Brownie:

Então, quando a função de venda for chamada, verificaremos se a transferência do endereço do chamador para o endereço do contrato foi bem-sucedida e, em seguida, enviaremos os ethers de volta para o endereço do chamador.

function sell(uint256 amount) public {
    require(amount > 0, "You need to sell at least some tokens");
    uint256 allowance = token.allowance(msg.sender, address(this));
    require(allowance >= amount, "Check the token allowance");
    token.transferFrom(msg.sender, address(this), amount);
    payable(msg.sender).transfer(amount);
    emit Sold(amount);
}

Se tudo funcionar, você deverá ver 2 eventos (um Transfer e um Sold) na transação e seu saldo de tokens e saldo de ether atualizados.

Two events in the transaction: Transfer and Sold


A partir deste tutorial, vimos como verificar o saldo e a permissão de um token ERC-20 e também como chamar Transfer e TransferFrom de um contrato inteligente ERC-20 usando a interface.

Depois de fazer uma transação, temos um tutorial em JavaScript para aguardar e obter detalhes sobre as transações (opens in a new tab) que foram feitas para o seu contrato e um tutorial para decodificar eventos gerados por transferências de tokens ou quaisquer outros eventos (opens in a new tab), desde que você tenha a ABI.

Aqui está o código completo do tutorial: