关于 ETH 上 Gas 的误解

in HuaRen.News4 years ago

如果执行的代码相同,我的交易所需消耗的 gas 量也相同。

不对。即使你使用相同的参数来执行相同的指令,gas 成本也有可能不同。例如,相比已经有非零值的存储位置,如果你要写入新的存储位置,SSTORE(写入存储操作)的成本会高得多(参见 EIP2200)。这就意味着,如果你向一个新地址发送两笔 ERC20 代币转账,第一笔交易的成本会比第二笔高得多,即使二者执行的代码完全相同。

调用 estimateGas 会返回交易所需消耗的 gas 量

调用 estimateGas 确实会返回一个 gas 耗费量,但这是该笔交易在 当前状态 下被打包会花费的 gas 量。而区块链的当前状态可能与你需要该笔交易上链时的状态大相径庭。因此,当你的交易被有效打包进区块时,可能会采用不同的代码路径,需要消耗的 gas 量也有可能完全不同。

如果状态完全相同,我的交易所需消耗的 gas 量也相同

通常情况下是的,除非你很倒霉地碰上了硬分叉,导致一些操作重新定价。虽然这听起来很复杂,但说白了就是,你无法针对 dApp 中交易的 gas 上限进行安全的硬编码,除非你决心在每次发生硬分叉后都发布 dApp 更新。

如果代码相同,状态也相同,且没有发生硬分叉,我就可以相信 estimateGas的返回值了吗?

这下你可以相信 estimateGas 的返回值就是你的交易所需消耗的 gas 量了,但是你不知道这笔交易是否会如你所愿的那般进行。所谓的 gas 估测,就是节点将使用不同的 gas 值来尝试你的交易,并返回确保你的交易不会失败的最低 gas 值。但是,节点只会看你的交易,不会看交易的内部调用。这就意味着,如果你调用的合约代码有一个 try/catch 块,导致内部调用发生后无法撤销,你获得的 gas 估测值对调用合约来说是够用的,但是对被调用合约来说就不够了。

在多签名钱包中,这种情况经常发生:即使是在交易失败的情况下,大多数多签钱包会将操作标记为已执行,也就是说它们无法撤销最外层的交易(所带来的影响)。因此,一个原生的 gas 估测返回的值可能对多签代码来说是足够的,对你实际想运行的操作来说不一定足够。这就是为什么 Gnosis Safe 有一个专门的 gas 估测方法。

请注意,这也就是为什么因为 gas 不够而导致操作失败的情况很难察觉。内部调用可能会因为被分配到的 gas 太少而将 gas 耗尽,而交易本身可能还有很多 gas 可用。这就意味着,查看交易的 gas 使用量和 gas 上限并非检测 gas 错误的可靠方式。

管他呢,我每次多发送点 gas 就好了

多数情况下,这个方法是管用的。但是请记住,合约是可以查看它在一笔交易中收到的 gas 的。因此,可以轻而易举地将合约编写成,一旦收到过多 gas,交易就会失败。不过我怀疑的是,除了证明这一点外,这么做没有任何意义。

本帖同步首发

关于 ETH 上 Gas 的误解

最近新帖

  1. 加密货币和区块链是变革催化剂
  2. 71 万人炒币被骗了 77 亿
  3. 波卡的DeFi生态系统正在扩展
  4. 分散投资
  5. 日渐壮大的波卡DeFi生态
  6. DeFi Pulse推出风险评估工具
  7. DeFi的安全难题
  8. 跨链+Defi融合
  9. 数字金融走向分布式 DeFi
  10. @hnt 尝试提供STEEM流动性服务,目前处于测试阶段
  11. BTC跌破$7000之际,STEEM暴跌20%创新低,投资者缺乏信心 steem | hive
  12. BTC突破$7000后蓄势待发,STEEM却突然出现异动?!恐有要事发生? steem | hive
  13. FileCoin继续跳票,IPFS矿机骗局还能搞多久? steem | hive
  14. steem 新分叉HF22.8888 和 hive 今日暴跌,或影响hive网络发展 steem | hive
  15. hive 硬分叉延缓了steem的SMT进度 steem | hive
Sort:  

This post has received a 52.09 % upvote from @boomerang.

Coin Marketplace

STEEM 0.20
TRX 0.13
JST 0.030
BTC 65306.74
ETH 3488.89
USDT 1.00
SBD 2.51