FeeLimit Parameter Setting

FeeLimit is a parameter of the smart contract transaction, which is used to set the upper limit of the energy cost that the caller is willing to undertake for the deployment or invocation of the smart contract, in sun (1TRX = 1e6 sun). The default value is 0. Currently, the upper limit of feelimit can be set is 15000 TRX.

When executing the contract, Energy is calculated and deducted one by one instruction. If the energy used is exceeded, the contract execution will fail and the deducted Energy will not be refunded. Therefore, before deploying or calling the contract, it is recommended to set an appropriate feelimit to ensure the normal execution of smart contract transactions. The following describes how to estimate the energy consumption of smart contract transactions and set the feelimit parameter.

How to determine the FeeLimit parameter?

Due to the Dynamic Energy Model mechanism, the energy consumption of popular contracts changes dynamically, so calling the same contract function in different time periods may result in different energy consumption, so in different time periods, transactions that call popular contracts need to set different feelimit parameters. Here we introduce three ways of setting feelimit:

  • Estimate energy before each contract call
    Before each transaction is sent, the total energy consumption of the transaction is estimated through API, and the FeeLimit parameter of the transaction is determined according to the estimated energy consumption:

    FeeLimit of contract transaction = estimated total energy consumption * EnergyPrice
    
  • Get the contract energy_factor once every maintenance cycle
    First, determine the basic energy consumption of a function of a contract through triggerconstantcontract API or past historical experience of the contract, and then get the energy_factor parameter of a contract at each maintenance cycle:

    FeeLimit of contract transaction = estimated basic energy consumption * (1 + energy_factor) * EnergyPrice
    
  • Set feelimit according to max_factor
    First, determine the basic energy consumption of a function of a contract through triggerconstantcontract 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 coefficient, so no matter how the energy consumption of popular contracts fluctuates, it will not exceed this maximum ratio:

    FeeLimit of contract transaction = estimated basic energy consumption *(1 + max_factor)* EnergyPrice
    

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 cycle (6 hours). The advantage of the third method is that it is easy to operate and does not need to frequently obtain the max_factor parameter, but the calculated FeeLimit will be greater than the actual energy cost, because the energy_factor of most contracts will not reach max_factor.

How to estimate energy consumption?

Developers can call wallet/triggerconstantcontract API to estimate the energy consumption value of a contract invocation or deployment transaction. Let's take an example to illustrate:

How to estimate the energy consumption of a contract call transaction

$ 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
}'

It returns:

{
   ……
   "result": {
       "result": true
   },
   "energy_used": 46236,
   "energy_penalty": 32983,
   ……


}

The result.result=true 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. If the result.result field is false, it means that the estimation failed. Please check whether the transaction data or contract and account information are correct before estimating again.

How to estimate the energy consumption of a contract deployment transaction

For the contract whose constructor has no parameters, when estimating the energy required for its deployment, you only need to put the contract's bytecode into the data field of the wallet/triggerconstantcontract interface. However, for the contract whose constructor has parameters, you should also pass in the parameters when deploying. The parameters are also passed in through the data field: the parameters are ABI-encoded and placed after the contract bytecode. Please refer to the following examples.

  • To estimate the energy consumption of deploying a contract whose constructor has no parameters.

Contract example:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

contract SimpleContract {
    uint storedData;
    
    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}

After compiling the contract, we get the contract bytecode:

608060405234801561000f575f80fd5b50d3801561001b575f80fd5b50d28015610027575f80fd5b5061015b806100355f395ff3fe608060405234801561000f575f80fd5b50d3801561001b575f80fd5b50d28015610027575f80fd5b506004361061004c575f3560e01c806360fe47b1146100505780636d4ce63c1461006c575b5f80fd5b61006a600480360381019061006591906100d2565b61008a565b005b610074610093565b604051610081919061010c565b60405180910390f35b805f8190555050565b5f8054905090565b5f80fd5b5f819050919050565b6100b18161009f565b81146100bb575f80fd5b50565b5f813590506100cc816100a8565b92915050565b5f602082840312156100e7576100e661009b565b5b5f6100f4848285016100be565b91505092915050565b6101068161009f565b82525050565b5f60208201905061011f5f8301846100fd565b9291505056fea26474726f6e58221220ca11b5749b47f126a08ed4dd6de453cf3e3e1d68c1105af0acdd8a38c18b37ac64736f6c63430008140033

Put the contract bytecode into the data field of the wallet/triggerconstantcontract interface. The estimated command is:

curl --request POST \
 --url https://api.shasta.trongrid.io/wallet/triggerconstantcontract \
 --header 'accept: application/json' \
 --header 'content-type: application/json' \
 --data '
{
  "owner_address": "TZ4UXDV5ZhNW7fb2AMSbgfAEZ7hWsnYS2g",
  "data":"608060405234801561000f575f80fd5b50d3801561001b575f80fd5b50d28015610027575f80fd5b5061015b806100355f395ff3fe608060405234801561000f575f80fd5b50d3801561001b575f80fd5b50d28015610027575f80fd5b506004361061004c575f3560e01c806360fe47b1146100505780636d4ce63c1461006c575b5f80fd5b61006a600480360381019061006591906100d2565b61008a565b005b610074610093565b604051610081919061010c565b60405180910390f35b805f8190555050565b5f8054905090565b5f80fd5b5f819050919050565b6100b18161009f565b81146100bb575f80fd5b50565b5f813590506100cc816100a8565b92915050565b5f602082840312156100e7576100e661009b565b5b5f6100f4848285016100be565b91505092915050565b6101068161009f565b82525050565b5f60208201905061011f5f8301846100fd565b9291505056fea26474726f6e58221220ca11b5749b47f126a08ed4dd6de453cf3e3e1d68c1105af0acdd8a38c18b37ac64736f6c63430008140033",
  "visible": true
}'

It returns:

{
	"result": {
		"result": true
	},
	"energy_used": 69558,
	......
}

  • To estimate the energy consumption of deploying a contract whose constructor has parameters

Contract example:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

contract SimpleContract {
    uint storedData;
    uint public num;

    constructor(uint _num) {
        num = _num;
    }
    
    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}

After compiling the contract, we get the contract bytecode:

608060405234801561000f575f80fd5b50d3801561001b575f80fd5b50d28015610027575f80fd5b5060405161024f38038061024f8339818101604052810190610049919061008d565b80600181905550506100b8565b5f80fd5b5f819050919050565b61006c8161005a565b8114610076575f80fd5b50565b5f8151905061008781610063565b92915050565b5f602082840312156100a2576100a1610056565b5b5f6100af84828501610079565b91505092915050565b61018a806100c55f395ff3fe608060405234801561000f575f80fd5b50d3801561001b575f80fd5b50d28015610027575f80fd5b5060043610610057575f3560e01c80634e70b1dc1461005b57806360fe47b1146100795780636d4ce63c14610095575b5f80fd5b6100636100b3565b60405161007091906100e2565b60405180910390f35b610093600480360381019061008e9190610129565b6100b9565b005b61009d6100c2565b6040516100aa91906100e2565b60405180910390f35b60015481565b805f8190555050565b5f8054905090565b5f819050919050565b6100dc816100ca565b82525050565b5f6020820190506100f55f8301846100d3565b92915050565b5f80fd5b610108816100ca565b8114610112575f80fd5b50565b5f81359050610123816100ff565b92915050565b5f6020828403121561013e5761013d6100fb565b5b5f61014b84828501610115565b9150509291505056fea26474726f6e582212205d0adb1a1985b9d6f432a9defc416a17dfe1c931bfb8554978c0f37cfe4cc99f64736f6c63430008140033

This contract needs to pass in a uint type parameter when deploying. Assuming that the value 2 is passed in during deployment, it will be ABI-encoded to 000000000000000000000000000000000000000000000000000000000000000000000002, which is put after the bytecode to get data field value. The estimated command is:

curl --request POST \
 --url https://api.shasta.trongrid.io/wallet/triggerconstantcontract \
 --header 'accept: application/json' \
 --header 'content-type: application/json' \
 --data '
{
  "owner_address": "TZ4UXDV5ZhNW7fb2AMSbgfAEZ7hWsnYS2g",
  "data":"608060405234801561000f575f80fd5b50d3801561001b575f80fd5b50d28015610027575f80fd5b5060405161024f38038061024f8339818101604052810190610049919061008d565b80600181905550506100b8565b5f80fd5b5f819050919050565b61006c8161005a565b8114610076575f80fd5b50565b5f8151905061008781610063565b92915050565b5f602082840312156100a2576100a1610056565b5b5f6100af84828501610079565b91505092915050565b61018a806100c55f395ff3fe608060405234801561000f575f80fd5b50d3801561001b575f80fd5b50d28015610027575f80fd5b5060043610610057575f3560e01c80634e70b1dc1461005b57806360fe47b1146100795780636d4ce63c14610095575b5f80fd5b6100636100b3565b60405161007091906100e2565b60405180910390f35b610093600480360381019061008e9190610129565b6100b9565b005b61009d6100c2565b6040516100aa91906100e2565b60405180910390f35b60015481565b805f8190555050565b5f8054905090565b5f819050919050565b6100dc816100ca565b82525050565b5f6020820190506100f55f8301846100d3565b92915050565b5f80fd5b610108816100ca565b8114610112575f80fd5b50565b5f81359050610123816100ff565b92915050565b5f6020828403121561013e5761013d6100fb565b5b5f61014b84828501610115565b9150509291505056fea26474726f6e582212205d0adb1a1985b9d6f432a9defc416a17dfe1c931bfb8554978c0f37cfe4cc99f64736f6c634300081400330000000000000000000000000000000000000000000000000000000000000002",
  "visible": true
}'

It returns:

{
	"result": {
		"result": true
	},
	"energy_used": 99278,
	......
}

In the above return value, if the result.result field is true, it means the estimation operation is executed successfully, and energy_used is the estimated value of the energy consumption of the transaction. If the result.result field is false, it means the estimation failed. Please check whether the transaction data is correct before making an estimation.


Note: The 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
}'

It returns:

{
   "result": {
      "result": true
   },
   "energy_required": 34830
}

The result.result = true 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.