How to Adapt the Dynamic Energy Model?
--
The dynamic energy model has been deployed and taken effect on the Nile testnet, this article will take the TRC-20 contract of BTT as an example to demonstrate how to adapt to the model for dApp users, developers, wallets, and exchanges. The contract address of BTT on the Nile testnet is TVSvjZdyDSNocHm7dP3jvCmMNsCnMTPa5W, obtain the BTT test coins: Faucet.
The parameters of the Nile testnet dynamic energy model are set in consideration of the current state of the testnet and the convenience of developer testing, and have nothing to do with the parameters of dynamic resource model will be depolyed and opened in the future on the mainnet. The parameters that will be implemented on the mainnet need to be discussed and voted on in the future.
This model dynamically adjusts the future energy consumption of the contract based on the known energy usage of the contract, users call popular contracts to generate additional energy consumption. This additional energy consumption will change with the popularity of the contract. The dynamic energy model increases the use cost of resource-intensive contracts without affecting other dApps, so as to reduce the future resource occupation of these contracts, make the allocation of energy resources on the chain more reasonable, and prevent excessive concentration of network resources on a few contracts, as well as ensure the robustness, diversity, and balanced development of the ecosystem. Before reading this article, please understand the principle and parameter introduction of the dynamic energy model: Introduction to Dynamic Energy Model.
By reading this article, you will learn the following:
- How to obtain the network parameters related to the dynamic energy model?
- How to get the
energy_factor
of the contract? - How to set the
feelimit
of smart contract transactions? - How to estimate the energy consumption of calling smart contracts?
- How to query the detailed fee structure of smart contract transactions?
How to obtain the network parameters related to the dynamic model on the Nile testnet?
Call /wallet/getchainparameters
to get the values of threshold
, increase_factor
, and max_factor
on the Nile testnet.
$ curl -X POST https://nile.trongrid.io/wallet/getchainparameters
{
"chainParameter": [
……
{
"key": "getDynamicEnergyThreshold",
"value": 2000000
},
{
"key": "getDynamicEnergyIncreaseFactor",
"value": 2000
},
{
"key": "getDynamicEnergyMaxFactor",
"value": 25000
}
]
}
Parameters explanation,
threshold
:getDynamicEnergyThreshold
= 2000000, the unit is energy, a contract that consumes more than 2,000,000 energy during the maintenance period is a popular contract. The contract will increase the penalty consumption by a certain percentage in the next maintenance period.increase_factor
:getDynamicEnergyIncreaseFactor
= 2000, the precision is 10,000. The 2,000 in the above example means that theincrease_factor
is 0.2. During the maintenance period of the Nile testnet, the energy consumed by the contract exceeds the threshold of 2,000,000 energy, and theenergy_factor
variable of the contract will be increased by 20%.max_factor
:getDynamicEnergyMaxFactor
= 25000, the precision is 10000, 25000 in the above example meansmax_factor
is 2.5. Theenergy_factor
variable of the Nile testnet smart contract will not exceed 2.5 at most.
How to get the energy_factor parameter of the Nile testnet BTT token contract?
Call /wallet/getcontractinfo
to obtain energy_factor
、energy_usage
of the BTT contract on the Nile testnet.
$ curl -X POST https://nile.trongrid.io/wallet/getcontractinfo -d '{"value": "TVSvjZdyDSNocHm7dP3jvCmMNsCnMTPa5W", "visible":true}'
{
……
"runtimecode": "",
"smart_contract": {},
"contract_state": {
"energy_usage": 4002406,
"energy_factor": 25000
"update_cycle": 167814,
}
}
energy_usage
indicates that the BTT contract has consumed 4,002,406 energy during the current maintenance period. The precision of energy_factor
is 10000, 25000 means the actual value of energy_factor
is 2.5. And update_cycle
is the current maintenance period number.
How to set the feelimit parameter of a smart contract transaction?
After the dynamic energy model is enabled, the energy consumption of calling popular contracts fluctuates, so calling the same contract in different time periods requires setting different feelimit
value. In this case, developers can use the following three methods to set the feelimit
of the transaction:
- Before each transaction is sent, the total energy consumption is estimated through the Java-tron estimated energy API, and
feelimit
of the transaction is determined according to the estimated total energy consumption. Assuming that the estimated total energy consumption is 1000 energy, then the transactionfeelimit
= 1000 * EnergyPrice, the currently EnergyPrice is 420 sun - First, determine the basic energy consumption of a contract function through the Java-tron estimated energy API or past historical experience of the contract. And then get the
energy_factor
parameter of the contract once every maintenance period, thenfeelimit
for calling this contract transaction = estimated basic energy consumption * (1 +energy_factor
) * EnergyPrice, the currently EnergyPrice is 420 sun - First estimate the basic energy consumption of the function of a contract through the Java-tron estimated energy API or past historical experience of the contract, and then obtain the
max_factor
parameter of the chain,max_factor
is the maximum ratio of the energy penalty factor, so no matter how the energy consumption of popular contracts fluctuates, it will not exceed this maximum ratio, then thefeelimit
of calling this contract transaction = estimated basic energy consumption * (1 +max_factor
) * EnergyPrice, the currently EnergyPrice is 420 sun
The advantage of the first method above is that the feelimit
setting is very accurate, but the disadvantage is that the operation is more cumbersome, and each transaction needs to be estimated. Compared with the first method, the second method maintains the accuracy of the feelimit
setting, but still needs to obtain the energy_factor
parameter of the contract every maintenance period (6 hours). The advantage of the third method is that it does not need to obtain the max_factor
parameter frequently, because max_factor
is a network parameter, and generally after an adjustment, it will not change for a long time, but the feelimit
calculated by the third method will be greater than the actual energy cost, because the energy amplification factor energy_factor
of most contracts will not reach max_factor
.
To sum up, after the dynamic energy model takes effect, the best strategy for feelimit
parameter settings of a transaction is to use the third method for popular contracts, and the first or second method for non-popular contracts.
How to estimate the energy consumption of calling smart contracts?
Developers can call wallet/triggerconstantcontract
API to estimate the energy consumption value of calling contracts.
An example is listed as follows:
$ curl -X POST https://nile.trongrid.io/wallet/triggerconstantcontract -d '{
"owner_address": "TTGhREx2pDSxFX555NWz1YwGpiBVPvQA7e",
"contract_address": "TVSvjZdyDSNocHm7dP3jvCmMNsCnMTPa5W",
"function_selector": "transfer(address,uint256)",
"parameter": "0000000000000000000000002ce5de57373427f799cc0a3dd03b841322514a8c00000000000000000000000000000000000000000000000000038d7ea4c68000",
"visible": true
}'
{
……
"energy_used": 46236,
"energy_penalty": 32983,
……
}
The result.result
in the example stands for the successful execution of estimating operation, the value of energy_used
is the estimated energy consumption of the transaction, where the basic energy consumption value is (energy_used
— energy_penalty
), and value of energy_penalty
is the additional energy consumption.
The wallet/triggerconstantcontract
API can be used to estimate the energy consumption value of calling most smart contracts on the chain, such as USDD, USDT, USDC, TUSD, etc. Meanwhile, in the Java-tron 4.7.0.1 version, a new API of wallet/estimateEnergy
is added. Compared to the existing wallet/triggerconstantcontract
API, the new API will be more accurate in estimating the energy consumption of calling a small number of special contract. But for FullNode, enabling the wallet/estimateEnergy
API is optional. So please pay attention that when developers call wallet/estimateEnergy
, if the error message shows that the node does not support this function when calling the new API (this node does not support estimate energy), it is recommended to continue using the wallet/triggerconstantcontract
API to estimate energy consumption.
An example is listed as follows:
$ curl -X POST https://nile.trongrid.io/wallet/estimateenergy -d '{
"owner_address": "TTGhREx2pDSxFX555NWz1YwGpiBVPvQA7e",
"contract_address": "TVSvjZdyDSNocHm7dP3jvCmMNsCnMTPa5W",
"function_selector": "transfer(address,uint256)",
"parameter": "0000000000000000000000002ce5de57373427f799cc0a3dd03b841322514a8c00000000000000000000000000000000000000000000000000038d7ea4c68000",
"visible": true
}'
{
"result": {
"result": true
},
"energy_required": 34830
}
The result.result
in the example stands for the successful execution of estimating operation, the value of energy_equired
is the estimated energy consumption of the transaction, it contains the basic energy consumption and additional energy consumption.
The appropriate feelimit can be determined according to the estimated energy consumption value obtained from these two methods shown before:
- feelimit = estimated energy consumption * energy unit price
The energy unit price could be queried by calling wallet/getchainparameters
API, which is 420 sun at present.
NOTE: the ratio of punitive consumption for popular contracts may vary for each maintenance period (6 hours), so the estimation operations spanning two periods need to be redone.
How to query the fee of calling smart contracts?
After the dynamic energy model is enabled, when wallets, exchanges, and dApps show users the cost composition details of smart contract call transactions, they should consider the cost of penalty consumption.
Take this BTT transfer transaction on the Nile testnet as an example, 50e99121ca7cfa408434d8c452d3c9eeafa63d44b389f9663bd44c78c9addbe1, call /wallet/gettransactioninfobyid
to get the consumption of the transaction:
$ curl -X POST https://nile.trongrid.io/wallet/gettransactioninfobyid -d '{"value": "50e99121ca7cfa408434d8c452d3c9eeafa63d44b389f9663bd44c78c9addbe1","visible": true}'
{
……
"id": "50e99121ca7cfa408434d8c452d3c9eeafa63d44b389f9663bd44c78c9addbe1",
"fee": 19684740,
"receipt": {
"energy_usage": 189,
"net_usage": 0,
"energy_fee": 19339740,
"energy_usage_total": 46236,
"net_fee": 345000,
"origin_energy_usage": 0,
"result": "SUCCESS",
"energy_penalty_total": 32983
},
……
}
Note: the actual call to the above API will not contain a field with a value of 0 in the return value, so if the field described below does not exist in the actual call, it means that the value of the field is 0.
The resource consumption details of this transaction are as follows:
1. Total energy consumption: receipt
.energy_usage_total
= 46,236
- Penalty energy consumption:
receipt
.energy_penalty_total
= 32,983 - Basic energy consumption:
receipt
.energy_usage_total
—receipt
.energy_penalty_total
= 46,236–32,983 = 13,253
2. Total bandwidth consumption: receipt
.net_fee
/ bandwidth price + receipt
.net_usage
= 345000/1000 + 0 = 345
The resource consumption source of this transaction is as follows:
1. Energy
- Energy from TRX staked:
receipt
.energy_usage
= 189 - Energy from TRX burned:
receipt
.energy_usage_total
—receipt
.energy_usage
= 46,236–189 = 46,047 - Energy from contract deployer:
receipt
.origin_energy_usage
= 0
2. Bandwidth
- Bandwidth from TRX staked:
receipt
.net_usage
= 0 - Bandwidth from TRX burned:
receipt
.net_fee
/ bandwidth price = 345000/1000 = 345
The fees for this transaction are broken down as follows:
1. Total cost = 19,684,740 (19.684740 TRX)
- Energy cost:
receipt
.energy_fee
= 19,339,740 (19.339740 TRX) - Bandwidth cost:
receipt
.net_fee
= 345,000 (0.345TRX)