Estimated time: 6 minutes read
What is gas estimation consumed in a Smart Contract?
Deploying and executing transactions on Smart Contracts on the blockchain involves a consumption measured in gas units, directly related to the size of the deployed code and the operations executed in the EVM.
These gas units translate into economic costs since each blockchain charges a specific cost in its native token.
Estimating gas costs involves calculating in advance (before interacting with the blockchain) how many gas units will be consumed. This can be very useful for attempting optimizations in the code to reduce costs.
In my article on gas optimization in Solidity, I provide some tips for reducing gas consumption in Smart Contract development.
Calculating the size of a Smart Contract with Hardhat
A preliminary calculation that can be made before deploying a smart contract is to know its size and the gas units of the initialization code when executing its constructor.
To do this in Hardhat, you can use the “hardhat-contract-sizer” plugin. Just add it to the project, include its definition in the “hardhat.config.js” file, and run it:
// Add plugin to project
yarn add --dev hardhat-contract-sizer
// Define in hardhat.config.js
require("hardhat-contract-sizer");
// Invoke command
yarn hardhat size-contracts
The result will be displayed in the console, distinguishing between the code size at deployment and the initialization code size (constructor).
The plugin presents some configuration options (in the ‘hardhat.config.js’ file), although the default values are generally adequate. In these examples, the ‘unit’ parameter has been defined to measure sizes in kB.
It is noted that the version of the compiler used and possible gas consumption optimizations to balance between deployment and execution are detailed.
If any allowed size limit is exceeded, a warning will appear:
In this example, the increase in size in the initialization code compared to the previous execution of the command is highlighted (+360.616 kB), and a warning is issued for exceeding the limit for deployment on the mainnet.
In this regard, there are currently two limits for deploying a smart contract on EVM-compatible networks:
- Maximum size of deployed code: 24 kB according to EIP-170.
- Maximum size of initialization code executed in the constructor: 48 kB according to EIP-3860.
Estimating gas consumption with Hardhat
To estimate gas consumption with Hardhat, the ‘hardhat-gas-reporter‘ plugin is used.
It should be added to the project, defined, and configured in the ‘hardhat.config.js’ file (the following example assumes the existence of a ‘.env’ properties file):
// Add plugin to project
yarn add --dev hardhat-gas-reporter
// Define in hardhat.config.js
require("hardhat-gas-reporter");
// Configure in hardhat.config.js
gasReporter: {
enabled: true,
currency: 'EUR',
coinmarketcap: `${COINMARKETCAP_APIKEY}`,
excludeContracts: [],
L1: "polygon",
L1Etherscan: `${POLYGON_SCAN_APIKEY}`,
trackGasDeltas: true,
},
The plugin allows for multiple configuration options. In the example, the following options are used:
- enabled: automatically activates the plugin when the ‘hardhat test’ task is run.
- currency and coinmarketcap: enable conversion of the gas consumed in deploying smart contracts and executing transactions to FIAT currency. To do this, a valid APIKEY must be provided on the CoinMarketCap platform.
- L1 and L1Etherscan: define which network the gas cost calculations should be performed on. A valid APIKEY must be provided for the appropriate block explorer to make the necessary calls to ‘eth_gasPrice’ and obtain the current ‘base gas price’ of the network.
- trackGasDeltas: if enabled, it will show the variation in gas consumption between consecutive executions of the plugin. This is useful for evaluating the extent to which any gas consumption optimizations being carried out are affecting the results.
Once the plugin is enabled, it runs automatically during calls to ‘hardhat test‘. It is necessary for the executed tests to cover all transactions you want to evaluate for gas consumption.
If the same method of a smart contract is executed more than once, the plugin will estimate minimum, maximum, and average gas consumption values. This is because consumption will generally not always be similar, as it will depend on the state of the EVM at each moment.
An example of execution (yarn hardhat test) would show the following result in the console:
It can be observed that the execution of the various methods tested in the tests for each contract (10 calls to the ‘fillCodes’ method for the ‘HashCodes’ contract) is distinguished from the deployments of the smart contracts. For each case, the cost in gas units is estimated.
The example highlights a decrease in gas consumption compared to a previous execution (-36,000 gas units for the ‘fillCodes’ method).
The value of 28 gwei per gas unit (gas price) and the exchange rate of 0.34 eur/pol obtained using the APIs defined in the plugin configuration are used to calculate the average cost in FIAT currency.
It should be emphasized that these costs are estimates of the ‘gas price’: when the transaction is actually executed on the blockchain, the ‘gas base fee’ may change depending on the network load. Additionally, the cost will increase to cover the tips that the blockchain ‘miners’ will receive based on the desired priority for the transaction.
Other Estimates
While the calculations from the ‘hardhat-gas-reporter’ plugin are very useful for knowing the gas units of methods and the deployment of smart contracts, it may be beneficial to use other tools to estimate the economic cost based on that information.
Here are some alternatives to find out the gas price:
- Call the ‘eth_gasPrice’ method through a JSON-RPC provider to obtain the current value of the ‘gas base fee.’
- Call the ‘eth_maxPriorityFeePerGas’ method through a JSON-RPC provider to get an estimate of the tip that should be added to the ‘gas base fee’ to get the transaction ‘mined’ on the network. This value should be chosen based on the desired priority.
- Gather the final ‘gas price’ through an estimation service. Notably, there can be significant variations between different providers. For example, several alternatives are cited for Polygon, although equivalent options will exist for other networks:
On the other hand, in certain networks, the estimated ‘gas price’ may not be decisive. For instance, in Polygon, since the transaction costs are relatively low, it is common to set a ‘gas price’ much higher than recommended to achieve prompt transaction ‘mining.’
Conclusion: Anticipating the Gas Cost of Contracts
Deploying and interacting with Smart Contracts on the blockchain involves costs classified at various levels:
- Gas consumption measured as computational units to process the operations of transactions. In this area, various optimizations can be made to minimize gas units.
- Economic costs incurred to cover the use of infrastructure and reward the ‘miners.’
The economic costs will be passed on to different actors in the web3 ecosystem: developers and project teams will generally bear the costs during the deployment and initialization of Smart Contracts. Furthermore, the costs of transactions when interacting with the contracts are typically borne by the users of the DApps.
To keep costs contained, it is advisable to know them in advance. This is where tools like Hardhat, through its numerous plugins, allow us to make estimates to act before the actual deployment of contracts.
While the calculation of gas units can be more or less accurate, the conversion to gas price and the economic cost depends on factors that only allow for estimates conditional on the actual moment of transacting with the blockchain and the desired priority in handling by the ‘miners.’
Are you accustomed to estimating gas costs in your projects? Do you use any other tools or guidelines that help you make the best design decisions in your Smart Contracts? I encourage you to share your experiences.
If you need a developer who takes all these aspects into account in the development of blockchain solutions, feel free to contact me. Thank you very much!