Advance Solidity Assembly: Storage Slots Part 1
Ruud Christopher Saimplice
Posted on February 25, 2023
Solidity's storage is organized into slots of 256 bits each, and variables are packed into these slots to make more efficient use of storage. When variables are packed into a slot, they are placed in the lowest-indexed positions in the slot first, with any remaining bits at the end of the slot unused.
Storage Slot.
A storage slot is a fixed-sized unit of storage that can hold 256 bits of data. Solidity's storage is organized into a virtual array of these slots, indexed by 256-bit unsigned integers. Each storage slot can hold one or more variables, depending on their size and packing rules.
When a variable is declared in a Solidity contract, it is assigned to a storage slot in a deterministic manner, based on its type and position in the contract's state variables. The Solidity compiler calculates the correct slot number for each variable and generates the necessary bytecode to access or modify its value in storage.
In Solidity, the .slot keyword is used to access the storage slot of a contract's state variable.
(variable_name).slot
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
contract GetBySlot{
uint256 public a = 34;
uint256 public b = 122;
function getSlotVarA() external pure returns(uint _slot){
assembly{
//return 0
_slot:= a.slot
}
}
function getSlotVarB() external pure returns(uint _slot){
assembly{
//return 1
_slot:= b.slot
}
}
}
Update Value using Storage Slot.
In Solidity assembly, the sstore opcode is used to store a value in the contract's storage.
The Solidity storage is a persistent key-value store that is used to store the state variables of the contract. Each key-value pair is stored in a unique storage slot, which is identified by a 256-bit key. The sstore opcode is used to store a 256-bit value in a specific storage slot, identified by its key.
// Be carefull with this instruction in your code
function setBySlot(uint256 slot,uint256 value) external {
assembly {
sstore(slot,value)
}
}
Warning ⚠️
When using Solidity assembly to manipulate storage slots, it is important to keep in mind that storage operations are very expensive in terms of gas consumption. Every read or write operation to a storage slot incurs a gas cost, which is significantly higher than the gas cost of equivalent operations on memory or stack.
As a result, it is generally a good practice to minimize the number of storage operations in your contract, and to carefully consider the layout of your data in storage to optimize for gas efficiency.
In addition, it is important to be aware of the potential risks of using assembly to directly manipulate storage slots, as this can introduce subtle bugs and security vulnerabilities in your contract. If you are new to Solidity programming, it is recommended that you start with simpler, high-level abstractions before diving into low-level assembly programming.
When working with storage slots in Solidity assembly, it is also important to be aware of the potential for collisions between different contract variables that share the same storage slot. This can occur if two variables are declared with the same storage location using the slot keyword, or if the same storage slot is used for different purposes at different points in the contract execution.
To avoid these risks, it is important to carefully manage your use of storage slots and to ensure that each variable has a unique storage location. It is also recommended to use higher-level Solidity constructs, such as structs and mappings, to manage complex data structures in storage, as these can help to simplify the logic of your code and reduce the risk of errors.
Follow me on Twitter !! https://twitter.com/web3_ruud
I’m on @buymeacoffee. If you like my work, you can buy me a and share your thoughts 🎉☕ https://www.buymeacoffee.com/officialsa4
Posted on February 25, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.