Saltar al contenido principal

Transferencias y aprobación de tokens ERC-20 desde un contrato inteligente en Solidity

contratos inteligentes
tokens
Solidity
erc-20
Intermedio
jdourlens
7 de abril de 2020
7 minutos de lectura

En el tutorial anterior estudiamos la anatomía de un token ERC-20 en Solidity en la cadena de bloques de Ethereum. En este artículo veremos cómo podemos usar un contrato inteligente para interactuar con un token usando el lenguaje Solidity.

Para este contrato inteligente, crearemos un intercambio descentralizado (DEX) ficticio real donde un usuario puede intercambiar ether por nuestro token ERC-20 recién desplegado.

Para este tutorial usaremos el código que escribimos en el tutorial anterior como base. Nuestro DEX instanciará una instancia del contrato en su constructor y realizará las operaciones de:

  • intercambiar tokens por ether
  • intercambiar ether por tokens

Comenzaremos el código de nuestro intercambio descentralizado añadiendo nuestra base de código simple ERC20:

Nuestro nuevo contrato inteligente de DEX desplegará el ERC-20 y obtendrá todo el suministro:

Así que ahora tenemos nuestro DEX y tiene toda la reserva de tokens disponible. El contrato tiene dos funciones:

  • buy: El usuario puede enviar ether y obtener tokens a cambio
  • sell: El usuario puede decidir enviar tokens para recuperar ether

La función de compra

Codifiquemos la función de compra. Primero necesitaremos comprobar la cantidad de ether que contiene el mensaje y verificar que el contrato posee suficientes tokens y que el mensaje tiene algo de ether. Si el contrato posee suficientes tokens, enviará la cantidad de tokens al usuario y emitirá el evento Bought.

Ten en cuenta que si llamamos a la función require en caso de error, el ether enviado se revertirá directamente y se devolverá al usuario.

Para mantener las cosas simples, solo intercambiamos 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);
}

En el caso de que la compra sea exitosa, deberíamos ver dos eventos en la transacción: el evento Transfer del token y el evento Bought.

Two events in the transaction: Transfer and Bought

La función de venta

La función responsable de la venta primero requerirá que el usuario haya aprobado la cantidad llamando a la función approve de antemano. Aprobar la transferencia requiere que el usuario llame al token ERC20Basic instanciado por el DEX. Esto se puede lograr llamando primero a la función token() del contrato DEX para recuperar la dirección donde el DEX desplegó el contrato ERC20Basic llamado token. Luego creamos una instancia de ese contrato en nuestra sesión y llamamos a su función approve. Entonces podremos llamar a la función sell del DEX e intercambiar nuestros tokens de vuelta por ether. Por ejemplo, así es como se ve esto en una sesión interactiva de Brownie:

Luego, cuando se llama a la función de venta, comprobaremos si la transferencia desde la dirección de la persona que llama a la dirección del contrato fue exitosa y luego enviaremos los ethers de vuelta a la dirección de la persona que llama.

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);
}

Si todo funciona, deberías ver 2 eventos (un Transfer y un Sold) en la transacción y tu saldo de tokens y saldo de ether actualizados.

Two events in the transaction: Transfer and Sold


En este tutorial vimos cómo comprobar el saldo y la asignación de un token ERC-20 y también cómo llamar a Transfer y TransferFrom de un contrato inteligente ERC20 usando la interfaz.

Una vez que realices una transacción, tenemos un tutorial de JavaScript para esperar y obtener detalles sobre las transacciones (opens in a new tab) que se hicieron a tu contrato y un tutorial para decodificar eventos generados por transferencias de tokens o cualquier otro evento (opens in a new tab) siempre que tengas el ABI.

Aquí está el código completo del tutorial: