Storage Variable: What are storage variables?

Variables declared in contract scope are storage variables

Solidity stores these in contiguous storage slots

contract Example {
  uint256 a; // storage slot - 0x0
  uint256 b; // storage slot - 0x1
  bool public c; // storage slot - 0x2

  function store() external {
    // read storage slot 0x1
    // store it in storage slot 0x0
    a = b;

    // read storage slot 0x1
    // store it in memory (not persistent!)
    uint x = b;
  }
}

Storage is going the most expensive thing that you can do in the smart contract. If you can cut down on the number of storage variables you are using, that will save your user significant money when interacting with your smart contract.

Things to know about storage slots

  • 🔭 variables stored in contract scope allocate a storage slot (except for constant)
  • 📏 slots are 32 bytes (0x1 means 0x000....001)
  • 🔢 solidity stores variables contiguously (0x00x1, etc…)
  • 💸 reading/writing to storage is relatively super expensive to other opcodes
  • 🎒 variables can be packed together, automatically or manually

Hands-on

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

import "forge-std/console.sol";

contract Example {
    uint256 constant a = 55; // constant is not stored in storage slot
    uint256 b = type(uint256).max; // storage slot - 0x0
    bool c = false; // storage slot - 0x1

    constructor() {
        // SSTORE - store to some storage location
        // SLOAD - read from some storage location
        bytes32 x;
        assembly {
            x := sload(0x1)
        }
        console.logBytes32(x);
    }
}