Solidity – What is the ‘receive’ Keyword in Solidity?

fallback-functionkeywordreceivesoliditysolidity-0.6.x

Solidity has a receive keyword. What is it and how do I use it?

Best Answer

TL;DR

receive is a new keyword in Solidity 0.6.x that is used as a fallback function that is only able to receive ether.

  • receive() external payable — for empty calldata (and any value)
  • fallback() external payable — when no other function matches (not even the receive function). Optionally payable.

Long Answer

Solidity 0.6.x introduced the receive keyword in order to make contracts more explicit when their fallback functions are called. The receive method is used as a fallback function in a contract and is called when ether is sent to a contract with no calldata. If the receive method does not exist, it will use the fallback function.

From the docs:

A contract can have at most one receive function, declared using receive() external payable { ... } (without the function keyword). This function cannot have arguments, cannot return anything and must have external visibility and payable state mutability. It is executed on a call to the contract with empty calldata. This is the function that is executed on plain Ether transfers (e.g. via .send() or .transfer()). If no such function exists, but a payable fallback function exists, the fallback function will be called on a plain Ether transfer. If neither a receive Ether nor a payable fallback function is present, the contract cannot receive Ether through regular transactions and throws an exception.

To use it, you can include it in your contract in the following way:

pragma solidity ^0.6.0;

// This contract keeps all Ether sent to it with no way
// to get it back.
//  This is example code. Do not use it in production.
contract Sink {
    event Received(address, uint);
    receive() external payable {
        emit Received(msg.sender, msg.value);
    }
}

When evaluating whether to use receive or fallback, consider the following:

This is why in version 0.6.x, the fallback function was split into two separate functions:

  • receive() external payable — for empty calldata (and any value)
  • fallback() external payable — when no other function matches (not even the receive function). Optionally payable.

This separation provides an alternative to the fallback function for contracts that want to receive plain ether.

Edit based on Ismael's comment: The 2300 gas stipend required by .send() and .transfer() apply to receive() in the same way that they apply to .transfer(). Additionally, contracts compiled with pre-0.6.0 solc versions are able to interact with the receive() function.

Additional information can be found in the Ethereum blog post here.

Related Topic