Skip to main content

How to Send an EIP-1559 Transaction

Updated on
May 26, 2023

How to Send an EIP-1559 Transaction

5 min read

Overview

While Ethereum has been trying to scale, it has encountered some gas price issues. Many layer 2 solutions and sidechains sprang into existence to solve this problem, but Ethereum is the main chain, and at some point, it has to be improved. EIP-1559 was introduced to reduce the volatility of gas prices on-chain. In this guide, we will learn how to send an EIP-1559 transaction using ethers.js.

Prerequisites

  • An Ethereum testnet node.
  • Ethereum wallet.
  • NodeJS installed.
  • Code editor and CLI.
  • Water, because it is good.

What is EIP-1559?

EIP stands for Ethereum Improvement Proposals, which defines the standards around Ethereum protocol. Anyone can propose EIPs as Ethereum is open source. Later these EIPs can integrate into the core protocol after going through an approval process.

Before EIP-1559, the transactions with a lesser gas fee on the Ethereum chain often remained pending for a long time because the blocks are always filled with the highest paying transactions. To eliminate this, EIP-1559 introduced a more sophisticated and fair system of gas fees with a base fee per block and a tip for the miner. The base fee makes sure that the transactions get included in the blocks, and the tip is to reward the miners. With EIP-1559, the gas limit of the blocks doubled. A 100% full block pre EIP-1559 is only 50% full post EIP-1559, which means there is more room for additional transactions.

Now let us understand the new variables/mechanics of gas after 1559:

  • baseFeePerGas: This is the base fee per gas generated with every block header by the protocol. baseFeePerGas requires the minimum multiplier for the gasUsed attribute for a transaction to be added to a block. For example, the gas for your transaction will be baseFeePerGas*gasUsed. This is the part of the transaction fee that is burned in every block. Each block's baseFeePerGas can increase or decrease by 12.5% depending on how full the block is compared to the previous block. For example, if 100% full then baseFeePerGas goes +12.5%, if 50% full then it remains same, if 0% full then -12.5%.
  • maxPriorityFeePerGas: Set by user. This is the part of the gas that goes to miners. Users can pay a premium for a high-priority transaction using this variable. Whenever a block gets 100% full, this is the deciding factor for transaction priority just like the pre-1559 era.
  • maxFeePerGas: Set by user. This represents the maximum amount of gas fee a user is willing to pay for a transaction (inclusive of baseFeePerGas + maxPriorityFeePerGas). Once the transaction is confirmed, the difference between maxFeePerGas and baseFeePerGas + maxPriorityFeePerGas is refunded back to the user/sender of the transaction.

Now that we know about the EIP-1559, it would be good to see it in action by sending an EIP-1559 transaction.

Booting our node

The first step on our journey to send a transaction would be to have an Ethereum Testnet node set up; we will be using the Kovan Testnet to make the transaction, as sending transactions on the Ethereum Mainnet would cost real ETH. For convenience, we will boot a free trial Kovan Node from QuickNode.

Screenshot of Quicknode Kovan Endpoint

Save the HTTP URL as we will be using it later.

Getting funds in the wallet

We will need some Kovan test ETH in our wallet to send some in the transaction and pay for gas. To get some, go over to the Kovan faucet, sign in, join the room and paste your wallet address in the chat. After successfully completing those steps, the Kovan test ETH will be sent to your wallet.

Installing required libraries

We will use the ethers.js library to send our transaction and the log-timestamp library to log the time of each step of our script execution. 

Create a project directory and cd into it

mkdir eipDemo
cd eipDemo

To install these libraries, we will use node.js’s package manager npm. 

npm install log-timestamp ethers@5.7

Make sure that your Ethers.js installation version is 5.7

Now we should have our libraries installed in our project directory.

Making an EIP-1559 transaction

Create a javascript file named index.js, and paste the following code in it:

require("log-timestamp");
const ethers = require("ethers");

const privateKey = ("ADD_YOUR_PRIVATE_KEY_HERE").toString('hex');
const wallet = new ethers.Wallet(privateKey);

const address = wallet.address;
console.log("Public Address:", address);

const httpsUrl = "ADD_YOUR_HTTP_URL_HERE";
console.log("HTTPS Target", httpsUrl);

const init = async function () {
const httpsProvider = new ethers.providers.JsonRpcProvider(httpsurl);

let nonce = await httpsProvider.getTransactionCount(address);
console.log("Nonce:", nonce);

let feeData = await httpsProvider.getFeeData();
console.log("Fee Data:", feeData);

const tx = {
type: 2,
nonce: nonce,
to: "0x8D97689C9818892B700e27F316cc3E41e17fBeb9", // Address to send to
maxPriorityFeePerGas: feeData["maxPriorityFeePerGas"], // Recommended maxPriorityFeePerGas
maxFeePerGas: feeData["maxFeePerGas"], // Recommended maxFeePerGas
value: ethers.utils.parseEther("0.01"), // .01 ETH
gasLimit: "21000", // basic transaction costs exactly 21000
chainId: 42, // Ethereum network id
};
console.log("Transaction Data:", tx);

const signedTx = await wallet.signTransaction(tx);
console.log("Signed Transaction:", signedTx);

const txHash = ethers.utils.keccak256(signedTx);
console.log("Precomputed txHash:", txHash);
console.log(`https://kovan.etherscan.io/tx/${txHash}`);

httpsProvider.sendTransaction(signedTx).then(console.log);

};

init();

Replace ADD_YOUR_PRIVATE_KEY_HERE on line 4 with your wallet private key, and ADD_YOUR_HTTP_URL_HERE on line 10 with your node's HTTP URL we got earlier.

Explanation of the code above:

Line 1-2: Importing the log-timestamp and ethers libraries.

Line 4-5: Saving our private key in the priavteKey variable, and initializing the wallet using privateKey.

Line 7-8: Getting the address of our wallet and printing it to the console.

Line10-11: Saving our node's HTTP URL in httpUrl variable and printing it to console.

Line 13: Starting an async init function.

Line 14: Initializing our provider and saving to httpsProvider variable.

Line 16-17: Getting nonce from the provider and printing it to console.

Line 19-20: Getting fee data i.e gasPrice, maxPriorityFeePerGas, maxFeePerGas from the node and saving it to feeData variable, then printing it to console.

Line 22-30: Transaction object tx: mentioning transaction as type 2 which is EIP-1559 transaction, mentioning nonce parameter, mentioning the receiver’s address, maxPriorityFeePerGas parameter and getting the info from feeData variable, maxFeePerGas parameter and getting the data from feeData variable, value parameter has the amount of ETH to be sent, gasLimit and chainId which is 42 here as the chain is Kovan.

Line 32: Printing the transaction object.

Line 34-35: Signing the transaction using our wallet and printing the signed transaction raw data to the console.

Line 37: Applying keccak256 to the raw transaction to get transaction hash and saving it to txHash variable.

Line 38-39: Printing the transaction has to console, along with the link to Kovan etherscan.

Line 41: Sending our transaction using our node.

Save the file and run the script using:

node index

Upon successful execution, the output will look like this

Conclusion

I hope now you have a better understanding of EIP-1559 as in this guide, we learned about EIP-1559, and how to send an EIP-1559 transaction.

Subscribe to our newsletter for more articles and guides on Ethereum. If you have any feedback, feel free to reach out to us via Twitter. You can always chat with us on our Discord community server, featuring some of the coolest developers you’ll ever meet :)

Share this guide