-
Notifications
You must be signed in to change notification settings - Fork 36
/
Video-05-Storage-2.sol
84 lines (76 loc) · 3.09 KB
/
Video-05-Storage-2.sol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// SPDX-License-Identifier: GPL-3.0
pragma solidity 0.8.17;
contract StoragePart1 {
uint128 public C = 4;
uint96 public D = 6;
uint16 public E = 8;
uint8 public F = 1;
function readBySlot(uint256 slot) external view returns (bytes32 value) {
assembly {
value := sload(slot)
}
}
// NEVER DO THIS IN PRODUCTION
function writeBySlot(uint256 slot, uint256 value) external {
assembly {
sstore(slot, value)
}
}
// masks can be hardcoded because variable storage slot and offsets are fixed
// V and 00 = 00
// V and FF = V
// V or 00 = V
// function arguments are always 32 bytes long under the hood
function writeToE(uint16 newE) external {
assembly {
// newE = 0x000000000000000000000000000000000000000000000000000000000000000a
let c := sload(E.slot) // slot 0
// c = 0x0000010800000000000000000000000600000000000000000000000000000004
let clearedE := and(
c,
0xffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
)
// mask = 0xffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff
// c = 0x0001000800000000000000000000000600000000000000000000000000000004
// clearedE = 0x0001000000000000000000000000000600000000000000000000000000000004
let shiftedNewE := shl(mul(E.offset, 8), newE)
// shiftedNewE = 0x0000000a00000000000000000000000000000000000000000000000000000000
let newVal := or(shiftedNewE, clearedE)
// shiftedNewE = 0x0000000a00000000000000000000000000000000000000000000000000000000
// clearedE = 0x0001000000000000000000000000000600000000000000000000000000000004
// newVal = 0x0001000a00000000000000000000000600000000000000000000000000000004
sstore(C.slot, newVal)
}
}
function getOffsetE() external pure returns (uint256 slot, uint256 offset) {
assembly {
slot := E.slot
offset := E.offset
}
}
function readE() external view returns (uint256 e) {
assembly {
let value := sload(E.slot) // must load in 32 byte increments
//
// E.offset = 28
let shifted := shr(mul(E.offset, 8), value)
// 0x0000000000000000000000000000000000000000000000000000000000010008
// equivalent to
// 0x000000000000000000000000000000000000000000000000000000000000ffff
e := and(0xffff, shifted)
}
}
function readEalt() external view returns (uint256 e) {
assembly {
let slot := sload(E.slot)
let offset := sload(E.offset)
let value := sload(E.slot) // must load in 32 byte increments
// shift right by 224 = divide by (2 ** 224). below is 2 ** 224 in hex
let shifted := div(
value,
0x100000000000000000000000000000000000000000000000000000000
)
e := and(0xffffffff, shifted)
}
}
}