Enviar Ether com transfer, send e call

porMatheusem21/05/2022

Nesse artigo iremos abordar sobre como enviar tokens através das funções transfer, send e call no seu contrato inteligente. Falaremos sobre transfer, send e call.

Como enviar Ether?

Você pode enviar Ether para outros contratos através das funções

  • transfer - 2300 gas, lança um erro
  • send - 2300 gas, retorna um valor bool
  • call - envia todo gas disponível ou o gas definido, retorna um valor bool

Como receber Ether?

Um contrato que receber Ether deve ter pelo menos uma das funções abaixo

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

receive() é chamado se msg.data estiver vazio, caso contrário fallback() é chamado

Qual método você deve usar?

call em combinação com a proteção de reentrada é o método recomendado para uso após dezembro de 2019

Proteja-se contra a reentrada

  • fazendo todas as mudanças de estado antes de chamar outros contratos
  • usando modificador de guarda de reentrada
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
contract ReceiveEther {
/*
Qual função é chamada, fallback() ou receive()?
send Ether
|
msg.data está vazio?
/ \
sim não
/ \
receive() existe? fallback()
/ \
sim não
/ \
receive() fallback()
*/
// Função para receber Ether, 'msg.data' deve estar vazio
receive() external payable {}
// A função '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 booleano indicando sucesso ou falha.
// Esta função não é recomendada para enviar Ether.
bool sent = _to.send(msg.value);
require(sent, "Falha ao enviar Ether");
}
function sendViaCall(address payable _to) public payable {
// Call retorna um valor booleano indicando sucesso ou falha.
// Este é o método recomendado atual para enviar Ether.
(bool sent, bytes memory data) = _to.call{value: msg.value}("");
require(sent, "Falha ao enviar Ether");
}
}

Testar no Remix