Solidity Receive and Fallback
Solidity receive and fallback are special functions that catch calls no named function matches. The receive function catches plain ether sends, and the fallback function catches calls with unmatched data.
receive runs on a plain ether send
The tip jar has no named deposit function. A plain ether send with empty data lands in receive, and the tip is counted.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract TipJar {
uint256 public tipCount;
uint256 public totalTips;
receive() external payable {
tipCount = tipCount + 1;
totalTips = totalTips + msg.value;
}
}fallback runs when no function matches
This jar has only a fallback function. A call carrying junk data names no real function, so fallback runs.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract FallbackJar {
uint256 public fallbackCount;
fallback() external {
fallbackCount = fallbackCount + 1;
}
}Two counters tell receive and fallback apart
This jar has both special functions, each with its own counter. A plain send raises only the receive counter, and a junk call raises only the fallback counter.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract TwoWayJar {
uint256 public receiveCount;
uint256 public fallbackCount;
receive() external payable {
receiveCount = receiveCount + 1;
}
fallback() external {
fallbackCount = fallbackCount + 1;
}
}Example
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.30;
contract FullTipJar {
uint256 public receiveCount;
uint256 public fallbackCount;
uint256 public totalTips;
receive() external payable {
receiveCount = receiveCount + 1;
totalTips = totalTips + msg.value;
}
fallback() external {
fallbackCount = fallbackCount + 1;
}
}Key points
- receive function: a special function that runs when a contract receives ether with no data attached.
- Data: the extra bytes sent with a call that say which function to run.
- fallback function: a special function that runs when a call names no real function in the contract.
- Payable: receive must be payable, which means it is allowed to accept ether.
- Separate counters: one counter for receive and one for fallback shows which one ran.
- Low-level call: a call written with call sends ether and raw data straight to an address.
In this example, the jar keeps one counter for receive, one counter for fallback, and a running total of tips. The receive function is external and payable, so a plain ether send with empty data runs it and adds msg.value to the total. The fallback function runs when a call carries data that names no real function. The separate counters show exactly which special function caught each call.
Note
a plain ether send with empty data runs receive, not fallback, when the contract has a receive function.
Try it Yourself
Edit the code, then press Run.
Running is simulated · Remix IDE
Exercise
A contract has both receive and fallback. Which function runs when someone sends ether with empty data?