EVM -Storage
Storage Layout
1.
contract X  {
    uint256 public a = 1;  // Slot 0
    uint128 public b = 2;  // Slot 1 (partially filled)
    uint128 public c = 3;  // Slot 1 (same as 'b', packed)
    bool public d = true;  // Slot 2 (partially filled)
    address public e = msg.sender; // Slot 3
    struct Data {
        uint256 x;
        uint256 y;
    }
    Data public data = Data(10, 20); // Slot 4 & 5 (separate storage)
    mapping(address => uint256) public balances; // Uses keccak256(address + slot)
    string public text = "Hello"; // Stored separately, reference stored in slot 6
}
Every Slot has: 256 bits (32 Bytes)
| Slot | Data | 
|---|---|
| Slot 0 | a (32 bytes) | 
| Slot 1 | b and c (16+16 bytes) | 
| Slot 2 | d (1 byte) (31 waste) | 
| Slot 3 | e | 
| Slot 4 | x in struct | 
| Slot 5 | y in struct | 
2.
contract x {
    struct User {
        uint128 id;   // 16 bytes
        bool active;  // 1 byte
        uint8 level;  // 1 byte
        uint256 score; // 32 bytes (New slot)
    }
}
| Slot | Data | 
|---|---|
| Slot 0 | id (uint128) + active (bool) + level (uint8) | 
| Slot 1 | score (uint256) | 
3.
contract {
    mapping(address => uint256) public balances;  // Slot 0
    function setBalance(address user, uint256 amount) public {
        balances[user] = amount;
    }
}
Storage slot = keccak256(abi.encode(0xABC, 0))
| Slot | Data | 
|---|---|
| Slot 0 | |
| Slot n | 
Gas Optimization
1.
Unsafe:
uint128 a; // Slot 0
uint256 b; // Slot 1
uint128 c; // Slot 2
Safe:
uint128 a;
uint128 c;
uint256 b; // This ensures `a` and `c` are packed into one slot.
Rule For Storage
- Every storage slot can store up to 32 bytes of data.
 - If a variable is ≤ 32 bytes, it fits into a single slot.
 - If a variable is > 32 bytes, it gets its own slot and additional storage.