资源模型¶
资源模型介绍¶
TRON网络中的资源有4种:带宽,CPU,存储和内存。得益于波场独有的内存模型,TRON网络中的内存资源几乎是无限的。 TRON网络引入了Bandwidth point 和 Energy 两种资源概念。其中Bandwidth Point表示带宽资源,Energy表示CPU和存储资源。
Note
- 普通交易仅消耗Bandwidth points
- 智能合约的操作不仅要消耗Bandwidth points,还会消耗Energy
带宽¶
交易以字节数组的形式在网络中传输及存储,一条交易消耗的 Bandwidth Points = 交易字节数 * Bandwidth Points费率。当前 Bandwidth Points费率 = 1.
如一条交易的字节数组长度为200,那么该交易需要消耗 200 Bandwidth Points。
Note
由于网络中总质押资金以及账户的质押资金随时可能发生变化,因此账户拥有的 Bandwidth Points 不是固定值。
1. Bandwidth Points的来源¶
Bandwidth Points的获取分两种:
- 通过质押TRX获取的Bandwidth Points, 额度 = 为获取Bandwidth Points质押的TRX / 整个网络为获取Bandwidth Points质押的TRX 总额 * 43_200_000_000. 也就是所有用户按质押TRX平分固定额度的Bandwidth Points.
- 每个账号每天有固定免费额度的带宽,为1500.
2. Bandwith Points的消耗¶
除了查询操作,任何交易都需要消耗 bandwidth points。
有一种特殊情况需要注意,如果是转账,包括普通转账或 TRC10 Token 转账,如果目标账户不存在,转账操作则会创建账户并转账,只会扣除创建账户消耗的Bandwidth Points,转账不会再消耗额外的Bandwidth Points.
3. Bandwidth Points的计算规则¶
Bandwidth Points是一个账户1天内能够使用的总字节数。一定时间内,整个网络能够处理的Bandwidth为确定值。
如果交易需要创建新账户,Bandwidth Points消耗如下:
- 尝试消耗交易发起者质押获取的Bandwidth Points。如果交易发起者Bandwidth Points不足,则进入下一步
- 尝试消耗交易发起者的TRX,这部分烧掉0.1TRX
如果交易是Token转账,Bandwidth Points消耗如下:
- 依次验证 发行Token资产总的免费Bandwidth Points是否足够消耗,转账发起者的Token剩余免费Bandwidth Points是否足够消耗,Token发行者质押TRX获取Bandwidth Points剩余量是否足够消耗。如果满足则扣除Token发行者质押获取的Bandwidth Points,任意一个不满足则进入下一步
- 尝试消耗交易发起者质押获取的Bandwidth Points。如果交易发起者Bandwidth Points不足,则进入下一步
- 尝试消耗交易发起者的免费Bandwidth Points。如果免费Bandwidth Points也不足,则进入下一步
- 尝试消耗交易发起者的TRX,交易的字节数 * 1000 sun
如果交易普通交易,Bandwidth Points消耗如下:
- 尝试消耗交易发起者质押获取的Bandwidth Points。如果交易发起者Bandwidth Points不足,则进入下一步
- 尝试消耗交易发起者的免费Bandwidth Points。如果免费Bandwidth Points也不足,则进入下一步
- 尝试消耗交易发起者的TRX,交易的字节数 * 1000 sun
4. 带宽的自动恢复¶
在网络总锁定资金以及账户锁定资金不变的情况向,账户的带宽的已使用量随着时间增加而按比例衰减,24h 衰减到 0. 如时间 T_1 时刻,账户带宽已使用量为 U, 到 T_1 + 12h ,账户再次使用带宽 u, 此时账户已使用带宽为 U / 2 + u. 具体公式如下:
即可以理解为每 24h,用户已使用的带宽值重置为0。
能量¶
智能合约运行时执行每一条指令都需要消耗一定的系统资源,资源的多少用Energy的值来衡量。
1. Energy的获取¶
质押获取Energy,即将持有的trx锁定,无法进行交易,作为抵押,并以此获得免费使用Energy的权利。具体计算与全网所有账户质押有关,可参考相关部分计算。
FreezeBalance 质押获得能量¶
freezeBalance frozen_balance frozen_duration [ResourceCode:0 BANDWIDTH,1 ENERGY]
通过质押TRX获取的Energy, 额度 = 为获取Energy质押的TRX / 整个网络为获取Energy质押的TRX 总额 * 90_000_000_000。 也就是所有用户按质押TRX平分固定额度的Energy。
示例:
如全网只有两个人A,B分别质押2TRX,2TRX。
二人质押获得的可用Energy分别是
A: 25_000_000_000 且energy_limit 为25_000_000_000
B: 25_000_000_000 且energy_limit 为25_000_000_000
当第三人C质押1TRX时。
三人质押获得的可用Energy调整为
A: 20_000_000_000 且energy_limit调整为20_000_000_000
B: 20_000_000_000 且energy_limit调整为20_000_000_000
B: 10_000_000_000 且energy_limit 为10_000_000_000
FreezeBalance 恢复能量¶
所消耗的能量会在24小时内平滑减少至0。
示例:
在某一时刻A的Energy已使用量为72_000_000 Energy
在没有其他消耗或质押的操作下:
一小时后A的Energy已使用量为 72_000_000 - (72_000_000 * (60*60/60*60*24)) Energy = 69_000_000 Energy
24小时后A的Energy已使用量为 0 Energy。
2. 如何填写 feeLimit(用户必读)¶
在本节范围内,将合约的开发部署人员,简称为“开发者”;将调用合约的用户或者其他合约,简称为“调用者”。
调用合约消耗的Energy能以一定比例折合成trx(或者sun),所以在本节范围内,指代合约消耗的资源时,并不严格区分Energy和 trx;仅在作为 数值的单位时,才区分Energy、trx和sun。
合理设置feeLimit,一方面能尽量保证正常执行;另外一方面,如果合约所需Energy过大,又不会过多消耗调用者的trx。在设置feeLimit之前,需要了解几个概念:
- 合法的feeLimit为0 - 10^9 之间的整数值,单位是sun,折合0 - 1000 trx;
- 不同复杂度的合约,每次正常执行消耗不同的Energy;相同合约每次消耗的Energy基本相同1;执行合约时,逐条指令计算并扣除Energy,如果超过feeLimit的限制,则合约执行失败,已扣除的Energy不退还;
- 目前feeLimit仅指调用者愿意承担的Energy折合的trx2;执行合约允许的最大Energy还包括开发者承担的部分;
- 一个恶意合约,如果最终执行超时,或者因bug合约崩溃,则会扣除该合约允许的所有energy;
- 开发者可能会承担一定比例的Energy消耗(比如承担90%)。但是,当开发者账户的Energy不足以支付时,剩余部分完全由调用者承担。在feeLimit限制范围内,如调用者的Energy不足,则会燃烧等价值的trx。2
开发者通常会有充足的Energy,以鼓励低成本调用;调用者在估算feeLimit时,可以假设开发者能够承担其承诺比例的Energy,如果一次调用因为feeLimit不足而失败,可以再适当扩大。
示例 下面将以一个合约C的执行,来具体举例,如何估算feeLimit:
- 假设合约C上一次成功执行时,消耗了18000 Energy,那么预估本次执行消耗的Energy上限为20000 Energy;3
- 质押trx时,当前全网用于CPU质押的TRX总量和Energy总量的比值,假设是质押1 trx,可以获得400 Energy;
- 燃烧trx时,4 trx固定可以兑换100000 Energy;4
- 假设开发者承诺承担90%的Energy,而且开发者账户有充足的Energy;
则,feeLimit的预估方法为:
- A = 20000 energy * (1 trx / 400 energy) = 50 trx = 50_000_000 sun,
- B = 20000 energy * (4 trx / 10000 energy) = 0.8 trx = 800_000 sun,
- 取A和B的最大值,为50_000_000 sun,
- 开发者承诺承担90%,用户需要承担10%,
那么,建议用户填写的feeLimit为 50_000_000 sun * 10% = 5_000_000 sun。
3. Energy的计算(开发者必读)¶
在讨论本章节前,需要了解:
- tron为了惩罚恶意开发者,对于异常合约,如果执行超时(超过50ms),或因bug异常退出(不包含revert),会扣除本次的最大可用Energy。若合约正常执行,或revert,则仅扣除执行相关指令所需的Energy;
- 开发者可以设置执行合约时,消耗Energy中自己承担的比例,该比例后续可修改。一次合约调用消耗的Energy,若开发者的Energy不足以支付其承担的部分,剩余部分全由调用者支付;
- 目前执行一个合约,可用的Energy总数由 调用者调用时设置的feeLimit 和 开发者承担部分共同决定;
下面具体举例,详细描述合约可用Energy的计算方法。
示例1 如果一个账户A的balance是 100 TRX(100_000_000 SUN),质押 10 TRX 获得了100000 Energy,未质押的balance是 90 TRX。 有一个合约C设置的消耗调用者资源的比例是100%,也就是完全由调用者支付所需资源。 此时A调用了合约C,填写的feeLimit是 30000000(单位是SUN, 30 TRX)。 那么A此次调用能够使用的Energy是由两部分计算出来的:
-
A质押剩余的Energy
这部分的价格是根据账户A当前质押的TRX和当前质押所获得的Energy总量按比例计算出来的,也就是:1 Energy = (10 / 100000) TRX,还剩100000 Energy,价值10 TRX,小于feeLimit,则能获得所有的100000 Energy,价值的10 TRX算进feeLimit中。
-
按照固定比例换算出来的Energy
如果feeLimit大于质押剩余Energy价值的TRX,那么需要使用balance中的TRX来换算。固定比例是: 1 Energy = 100 SUN, feeLimit还有(30 - 10) TRX = 20 TRX,获得的Energy是 20 TRX / 100 SUN = 200000 Energy
所以,A此次调用能够使用的Energy是 (100000 + 200000) = 300000 Energy
如果合约执行成功,没有发生任何异常,则会扣除合约运行实际消耗的Energy,一般都远远小于此次调用能够使用的Energy。如果发生了Assert-style异常,则会消耗feeLimit对应的所有的Energy。
Assert-style异常的介绍详见异常介绍
示例2 如果一个账户A的balance是 100 TRX(100000000 SUN),质押 10 TRX 获得了100000 Energy,未质押的balance是 90 TRX。 有一个合约C设置的消耗调用者资源的比例是40%,也就是由合约开发者支付所需资源的60%。 开发者是D,质押 50 TRX 获得了500000 Energy。 此时A调用了合约C,填写的feeLimit是 200000000(单位是SUN, 200 TRX)。 那么A此次调用能够使用的Energy是于以下三部分相关:
-
调用者A质押剩余的Energy(X Energy)
这部分的价格是根据账户A当前质押的TRX和当前质押所获得的Energy总量按比例计算出来的,也就是:1 Energy = (10 / 100000) TRX,还剩100000 Energy,价值10 TRX,小于剩下的feeLimit,则能获得所有的100000 Energy,价值的10 TRX算进feeLimit中。
-
从调用者A的balance中,按照固定比例换算出来的Energy (Y Energy)
如果feeLimit大于1和2的和,那么需要使用A的balance中的TRX来换算。固定比例是: 1 Energy = 100 SUN, feeLimit还有(200 - 10)TRX = 190 TRX,但是A的balance只有90 TRX,按照min(190 TRX, 90 TRX) = 90 TRX来计算获得的Energy,即为 90 TRX / 100 SUN = 900000 Energy
-
开发者D质押剩余的Energy (Z Energy)
开发者D质押剩余500000 Energy。
会出现以下两种情况:
- 当(X + Y) / 40% >= Z / 60%,A此次调用能够使用的Energy是 X + Y + Z Energy。
- 当(X + Y) / 40% < Z / 60%,A此次调用能够使用的Energy是 (X + Y) / 40% Energy。
若A此次调用能够使用的Energy是 Q Energy
同上,如果合约执行成功,没有发生任何异常,消耗总Energy小于Q Energy,如消耗 500000 Energy ,会按照比例扣除合约运行实际消耗的Energy,调用者A消耗 500000 * 40\% =200000 Energy,开发者D消耗 500000 * 60\% = 300000 Energy。
一般实际消耗Energy都远远小于此次调用能够使用的Energy。如果发生了Assert-style异常,则会消耗feeLimit对应的所有的Energy。
Assert-style异常的介绍详见异常介绍
注意: 开发者创建合约的时候,consume_user_resource_percent不要设置成0,也就是开发者自己承担所有资源消耗。 开发者自己承担所有资源消耗,意味着当发生了Assert-style异常时,会消耗开发者质押的所有Energy。 Assert-style异常的介绍详见异常介绍
为避免造成不必要的损失consume_user_resource_percent建议值是10-100。
资源委托¶
在TRON中,一个账户可以通过质押TRX来获取带宽和能量。同时,也可以把质押TRX获取的带宽或者能量委托(delegate)给其他地址。 此时,主账号拥有质押的TRX以及相应的投票权,受委托账户拥有质押获取的资源(带宽或者能量)。 和普通质押一样,委托资源也至少质押3天。
资源委托的命令如下:
freezeBalance frozen_balance frozen_duration [ResourceCode:0 BANDWIDTH,1 ENERGY] [receiverAddress]
frozen_balance是质押的TRX数量(单位为sun)
frozen_duration为质押的天数(目前固定为3天)
ResourceCode表示要获取的资源是带宽还是能量
receiverAddress表示受委托账户的地址
其他交易费¶
交易类型 | 费用 |
---|---|
创建witness | 9999 TRX |
发行token | 1024 TRX |
创建account | 1 TRX |
创建exchange | 1024 TRX |