分配给 `uint` 如何在以太坊中节省 "storage read" 成本?

How does assigning to `uint` save "storage read" costs in Ethereum?

我正在看 uniswapv2 教程 walkthrough

以下是参考此函数 in the github repo 并且教程说明如下:

    uint _kLast = kLast; // gas savings

The kLast state variable is located in storage, so it will have a value between different calls to the contract. Access to storage is a lot more expensive than access to the volatile memory that is released when the function call to the contract ends, so we use an internal variable to save on gas.

所以在传统编程中,_kLast 将是对 kLast 的引用。 _kLast 在实例化后被引用了 3 次。

同一槽的每次存储读取(操作码sload)在交易期间第一次花费 2,100 gas,然后在同一交易期间每次都花费 100 gas。 (柏林硬分叉实施EIP-2929之后。在此之前,不管读多少次,每次读都是800。)

每次内存写入(操作码mstore)和每次内存读取(操作码mload)花费3 gas。


So in traditional programming, _kLast would be a reference to kLast

在这个特定的 Solidity 片段中,_kLast 不是指向存储的引用。它是一个内存变量,从存储变量中赋值。

所以 3 次存储读取 - 不创建内存变量 - 将花费 2,300 gas (= 2,100 + 100 + 100)。

但是因为代码创建了内存变量,它执行了一次存储读取(2,100 gas),一次内存写入(3 gas)和三次内存读取(3 x 3 gas) - 总共 2,112 gas。哪个更便宜。


其他一些与 EVM 兼容的网络,例如 BSC,可能仍使用每个 sload 800 的原始 gas 计算。这会产生更大的差异 - 未优化的 2,400 gas (3 x 800) 和优化的 812 gas (800 + 3 + 3x3)。