How to send Ether?

You can send Ether to other contracts by

  • transfer (2300 gas, throws error)
  • send (2300 gas, returns bool)
  • call (forward all gas or set gas, returns bool)

How to receive Ether?

A contract receiving Ether must have at least one of the functions below

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

receive() is called if is empty, otherwise fallback() is called.

Which method should you use?

call in combination with re-entrancy guard is the recommended method to use after December 2019.

Guard against re-entrancy by

  • making all state changes before calling other contracts
  • using re-entrancy guard modifier
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract ReceiveEther {
    Which function is called, fallback() or receive()?
           send Ether
               | is empty?
              / \
            yes  no
            /     \
receive() exists?  fallback()
         /   \
        yes   no
        /      \
    receive()   fallback()
    // Function to receive Ether. must be empty
    receive() external payable {}
    // Fallback function is called when is not empty
    fallback() external payable {}
    function getBalance() public view returns (uint) {
        return address(this).balance;
contract SendEther {
    function sendViaTransfer(address payable _to) public payable {
        // This function is no longer recommended for sending Ether.
    function sendViaSend(address payable _to) public payable {
        // Send returns a boolean value indicating success or failure.
        // This function is not recommended for sending Ether.
        bool sent = _to.send(msg.value);
        require(sent, "Failed to send Ether");
    function sendViaCall(address payable _to) public payable {
        // Call returns a boolean value indicating success or failure.
        // This is the current recommended method to use.
        (bool sent, bytes memory data) ={value: msg.value}("");
        require(sent, "Failed to send Ether");

Try on Remix