diff --git a/docs/developers/governance.md b/docs/developers/governance.md index d8845d3..7573015 100644 --- a/docs/developers/governance.md +++ b/docs/developers/governance.md @@ -22,7 +22,7 @@ TRON网络的治理是通过修改 [网络参数](https://tronscan.org/#/sr/comm ### 标题 我们希望TRON生态所有用户都能参与到网络治理中,为了能够在社区进行更好的宣传,建议您为提议投票进行命名,并将名称写在标题的最前面,下面是一个示例: ``` -Palma Upgrade:proposal to change the unit price of energy to 420 sun +Palma Upgrade:proposal to change the unit price of energy to 210 sun ``` ### 主体内容 diff --git a/docs/mechanism-algorithm/resource.md b/docs/mechanism-algorithm/resource.md index c257871..9e47b56 100644 --- a/docs/mechanism-algorithm/resource.md +++ b/docs/mechanism-algorithm/resource.md @@ -20,7 +20,7 @@ 交易以字节数组的形式在网络中传输及存储,一条交易消耗的 Bandwidth Points = 交易字节数 * Bandwidth Points费率。当前 Bandwidth Points费率 = 1. -如一条交易的字节数组长度为200,那么该交易需要消耗 200 Bandwidth Points。 +如一条交易的字节数为200,那么该交易需要消耗 200 Bandwidth Points。 !!! note 由于网络中总质押资金以及账户的质押资金随时可能发生变化,因此账户拥有的 Bandwidth Points 不是固定值。 @@ -29,20 +29,19 @@ Bandwidth Points的获取分两种: -- 通过质押TRX获取的Bandwidth Points, 额度 = 为获取Bandwidth Points质押的TRX / 整个网络为获取Bandwidth Points质押的TRX 总额 * 43_200_000_000. 也就是所有用户按质押TRX平分固定额度的Bandwidth Points. +- 通过质押TRX获取的Bandwidth Points, 额度 = 为获取Bandwidth Points质押的TRX / 整个网络为获取Bandwidth Points质押的TRX 总额 * 43_200_000_000,也就是所有用户按质押的TRX数量平分固定额度的Bandwidth Points. - 每个账号每天有固定免费额度的带宽,为600。 ### 2. Bandwith Points的消耗 除了查询操作,任何交易都需要消耗 bandwidth points。 -有一种特殊情况需要注意,如果是转账,包括普通转账或 TRC10 Token 转账,如果目标账户不存在,转账操作则会创建账户并转账,只会扣除创建账户消耗的Bandwidth Points,转账不会再消耗额外的Bandwidth Points. ### 3. Bandwidth Points的计算规则 Bandwidth Points是一个账户1天内能够使用的总字节数。一定时间内,整个网络能够处理的Bandwidth为确定值。 -如果交易需要创建新账户,Bandwidth Points消耗如下: +如果交易需要创建新账户(如创建新账户交易,向未激活的账户转账TRX或者TRC10代币),Bandwidth Points消耗如下: 1. 尝试消耗交易发起者质押获取的Bandwidth Points。如果交易发起者Bandwidth Points不足,则进入下一步 2. 尝试消耗交易发起者的TRX,这部分烧掉0.1TRX @@ -64,11 +63,22 @@ Bandwidth Points是一个账户1天内能够使用的总字节数。一定时间 账户的免费带宽和质押TRX获取的带宽消耗后, 会在24小时内逐步恢复。 +### 5. 账户带宽余额查询 + +首先调用节点HTTP接口`wallet/getaccountresource`来获取账户当前的资源状态,然后通过如下公式计算带宽余额: + +``` +免费带宽余额 = freeNetLimit - freeNetUsed +通过质押获取的带宽余额 = NetLimit - NetUsed +``` + +注:如果接口返回的结果中没有包含上述公式中的参数,表示该参数值为0。 + ## 能量 智能合约运行时执行每一条指令都需要消耗一定的系统资源,资源的多少用Energy的值来衡量。 -### 1. Energy的获取 +### 1. Energy的获取与消耗 质押获取Energy,即将持有的trx锁定,无法进行交易,作为抵押,并以此获得免费使用Energy的权利。具体计算与全网所有账户质押有关,可参考相关部分计算。 @@ -78,36 +88,56 @@ Bandwidth Points是一个账户1天内能够使用的总字节数。一定时间 freezeBalanceV2 frozen_balance [ResourceCode:0 BANDWIDTH,1 ENERGY] ``` -通过质押TRX获取的Energy, 额度 = 为获取Energy质押的TRX / 整个网络为获取Energy质押的TRX 总额 * 90_000_000_000。 -也就是所有用户按质押TRX平分固定额度的Energy。 +通过质押TRX获取的Energy 额度 = 为获取Energy质押的TRX / 整个网络为获取Energy质押的TRX 总额 * 150_000_000_000。 -示例: +也就是所有用户按质押的TRX数量平分固定额度的Energy,示例: ```text 如全网只有两个人A,B分别质押2TRX,2TRX。 二人质押获得的可用Energy分别是 -A: 25_000_000_000 且energy_limit 为25_000_000_000 +A: 75_000_000_000 且energy_limit 为75_000_000_000 -B: 25_000_000_000 且energy_limit 为25_000_000_000 +B: 75_000_000_000 且energy_limit 为75_000_000_000 当第三人C质押1TRX时。 三人质押获得的可用Energy调整为 -A: 20_000_000_000 且energy_limit调整为20_000_000_000 +A: 60_000_000_000 且energy_limit调整为60_000_000_000 -B: 20_000_000_000 且energy_limit调整为20_000_000_000 +B: 60_000_000_000 且energy_limit调整为60_000_000_000 -B: 10_000_000_000 且energy_limit 为10_000_000_000 +B: 30_000_000_000 且energy_limit 为30_000_000_000 ``` +#### 能量的消耗 + +在执行合约时,逐条指令计算并扣除账户能量,账户能量消耗的优先级如下: + +* 质押TRX获取的能量 +* 燃烧TRX + +首先会消耗交易发起者质押TRX获取的能量,如果消耗完这部分能量后还不够,会继续燃烧账户的TRX来支付交易所需的能量资源,按照每一个能量0.00021TRX的单价来支付。 + +如果合约中途由于抛出revert异常而退出,则仅扣除已经执行的指令所对应的能量,但是对于异常合约,比如合约执行超时,或因bug异常退出,会扣除本次交易最大可用的能量,用户可以通过设置交易的fee_limit参数来限定这笔交易最多可以消耗的能量费用上限。 + #### 能量的恢复 账户的能量资源消耗后,会在24小时内逐步恢复。 +#### 账户能量余额查询 + +首先调用节点HTTP接口wallet/getaccountresource来获取账户当前的资源状态,然后通过如下公式计算能量余额: + +``` +能量余额 = EnergyLimit - EnergyUsed +``` + +注:如果接口返回的结果中没有包含上述公式中的参数,表示该参数值为0。 + ### 2. 如何填写 feeLimit(用户必读) *** @@ -119,8 +149,8 @@ B: 10_000_000_000 且energy_limit 为10_000_000_000 合理设置feeLimit,一方面能尽量保证正常执行;另外一方面,如果合约所需Energy过大,又不会过多消耗调用者的trx。在设置feeLimit之前,需要了解几个概念: -1. 合法的feeLimit为0 - 10^9 之间的整数值,单位是sun,折合0 - 1000 trx; -2. 不同复杂度的合约,每次正常执行消耗不同的Energy;相同合约每次消耗的Energy基本相同[^1];执行合约时,逐条指令计算并扣除Energy,如果超过feeLimit的限制,则合约执行失败,已扣除的Energy不退还; +1. 合法的feeLimit为0 - 15*10^9 之间的整数值,单位是sun,折合0 - 15000 trx; +2. 不同复杂度的合约,每次正常执行消耗不同的Energy;相同合约每次消耗的Energy基本相同[^1],但由于动态能量模型机制,对于热门合约,不同时刻执行时可能需要的能量不同,具体请参考[动态能量模型章节](#_10);执行合约时,逐条指令计算并扣除Energy,如果超过feeLimit的限制,则合约执行失败,已扣除的Energy不退还; 3. 目前feeLimit仅指调用者愿意承担的Energy折合的trx[^2];执行合约允许的最大Energy还包括开发者承担的部分; 4. 一个恶意合约,如果最终执行超时,或者因bug合约崩溃,则会扣除该合约允许的所有energy; 5. 开发者可能会承担一定比例的Energy消耗(比如承担90%)。但是,当开发者账户的Energy不足以支付时,剩余部分完全由调用者承担。在feeLimit限制范围内,如调用者的Energy不足,则会燃烧等价值的trx。[^2] @@ -130,25 +160,22 @@ B: 10_000_000_000 且energy_limit 为10_000_000_000 **示例** 下面将以一个合约C的执行,来具体举例,如何估算feeLimit: -- 假设合约C上一次成功执行时,消耗了18000 Energy,那么预估本次执行消耗的Energy上限为20000 Energy;[^3] -- 质押trx时,当前全网用于CPU质押的TRX总量和Energy总量的比值,假设是质押1 trx,可以获得400 Energy; -- 燃烧trx时,4 trx固定可以兑换100000 Energy;[^4] +- 假设合约C上一次成功执行时,消耗了18000 Energy,那么预估本次执行消耗的Energy上限为20000 Energy; +- 燃烧trx时,由于能量单价目前为210sun,所以 21 trx固定可以兑换100000 Energy; - 假设开发者承诺承担90%的Energy,而且开发者账户有充足的Energy; 则,feeLimit的预估方法为: -1. A = 20000 energy * (1 trx / 400 energy) = 50 trx = 50_000_000 sun, -2. B = 20000 energy * (4 trx / 10000 energy) = 0.8 trx = 800_000 sun, -3. 取A和B的最大值,为50_000_000 sun, -4. 开发者承诺承担90%,用户需要承担10%, +1. A = 20000 energy * 210sun = 4_200_000 sun = 4.2 trx, +2. 开发者承诺承担90%,用户需要承担10%, -那么,建议用户填写的feeLimit为 50_000_000 sun * 10% = 5_000_000 sun。 +那么,建议用户填写的feeLimit为 4_200_000 sun * 10% = 420_000 sun。 ### 3. Energy的计算(开发者必读) 在讨论本章节前,需要了解: -1. tron为了惩罚恶意开发者,对于异常合约,如果执行超时(超过50ms),或因bug异常退出(不包含revert),会扣除本次的最大可用Energy。若合约正常执行,或revert,则仅扣除执行相关指令所需的Energy; +1. tron为了惩罚恶意开发者,对于异常合约,如果执行超时(超过80ms),或因bug异常退出(不包含revert),会扣除本次的最大可用Energy。若合约正常执行,或revert,则仅扣除执行相关指令所需的Energy; 2. 开发者可以设置执行合约时,消耗Energy中自己承担的比例,该比例后续可修改。一次合约调用消耗的Energy,若开发者的Energy不足以支付其承担的部分,剩余部分全由调用者支付; 3. 目前执行一个合约,可用的Energy总数由 调用者调用时设置的feeLimit 和 开发者承担部分共同决定; @@ -166,13 +193,13 @@ B: 10_000_000_000 且energy_limit 为10_000_000_000 - A质押剩余的Energy - 这部分的价格是根据账户A当前质押的TRX和当前质押所获得的Energy总量按比例计算出来的,也就是:1 Energy = (10 / 100000) TRX,还剩100000 Energy,价值10 TRX,小于feeLimit,则能获得所有的100000 Energy,价值的10 TRX算进feeLimit中。 + 这部分是根据账户A当前质押的TRX和当前质押所获得的Energy总量按比例计算出来的,也就是:1 Energy = (10 / 100000) TRX,还剩100000 Energy,价值10 TRX,小于feeLimit,则在本次调用中,可以使用所有的100000 Energy,价值的10 TRX。 -- 按照固定比例换算出来的Energy +- 按照能量单价换算出来的Energy - 如果feeLimit大于质押剩余Energy价值的TRX,那么需要使用balance中的TRX来换算。固定比例是: 1 Energy = 100 SUN, feeLimit还有(30 - 10) TRX = 20 TRX,获得的Energy是 20 TRX / 100 SUN = 200000 Energy + 如果feeLimit大于质押剩余Energy价值的TRX,那么需要使用balance中的TRX来换算。能量单价是: 1 Energy = 210 sun, feeLimit还有(30 - 10) TRX = 20 TRX,则这部分可用的Energy是 20 TRX / 210 sun = 95238 Energy -所以,A此次调用能够使用的Energy是 (100000 + 200000) = 300000 Energy +所以,A此次调用能够使用的Energy是 (100000 + 95238) = 195238 Energy 如果合约执行成功,没有发生任何异常,则会扣除合约运行实际消耗的Energy,一般都远远小于此次调用能够使用的Energy。如果发生了Assert-style异常,则会消耗feeLimit对应的所有的Energy。 @@ -187,11 +214,11 @@ Assert-style异常的介绍详见[异常介绍](https://github.com/tronprotocol/ - 调用者A质押剩余的Energy(X Energy) - 这部分的价格是根据账户A当前质押的TRX和当前质押所获得的Energy总量按比例计算出来的,也就是:1 Energy = (10 / 100000) TRX,还剩100000 Energy,价值10 TRX,小于剩下的feeLimit,则能获得所有的100000 Energy,价值的10 TRX算进feeLimit中。 + 这部分是根据账户A当前质押的TRX和当前质押所获得的Energy总量按比例计算出来的,也就是:1 Energy = (10 / 100000) TRX,还剩100000 Energy,价值10 TRX,小于剩下的feeLimit,则在本次调用中,可以使用所有的100000 Energy,价值的10 TRX。 - 从调用者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 + 如果feeLimit大于质押剩余Energy价值的TRX,那么需要使用A的balance中的TRX来换算。能量单价是: 1 Energy = 210 sun, feeLimit还有(200 - 10) TRX = 190 TRX,但是A的balance只有90 TRX,按90TRX来计算可用的energy为 90 TRX / 210 SUN = 428571 Energy。 - 开发者D质押剩余的Energy (Z Energy) @@ -206,23 +233,63 @@ Assert-style异常的介绍详见[异常介绍](https://github.com/tronprotocol/ 同上,如果合约执行成功,没有发生任何异常,消耗总Energy小于Q Energy,如消耗 500000 Energy ,会按照比例扣除合约运行实际消耗的Energy,调用者A消耗 $500000 * 40\% =200000$ Energy,开发者D消耗 $500000 * 60\% = 300000$ Energy。 -一般实际消耗Energy都远远小于此次调用能够使用的Energy。如果发生了Assert-style异常,则会消耗feeLimit对应的所有的Energy。 - -Assert-style异常的介绍详见[异常介绍](https://github.com/tronprotocol/Documentation/blob/master/%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3/%E8%99%9A%E6%8B%9F%E6%9C%BA/%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86.md) +一般实际消耗Energy都远远小于此次调用能够使用的Energy。如果发生了Assert-style异常,则会消耗feeLimit对应的所有的Energy。Assert-style异常的介绍详见[异常介绍](https://github.com/tronprotocol/Documentation/blob/master/%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3/%E8%99%9A%E6%8B%9F%E6%9C%BA/%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86.md) 注意: 开发者创建合约的时候,consume_user_resource_percent不要设置成0,也就是开发者自己承担所有资源消耗。 -开发者自己承担所有资源消耗,意味着当发生了Assert-style异常时,会消耗开发者质押的所有Energy。 -Assert-style异常的介绍详见[异常介绍](https://github.com/tronprotocol/Documentation/blob/master/%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3/%E8%99%9A%E6%8B%9F%E6%9C%BA/%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86.md) +开发者自己承担所有资源消耗,意味着当发生了Assert-style异常时,会消耗开发者质押的所有Energy。为避免造成不必要的损失consume_user_resource_percent建议值是10-100。 + +## 动态能量模型 +动态能量模型是波场网络的一个资源平衡机制,可以根据合约的资源占用情况动态调整每个合约的能量消耗量,从而使能量资源在链上的分配更加合理,防止网络资源过度集中在少数热门合约上,详情请参考[动态能量模型介绍](https://medium.com/tronnetwork/introduction-to-dynamic-energy-model-31917419b61a)。 + +### 工作原理 +如果合约在一个维护周期(目前是6小时)内使用过多的能量,则在下一个维护周期内,用户向该合约发送相同的交易将产生更多的额外能量消量。当合约合理使用资源时,用户调用该合约所产生的能量消耗将逐渐恢复正常。 + +每一个合约有一个能量消耗放大系数 `energy_factor`,表示该智能合约交易的能量消耗相对于基础能量消耗的增加倍数,初始值是0。合约的`energy_factor`为0时,表示该合约在合理的使用资源,调用该合约不会有额外的能量消耗。当`energy_factor`大于0时,表示该合约已经是热门合约,调用该合约时将消耗额外的能量。合约的能量消耗放大系数可以通过 [getcontractinfo](https://developers.tron.network/reference/getcontractinfo) 接口查询。 + +合约调用交易最终需要消耗的能量的计算公式为: + +``` +合约交易能量消耗量 = 合约调用交易产生的基础能量消耗 * (1 + energy_factor) +``` + +动态能量模型引入了如下三个TRON网络参数,它们共同控制合约的`energy_factor`字段: + +* `threshold`:合约基础能量消耗的阈值,如果合约在一个维护周期中的基础能量消耗超过这个阈值,下一个维护周期,该合约的能量消耗量就会增加。 +* `increase_factor`:合约在某个维护周期的能量消耗超过阈值,则在下一个维护周期,`energy_factor`就会根据increase_factor增加一定的比例。 +* `max_factor`:合约`energy_factor`的最大值 + +另外还有一个变量`decrease_factor`用于降低合约的`energy_factor`: + +* `decrease_factor`:`increase_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:5,000,000,000 +* increase_factor:0.2 +* max_factor:3.4 + +由于热门合约在不同的维护周期的能量消耗是不一样的,所以在调用合约时要为交易设置合适的feelimit参数。 -为避免造成不必要的损失consume_user_resource_percent建议值是10-100。 ## 在TRON网络上质押 ### 如何质押获取系统资源 -能量和带宽资源由帐户所有者通过质押来获取,请使用`wallet/freezebalancev2`HTTP API完成质押操作、或者使用[Stake2.0 Solidity API](https://cn.developers.tron.network/docs/stake-20-solidity-api)通过合约完成质押操作。 +能量和带宽资源由帐户所有者通过质押来获取,请使用`wallet/freezebalancev2`HTTP API完成质押操作、或者使用[Stake2.0 Solidity API](https://developers.tron.network/docs/stake-20-solidity-api)通过合约完成质押操作。 TRON通过质押机制分配网络资源。质押TRX除了可以获取带宽或者能量资源外,还将同时获得与质押量等量的投票权(TRON Power,简称TP),质押1TRX,获得1TP。质押获取到的带宽或者能量资源用于支付交易费用,获取到的投票权用于给超级代表投票以获取投票奖励。 @@ -265,6 +332,11 @@ TRON通过质押机制分配网络资源。质押TRX除了可以获取带宽或 目前TRON网络使用的是Stake2.0质押机制,但Stake1.0 质押获得的资源和投票继续有效,在Stake 1.0质押的TRX,仍然可以通过 Stake1.0 API `wallet/unfreezebalance`赎回,但需要注意的是,如果解质押Stake 1.0质押的TRX,会撤销账户所有的投票。 +### 如何取消全部解质押 +Stake2.0支持在用户解质押TRX后随时取消全部解质押,这样会使资产再次用于质押以获取相应的资源,而不必等待解质押本金过了锁定期后,将本金提取到账户内,再进行质押。请使用 `cancelallunfreezev2`API完成取消全部解质押操作。 + +在执行取消解质押时,会将所有未完成的解质押的本金重新用于质押,获取的资源类型与之前质押时相同。如果存在已过锁定期的解质押的本金,那么本次取消解质押操作会同时将已过锁定期的解质押本金提取到账户内,用户可通过`gettransactioninfobyid`接口查询本次交易取消的解质押本金数额 `cancel_unfreezeV2_amount`,以及提取到的已过锁定期的本金数量`withdraw_expire_amount` 。 + ### API 下表为质押模型相关接口及其说明: @@ -283,16 +355,4 @@ TRON通过质押机制分配网络资源。质押TRX除了可以获取带宽或 | wallet/getdelegatedresourceaccountindexv2 | 查看某地址资源代理情况与资源被代理情况 | | wallet/getaccount | 查看账户质押情况、资源份额、解质押情况、投票情况 | | wallet/getaccountresource | 查看资源总量、已使用量、可用数量 | - -## 其他交易费 - -|交易类型|费用| -| :------|:------:| -|创建witness|9999 TRX| -|发行token|1024 TRX| -|创建account|1 TRX| -|创建exchange|1024 TRX| -|更新账户权限|100 TRX| -|交易备注|1 TRX| -|多签交易|1 TRX| - +| wallet/cancelallunfreezev2 | 取消全部解质押 | diff --git a/docs/releases/history.md b/docs/releases/history.md index e56ab70..c280129 100644 --- a/docs/releases/history.md +++ b/docs/releases/history.md @@ -1105,7 +1105,7 @@ GreatVoyage-v4.7.0.1(Aristotle)版本新增了10个 API 以支持Stake 2.0质押 在GreatVoyage-v4.7.0.1(Aristotle)之前的版本中,可以通过`/wallet/triggerconstantcontract`接口预估执行智能合约交易所需的能量消耗量,然后根据预估的消耗量来设置交易的`feelimit`参数。但由于某些智能合约交易可能存在对其他智能合约的调用,这时有可能出现预估`feelimit`参数不准确的情况。 -因此,GreatVoyage-v4.7.0.1(Aristotle)版本新增了一个能量预估接口`/wallet/estimateenergy`,利用该接口预估的`feelimit`在任何情况下都是可靠的。该接口返回值中的`energy_required`字段表示这笔智能合约调用交易执行成功所需要的能量预估量,用户根据该字段来计算`feelimit`参数:`feelimit` = `energy_required` * 能量单价, 当前能量单价是420sun 。 +因此,GreatVoyage-v4.7.0.1(Aristotle)版本新增了一个能量预估接口`/wallet/estimateenergy`,利用该接口预估的`feelimit`在任何情况下都是可靠的。该接口返回值中的`energy_required`字段表示这笔智能合约调用交易执行成功所需要的能量预估量,用户根据该字段来计算`feelimit`参数:`feelimit` = `energy_required` * 能量单价, 当前能量单价是210sun 。 如果由于某种原因导致预估接口执行失败时,`energy_required`字段值为0,在返回值中将不显示该字段,这时可以通过`result`字段查看预估失败原因。