Skip to content

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 22512^{251} 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 stored
  • offset 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
  • Variable b (u8):
    • Base address: selector!("b")
    • Uses lowest 8 bits of the slot at offset 0
    • Leaves 244 bits unused
  • 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
Powered By Nethermind