Hardhat: Optimizing the gas usage of smart contracts
In this tutorial, you’ll learn how to profile and optimize your smart contract’s gas usage with Hardhat and the Hardhat Gas Reporter plugin.Objectives
By the end of this tutorial you should be able to:- Use the Hardhat Gas Reporter plugin to profile gas usage
- Describe common strategies for improving the gas usage of a contract
Overview
In the world of smart contract development, optimizing the gas consumption of your smart contracts is important. Smaller contracts consume fewer gas resources during deployment and execution, resulting in significant cost savings for your users. In this tutorial, you will leverage the Hardhat Gas Reporter plugin to help you analyze and optimize your smart contract’s gas usage. The following provides further information about smart contract profiling and gas optimization.Setting up the Hardhat Gas Reporter plugin
The Hardhat Gas Reporter plugin is an invaluable tool for profiling gas usage in your smart contracts. It allows you to gain insights into the gas consumption of various contract functions, making it easier to identify potential optimization opportunities. This tool is particularly useful during development when you want to ensure your contracts are as gas-efficient as possible. To install, runnpm install -D hardhat-gas-reporter
.
Then, import hardhat-gas-reporter
in hardhat.config.ts
:
hardhat.config.ts
file:
Your first gas profiling
Create a contract calledStore
with the following settings:
Store.test.ts
in order to test the gas reporter plugin. The test file should contain the following:
npx hardhat test
. The following report appears:
addItem
and the deployment costs.
Common strategies to optimize contract sizes
After performing the first gas profiling, you can start ideating strategies to improve the gas costs. These strategies are certainly vast and this tutorial only covers some basic examples.Using the optimizer
From the previous report, you can identify that the optimizer of the project has a value of 10000 runs. This means the deployment costs will be more expensive. However, if you modify that value to 200, you get:Using immutable variables
In ourStore
contract, you can identify certain variables that are only set during the creation of the contract. This means that an opportunity is possible to turn those variables into immutable, since immutable variables can still be assigned at construction time.
If you modify the Store
contract to:
Avoid unnecessary data storage
Storing data and not storing data in a smart contract is a design decision that has pros and cons. Some of the pros are certainly that all the information is stored in the smart contract and you don’t necessarily need to rely on events or any other service to access the storage of a contract. However, the cons of storing all the information on the contract is the fact that it will be more expensive to perform actions against the smart contract. In theStore
smart contract, you have the following:
Id
of the Item
struct and the id
used in the mapping are similar. You can avoid duplicating this information by removing the id of the Item
struct.
The contract looks like:
Store
smart contract. However, you can go further and instead of storing the items in a mapping
, you can simply emit events
and use the events as a cheap form of storage.
For instance, you can modify the contract to look like:
ItemCreated
event, which reduces the gas costs for deployment and execution:
ItemCreated
events emitted by the contract.
Using custom errors
Another common way to optimize gas costs is by removingrequire
s and use custom errors. For instance, you can do the following: