Storage
Basic Contract Structure
Every Starknet contract must be defined as a module with the #[starknet::contract]
attribute. Here's the simplest possible Cairo contract:
#[starknet::contract]
mod Contract {
#[storage]
struct Storage {}
}
Contract Storage Basics
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 Variables
You can define Storage Variables to store and retrieve data in your contract:
#[starknet::contract]
mod Contract {
#[storage]
struct Storage {
a: u128,
b: u8,
c: u256,
}
}
For more complex data structures, see Storing Custom Types.
Storage Space (advanced)
The contract's storage space consists of storage slots, where each slot:
- Can store a single
felt252
value - Is initialized to 0
Storage Pointers
Storage variables are stored in storage slots using Starknet's memory model abstraction called Storage Pointers. A storage pointer is a tuple (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
To get the base address of a storage variable, you can use the selector!
macro to derive it from the variable name: for example, selector!("variable_name")
.
Storage Layout Example
In our previous contract 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: