gas优化:写入storage前使用memory变量作为中继
2023-03-21 本文已影响0人
梁帆
有这么一个情景,又一个storage的变量,它是一个复杂的struct,如下:
struct MyStruct {
address account;
uint256 value;
bool isTrue;
}
假设变量名为myStruct,有合约如下:
contract Test {
MyStruct public myStruct;
constructor() {}
function setDirectly(uint256 value_, bool isTrue_) external {
myStruct.account = msg.sender;
myStruct.value = value_;
myStruct.isTrue = isTrue_;
}
function setWithMemory(uint256 value_, bool isTrue_) external {
MyStruct memory _myStruct;
_myStruct.account = msg.sender;
_myStruct.value = value_;
_myStruct.isTrue = isTrue_;
myStruct = _myStruct;
}
}
这里面有两个函数,一个是setDirectly,顾名思义,就是直接采用存储在myStruct来为每一个属性依次接收传入的参数;而另一个函数setWithMemory,则是先定义了一个memory中的_myStruct的变量,再将传入参数赋给_myStruct,最后再将_myStruct赋给storage变量myStruct。
最后的gas对比如下:
| 函数 | 写入类型 | gas消耗量 |
|---|---|---|
| setDirectly | 直接写入storage | 101628 |
| setWithMemory | 以memory变量为中继 | 33324 |
可以看到,采用memory变量作为复杂struct的中继,要比直接写入storage节省gas得多。