Skip to content

Instantly share code, notes, and snippets.

@KolevDarko
Last active April 1, 2023 07:50
Show Gist options
  • Save KolevDarko/761d77130a69beec4d9b54bef227965b to your computer and use it in GitHub Desktop.
Save KolevDarko/761d77130a69beec4d9b54bef227965b to your computer and use it in GitHub Desktop.
Storage read/write
//SPDX-License-Identifier: MIT
pragma solidity 0.8.19;
contract StoragePart1 {
uint128 public C = 4;
uint8 public D = 6;
uint24 public E = 8;
function readBySlot() external view returns(bytes32 value) {
assembly {
value := sload(C.slot)
}
}
function getOffsets() external pure returns (uint256 offsetC, uint256 offsetD, uint256 offsetE){
assembly {
offsetC := C.offset
offsetD := D.offset
offsetE := E.offset
}
}
function readD() external view returns (uint8 d){
assembly {
let fullWord := sload(D.slot) // read the full word
let shifted := shr(mul(D.offset, 8), fullWord) // shift right by offset * 8,
// shift right moves the whole word to the right, while appending 0s from the left.
// it's the same as dividing by 2, but shift is more gas efficient.
d := and(0xff, shifted) // get the first 2 bytes from the shifted word,
// because E is at the front now, but we don't want to fetch F as well
}
}
function writeToD(uint8 newD) external {
assembly {
let c := sload(D.slot)
let clearedD := and(c, 0xffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffff)
// We keep all vals but D is 00
let shiftedNewD := shl(mul(D.offset, 8), newD)
// fillup 0s to the right of newD so it can be applied on the spot of existing D
let newVal := or(shiftedNewD, clearedD)
sstore(D.slot, newVal)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment