Why send()
and transfer()
doesn't work?
I just learned solidity and I'm curious about the methods of sending ether.
I wrote two smart contract in solidity and deployed them with Remix IDE(Environment is Remix VM(Merge)). I tried to send 1 ether from Sender contract to Receiver contract in three different ways, send()
, transfer()
, call()
.
I was able to send ether trough call()
, but I was unable to send ether with send()
and transfer()
function.
Here is the code.
pragma solidity ^0.8.0;
contract Receiver {
address receiver;
uint public prize;
address public owner;
constructor() payable {
receiver = msg.sender;
owner = msg.sender;
prize = 0.001 ether;
}
receive() external payable {
require(msg.value >= prize || msg.sender == owner);
payable(receiver).transfer(msg.value);
receiver = msg.sender;
prize = msg.value;
}
}
contract Sender {
constructor() payable{
}
function sendWithSend(address payable _to) public payable{
//send ether with send
//failed
bool success = _to.send(msg.value);
require(success, "failed");
}
function sendWithTransfer(address payable _to) public payable{
//send ether with transfer
//failed
_to.transfer(msg.value);
}
function sendWithCall(address payable _to) public payable{
//send ether with call
//success
(bool sent, ) = _to.call{value: msg.value}("");
require(sent, "Failled" );
}
}
Sender contract has three functions, "sendWithSend", "sendWithTransfer" and "sendWithCall".
I tried to sent 1 ether to Receiver contract with each function and I expected all worked so Receiver contract would have 3 ether. But it got only 1 ether.
call()
worked but send()
and transfer()
failed.
I tried many times but send()
and transfer()
never works.
here is the error log
send()
error
transfer()
error
and here is call()
method success log
I would really appreciate your help.
send() and transfer() have a gas limit of 21000 while call() does not have default gas limit.
For the send() and transfer() function, when the funds are received, the receive() function will execute additional code which will reach the gas limit. Therefor the transaction will be reverted.
If you make an empty receive function, this should work as the gas limit will not be reached.
This is why the best practice is to always use the call() function if you may interact with a smart contract.