title: "理解以太坊 Gas 燃料和交易手续费" menuTitle: "Gas" weight: 100009

Gas 中译是:瓦斯、汽油,代表一种可燃气体。 这形象地比喻以太坊的交易手续费计算模式,不同于比特币中直接支付比特币作为转账手续费, 以太坊视为一个去中心化的计算网络,当你发送Token、执行合约、转移以太币或者在此区块上干其他的时候,计算机在处理这笔交易时需要进行计算消耗网络资源,这样你必须支付燃油费购买燃料才能让计算机为你工作。最终燃料费作为手续费支付给矿工。

与比特币不同的是,无论交易成功与否,你都需要为此支付燃料费。这是因为即使交易失败,矿工依旧为此交易进行校验和计算,消耗了资源。同时你也无法在钱包中直接设置支付多少燃料费,因为实际燃料费是矿工根据计算得出的,并记录在包含此交易的区块中。

当你听到别人谈论 gas 时,实际是在讨论两个概念:gasUsed 和 gasPrice,默认情况下是指 gasUsed。你可以把 gasUsed 看成是汽车所需多少升燃油。把 gas price 看成是燃油单价。

对于汽车,每升汽油6.46元(price),10 升汽油就是64.6元。对于以太坊,每gas是20Gwei(price),21000 个 gas 就是 20*21000 Gwei= 420000 Gwei= 0.00042 Ether。也就是说本次交易手续为 0.00042 Ether。

Gwei是以太币的一种计算单位,具体见文末附录:以太币单位

Gas Used

那么,以太坊这台计算机在处理交易时是如何统计计算量的呢? 以太坊有专门的虚拟机处理交易,虚拟机根据交易中确定的一个一个的操作指令进行逐个处理, 而每个操作指令都有明文规定的Gas消耗量。 比如执行一次加法运算将消耗 3Gas, 这样交易需要消耗多少Gas完全取决于执行完交易中的所有操作指令的累计Gas, 交易执行完成时虚拟机将反馈总消耗Gas量,称之为 gasused。 而你所需支付的手续费等于*gasPrice gasUsed**。

指令 Gas Used Notes
STOP 0 停止执行
ADD 3 两个数相加
MUL 5 两个数相乘
SUB 3 两个数相减
DIV 5 两个数相除

更多细节请参见:Gas清单

Gas Limit

因为手续费等于 gasPrice * gasUsed,用户在转账,特别是执行智能合约时 gasUsed 无法提前预知。 这样存在一个风险,当用户的交易涉及一个恶意的智能合约,该合约执行将消耗无限的燃料, 这样会导致交易方的余额全部消耗(恶意的智能合约有可能是程序Bug,如合约执行陷入一个死循环)。

为了避免合约中的错误引起不可预计的燃料消耗,用户需要在发送交易时设定允许消耗的燃料上限,即 gasLimit。 这样不管合约是否良好,最坏情况也只是消耗 gasLimit 量的燃料。

然而,一笔交易所必须支付的燃料已经在区块中通过该交易已执行的计算量记录。 如果你不想支出太多燃料,而故意设置过底的 gas limit 是没太多帮助的。 你必须支付足够燃料来支付本交易所必要的计算资源。如果交易尚未执行完成,而燃料已用完, 将出现一个 Out of Gas 的错误。特别注意的是,即使交易失败,你也必须为已占用的计算资源所支付手续费。 比如,你通过合约给 TFBOYS 投票,设置 gasPrice=2 gwei,gasLimit=40000(实现投票需要40001的燃料开销), 最终你投票失败且仍然需要支付 40000*2 gwei= 80000 gwei= 0.00008 ETH。

另外,如果最终 gasUsed 低于 gasLimit,即燃料未用完。则剩余燃料(gasLimit - gasUsed )将在交易后退还给你。 比如你发送 1 Ether 到另一个账户B,设置 gas limit 为 400000,将有 400000 - 21000 返回给你。

21000 是标准转账交易的gasUsed。因此一笔标准的转账交易你可以设置 gasLimit 为21000。

Gas Price

因为你所需要支付的燃料费为燃料单价(gasPrice) * 燃料开销(gasUsed),如果你想让交易花费更少, 你能够做的是降低你愿意支付的燃料单价。 另一方面,降低燃料单价的坏处是交易可能需要等待很长时间才被打包到区块中。

这是因为交易燃料费将归属于挖出本区块的矿工。当矿工挖矿时,他需要决定哪些交易放入到区块中,可以随机选择交易, 也可以不包含任何交易。为了鼓励让矿工将你的交易放入区块,你会考虑将燃料单价设置得足够诱人,已确保能优先放入区块。

但这还是一厢情愿,因为这个最终取决于矿工。大部分矿工遵循一个简单策略,优先打包本地交易, 将接受到的交易按燃油单价从高到底排列,依次放入区块中直到塞满区块,或者直到低于矿工所设置的燃料单价底限。

如果你着急交易,高燃料单价会使得你的交易排在别人前面。 如果不着急,你只需设置一个足够让矿工包含你交易的燃油单价即可。

一般情况下:

  • 高燃料单价为50 GWEI 的交易几乎总能放到下一个区块。
  • 高燃料单价为22 GWEI 的交易通常会把它放到未来的几个区块中。
  • 高燃料单价为8 GWEI 的交易通常会在未来几分钟内放入区块。

下图是最近1000个区块中不同燃料价格对交易确认时间的影响: 不同燃料价格对交易确认时间

可以因为当前以太坊的交易处理性能(15笔/秒),当出现交易高峰期拥堵时,你需要考虑调整燃料单价, 比如在Token创建后,抢购火热,为了中签你需要设置更高的燃料单价,以能够优先抢购Token。

在设置燃料单价时,你还需要考虑加密货币的价格波动,相对人民币随时都涨跌20%。 按人民币考虑,之前的交易 10 gas price 相当于0.3元,而现在可能已经是0.4元。 所以需要根据实际情况,尽量调低燃料单价。而当网络中大部分交易都是较低燃料单价时,矿工也会去调整他的底限。

那么问题来了,到底该设置多少燃料单价才合适呢? 你可以到ethgasstation网站上查看。它将告诉你现在整个以太坊的情况,并给你建议的燃料单价,下图是当前的燃料单价设置建议。

"以太坊交易燃料单价设置建议"

附录-以太币的计算单位

  • Kwei(Babbage) = 10**3 Wei
  • Mwei(Lovelace) = 10**6 Wei
  • Gwei(Shannon) = 10**9 Wei
  • Microether(Szabo) = 10**12 Wei
  • Milliether(Finney) = 10**15 Wei
  • Ether = 10**18 Wei

Copyright© 2013-2020

All Rights Reserved 京ICP备2023019179号-8