Introduction
The London Hard Fork in August 2021 marked one of Ethereum's most significant upgrades. This fork implemented EIP-1559, a gas pricing mechanism designed to replace the traditional blind auction model. It also introduced fundamental changes to Ethereum's monetary policy, making ETH a deflationary asset—at least in the short term.
In this tutorial, we’ll build a gas tracker to monitor the two new components of gas fees under EIP-1559, along with other key statistics (like block size) from the latest 20 blocks. By doing so, we’ll achieve two goals:
- Gain a deeper understanding of EIP-1559 and its improvements.
- Develop a fully functional gas tracker app that retrieves recent block sizes and gas fees, categorized by base fees and priority fees.
We’ll use Alchemy, the Alchemy Web3.js library, Node.js, and React. Don’t worry if these tools are unfamiliar—we’ll explain each step!
Prerequisites
- Basic knowledge of Ethereum gas and gas pricing.
- Familiarity with EIP-1559 is helpful but not required.
Quick Recap of EIP-1559
EIP-1559 introduced these key changes to Ethereum’s gas pricing:
- Base Fee: Automatically set by the network. Adjusts ±12.5% based on block fullness.
- Priority Fee (Tip): Paid directly to miners, customizable by users.
- Burn Mechanism: Base fees are burned to prevent spam, while tips go to miners.
- Dynamic Block Size: Blocks now expand to 30M gas (from 15M) during congestion, with fees adjusting to keep average usage near 50%.
Our gas tracker will visualize these mechanics in real time.
Part 1: Node.js Script for Gas Fee History
Step 0: Setup
- Ensure Node.js v14+ and npm are installed.
Step 1: Create an Alchemy Account
- Sign up at Alchemy to access Ethereum node APIs.
Step 2: Generate an API Key
- Create an app in the Alchemy Dashboard.
- Select Ethereum and Mainnet.
- Copy the WebSocket URL (we’ll use this later).
Step 3: Initialize Project
mkdir gas-tracker-script && cd gas-tracker-script
npm init -y
npm install @alch/alchemy-web3
touch main.jsStep 4: Connect to Ethereum via Alchemy
Add this to main.js:
const { createAlchemyWeb3 } = require("@alch/alchemy-web3");
const web3 = createAlchemyWeb3("wss://eth-mainnet.alchemyapi.io/v2/YOUR_API_KEY");Step 5: Fetch Fee History
Retrieve data for the latest 20 blocks:
web3.eth.getFeeHistory(20, "latest", [25, 50, 75]).then(console.log);Step 6: Format Data
Convert hex values to Gwei and structure the output:
const formatOutput = (data, numBlocks) => {
let blocks = [];
for (let i = 0; i < numBlocks; i++) {
blocks.push({
blockNumber: Number(data.oldestBlock) + i,
reward: data.reward[i].map(r => Math.round(Number(r) / 10 ** 9)),
baseFeePerGas: Math.round(Number(data.baseFeePerGas[i]) / 10 ** 9),
gasUsedRatio: data.gasUsedRatio[i],
});
}
return blocks;
};Step 7: Subscribe to New Blocks
Update data in real time:
let subscription = web3.eth.subscribe('newBlockHeaders');
subscription.on("data", () => {
web3.eth.getFeeHistory(20, "latest", [25, 50, 75]).then((data) => {
const blocks = formatOutput(data, 20);
console.log(blocks);
});
});👉 Run your gas tracker script to see live data!
Part 2: React Frontend
Step 1: Create React App
npx create-react-app gas-tracker-frontend
cd gas-tracker-frontend
npm install @alch/alchemy-web3Step 2: Build the App
Replace App.js with:
import { useEffect, useState } from 'react';
import { createAlchemyWeb3 } from '@alch/alchemy-web3';
function App() {
const [blockHistory, setBlockHistory] = useState(null);
const [avgGas, setAvgGas] = useState(null);
const [avgBlockVolume, setAvgBlockVolume] = useState(null);
useEffect(() => {
const web3 = createAlchemyWeb3("YOUR_ALCHEMY_WS_URL");
const subscription = web3.eth.subscribe('newBlockHeaders');
subscription.on("data", () => {
web3.eth.getFeeHistory(20, "latest", [25, 50, 75]).then((data) => {
const [blocks, avgGasFee, avgFill] = formatOutput(data);
setBlockHistory(blocks);
setAvgGas(avgGasFee);
setAvgBlockVolume(avgFill);
});
});
return () => web3.eth.clearSubscriptions();
}, []);
return (
<div className="main-container">
<h1>EIP-1559 Gas Tracker</h1>
{avgGas && <h3>Avg Gas: {avgGas} Gwei | Block Volume: {avgBlockVolume}%</h3>}
{blockHistory && (
<table>
<thead>
<tr>
<th>Block</th>
<th>Base Fee</th>
<th>Priority Fee (25/50/75%)</th>
<th>Gas Used</th>
</tr>
</thead>
<tbody>
{blockHistory.map(block => (
<tr key={block.blockNumber}>
<td>{block.blockNumber}</td>
<td>{block.baseFeePerGas} Gwei</td>
<td>{block.reward.join('/')} Gwei</td>
<td>{Math.round(block.gasUsedRatio * 100)}%</td>
</tr>
))}
</tbody>
</table>
)}
</div>
);
}Step 3: Add Styling
Update App.css:
.main-container { padding: 20px; }
table { margin: 20px auto; border-collapse: collapse; }
th, td { padding: 10px; border: 1px solid #ddd; }Step 4: Run the App
npm start👉 View your live gas tracker in the browser!
Analysis
Key observations from our tracker:
- Base Fees fluctuate predictably (±12.5% per block).
- Priority Fees are typically a small fraction of total costs.
- Block Size averages near 50%, aligning with EIP-1559’s design.
FAQs
1. Why does EIP-1559 burn base fees?
Burning base fees reduces ETH supply, creating deflationary pressure and preventing spam.
2. How is block size dynamic?
Blocks expand to 30M gas during congestion but target 15M gas long-term.
3. Can miners manipulate fees?
No—base fees are algorithmically set, and tips are transparent.
Conclusion
We’ve built a gas tracker that demystifies EIP-1559’s mechanics. By leveraging Alchemy and React, we now have a tool to monitor Ethereum’s evolving fee market in real time.
Next Steps:
- Add historical charts.
- Deploy to a live website.
Happy tracking! 🚀