Skip to Content

Fallback Functions: receive Ether

So far, all we did, was to receive Ether through an explicit function call. But how can you actually send a plain eth transaction to a smart contract?

That is, through the receive function and/or through the fallback function.

Let’s get started with an example smart contract…

View the Full Course Now 

Example Contract

Add this contract to Remix:

//SPDX-License-Identifier: MIT pragma solidity 0.8.15; contract SampleFallback { uint public lastValueSent; }

If you try and send 1 wei to this contract, it will fail:

ethereum-blockchain-developer-image

  1. Enter 1 Wei (or basically any value > 0) into the value field
  2. Hit the ā€œtransactā€ button, so you send a low-level transaction
  3. You will get an error that you need a receive or payable fallback function

The Receive Function

Let’s add a receive function first, to showcase how that works.

Extend the Smart Contract, so it records the value sent and the function string:

//SPDX-License-Identifier: MIT pragma solidity 0.8.15; contract SampleFallback { uint public lastValueSent; string public lastFunctionCalled; receive() external payable { lastValueSent = msg.value; lastFunctionCalled = "receive"; } }

If you try to send now 1 wei using the low-level transact and then look into the ā€œlastValueSentā€ function, as well as the ā€œlastFunctionCalledā€ getter function, you will get ā€œ1ā€ and ā€œreceiveā€:

ethereum-blockchain-developer-image

The Fallback Function

Let’s now extend the smart contract to add a fallback function to the contract:

//SPDX-License-Identifier: MIT pragma solidity 0.8.15; contract SampleFallback { uint public lastValueSent; string public lastFunctionCalled; receive() external payable { lastValueSent = msg.value; lastFunctionCalled = "receive"; } fallback() external payable { lastValueSent = msg.value; lastFunctionCalled = "fallback"; } }

If you now, again, send 1 wei to the smart contract using the low-level transact functionality, yet again, the lastFunctionCalled will be receive:

ethereum-blockchain-developer-image

Now, lets try ā€œtransactā€ with 0 value. You will see, the lastFunctionCalled will still be ā€œreceiveā€.

But now, let’s add a calldata 0x123456 and hit ā€œtransactā€ with 0 value:

ethereum-blockchain-developer-image

Now, suddenly the ā€œlastFunctionCalledā€ is fallback.

But what happens if you try to send 0x123456 as calldata with value > 0? Try it! Is it fallback or receive?

Receive vs Fallback

receive() is a function that gets priority over fallback() when a calldata is empty. But fallback gets precedence over receive when calldata does not fit a valid function signature.

Last updated on