首次调用智能合约函数时Gas消耗为何远高于后续调用?
以太坊合约首次调用Gas消耗高于后续调用的原因
测试代码
Demo合约
contract Demo { function add1(uint256 a, uint256 b) public pure returns (uint256) { if (a==0) { return 0; } uint256 c = a + b; return c; } }
Test合约
contract Test { Demo demo = new Demo(); function testGas() public { uint256 startGas = gasleft(); demo.add1(1, 2); uint256 endGas = gasleft(); uint256 gasUsage1 = startGas - endGas; startGas = gasleft(); demo.add1(1, 2); uint256 endGas = gasleft(); uint256 gasUsage2 = startGas - endGas; } }
测试结果
测试结果显示,gasUsage1为6434,gasUsage2为1919;第三次调用该函数时,Gas消耗与第二次一致。
问题
为何首次调用函数时Gas消耗远高于后续调用?
原因解析
这是以太坊虚拟机(EVM)的合约代码加载机制导致的:
- 首次调用目标合约的函数时,EVM需要从区块链存储中读取该合约的完整字节码,并将其加载到内存中。这个过程涉及多次
SLOAD操作(读取链上存储的成本)以及内存分配的开销,这些都会额外消耗Gas。 - 后续调用时,合约的字节码已经被缓存到EVM的内存中,无需再从链上读取。此时仅需要执行函数本身的逻辑运算,比如参数判断、加法计算等,这些操作的Gas消耗远低于首次加载代码的成本,因此后续调用的Gas消耗会显著降低并保持稳定。
由于你测试的add1是pure函数,本身执行逻辑的Gas消耗极低,所以首次加载代码的额外成本显得格外突出。即使是复杂函数,首次调用也会因代码加载产生额外Gas,只是这部分成本在总消耗中的占比会相对减小。
内容的提问来源于stack exchange,提问作者Zoey
相关产品推荐
相关产品推荐

