How to use ethers.js to set a custom gas price and gas limit for a transaction
December 19th, 2023

If you've got some experience with MetaMask or other web3 wallets, you’ve probably encountered a stuck (or ‘Pending’) transaction already. Often the best and fastest solution is to increase the gas fee for your transaction. Sending a higher gas fee along with your transaction incentivises nodes to process your transaction with higher priority.

But what exactly is a ‘gas fee’?

EIP-1559 introduced some new gas mechanics, so it’s important we understand the key factors:

  • baseFeePerGas: The base fee per unit of gas utilized, set with each block header. This cannot be influenced by the users. The network sets the baseFeePerGas automatically.

  • maxPriorityFeePerGas: The ‘tip’ a user can send along with a transaction, to incentivize validators to include the transaction in the next block. A higher tip means a higher chance the transaction is included in the next block.

  • maxFeePerGas: The maximum price a user is willing to pay per unit of gas for the transaction. It is the sum of baseFeePerGas and maxPriorityFeePerGas.

​​As you can see, we can use the maxPriorityFeePerGas and/or the maxFeePerGas to increase or decrease the chance of getting a transaction confirmed in the next block.

Although MetaMask already calculates ‘the best’ total gas fee for a transaction, it’s sometimes not sufficient. For example, there could be a sudden increase in gas prices because of network congestion.

Before signing a transaction with MetaMask, you can easily adjust the gas fee by selecting ‘Low,’ ‘Market’ or ‘Aggressive’ in the fee settings – ‘Low’ being the slowest and cheapest, ‘Aggressive’ being the fastest and most expensive option.

An example of the different gas fee options in Metamask/Linea
An example of the different gas fee options in Metamask/Linea

As a Linea builder, it could be beneficial to include a custom gas fee or limit, in the transactions your users will be signing. There could be certain transactions that are time sensitive or more important than others. You can even limit the gas fee if you only want certain functions to be executed when gas fees are low.

Adding a custom maxPriorityFeePerGas and maxFeePerGas to a transaction

In this guide, we will add a higher gas fee to our transaction, so we can increase the chance our users can mint their NFT.

The goal is to include our transaction in the next block, so the maxPriorityFeePerGas will be very high. For regular transactions, a maxPriorityFeePerGas of 2 gwei is usually enough to get the transaction included in the next block.

Let’s query the blockchain to see what the current gas status is using ethers.js:

let feeData = await provider.getFeeData();

This will output some familiar numbers:

{
lastBaseFeePerGas: BigNumber { value: "22114103899" }, 
maxFeePerGas: BigNumber { value: "45728207798" }, 
maxPriorityFeePerGas: BigNumber { value: "1500000000" },
gasPrice: BigNumber { value: "22164103899" }
}

We can easily define the maxPriorityFeePerGas:

let currentTip = feeData.maxPriorityFeePerGas;

Let’s multiply the fetched ‘currentTip’ by 10, so our user will have a very high chance of getting his transaction included in the next block.

let customTip = currentTip * 10; let transaction = await myContract.mint( { maxPriorityFeePerGas: customTip } );

await transaction.wait();

Pretty easy, right? You can also manually set the maxPriorityFeePerGas using:

let transaction = await myContract.mint( { maxPriorityFeePerGas: 3000000000 } );

The downside to this is you will need to check the current maxPriorityFeePerGas and then input a higher value yourself.

Our first example already outputs a good estimate of the current gas situation, regardless of when the function is called.

Expanding our function call to include a maxFeePerGas value as well:

Defining a maxFeePerGas value should be done with caution. Depending on the current gas situation, it can cause your transaction to stay pending for a very long time. As we already know, the maxFeePerGas consists of the baseFeePerGas + maxPriorityFeePerGas.

If we set a high maxPriorityFeePerGas and a low maxFeePerGas, we’re essentially asking the blockchain to include our transaction when the baseFeePerGas is very low.

Let’s pass a MaxFeePerGas of 15000000000. Our fetched data shows a value of 45728207798, so we divided the fetched value by 3.

let customTip = currentTip * 10; let maximumGasFee = 15000000000; let transaction = await myContract.mint( { maxPriorityFeePerGas: customTip, maxFeePerGas: maximumGasFee} );

await transaction.wait();

And that’s it! We added our custom gas values to our Linea transaction and greatly increased the chance our users could mint their NFT, without them having to worry about the gas fee being too low.

Now it’s your turn, play around with different values to see which transactions are included and which ones stay pending for a while. Remember that each use case has its own approach.

You can get some Linea test ETH from the official faucet here.

Useful links:

  • EIP-1559: Fee market change for ETH 1.0 chain (ethereum.org)

  • Build on Linea (Linea documentation)

  • Learn more about gas (MetaMask Support user guide about gas)

Subscribe to Pieter
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.
More from Pieter

Skeleton

Skeleton

Skeleton