Introduction
You can define storage variables to store and retrieve data in your contract. Storage in Cairo contracts is implemented as a key-value store using a struct marked with the#[storage]
attribute.
Every contract must have exactly one storage definition, which serves as the contract’s persistent state on the blockchain and is kept between contract executions.
Storage space and pointers
The contract’s storage space consists of storage slots, where each slot:- Can store a single
felt252
value - Is initialized to 0
(base_address, offset)
where:
base_address
is the address of the first slot where the variable is storedoffset
is the distance from the base address where the variable is stored
selector!
macro to derive it from the variable name (i.e., selector!("variable§_name")
).
Example
- Variable
a
(u128
):- Base address:
selector!(
”a”)` - Uses lowest 128 bits of the slot at offset 0
- Leaves 124 bits unused
- Base address:
- Variable
b
(u8
):- Base address:
selector!("b")
- Uses lowest 8 bits of the slot at offset 0
- Leaves 244 bits unused
- Base address:
- Variable
c
(u256
):- Base address:
selector!("c")
- Too large for a single slot, uses two consecutive slots:
- First slot: lower 128 bits at offset 0
- Second slot: lower 128 bits at offset 1
- Leaves 248 bits unused, 124 in each slot
- Base address:
For more complex data structures, see storing custom types.
Notice how many bits are left unused in each slot?
This can make storage operations expensive.
To optimize storage usage, you can pack multiple variables together.
Learn more in storage optimization.