Receive and fallback functions in Blockchain / Solidity - Time & Space Complexity
When a smart contract receives Ether, it uses special functions called receive and fallback. Understanding how long these functions take to run helps us know how the contract behaves as more transactions come in.
We want to see how the time to handle incoming payments grows as the number of calls increases.
Analyze the time complexity of the following Solidity contract snippet.
contract SimpleWallet {
event Received(address, uint);
receive() external payable {
emit Received(msg.sender, msg.value);
}
fallback() external payable {
// fallback logic
}
}
This contract uses receive to accept Ether and emit an event, and fallback to handle other calls.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Each call to receive or fallback runs once per transaction.
- How many times: Once per incoming transaction; no loops inside these functions.
Each transaction triggers the receive or fallback function once, so the work grows directly with the number of transactions.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 10 function calls |
| 100 | 100 function calls |
| 1000 | 1000 function calls |
Pattern observation: The total work increases in a straight line as more transactions arrive.
Time Complexity: O(n)
This means the time to handle all incoming calls grows directly with the number of calls.
[X] Wrong: "The receive or fallback function runs multiple times inside one transaction, so complexity is higher."
[OK] Correct: Each transaction triggers these functions only once, so no repeated loops happen inside them by default.
Knowing how receive and fallback scale helps you design contracts that handle payments efficiently and predict costs as usage grows.
"What if the fallback function included a loop over an array of stored addresses? How would the time complexity change?"
Practice
What is the main purpose of the receive() function in a Solidity contract?
Solution
Step 1: Understand the role of
Thereceive()receive()function is designed to accept Ether sent to the contract without any accompanying data.Step 2: Differentiate from fallback function
The fallback function handles calls with data or unknown function calls, whilereceive()is only for plain Ether transfers.Final Answer:
To handle plain Ether transfers without any data -> Option DQuick Check:
receive() handles plain Ether = C [OK]
- Confusing receive() with fallback()
- Thinking receive() handles calls with data
- Assuming receive() rejects Ether
Which of the following is the correct syntax for a receive() function in Solidity?
?
Solution
Step 1: Recall receive() function syntax
Thereceive()function must be declared without thefunctionkeyword, must beexternalandpayable.Step 2: Check each option
receive() external payable {}matches the correct syntax. Options using thefunctionkeyword are invalid, as are those lackingpayableor usingfallbackinstead ofreceive.Final Answer:
receive() external payable {} -> Option AQuick Check:
receive() syntax requires external payable = B [OK]
- Adding 'function' keyword to receive()
- Omitting 'payable' modifier
- Confusing fallback() with receive()
Consider this Solidity contract snippet:
contract Test {
event Log(string func);
receive() external payable {
emit Log("receive");
}
fallback() external payable {
emit Log("fallback");
}
}What event is emitted when someone sends 1 Ether with empty data?
Solution
Step 1: Identify the call type
Sending Ether with empty data triggers thereceive()function if it exists.Step 2: Check which event is emitted
Thereceive()function emits the event with "receive" string.Final Answer:
"receive" -> Option AQuick Check:
Empty data + Ether triggers receive() = "receive" [OK]
- Assuming fallback() triggers on empty data
- Thinking no event is emitted
- Confusing receive() and fallback() roles
Given this contract snippet, what is the error?
contract Example {
fallback() external {
// code
}
receive() external {
// code
}
}Solution
Step 1: Check payable modifiers
To accept Ether, bothreceive()andfallback()must be markedpayable.Step 2: Analyze given code
Both functions lackpayable, so contract cannot receive Ether via these functions.Final Answer:
Both fallback and receive must be payable to accept Ether -> Option BQuick Check:
Missing payable means no Ether acceptance = A [OK]
- Thinking order of functions matters
- Assuming fallback needs 'function' keyword
- Ignoring payable requirement
You want your contract to accept Ether sent with or without data, and log which function was called. Which is the best way to implement this?
?
Solution
Step 1: Understand Ether transfer scenarios
Ether can be sent with empty data (calls receive) or with data (calls fallback).Step 2: Implement both functions to handle all cases
Implementing bothreceive()andfallback()asexternal payablelets the contract accept Ether in both cases and emit distinct events.Final Answer:
Implement both receive() external payable and fallback() external payable functions, each emitting a distinct event -> Option CQuick Check:
Both functions needed for all Ether types = D [OK]
- Implementing only one function and missing some Ether transfers
- Ignoring fallback for calls with data
- Using regular payable function instead of receive/fallback
Ready to prove it?
Pass the test and this pattern moves unknown
