概念
在 Aptos 主网络上,想要完成任意一笔交易,都需要缴纳处理手续费。这笔手续费,会被分发给客户端应用、币权质押人、节点处理人或者投票人。交易手续费的多少,取决于你在链上消耗的计算和存储资源:
- 在链上处理交易
- 把已验证的交易记录传播到整个分布式网络
把交易记录写入链上分布式存储
概念上,这个手续费跟我们居家缴纳的水电费很像
交易优先级
如果你愿意付出更多手续费,就可以提升交易在链上的优先级。对于自己的交易,你在提交时,就可以给一个高出市场的价格。这可以让你的交易在优先级列表中提升权重,从而更快得到处理。
Gas 单位
你可以创建简单而便宜的交易,也可以创建复杂又贵的交易,后者显然要消耗更多的计算和存储资源。无论哪种情况,你都需要支付一笔足够完成交易的手续费。这就是 gas 这个名称的由来。系统是这样处理的:
Aptos 链上,一个单位的 gas 代表了资源的基本消费单元。一个单位的 gas 包含了:
- 计算资源
- 存储资源
当你的交易在链上执行的时候,Aptos 链不会分别统计每种资源消耗了多少,而是统一表达为消费了多少个 gas 单位。
详见 基础 Gas 是如何工作的,这份文档描述了 gas 费的类型和优化方案。
Gas 费
Aptos 的治理规则,会设置一个最小 gas 单位价格,不过真正的最后单位价格,是由市场决定的。原理见 以太坊 Gas 追踪, 这里可以看到以太坊的 Gas 费是如何随着市场价格变动的。
1个单位的 gas,是个无量纲数,用整型表示。一笔交易消耗的总 gas 单位,取决于交易的复杂度。另一方面,Gas 价格是以 Aptos 链上的原生币(Octas)来表示的。想了解交易如何被提交到链,可以查看 交易与状态 文档。
Aptos 链上的 Gas 和交易
任何一笔提交到链上的交易,都必须包含以下关于 Gas 的字段:
max_gas_amount
:发送者愿意为这笔交易付出的最大 gas 单元数。它决定了该交易能消耗的最大可计算资源gas_price
:发送者愿意出的 gas 单位价格,用 Octa 表示:- 1 Octa = 10-8 APT
- APT 即 Aptos 链上币
交易执行的总 gas 费,可以这样计算:总消耗的gas单元数 * gas单位价格
当然如果总 gas 费超过了max_gas_amount
中定义的数,交易就被取消了。所以最终,向客户端收取的最高费用,也就是gas_price * max_gas_amount
链上治理相关的 Gas 参数
Aptos 链上治理,会设置以下这些跟 Gas 相关的参数:
txn.maximum_numberof_gas_units
:一笔交易中,可以花费的最大 gas 单位数(也就是客户端能够设置的max_gas_amount
这个参数的上限)。这个设置,保证了在做动态价格调整的时候,总花费不会超过上限值。txn.min_transaction_gas_units
:可以花费的最小 gas 单位数,也就是客户端设置的max_gas_amount
这个参数的下限。存储资源的动态 gas 价格
Aptos 针对存储资源的价格,是动态调整的。这就意味着,随着 Aptos 链上状态数据库越填越满,存储的 gas 消耗(
gas_used
)会呈指数级增长。在100%的利用率下,存储成本会变得高大100倍。不过,有理由相信,验证者们将会使用更大、更便宜的存储设备,来缓解指数增长的成本。
动态价格可以保证 Aptos 网络面临最糟糕的情形依然可用。不过,我们预计在陷入这高成本的局面之前,会通过升级网络来获得更好的结果。示例
示例1:账户余额 vs 交易费
发送者账户必须有充足的资金,来缴纳交易费
假如,你试图转走账户中所有的钱,以至于余额不足以支付交易费了,Aptos 链会反馈“交易失败”。也就是说,你不可能把账户中的钱转出为0。示例2:交易数额 vs 交易费
交易费和交易数额无关
有一笔交易,叫它“交易A”吧,准备把 1千 个币,从一个账户转到另一个账户;同时有另外一笔“交易B”,准备把 10万 个币,从一个账户转到另一个账户。假设它们几乎同时发生,那么他们的交易费就几乎是一样的。预估 gas 费
可以通过模拟一笔交易的执行,来预估需要花费的 gas 费。在模拟交易的时候,返回的结果表示了,在当时那个时刻,那个特定的链状态下,需要花费 gas 的准确数量。Gas 费会随着链的状态变化而变化。因此,所有模拟出来的结果,都是预估。在设置最大 gas 费的时候,应该在预估结果的基础上,加上一个你能接受的量。
模拟交易来预估 gas 费
可以通过
SimulateTransaction
API 来模拟交易。这个 API 会执行你的交易。注意模拟交易的 签名 必须为全0,以预防某些人使用真正的签名。
模拟交易的的时候,有以下两个标志位参数:
estimate_gas_unit_price
:这个标志就指示 API 返回gas_unit_price
,就像调用estimate_gas_price
这个 API 返回的结果一样。estimate_max_gas_amount
:这个标志提示 API 返回可能需要花费的最大 gas 费,并且通过模拟交易返回一个“实际 gas 费”(gas_used
)模拟步骤
通过模拟交易,获取正确 gas 费设置的步骤如下:
- 把
estimate_gas_unit_price
和estimate_max_gas_amount
这个标记都设置为true
,模拟交易执行,并获得预估值。 - 使用返回的
gas_unit_price
值,作为新交易的gas_unit_price
。 - 把返回的
gas_used * gas_unit_price
,看作交易成本的下限。 - 要获得交易成本的上限,首先取返回的
max_gas_amount
中的最小值,然后计算gas_used * safety factor
(安全系数)。在 Aptos CLI 中,缺省安全系数为 1.5。把这个值当做你要真正提交交易的max_gas_amount
参数。 请注意,交易费用的上限是max_gas_amount * gas_unit_price
,也就是说,这是交易的发送者被收取的最高费用。 此时你已经获得了提交交易需要的两个参数:
gas_unit_price
:从模拟交易的返回值直接得到max_gas_amount
:gas_used * safety factor
中的最小值,或者,直接取回复的max_gas_amount
。
- 如果你需要改变交易的优先级,就可以通过调整
gas_unit_price
来实现:调高价格提高优先级;调低价格降低优先级。
我的语雀原文链接在这里
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。