Understanding Storage, Memory, and Calldata in Solidity
📖 Scenario: Imagine you are building a simple smart contract for a blockchain-based voting system. You need to understand how to store and handle data efficiently using storage, memory, and calldata in Solidity.
🎯 Goal: You will create a Solidity contract that stores candidates in storage, uses memory to handle temporary data inside functions, and uses calldata to accept input parameters efficiently.
📋 What You'll Learn
Create a string[] array called candidates stored in storage
Create a function addCandidate that accepts a string parameter using calldata and adds it to candidates
Create a function getCandidateCopy that returns a copy of a candidate's name using memory
Print the candidate's name from getCandidateCopy to demonstrate the output
💡 Why This Matters
🌍 Real World
Smart contracts on blockchains need to manage data efficiently to save gas and work correctly. Understanding where data lives helps developers write better contracts.
💼 Career
Blockchain developers must know how to use <code>storage</code>, <code>memory</code>, and <code>calldata</code> to optimize smart contracts for performance and cost.
Progress0 / 4 steps
1
Create the candidates array in storage
Create a public string[] array called candidates that is stored in storage inside the contract.
Blockchain / Solidity
Hint
Use string[] public candidates; inside the contract to create a storage array.
2
Add a candidate using calldata parameter
Create a public function called addCandidate that takes a string calldata parameter named name and adds it to the candidates array.
Blockchain / Solidity
Hint
Use string calldata name to accept the input efficiently and candidates.push(name); to add it.
3
Return a candidate's name using memory
Create a public view function called getCandidateCopy that takes a uint parameter index and returns a string memory copy of the candidate's name at that index.
Blockchain / Solidity
Hint
Use string memory as the return type to return a copy of the candidate's name.
4
Print the candidate's name from getCandidateCopy
Add a public function called printCandidate that takes a uint parameter index, calls getCandidateCopy with that index, and returns the candidate's name as a string.
Blockchain / Solidity
Hint
Call getCandidateCopy inside printCandidate and return the result.
Practice
(1/5)
1. Which of the following correctly describes storage in Solidity?
easy
A. It stores data permanently on the blockchain.
B. It holds temporary data only during function execution.
C. It is used for read-only input data in external functions.
D. It is a type of event logging mechanism.
Solution
Step 1: Understand storage role
storage variables are saved permanently on the blockchain and persist between function calls.
Step 2: Compare with memory and calldata
memory is temporary during function execution, and calldata is read-only input data for external functions.
Final Answer:
It stores data permanently on the blockchain. -> Option A
Quick Check:
Storage = permanent data [OK]
Hint: Storage is permanent, memory is temporary, calldata is input [OK]
Common Mistakes:
Confusing storage with memory as temporary
Thinking calldata can be modified
Assuming storage is read-only
2. Which keyword is used to declare a function parameter that is read-only and passed from an external caller?
easy
A. calldata
B. storage
C. memory
D. event
Solution
Step 1: Identify parameter data location for external input
Function parameters from external callers that should not be modified use calldata.
Step 2: Recall other data locations
memory is for temporary data inside functions, storage is persistent, and event is unrelated to data location.
Final Answer:
calldata -> Option A
Quick Check:
External input = calldata [OK]
Hint: External read-only params use calldata [OK]
Common Mistakes:
Using memory for external parameters
Confusing event with data location
Using storage for function parameters
3. What will be the output of this Solidity function when called externally with _data = [1, 2, 3]?
function process(uint[] calldata _data) external pure returns (uint) {
uint sum = 0;
for (uint i = 0; i < _data.length; i++) {
sum += _data[i];
}
return sum;
}
medium
A. Runtime error
B. 6
C. Compilation error
D. 0
Solution
Step 1: Understand calldata usage
The function receives an array _data as calldata, which is read-only but accessible for reading elements.
Step 2: Calculate sum of array elements
Sum of [1, 2, 3] is 1 + 2 + 3 = 6, which is returned.
Final Answer:
6 -> Option B
Quick Check:
Sum of input array = 6 [OK]
Hint: Sum array elements from calldata works like memory [OK]
Common Mistakes:
Thinking calldata cannot be read
Expecting compilation error due to calldata
Confusing sum calculation logic
4. Identify the error in this Solidity function:
function updateData(uint[] calldata _input) external {
_input[0] = 10;
}
medium
A. Calldata arrays cannot be passed as parameters.
B. Function must be marked pure.
C. Missing return statement.
D. Cannot assign to calldata array elements.
Solution
Step 1: Check mutability of calldata
calldata is read-only, so assigning to _input[0] causes an error.
Step 2: Validate other options
The function can be non-pure, no return needed, and calldata arrays are allowed as parameters.
Final Answer:
Cannot assign to calldata array elements. -> Option D
Quick Check:
Calldata is read-only [OK]
Hint: Calldata arrays are read-only, no assignment allowed [OK]
Common Mistakes:
Trying to modify calldata elements
Thinking pure is required here
Assuming return is mandatory
5. You want to write a Solidity function that accepts a large array from an external caller, processes it temporarily, and then stores the result permanently. Which combination of data locations should you use for the parameter and the storage variable?
hard
A. Parameter as memory, storage variable as calldata
B. Parameter as storage, storage variable as memory
C. Parameter as calldata, storage variable as storage
D. Parameter as calldata, storage variable as memory
Solution
Step 1: Choose parameter data location for large external input
calldata is efficient and read-only for large external arrays, avoiding unnecessary copying.
Step 2: Choose storage variable for permanent data
To keep data permanently on blockchain, use storage for the variable that stores the processed result.
Final Answer:
Parameter as calldata, storage variable as storage -> Option C
Quick Check:
External input = calldata, permanent store = storage [OK]
Hint: Use calldata for input, storage for permanent save [OK]
Common Mistakes:
Using memory for large external input (inefficient)
Trying to store permanent data in memory or calldata
Confusing storage and memory roles
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.