Enviando Ether (transferir, enviar, chamar)
WEB3DEV Team   
# Enviando Ether (transferir, enviar, chamar)
# Como enviar Ether?
Você pode enviar Ether para outros contratos por meio de
transfer(2300 gás, lança erro)send(2300 gás, retorna um bool)call(encaminha todo o gás ou colocar gás, retorna um bool)
# Como receber Ether?
Um contrato que recebe Ether deve ter pelo menos uma das funções abaixo
receive() external payablefallback() external payable
receive() é chamada se msg.data estiver vazio, caso contrário fallback()é chamada.
# Qual método você deve usar?
call em combinação com proteção de reentrada é o método recomendado para ser usado depois de dezembro de 2019.
Proteção contra reentrada
- fazendo todas as mudanças de estado antes de chamar outros contratos
 - usando modificador de proteção de reentrada
 
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract ReceiveEther {
    /*
    Qual função é chamada, fallback() ou receive()?
           envie Ether
               |
         msg.data está vazia?
              / \
            sim  não
            /     \
receive() existe?  fallback()
         /   \
        sim   não
        /      \
    receive()   fallback()
    */
    // Função para receber Ether. msg.data deve estar vazio
    receive() external payable {}
    // Função de fallback é chamada quando msg.data não está vazio
    fallback() external payable {}
    function getBalance() public view returns (uint) {
        return address(this).balance;
    }
}
contract SendEther {
    function sendViaTransfer(address payable _to) public payable {
        // Esta função não é mais recomendada para enviar Ether.
        _to.transfer(msg.value);
    }
    function sendViaSend(address payable _to) public payable {
        // Send retorna um valor boolean indicando sucesso ou falha.
        // Esta função não é recomendada para enviar Ether.
        bool sent = _to.send(msg.value);
        require(sent, "Failed to send Ether");
    }
    function sendViaCall(address payable _to) public payable {
        // Call retorna um valor boolean indicando sucesso ou falha.
        // Esse é o método atual recomendado para ser usado.
        (bool sent, bytes memory data) = _to.call{value: msg.value}("");
        require(sent, "Failed to send Ether");
    }
}