Learning Objectives – after this chapter you will be able to:
- Differentiate state, local and global variables.
- Use
constantandimmutableto save gas. - Choose between the
storage,memoryandcalldatadata locations. - Predict whether an assignment copies data or creates a reference.
Three Kinds of Variables
| Kind | Where declared | Where stored / lifetime | Gas |
|---|---|---|---|
| State | At contract level, outside functions | Permanently in the contract’s storage on the blockchain | Expensive to write |
| Local | Inside a function | Only while the function runs (stack or memory) | Cheap |
| Global | Pre-defined by Solidity | Provide information about the blockchain and the call, e.g. msg.sender, block.timestamp (Chapter 14) | Reading is cheap |
State Variables
- Declared at contract level.
- Permanently stored in contract storage, so their values remain between function calls and transactions.
- Writing (and the first read in a transaction) is expensive because the data is kept by every node.
- They can be initialised at declaration, in the constructor, or later by calling setter functions.
- They can be declared
constantorimmutable(see below).
Local Variables
- Declared inside functions (including function parameters and return variables).
- Value-type local variables (
uint,bool,address…) need no location keyword – they live on the EVM stack. - Reference-type local variables (
string,bytes, arrays, structs) must specify a data location:memory,storageorcalldata. - The keywords
memoryandcalldatacannot be used for state variables – state variables are always in storage.
Constant and Immutable
| Keyword | When is the value set? | Can it change? | Benefit |
|---|---|---|---|
constant | Fixed in the source code at compile time | Never | No storage slot; cheapest to read |
immutable | Assigned once, in the constructor (or at declaration) | Never after deployment | Stored in the contract code, not storage; cheap to read |
Data Locations : storage, memory, calldata
| Location | Lifetime | Modifiable? | Typical use |
|---|---|---|---|
storage | Permanent (on the blockchain) | Yes | State variables; local pointers to state data |
memory | Only during the function call – wiped afterwards (like RAM) | Yes | Temporary strings, arrays and structs; return values |
calldata | Only during the call; holds the call’s input data | No (read-only) | Parameters of external/public functions – cheapest because no copy is made |
Copy or reference?
- storage → memory: makes an independent copy; changing the copy does not change the state.
- storage → local storage variable: creates a reference (pointer); changes update the state variable.
- memory → memory: creates a reference to the same memory data.
Example : Variables and Data Locations
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract VariablesDemo {
uint256 public constant MAX_STUDENTS = 60; // constant: fixed at compile time
address public immutable admin; // immutable: set once in constructor
string[] public students; // state variable (storage)
constructor() {
admin = msg.sender; // msg.sender is a global variable
}
function addStudent(string calldata name) external { // calldata: read-only input
require(students.length < MAX_STUDENTS, "Class is full");
students.push(name);
}
function renameCopy(uint i) external view returns (string memory) {
string memory copy = students[i]; // storage -> memory = COPY
return copy; // state is not changed
}
function renameInPlace(uint i, string calldata newName) external {
string[] storage list = students; // storage pointer = REFERENCE
list[i] = newName; // updates the state variable
}
function total(uint a, uint b) external pure returns (uint) {
uint sum = a + b; // local value-type variable (stack)
return sum;
}
}
Key Takeaways
- State variables live in storage permanently; local variables exist only during the call.
- Use
constant/immutablefor values that never change – they save gas. - Reference types need a location: storage (permanent), memory (temporary), calldata (read-only input).
Download | Print E-Notes
The PDF E-Notes are the earlier printable version of this chapter. The notes on this page are the latest, revised version.
Question / Answer (15 questions)
Answer : State variables (declared at contract level and stored permanently in storage), local variables (declared inside functions and existing only during the call) and global variables (pre-defined values such as msg.sender and block.timestamp).
Answer : State variables are stored in the contract’s storage on the blockchain. Every node must keep that data permanently, so writing to storage costs much more gas than working with temporary data.
Answer : At declaration (e.g.
uint x = 5;), inside the constructor at deployment, or later through a setter function called by a transaction.Answer : A constant’s value is fixed in the source code at compile time. An immutable variable is assigned once at deployment, normally in the constructor. Neither can change afterwards, and neither occupies a storage slot, so both are cheap to read.
Answer : storage (permanent, on-chain), memory (temporary, exists during the function call and can be modified) and calldata (temporary and read-only, holds function input data).
Answer : calldata is read directly from the transaction input without copying it into memory, and it cannot be modified, which avoids extra copy operations.
Answer : No. Value types such as uint, bool and address live on the EVM stack; only reference types (string, bytes, arrays, structs) need storage, memory or calldata.
Answer : No. State variables are always stored in storage; memory and calldata can only be used for local variables, parameters and return values.
Answer : An independent copy is created in memory. Changing the memory copy does not change the state variable.
Answer : The local variable becomes a reference (pointer) to the state variable, so changes made through it update the stored state.
Answer : string is a reference type of dynamic size, so the compiler must know where the data lives during the function call; memory or calldata (for parameters) must be stated explicitly.
Answer :
msg.sender (address of the current caller) and block.timestamp (timestamp of the current block). Others include msg.value and block.number.Answer : Memory exists only for the duration of an external function call; once execution finishes it is cleared, similar to RAM.
Answer : Its value (60) never changes, so declaring it constant avoids a storage slot and makes every read cheaper.
Answer : When the value is only known at deployment (for example the admin address taken from msg.sender) and never changes afterwards; immutable saves gas on every read.
MCQ Test : Check Your Understanding (5 questions)
Select an option and press Check Answer, or answer all questions and press Submit Test to see your score. Each answer comes with an explanation.
Bibliography/References
The notes, questions and MCQs on this page are original explanations written for this course. The works listed below were consulted and are cited for attribution and further reading. Product names, logos and trademarks belong to their respective owners. Short quotations, where used, are marked and attributed.
- Solidity Team. (n.d.). Types (value types, reference types, mappings, operators, conversions). Solidity Documentation. https://docs.soliditylang.org/en/latest/types.html
- Solidity Team. (n.d.). Contracts (creating contracts, visibility and getters, function modifiers, constant and immutable, functions, events, custom errors, inheritance, abstract contracts, interfaces, libraries). Solidity Documentation. https://docs.soliditylang.org/en/latest/contracts.html
- Solidity Team. (n.d.). Layout of State Variables in Storage. Solidity Documentation. https://docs.soliditylang.org/en/latest/internals/layout_in_storage.html
- Solidity Team. (n.d.). Units and Globally Available Variables. Solidity Documentation. https://docs.soliditylang.org/en/latest/units-and-global-variables.html
- Modi, R. (2018). Solidity Programming Essentials: A beginner’s guide to build smart contracts for Ethereum and blockchain. Packt Publishing. ISBN 978-1-78883-138-3.