Enviando Ether (transferencia, envío, llamada)

# Enviando Ether (transferencia, envío, llamada)

# Como enviar Ether?

Puedes enviar Ether a otros contratos haciendo

  • transfer (2300 gás, da error)
  • send (2300 gás, devuelve un bool)
  • call (reenvía todo el gas o establece gas, devuelve un bool)

# Como recibir Ether?

Un contrato que recibe Ether debe tener, al menos, una de las siguientes funciones

  • receive() external payable
  • fallback() external payable

receive() es llamado si msg.data está vacío, si no fallback()es llamado / invocado.

# Cuál método debes usar?

call en combinación con la protección de reentrada (re-entrancy guard), es el método recomendado a usar a partir de diciembre del 2019.

Protégete contra la reentrada

  • Haciendo todos los cambios de estado antes de llamar a otros contratos
  • Usando el modificador de la protección de reentrada
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.3;

contract ReceiveEther {
    /*
    Cuál función es invocada, fallback() o receive()?

           enviar Ether
               |
         msg.data está vacío?
              / \
            si  no
            /     \
receive() existe?  fallback()
         /   \
        si   no
        /      \
    receive()   fallback()
    */

    // Función para recibir Ether. Msg.data tiene que estar vacío
    receive() external payable {}

    // Función de fallback es invocada cuando msg.data no está vacío
    fallback() external payable {}

    function getBalance() public view returns (uint) {
        return address(this).balance;
    }
}

contract SendEther {
    function sendViaTransfer(address payable _to) public payable {
        // Esta función no es recomendada para enviar Ether.
        _to.transfer(msg.value);
    }

    function sendViaSend(address payable _to) public payable {
        // Send regresa un valor boolean, indicando si fue exitoso o falló.
        // Esta función no es recomendada para enviar Ether.
        bool sent = _to.send(msg.value);
        require(sent, "Failed to send Ether");
    }

    function sendViaCall(address payable _to) public payable {
        // Call regresa un valor boolean, indicando si fue exitoso o falló.
        // Este es el método de uso actual recomendado.
        (bool sent, bytes memory data) = _to.call{value: msg.value}("");
        require(sent, "Failed to send Ether");
    }
}
Last Updated: 10/10/2022, 5:48:20