Learn on Mantle: Solidity Series Part 1
05/07/234 min read
by Mantle
Developers
Training
Tutorials

Solidity is a programming language used to write smart contracts on the Ethereum blockchain and other Ethereum Virtual Machine (EVM) blockchains including Mantle. As with any programming language, Solidity has its own set of unique features and quirks, one of which is storage slots, which is usually abstracted away from the user.
In Solidity, storage slots refer to the locations where contract data is stored on the blockchain. These storage slots are essentially a key-value store, where each key is an index, and each value is a 32-byte word. These storage slots can be thought of as an array of 32-byte words, where each word can be accessed using its index.
[0x...0000]: 0x0000000000000000000000000000000000000000000000000000000000000000
[0x...0001]: 0x0000000000000000000000000000000000000000000000000000000000000000
[0x...0002]: 0x0000000000000000000000000000000000000000000000000000000000000000
[0x...0003]: 0x0000000000000000000000000000000000000000000000000000000000000000
…
[0x...FFFF]: 0x0000000000000000000000000000000000000000000000000000000000000000
When you write a smart contract in Solidity, you declare the variables that your contract will use. These variables can be of different data types, such as uint, bool, address, and so on. When you declare a variable, Solidity automatically assigns it a storage slot, based on its type and position in the contract. For example, bools in storage are represented as 256-bit values, with true being represented by a value of 1 and false being represented by a value of 0.
0x0000000000000000000000000000000000000000000000000000000000000000: true
0x0000000000000000000000000000000000000000000000000000000000000000: false
For example, if you declare a uint variable named “myNumber” as the first variable in your contract, Solidity will assign it the first storage slot, which has an index of 0. If you declare another uint variable named “myOtherNumber” as the second variable in your contract, Solidity will assign it the second storage slot, which has an index of 1.
contract MyContract {
uint myNumber; // Slot 0
uint myOtherNumber; // Slot 1
}
It’s important to note that Solidity will always assign storage slots in the order that variables are declared in the contract. This means that if you later declare another variable, it will be assigned the next available storage slot, which may not be contiguous with the previous variable’s storage slot. This is something important to note especially if you’re upgrading a proxy contract, as it might yield irreversible results. One way to avoid this is to declare all variables in a single file, and only append a list of variables.
You can also overwrite/access the data stored in a storage slot manually, you need to invoke it via inline assembly through the SSTORE and SLOAD opcodes. For example:
function getStorageValue(uint slot) public view returns (uint256 result) {
assembly {
result := sload(slot)
}
}
function setStorageValue(uint slot, uint value) public {
assembly {
sstore(slot, value)
}
}
In conclusion, storage slots in Solidity are a way of storing contract data on the blockchain. They are essentially a key-value store, where each key is an index and each value is a 32-byte word. With clever encoding, one might even be able to store a lot of data in a single storage slot to save on gas ;)