Gas 是ETH中所有计算量的计价单位,ETH正是使用 Gas 来解决 “谁为服务买单” 的问题。你想要转账给另一个ETH账户吗?你想要部署智能合约来存储手机通讯录吗?没问题,请先支付 Gas 。
这很容易让人联想到,汽车和燃油的关系:如果你想从 A 地开车到 B 地,一定要耗费部分燃油;同理,如果你想要在ETH EVM 上执行某些运算,也要支付 Gas。车想要开得越远,则需要越多燃油;想要在ETH上进行越多计算,则要支付越多 Gas。
我们可以在ETH黄皮书的附录 G,找到每一种 EVM 运算对应所需要消耗的 Gas 数量;这些数值看起来很随意,但其实背后是有道理的。一般来讲,这些数值反映了执行运算的成本(按时间维度度量),和占用的永久存储器资源(当写入数据的时候)。如果想要了解更详细的 Gas 成本计算公式,可以查阅 “ETH 1.0 Gas 成本表”。我不太确定它与最新采用的 Gas 消耗量是否一致,但至少能让你对操作码的 Gas 耗用量制定原则更有概念。
从另一个角度来说,ETH采取使用者付费的模式,能够避免资源的滥用。一旦你必须为每种运算支付费用,你就会尽可能的将代码写得简洁高效;Gas 的存在还能阻止攻击者通过无效运算,对ETH网路进行泛洪(Flooding)攻击。(除非攻击者愿意支付一大笔钱来执行无效运算)
gasPrice 和 gasLimit
现在我们明白了 Gas,是时候谈谈 Gas 究竟要如何定价;先让我们回到汽车和燃油的例子。
如果你的车子油箱容量为 50 升,装满这个油箱你要支付多少钱?这取决于加油站每升的油价对吧?ETH中 Gas 的定价也是一样的!如果你要执行的交易需要耗费 10 Gas,则你要支付的费用取决于每单位 Gas 的价格。
那我们怎么知道每单位 Gas 的价格是多少呢?有种误导性的说法是:自己爱定多少就定多少。虽然从技术角度来讲没有错,但要具体知道 Gas 的定价,我们需要更多知识作为铺垫。
如果你读过ETH解析系列的上一篇文章,应该记得ETH交易结构中,除了其他部分,还包含了 gasPrice 和 gasLimit。 gasPrice表示交易发送方对每单位Gas愿意支付的价格(以 Wei 计量),这意味着交易发送方可以自定义愿意支付的每单位 Gas 价格。假设一笔交易需要耗费 10 Gas,而我们愿意支付 3 Wei/Gas ,则发送这笔交易的成本总价就是 30 Wei(非实际数值,只是便于大家理解怎么计算的)。 gasLimit表示交易发送方最多能接受多少 Gas 被用于执行此交易。因为有时候,你无法确切知道执行一笔交易要耗费多少 Gas;又或是你的智能合约中,有永远跳不出的死循环 bug,假如没有 gasLimit,这会导致发送方的账户余额被误消耗殆尽。 gasLimit 就是一种安全机制,防止有人因为错误估算或 bug 而把账户中所有以太币消耗掉。
另一个有趣的点是,gasLimit 可以被视为预付的 Gas。当节点在验证交易时,先将 gasPrice 乘 gasLimit 算出交易的固定成本。如果交易发送方的账户余额小于交易固定成本,则该交易视为无效。交易执行完之后,剩余的 Gas 会退回至发送方账户;当然,如果交易执行中 Gas 耗尽,则不会退回任何东西。这也能解释为什么交易发送方总是将 gasLimit 设得高于预估的 Gas 量。
搞清楚这两个参数的意思之后,你可能会想问:“为什么是交易发送方自行决定每单位 Gas 的价格”。如果你跑去最近的加油站告诉收银员,“每升油我就愿意支付 5 分钱”;好一点的收银员可能就一笑而过,而理智的收银员可能会报警。所以想要了解设计机制,你需要知道矿工节点的工作以及手续费是什么。
原文链接: https://www.lucassaldanha.com/ethereum-yellow-paper-walkthrough-3-7-gas-and-payment/ 作者: Lucas Saldanha 翻译&校对: IAN LIU & 阿剑
(本文来源于ETH爱好者 EthFans,未经作者许可严禁转载,违者法律必究)