资源模型

带宽和能量是TRON网络两种重要的系统资源。其中带宽是衡量保存在区块链数据库中的交易字节大小的单位,交易越大,消耗的带宽资源会越多。能量是衡量在TRON网络上TVM虚拟机执行特定操作所需的计算量的单位,由于智能合约交易都需要计算资源来执行,因此每笔智能合约交易都需要付费。

下文我们把带宽也称为Bandwidth Points,能量也称为Energy。

带宽

所有类型的交易都需要支付Bandwidth Points, 交易以字节数组的形式在网络中传输以及存储,一个字节需要一个Bandwidth Points,因此一笔交易需要消耗的Bandwidth Points等于交易字节数。

当可用带宽不足时,需要燃烧TRX来支付Bandwidth Points费用:

燃烧的TRX = 消耗带宽数量 * 带宽单价

目前,带宽单价为1000sun。

带宽的获取

每一个外部账户每天有1500个免费带宽,还可以通过质押TRX获取更多的带宽,所有用户按质押的TRX的数量平分固定额度的带宽,全网每日固定总带宽的供应数量是43,200,000,000个,按如下公式可以计算得到质押一定数量的TRX能获得多少带宽:

获得的带宽数量 = 为获取带宽的TRX质押量 / 全网为获取带宽质押TRX的总量 * 43_200_000_000 

发送FreezeBalanceContract类型交易来质押TRX获取带宽,使用wallet-cli为例:

wallet> freezeBalance TC9vGE2cPC3AkLtCpRvDjNvLh7Efap9Pvg  1000000 3 0  TC9vGE2cPC3AkLtCpRvDjNvLh7Efap9Pvg

带宽的消耗

除了查询操作,任何交易都需要消耗带宽,账户带宽的消耗规则为,首先,判断交易发起者质押TRX获取的带宽是否足够,如果足够,则消耗质押TRX获取的带宽,否则,判断交易发起者的免费带宽是否足够,如果足够,则消耗账户的免费带宽,否则,将燃烧TRX来支付交易的带宽费用,并按照每一个带宽0.001TRX的单价来支付。

带宽的恢复

账户的免费带宽和质押TRX获取的带宽消耗后, 会在24小时内逐步恢复。

账户带宽余额查询

首先调用节点HTTP接口wallet/getaccountresource来获取账户当前的资源状态,然后通过如下公式计算带宽余额:

免费带宽余额 = freeNetLimit - freeNetUsed

通过质押获取的带宽余额 = NetLimit - NetUsed

注:如果接口返回的结果中没有包含上述公式中的参数,表示该参数值为0。

能量

智能合约运行时,每一条指令的执行都需要消耗一定的能量,所以不同复杂度的合约,消耗的能量数量是不一样的。在执行合约时,逐条指令计算并扣除Energy,当账户可用能量不足时,需要燃烧TRX来支付相应的能量费用

燃烧的TRX = Energy数量 * Energy单价

目前,Energy单价为420sun。

能量的获取

能量只能通过质押TRX来获取,所有用户按质押的TRX的数量平分固定额度的能量,全网每日固定总能量的供应数量是90,000,000,000个,按如下公式可以计算得到质押一定数量的TRX能获得多少能量:

获得的能量数量 = 为获取能量质押的TRX数量 / 全网为获取能量质押TRX的总量 * 90_000_000_000

发送FreezeBalanceContract类型交易来质押TRX获取能量,使用wallet-cli为例:

wallet> freezeBalance TC9vGE2cPC3AkLtCpRvDjNvLh7Efap9Pvg  1000000 3 1  TC9vGE2cPC3AkLtCpRvDjNvLh7Efap9Pvg

能量的消耗

在执行合约时,逐条指令计算并扣除账户能量,账户能量消耗的优先级如下:

  • 质押TRX获取的能量
  • 燃烧TRX

首先会消耗交易发起者质押TRX获取的能量,如果消耗完这部分能量后还不够,会继续燃烧账户的TRX来支付交易所需的能量资源,按照每一个能量0.00042TRX的单价来支付。

如果合约中途由于抛出revert异常而退出,则仅扣除已经执行的指令所对应的能量,但是对于异常合约,比如合约执行超时,或因bug异常退出,会扣除本次交易最大可用的能量,用户可以通过设置交易的fee_limit参数来限定这笔交易最多可以消耗的能量费用上限。

能量的恢复

账户的能量资源消耗后,会在24小时内逐步恢复。

账户能量余额查询

首先调用节点HTTP接口wallet/getaccountresource来获取账户当前的资源状态,然后通过如下公式计算能量余额:

能量余额 = EnergyLimit - EnergyUsed

注:如果接口返回的结果中没有包含上述公式中的参数,表示该参数值为0。

动态能量模型

动态能量模型是波场网络的一个资源平衡机制,可以根据合约的资源占用情况动态调整每个合约的能量消耗量,从而使能量资源在链上的分配更加合理,防止网络资源过度集中在少数热门合约上,详情请参考动态能量模型介绍

工作原理

如果合约在一个维护周期(目前是6小时)内使用过多的能量,则在下一个维护周期内,用户向该合约发送相同的交易将产生更多的额外能量消量。当合约合理使用资源时,用户调用该合约所产生的能量消耗将逐渐恢复正常。

每一个合约有一个能量消耗放大系数 - energy_factor,表示该智能合约交易的能量消耗相对于基础能量消耗的增加倍数,初始值是0。合约的energy_factor为0时,表示该合约在合理的使用资源,调用该合约不会有额外的能量消耗。当energy_factor大于0时,表示该合约已经是热门合约,调用该合约时将消耗额外的能量。合约的能量消耗放大系数可以通过 getcontractinfo 接口查询。

合约调用交易最终需要消耗的能量的计算公式为:

合约交易能量消耗量 = 合约调用交易产生的基础能量消耗 * (1 +  energy_factor)

动态能量模型引入了如下三个TRON网络参数,它们共同控制合约的energy_factor字段:

  • threshold:合约基础能量消耗的阈值,如果合约在一个维护周期中的基础能量消耗超过这个阈值,下一个维护周期,该合约的能量消耗量就会增加。
  • increase_factor:合约在某个维护周期的能量消耗超过阈值,则在下一个维护周期,energy_factor就会根据increase_factor增加一定的比例。
  • max_factor:合约energy_factor的最大值

另外还有一个变量decrease_factor用于降低合约的energy_factor

  • decrease_factorincrease_factor的四分之一,合约基础能耗降低到阈值以下后energy_factor会根据decrease_factor减少一定比例。

当合约的基础能量消耗量在一个维护周期内超过了threshold,那么在下一个维护周期它的energy_factor将增加,但最大不会超过max_factor,计算公式为:

energy_factor = min((1 + energy_factor) * (1 + increaese_factor)-1, max_factor)

当合约的基础能量消耗量在一个维护周期内下降到threshold及以下后,那么在下一个维护周期energy_factor就会降低,但最小值不会低于0,计算公式如下:

energy_factor = max((1 + energy_factor) * (1 - decrease_factor)- 1, 0)

动态能量模型在主网已经开启,相关参数设置如下:

  • threshold:3,000,000,000
  • increase_factor:0.2
  • max_factor:1.2

由于热门合约在不同的维护周期的能量消耗是不一样的,所以在调用合约时要为交易设置合适的feelimit参数,更多请参考设置智能合约交易的feelimit

API

下表为动态能量模型相关接口及其说明:

API描述返回值说明
getcontractinfo查询合约信息contract_state.energy_usage:表示合约在当前维护周期内的基础能量使用总量;contract_state.energy_factor:合约的能量消耗放大系数,0表示非热门合约,大于0表示热门合约;contract_state.update_cycle:当前维护周期号
triggerconstantcontract查询合约数据或预估能量energy_penalty 表示惩罚的能量;energy_used 表示总能量(基础能量和惩罚能量的总和)
gettransactioninfobyid查询交易信息receipt.energy_penalty_total 表示惩罚的能量
gettransactionreceiptbyid查询交易执行结果、费用等信息receipt.energy_penalty_total 表示惩罚的能量