资源支付与能量分摊
当带宽或能量不足时, 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 通常按以下顺序支付:
- 首先使用账户通过自身质押或接收代理获得的 Bandwidth。
- 通过质押或接收代理获得的 Bandwidth 不能完整支付本次交易时,再尝试使用账户免费 Bandwidth,当前额度为 600 Bandwidth。
- 免费 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 支付顺序
- 先按合约的
consume_user_resource_percent切分理论份额:调用方承担totalEnergy × percent / 100,部署方承担totalEnergy × (100 - percent) / 100。 - 部署方实际承担值为
min(部署方理论份额, origin_energy_limit, 部署方通过质押或接收代理获得的可用 Energy)。 - 调用方实际承担值为
totalEnergy - 部署方实际承担值。如果部署方可用 Energy 不足,或被origin_energy_limit限制,未覆盖部分会并入调用方成本。 - 调用方份额先消耗调用方可用 Energy;仍不足时,按当前能量单价从调用方余额燃烧 TRX。
- 调用方可承担的 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 或协议前端可以为核心合约路径补贴能量,把费用体验从“每次调用都由用户承担”改为“由协议方按预算承担一部分”。
这个机制只适用于部署方控制的合约。若要替用户承担第三方合约的成本,通常应使用资源代理,而不是尝试修改对方合约的分摊参数。
修改参数
部署方可以在合约部署后修改这两个参数:
wallet/updatesetting:修改consume_user_resource_percent。wallet/updateenergylimit:修改origin_energy_limit。
参数更新交易生效后,节点执行后续合约调用时会读取当时的链上配置。交易是否已进入交易池不会把旧配置固定在该交易中。
能量分摊示例
假设某次合约调用消耗 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,000 | 90,000 Energy |
| 调用方质押抵扣 | 可用 30,000 Energy | 抵扣 30,000 Energy |
| 调用方燃烧 TRX | 60,000 × 0.0001 TRX | 6 TRX |
虽然理论比例是调用方 30%、部署方 70%,但部署方受 origin_energy_limit 限制,只实际承担 10,000 Energy。剩余成本全部回到调用方侧。
fee_limit
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,后续调用会附加一个动态能量因子,使同一路径的实际能量成本升高。使用率回落后,该因子会逐步降低。
相关链参数包括:
| 参数 ID | API key | 作用 |
|---|---|---|
#72 | getAllowDynamicEnergy | 动态能量模型开关 |
#73 | getDynamicEnergyThreshold | 触发动态调整的合约能耗阈值 |
#74 | getDynamicEnergyIncreaseFactor | 超过阈值后的增长因子 |
#75 | getDynamicEnergyMaxFactor | 动态能量因子上限 |
开发者在估算热门合约成本时,应把动态能量纳入考虑。triggerconstantcontract 和 estimateenergy 返回的估算结果能帮助判断当前调用是否带有能量惩罚。
相关资源
- 带宽与能量 — 两类资源的工作原理和获取方式
- FeeLimit 与能量成本 —
fee_limit设置和估算方法 - 资源模型 — 带宽、能量与 TRON Power 概览
- TVM — 智能合约执行环境与能量计量
- 网络参数 — 费用相关链参数
wallet/updatesetting— 修改consume_user_resource_percentwallet/updateenergylimit— 修改origin_energy_limit
Updated 2 days ago
