gas优化:使用storage临时存储避免重复索引

在比较下面合约中的两个方法时:

contract MyTest {
    uint256 public nonce = 0;
    mapping(address => mapping(uint256 => MyStruct)) public getStructByNonceByAccount;

    constructor(uint256 value_, bool isTrue_) {
        MyStruct memory _myStruct;
        _myStruct.account = msg.sender;
        _myStruct.value = value_;
        _myStruct.isTrue = isTrue_;

        getStructByNonceByAccount[msg.sender][nonce] = _myStruct;

        nonce++;
    }

    function getMyStructAttributes() external view returns(address, uint256, bool) {
        address account = getStructByNonceByAccount[msg.sender][0].account;
        uint256 value = getStructByNonceByAccount[msg.sender][0].value;
        bool isTrue = getStructByNonceByAccount[msg.sender][0].isTrue;

        return (account, value, isTrue);
    }

    function getMyStructAttributesWithTempStorage() external view returns(address, uint256, bool) {
        MyStruct storage myStruct = getStructByNonceByAccount[msg.sender][0];
        address account = myStruct.account;
        uint256 value = myStruct.value;
        bool isTrue = myStruct.isTrue;

        return (account, value, isTrue);
    }
}
函数 写入类型 gas消耗量
getMyStructAttributes 重复索引 7528
getMyStructAttributesWithTempStorage 以storage变量为中继 7291

可以发现第二个方法 getMyStructAttributesWithTempStorage()更节约gas。原因如下:

在第一个方法 getMyStructAttributes() 中,我们在每次调用该函数时都要使用 getStructByNonceByAccount()函数查询映射中的值,并将其存储在新的变量中。这意味着我们需要进行多次映射查询多次变量分配,从而增加了燃气成本。

而在第二个方法 getMyStructAttributesWithTempStorage()中,我们首先将 MyStruct 变量存储在一个Storage变量中,然后使用该Storage变量进行映射访问和属性查询。这减少了映射访问和变量分配的次数,从而减少了燃气成本。

因此,第二个方法更节约gas。虽然节约的gas有限,但是第二种方法能使得代码更为简洁,因此很鼓励使用。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容