Building an Ethereum Gas Tracker

·

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:

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


Quick Recap of EIP-1559

EIP-1559 introduced these key changes to Ethereum’s gas pricing:

Our gas tracker will visualize these mechanics in real time.


Part 1: Node.js Script for Gas Fee History

Step 0: Setup

Step 1: Create an Alchemy Account

Step 2: Generate an API Key

  1. Create an app in the Alchemy Dashboard.
  2. Select Ethereum and Mainnet.
  3. 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.js

Step 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-web3

Step 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:

  1. Base Fees fluctuate predictably (±12.5% per block).
  2. Priority Fees are typically a small fraction of total costs.
  3. 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:

Happy tracking! 🚀