gas优化之短路(Short-circuit )优化原理

  • iszzm123
  • 发布于 7 小时前
  • 阅读 17

把最可能决定最终结果且最便宜的条件放在最前面,让后面的昂贵检查尽可能被短路掉。&&串联:最左边的条件应当是最可能为false且最便宜的。||串联:最左边的条件应当是最可能为true且最便宜的。

把 最可能决定最终结果 且 最便宜 的条件放在最前面,让后面的昂贵检查尽可能被短路掉。

&& 串联:最左边的条件应当是 最可能为 false 且最便宜 的。

|| 串联:最左边的条件应当是 最可能为 true 且最便宜 的。

同时,考虑 gas 成本排序:

便宜操作:比较局部变量(栈变量)、常量、函数参数、msg.sender 等

昂贵操作:SLOAD(读取状态变量)、跨合约调用、计算哈希等

例:

// 状态变量
  address public owner;
  mapping(address => bool) public whitelist;
  bool public paused;
  
  //  未优化:每次都读取 paused 和 whitelist(SLOAD),即使调用者是 owner
  function sensitiveAction() external {
          require(paused == false, "Paused");
          require(whitelist[msg.sender] || msg.sender == owner, "Not allowed");
          // ... 业务逻辑
  }

每次都会执行 2 次 SLOAD(paused、whitelist),即使 msg.sender == owner 直接允许。

// 优化后(利用短路)
function sensitiveAction() external {
	require(msg.sender == owner || (!paused && whitelist[msg.sender]), "Not allowed");
	// ... 业务逻辑
}    

执行逻辑:

  1. 先检查 msg.sender == owner(极便宜,比较栈上的地址)。
  2. 如果为 true短路,不再读取 pausedwhitelist,直接通过。
  3. 如果 msg.sender 不是 owner,才继续读取 pausedwhitelist[msg.sender](两次 SLOAD)。

结果:普通用户调用时 gas 差不多,但 owner 调用时可省下两次 SLOAD(~2100+ gas)。如果合约有大量仅管理员可用的函数,节省非常可观。

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
iszzm123
iszzm123
最近有应聘的意向