1. 与永久性存储交互

查看以太坊黄皮书 附录G 全面了解EVM操作码成本。
永久性存储操作码(SSTORE)非常昂贵。首次写插槽时,每个32个字节的当前成本是为20,000 Gas(在10 Gwei gas价格下为5美分,每ETH为250美元),而后续每次修改则为5,000 Gas。尽管从理论上讲复杂度成本是恒定的,但它却是算术或内存运算成本的一千倍以上,而算术或内存运算的成本通常不到10 Gas。目前整个区块(截至2020年10月)的Gas限制为〜12,000,000 Gas实,开发人员应设计其智能合约以最大程度地减少所需的存储插槽数量。请注意,即将到来(?)的状态租赁升级将不必要使用存储。幸运的是,有一些方法可以帮助缓解问题。

2. 不要存储不必要的数据

image.png
如果经常调用createPoll函数,则可以考虑从Poll结构体中删除memo,因为它不会直接影响合约的逻辑。而且触发的备忘录的事件已经包含了memo,而它仅需要存储memo的哈希值(32字节),就可以方便日后进行快速验证。开发者应仔细考虑 gas 成本与合约简便性之间的权衡。

3. 将多个小变量打包到单个字中

EVM在32字节字长存储模型下运行。可以将小于32个字节的多个变量打包到一个存储槽中,以最大程度地减少SSTORE操作码的数量。尽管Solidity 自动尝试将小的基本类型打包到同一插槽中,但是糟糕的结构体成员排序可能会阻止编译器执行此操作。考虑下面的Good和Bad结构体。
image.png
使用启用了优化的编译器:solc 0.5.9 + commit.e560f70d,第一个doBad()函数调用执行消耗约60,000 Gas,而doGood()仅消耗约40,000 Gas。注意是一个字长存储的差异(20,000 Gas),因为Good结构将两个uint128打包为一个字。