资源支付与能量分摊
当带宽或能量不足时, TRON 如何通过 TRX 余额支付资源成本,以及合约部署方如何为调用方分摊能量。
TRON 的资源支付围绕两个问题展开:资源不足时谁付费,以及智能合约调用的能量成本能否由 DApp 承担。
普通交易主要消耗带宽;智能合约调用还会消耗能量。账户的质押资源、免费带宽和代理资源不足时,网络会按当前资源单价从发送方余额中燃烧 TRX,用于支付资源成本。智能合约还多了一个 TRON 特有能力:合约部署方可以用自己的质押能量为调用方分摊部分或全部能量成本。
前置阅读
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。
- 再消耗账户每日 600 免费 Bandwidth。
- 仍不足时,按当前带宽单价从发送方余额燃烧 TRX。
能量:
- 先按合约的
consume_user_resource_percent切分理论份额:调用方承担totalEnergy × percent / 100,部署方承担totalEnergy × (100 - percent) / 100。 - 部署方实际承担值为
min(部署方理论份额, origin_energy_limit, 部署方可用质押 Energy)。 - 调用方实际承担值为
totalEnergy - 部署方实际承担值。如果部署方可用 Energy 不足,或被origin_energy_limit限制,未覆盖部分会并入调用方成本。 - 调用方份额先消耗调用方可用 Energy;仍不足时,按当前能量单价从调用方余额燃烧 TRX。
- 调用方可通过燃烧 TRX 覆盖的 Energy 上限受
fee_limit约束,计算方式为fee_limit / sunPerEnergy。超过该预算时,交易会以OUT_OF_ENERGY失败并回滚状态,已经消耗的资源不会退还。
部署方不会因为能量分摊而直接燃烧自己的 TRX 余额。部署方能承担的是其账户中可用的质押 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;部署方覆盖不足时,缺口才并入调用方侧,并受调用方 fee_limit 约束。
更详细的设置方法参见 FeeLimit 与能量成本。
动态能量模型
动态能量模型用于调节热门合约的资源占用。当某个合约在计算窗口内消耗过多 Energy,后续调用会附加一个动态能量因子,使同一路径的实际能量成本升高。使用率回落后,该因子会逐步降低。
相关链参数包括:
| 参数 ID | API key | 作用 |
|---|---|---|
#72 | getAllowDynamicEnergy | 动态能量模型开关 |
#73 | getDynamicEnergyThreshold | 触发动态调整的合约能耗阈值 |
#74 | getDynamicEnergyIncreaseFactor | 超过阈值后的增长因子 |
#75 | getDynamicEnergyMaxFactor | 动态能量因子上限 |
开发者在估算热门合约成本时,应把动态能量纳入考虑。triggerconstantcontract 和 estimateenergy 返回的估算结果能帮助判断当前调用是否带有能量惩罚。
账户创建的特殊费用
激活新账户除了正常带宽成本外,还会收取固定账户创建费。常见路径包括:
- 从已有账户向新地址转账 TRX 或 TRC-10 Token。
- 调用
wallet/createaccount。 - 通过智能合约逻辑间接激活新地址。
普通账户激活会收取 1 TRX 账户创建费;如果发送方带宽不足,还会额外销毁 0.1 TRX 补足带宽。通过智能合约激活新地址时,还会额外消耗 25,000 Energy。
账户激活细节参见账户与密钥。
相关资源
- 带宽与能量 — 两类资源的工作原理和获取方式
- FeeLimit 与能量成本 —
fee_limit设置和估算方法 - 资源模型 — 带宽、能量与 TRON Power 概览
- TVM — 智能合约执行环境与能量计量
- 网络参数 — 费用相关链参数
wallet/updatesetting— 修改consume_user_resource_percentwallet/updateenergylimit— 修改origin_energy_limit
Updated 26 days ago