## 1. 简单的例子

``````// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Test {
uint balance;
uint balance2;
uint balance3;

function modify() external {
balance = 1;
balance2 = 2;
balance3 = 3;
}
}``````

``````045 JUMPDEST |0x64cf33b8| (this is the function signature, we will discard it)
046 PUSH1 42 |0x42|
048 PUSH1 01 |0x01|0x42|
050 PUSH1 00 |0x00|0x01|0x42|
052 DUP2     |0x01|0x00|0x01|0x42|
053 SWAP1    |0x00|0x01|0x01|0x42|
054 SSTORE   |0x01|0x42|
055 PUSH1 02 |0x02|0x01|0x42|
057 SWAP1    |0x01|0x02|0x42|
058 DUP2     |0x02|0x01|0x02|0x42|
059 SWAP1    |0x01|0x02|0x02|0x42|
060 SSTORE   |0x02|0x42|
061 PUSH1 03 |0x03|0x02|0x42|
063 SWAP1    |0x02|0x03|0x42|
064 SSTORE   |0x42|
065 JUMP     ||
066 JUMPDEST ||
067 STOP     ||``````

``````sstore(0x0,0x1)
sstore(0x1,0x2)
sstore(0x2,0x3)``````

> 修改函数的Gas成本

## 2. 使用uint8 而不是uint256

``````// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;  contract Test {
uint8 balance;
uint8 balance2;
uint8 balance3;

function modify() external {
balance = 1;
balance2 = 2;
balance3 = 3;
}
function modify2() external {
balance2 = 5;
}
}``````

``````045 JUMPDEST     |function signature (discarded)|
046 PUSH1 00     |0x00|
048 DUP1         |0x00|0x00|
049 SLOAD        |0x00|0x00| (the slot 0 in storage contains 0x030201)
050 PUSH3 ffffff |0xffffff|0x00|0x00|
054 NOT          |0xffffff...fffff000000|0x00|0x00| (the NOT inverse all 32 bytes of Stack(0)
055 AND          |0x00|0x00|
056 PUSH3 030201 |0x030201|0x00|0x00|
060 OR           |0x030201|0x00|
061 SWAP1        |0x00|0x030201|
062 SSTORE       ||
063 STOP         ||``````

EVM推送 "ffffff" 和NOT（取反）这个，结果是 0xfffffffffffffffffffffffffffffffffffffffffffffffff000000， NOT指令反转了Stack(0)的所有字节。

``````075 PUSH1 00   |0x00|
077 DUP1       |0x00|0x00|
078 SLOAD      |0x030201|0x00| (Slot 0 = balance which contains 0x030201 as set previously)
079 PUSH2 ff00 |0xff00|0x030201|0x00|
082 NOT        |0xfff...fffff00ff|0x030201|0x00|
083 AND        |0x000...000030001|0x01|0x00|
084 PUSH2 0500 |0x0500|0x000...000030001|0x01|0x00|
087 OR         |0x000...000030501|0x01|0x00|
088 SWAP1      |0x01|0x000...000030501|0x00|
089 SSTORE     |0x00|
090 STOP       ||``````
1. 首先（指令78），EVM 加载存储的槽 0，即0x030201
2. 其次(指令79-82)，EVM对 ff00 取反(NOT)，在32个字节的结果是 0xfffffffffffffffffffffffffffffffffffffffffffffffffff00ff
3. 在指令83，2个结果进行与运算，即0x00000000000000000000000000000000000000000000000000030001(或0x030001)。 这和存储槽0是一样的，但是没有02（合约中的 "balance2"的部分），这是正常的！为什么？ 这是因为在modify2()中，EVM修改了balance2。首先它需要擦除之前的结果，而不擦除balancebalance3（因为它们在同一个槽中），所以它通过使用0xfff...ff00ff掩码来 "清洗" 结果。
4. 之后，0500被推入堆栈（指令84），最后的2个结果进行OR操作（指令85），最后的结果是：0x030501，"OR"的目的是在03和01的边上加上05。因此余额2被成功地修改，而没有改变余额和余额3。

0x9e64...7c84