资源支付与能量分摊

当带宽或能量不足时, TRON 如何通过 TRX 余额支付资源成本,以及合约部署方如何为调用方分摊能量。

TRON 的资源支付围绕两个问题展开:资源不足时谁付费,以及智能合约调用的能量成本能否由 DApp 承担。

TRX 转账、投票和质押等系统合约交易消耗 Bandwidth;智能合约部署和调用还会消耗 Energy。账户的质押资源、免费 Bandwidth 和代理资源不足时,网络会按当前资源单价从发送方余额中燃烧 TRX,用于支付资源成本。智能合约还支持由部署方使用自己通过质押或接收代理获得的 Energy,为调用方分摊部分或全部 Energy 成本。

📘

前置阅读

TRX 燃烧费率

当可用资源不足以覆盖交易成本时,网络按以下链参数费率燃烧 TRX:

资源主网当前燃烧单价链参数
Bandwidth每 Bandwidth 0.001 TRX#3 getTransactionFee
Energy每 Energy 0.0001 TRX#11 getEnergyFee

这些单价是链上参数,不是写死常量。集成时应通过 wallet/getchainparameters 查询实时值;参数变更流程参见网络参数。

示例:一笔 270 Bandwidth 的 TRX 转账,如果发送方没有可用带宽,将燃烧 270 × 0.001 = 0.27 TRX。

扣费顺序与计算逻辑

Bandwidth 常规支付顺序

除账户创建和 TRC-10 发行方赞助等特殊支付规则外,交易所需的 Bandwidth 通常按以下顺序支付:

  1. 首先使用账户通过自身质押或接收代理获得的 Bandwidth。
  2. 通过质押或接收代理获得的 Bandwidth 不能完整支付本次交易时,再尝试使用账户免费 Bandwidth,当前额度为 600 Bandwidth。
  3. 免费 Bandwidth 也不能完整支付时,按整笔交易所需的 Bandwidth 燃烧 TRX。

每种方式都必须能够单独支付整笔交易所需的 Bandwidth,不会组合使用,也不会只对未覆盖的部分燃烧 TRX。主网当前 getTransactionFee 为每 Bandwidth 1,000 sun,即 0.001 TRX。

使用免费 Bandwidth 时,账户自身的剩余额度和全网共享的免费 Bandwidth 额度都必须能够完整支付本次交易;任一不足,都不能使用该免费额度。

账户创建的特殊费用

通过系统合约创建或激活新账户时,会收取固定账户创建费,并采用单独的 Bandwidth 支付规则。常见路径包括:

  • 从已有账户向新地址转账 TRX 或 TRC-10 Token。
  • 调用 wallet/createaccount。

主网当前固定账户创建费为 1 TRX。创建新账户所需的 Bandwidth 不能使用账户免费 Bandwidth;网络会尝试从发送方通过质押或接收代理获得的 Bandwidth 中扣除“交易 Bandwidth × getCreateNewAccountBandwidthRate”,主网当前倍率为 1。若该额度不能完整覆盖,则不扣除部分 Bandwidth,并在账户创建费之外另固定燃烧 0.1 TRX(getCreateAccountFee)。

合约激活:智能合约向未激活地址转移 TRX 或 TRC-10 Token 时,会自动激活接收方。该路径不收取上述 1 TRX 账户创建费。外层交易也不采用账户创建的专用 Bandwidth 计费方式,因此不会收取 getCreateAccountFee 对应的 0.1 TRX 固定费用。

承载本次合约执行的外层交易仍由交易发起账户按常规顺序支付 Bandwidth。其通过质押或接收代理获得的 Bandwidth 与免费 Bandwidth 均不能单独覆盖整笔交易时,按“外层交易所需 Bandwidth × getTransactionFee”燃烧 TRX。合约内部转账本身不另计 Bandwidth。

激活新账户时,相关 TVM 调用的基础 Energy 成本增加 25,000;该数值是协议实现常量,不是链参数。

账户激活细节参见账户与密钥。

TRC-10 发行方 Bandwidth 赞助

非发行方向已激活账户转移 TRC-10 Token 时,网络会优先尝试使用发行方通过质押或接收代理获得的 Bandwidth 支付本次交易。只有发送方针对该 Token 的剩余赞助额度、该 Token 面向所有非发行方转账的共享剩余赞助额度,以及发行方的上述 Bandwidth 都足以支付整笔交易,赞助才会生效;否则由发送方按常规顺序支付。

向未激活地址转移 TRC-10 Token 时,采用账户创建规则,不使用发行方赞助。

Energy 支付顺序

  1. 先按合约的 consume_user_resource_percent 切分理论份额:调用方承担 totalEnergy × percent / 100,部署方承担 totalEnergy × (100 - percent) / 100。
  2. 部署方实际承担值为 min(部署方理论份额, origin_energy_limit, 部署方通过质押或接收代理获得的可用 Energy)。
  3. 调用方实际承担值为 totalEnergy - 部署方实际承担值。如果部署方可用 Energy 不足,或被 origin_energy_limit 限制,未覆盖部分会并入调用方成本。
  4. 调用方份额先消耗调用方可用 Energy;仍不足时,按当前能量单价从调用方余额燃烧 TRX。
  5. 调用方可承担的 Energy 上限受 fee_limit 约束,按 fee_limit / sunPerEnergy 换算;该预算同时覆盖调用方通过质押或接收代理获得的 Energy,以及通过燃烧 TRX 支付的 Energy。超过该预算时,交易会以 OUT_OF_ENERGY 失败并回滚状态,已经消耗的资源不会退还。

部署方不会因为能量分摊而直接燃烧自己的 TRX 余额。部署方能承担的是其通过质押或接收代理获得的可用 Energy;如果部署方 Energy 不足,缺口会回到调用方侧结算。如果调用方与部署方是同一账户,则按调用方路径结算,不再产生“部署方为调用方代付”的实际分摊。

部署方能量分摊

合约部署时,部署方可以通过两个参数控制每次调用的能量分摊:

参数含义
consume_user_resource_percent调用方承担的能量百分比
origin_energy_limit部署方单笔最多代付的 Energy

consume_user_resource_percent 决定理论比例:

  • 0:调用方承担 0%,部署方理论上承担 100%。
  • 100:调用方承担 100%,行为接近以太坊的调用方全额付费模式。
  • 30:调用方承担 30%,部署方理论上承担 70%。

origin_energy_limit 决定部署方单笔最多承担多少 Energy。即使理论比例要求部署方承担更多,只要超过该上限,超出部分就会转回调用方。

为什么对 DApp 有用

部署方能量分摊让 DApp 可以在不引入中继服务或链下代付系统的情况下,为用户承担合约执行成本。典型用法包括:

  • 新用户只需要激活账户和免费带宽,就能完成部分低成本交互。
  • 游戏、NFT、社交类 DApp 可以降低高频状态写入给用户带来的 TRX 余额压力。
  • DEX 或协议前端可以为核心合约路径补贴能量,把费用体验从“每次调用都由用户承担”改为“由协议方按预算承担一部分”。

这个机制只适用于部署方控制的合约。若要替用户承担第三方合约的成本,通常应使用资源代理,而不是尝试修改对方合约的分摊参数。

修改参数

部署方可以在合约部署后修改这两个参数:

参数更新交易生效后,节点执行后续合约调用时会读取当时的链上配置。交易是否已进入交易池不会把旧配置固定在该交易中。

能量分摊示例

假设某次合约调用消耗 100,000 Energy,合约参数和账户状态如下:

  • consume_user_resource_percent = 30:调用方理论承担 30%,部署方理论承担 70%。
  • origin_energy_limit = 10,000:部署方单笔最多代付 10,000 Energy。
  • 部署方当前通过质押或接收代理获得的可用 Energy 为 50,000。
  • 调用方当前通过质押或接收代理获得的可用 Energy 为 30,000。
  • 当前能量单价为每 Energy 0.0001 TRX(100 sun)。

结算过程如下:

阶段计算结果
部署方理论份额100,000 × 70%70,000 Energy
部署方实际承担min(70,000, 10,000, 50,000)10,000 Energy
调用方实际承担100,000 - 10,00090,000 Energy
调用方质押抵扣可用 30,000 Energy抵扣 30,000 Energy
调用方燃烧 TRX60,000 × 0.0001 TRX6 TRX

虽然理论比例是调用方 30%、部署方 70%,但部署方受 origin_energy_limit 限制,只实际承担 10,000 Energy。剩余成本全部回到调用方侧。

fee_limit

每笔写入类智能合约交易都带有 fee_limit 字段。它以 sun 为单位填写,用于确定调用方在本次交易中可使用的 Energy 上限。这个上限覆盖调用方通过质押或接收代理获得的可用 Energy,以及调用方余额可通过燃烧 TRX 支付的 Energy:

调用方可使用的最大 Energy = fee_limit / sunPerEnergy

其中 sunPerEnergy 来自链参数 #11 getEnergyFee。

因此,fee_limit 更准确地说是调用方侧的 Energy 预算上限,而不是简单的“最多燃烧多少 TRX”。

如果调用方侧最终需要燃烧的 TRX 超过 fee_limit 可覆盖的能量预算,交易会以 OUT_OF_ENERGY 失败并回滚状态。已经消耗的资源不会退还。fee_limit 的最大可设置值受链参数 #47 getMaxFeeLimit 限制,主网当前上限为 15,000 TRX。

fee_limit 只约束调用方侧成本。部署方分摊的 Energy 来自其通过质押或接收代理获得的 Energy;部署方覆盖不足时,缺口才并入调用方侧,并受调用方 fee_limit 约束。

更详细的设置方法参见 FeeLimit 与能量成本。

动态能量模型

动态能量模型用于调节热门合约的资源占用。当某个合约在计算窗口内消耗过多 Energy,后续调用会附加一个动态能量因子,使同一路径的实际能量成本升高。使用率回落后,该因子会逐步降低。

相关链参数包括:

参数 IDAPI key作用
#72getAllowDynamicEnergy动态能量模型开关
#73getDynamicEnergyThreshold触发动态调整的合约能耗阈值
#74getDynamicEnergyIncreaseFactor超过阈值后的增长因子
#75getDynamicEnergyMaxFactor动态能量因子上限

开发者在估算热门合约成本时,应把动态能量纳入考虑。triggerconstantcontract 和 estimateenergy 返回的估算结果能帮助判断当前调用是否带有能量惩罚。

相关资源