This chapter explains how smart contracts can receive Ether (ETH) in Solidity.
Smart contracts can store Ether (ETH) and receive ETH from external accounts. However, not all contracts inherently possess the ability to receive ETH.
For a smart contract to receive ETH, it must implement either a receive or fallback function.
Before learning about the receive function, it's essential to understand Ethereum's account types. If neither of these functions is defined, the contract cannot receive Ether.
According to Solidity's specifications, using the receive function is recommended because it's straightforward and purpose-specific, whereas the fallback function primarily handles calls to undefined functions.
1. The Receive Function
The receive function is defined as follows:
receive() external payable {
// Custom logic (optional)
}Key characteristics of the receive function:
- Does not require the
functionkeyword - Has no parameters
- Must have
externalvisibility - Must be
payable
When ETH is sent to the contract's address, the receive function is triggered.
While custom logic can be added, it's common to leave the function body empty. If logic is necessary, keep it minimal since methods like send and transfer limit gas to 2300 to prevent reentrancy attacks, potentially causing transactions to revert if execution is too complex.
Example: Logging ETH Receipts
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract FuncReceive {
event Received(address sender, uint amount);
receive() external payable {
emit Received(msg.sender, msg.value);
}
}After deploying this contract (e.g., using Remix), sending ETH (e.g., 100 wei) will:
- Increase the contract's balance by 0.0000000000000001 ETH
- Trigger the
Receivedevent (visible in transaction logs)
2. The Fallback Function
In Solidity, fallback is a special function that handles:
- Calls to undefined functions
- ETH receipts (when no
receivefunction exists)
Definition
fallback() external [payable] {
// Custom logic (optional)
}Key characteristics:
- No
functionkeyword - No parameters
externalvisibility- Optional
payablemodifier
2.1 When Fallback is Triggered
Scenario 1: Calling undefined functions
fallback() external {}Scenario 2: Receiving ETH (no receive function)
fallback() external payable {}๐ Learn more about Solidity fallback patterns
2.2 Receive vs. Fallback Workflow
msg.dataempty (ETH transfer):- Triggers
receiveif present - Falls back to
payable fallback - Reverts if neither exists
- Triggers
msg.datanon-empty (function call):- Triggers
fallbackfor undefined functions
- Triggers
2.3 Testing Fallback Functions
a) Payable Fallback Only
contract FuncFallback {
event Fallback();
fallback() external payable {
emit Fallback();
}
}Sending ETH triggers the Fallback event.
b) Both Receive and Fallback
contract FuncFallback {
event Receive();
event Fallback();
receive() external payable {
emit Receive();
}
fallback() external payable {
emit Fallback();
}
}- ETH transfers trigger
receive - Undefined function calls trigger
fallback
c) Calling Undefined Functions
Providing non-empty msg.data (e.g., via Remix's "CALLDATA") triggers the fallback.
2.4 Practical Use Cases
Preferred Approach: Use receive for ETH deposits and fallback for undefined function calls to maintain clarity.
Applications:
- Airdrops: Users send 0-value transactions to claim tokens
- Token Locking: Deposit-triggered vesting schedules
- Token Swaps: Auto-conversion of ETH to WETH (e.g., WETH contracts)
๐ Explore real-world Solidity contract examples
FAQ
Q: Why can't some contracts receive ETH?
A: Contracts lacking both receive and payable fallback functions cannot process ETH transfers.
Q: What's the gas limit for receive/fallback?
A: Methods like transfer impose a 2300 gas limit, necessitating minimal logic in these functions.
Q: When should I use fallback instead of receive?
A: Only when handling undefined function calls. For pure ETH receipts, receive is clearer.
Q: Can fallback handle both ETH and function calls?
A: Yes, but separating concerns using receive for ETH is recommended.
Q: How do I debug failed ETH transfers?
A: Check if:
- The contract has a
receiveorpayable fallback - The sending method provides sufficient gas