イーサリアム ガス トラッカーを 5 分で構築する方法を理解する

導入
副題
導入
2021年8月のロンドンのハードフォークは、イーサリアムネットワーク史上最大のアップグレードをもたらしました。このフォークは、ブラインド オークション モデルよりも優れていると宣伝されるガス価格設定メカニズムである EIP-1559 を実装しています。また、イーサリアム(ETH)の金融政策に根本的な変更を導入し、少なくとも短期的にはイーサリアムをデフレ通貨にします。
このチュートリアルでは、EIP-1559 のガス料金の 2 つの新しいコンポーネントと、最後の 20 ブロックの他の統計 (ブロック サイズなど) を追跡するガス トラッカーを構築します。これにより、次の 2 つの重要な目標を達成できます。
EIP-1559 がどのように機能し、どのような改善がもたらされるのかについて、より深く理解できます。
最新のブロック量とガス料金を基本料金と優先料金ごとに分類して取得する、フル機能のガス追跡アプリケーションです。
これを行うには、Alchemy、Alchemy web3.js ライブラリ、Node、および React を使用します。これらの言葉に聞き覚えがないとしても、心配しないでください。詳しく説明します。
このチュートリアルは、読者がイーサリアムでのガスとガス価格の仕組みについて基本的に理解していることを前提としています。 EIP-1559 について予備的に理解しておくことも役に立ちますが、必須ではありません。
EIP-1559 クイックレビュー
EIP-1559 は、イーサリアムのガス価格設定メカニズムに次の変更をもたらします。
ブラインド オークションのガス料金は、基本料金と優先料金 (またはマイナー チップ) の 2 つの料金に置き換えられました。
基本料金はネットワークによって自動的に決定されます。前のブロックがいっぱいの場合は 12.5% に増加し、前のブロックが空の場合は 12.5% に減少します。
マイナーズチップはユーザーによって決定され、トランザクションの緊急性に応じて調整できます。
基本料金は、マイナーが人為的にブロックをフラッディングするのを防ぐために、ネットワークによって燃やされます。ただし、マイナーはチップをポケットに入れることができます。
EIP-1559 では、ガス価格の改善に加えて、突然のトラフィックの急増に対処するためのネットワークの装備を改善するための改善も提案されています。おそらくご存知のとおり、イーサリアムのトランザクションはブロックにグループ化されています。フォーク以前は、トラフィックに関係なく、ブロックは 1,500 万件のガス トランザクションしか保持できませんでした。
アップグレードにより、ブロック サイズの上限は 2 倍の 3,000 万ガスに増加しました。これは、需要が増加する時期によりよく対応するために行われます。ただし、基本料金はブロック容積 (またはブロックで使用されるガス) の平均 50%、または約 1,500 万ガスに調整されることが予想されます。
私たちが作成したガストラッカーを使用すると、これがどのようにリアルタイムで機能するかを確認できます。このプロジェクトは 2 つの部分で構築します。最初の部分では、トランザクション手数料の履歴をリアルタイムで追跡するノード スクリプトを作成します。 2 番目のパートでは、このスクリプトを利用して React アプリケーションを作成し、最終的なトラッカーを構築します。
パート 1: 取引手数料履歴スクリプト

このセクションでは、イーサリアム ネットワーク上の最後の 20 ブロックのガス料金の履歴を取得できるスクリプトを (ノード内に) 作成します。
ステップ 0: ノードと npm をインストールする
ローカル マシンにノードと npm (少なくとも v14 以降) がインストールされていることを確認してください。
ステップ 1: Alchemy アカウントを作成する

ブロックの最新のガス料金履歴を取得するには、イーサリアムネットワークに接続して通信する必要があります。 Alchemy は、独自のノードを起動せずにこれを可能にするブロックチェーン開発プラットフォームです。

ステップ 2: Alchemy アプリケーション (および API キー) を作成する
Alchemy ダッシュボードでアプリケーションを作成します。チェーンはイーサリアムに設定され、ネットワークはメインネットに設定されます。
次に、アプリケーション ページにアクセスし、[キーの表示] をクリックします。これにより、アプリケーションの HTTP および Websocket URL を含むポップアップが開きます。このチュートリアルでは、Websocket URL を使用します。
ステップ 3: ノード プロジェクトを作成し、依存関係をインストールする
> mkdir gas-tracker-script && cd gas-tracker-script > npm init -y > npm install --save @alch/alchemy-web3 > touch main.js
これで、ノード スクリプトの作成を開始できます。空のリポジトリを作成して依存関係をインストールしましょう。このスクリプトには、Alchemy web3.js ライブラリが必要です。
ターミナル (またはコマンド プロンプト) で次のコマンドを実行します。
これにより、必要なすべてのファイルと依存関係を含む、gas tracker-script というリポジトリが作成されます。お気に入りのコード エディターでこのリポジトリを開きます。すべてのコードを main.js ファイルに記述します。
ステップ 4: Alchemy を使用して Web3 クライアント インスタンスを作成する
const { createAlchemyWeb3 } = require("@alch/alchemy-web3");// Using WebSockets
const web3 = createAlchemyWeb3(
"wss://eth-mainnet.alchemyapi.io/v2/<--API KEY-->",
);
Alchemy web3 を使用してクライアント インスタンスを作成するのは非常に簡単です。
main.js ファイルに、次のコード行を追加します。
上記のプレースホルダーをアプリケーションの WebSocket URL に置き換えてください。
ステップ 5: 過去 20 ブロックの履歴を取得する
過去 10 ブロックのガス料金履歴が必要です。私たちが関心のあるデータには、基本料金、優先料金範囲、ブロック サイズ、ブロック番号が含まれます。
幸いなことに、Alchemy には、前述のすべてのデータを自動的に返す非常に便利な eth_feeHistory があります。
web3.eth.getFeeHistory(20, "latest", [25, 50, 75]).then(console.log)
指定する必要があるのは、データが必要な最新のブロック、確認するブロックの総数、および希望料金の割合の範囲だけです。

私たちは、最新の 20 ブロックと、優先料金の 25、50、および 75 パーセンタイルに興味を持っています。
このスクリプトを (ノード main.js を使用して) 実行すると、探しているデータがフェッチされるはずです。これは、5 ブロックのデータをリクエストした後に受け取った結果です。
ステップ 6: 出力のフォーマット設定
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;
ステップ 5 で受け取った出力は正しいですが、あまり読みやすいものではありませんでした。料金は16進数で表現されており、どのデータがどのブロックに対応するのか分かりにくいデータ構造になっています。
const numBlocks = 5;web3.eth.getFeeHistory(numBlocks, "latest", [25, 50, 75]).then((data) => {
const blocks = formatOutput(data, numBlocks);
console.log(blocks);
});
生データを辞書のリストに変換する小さな関数を書いてみましょう。各辞書には特定のブロックのデータが含まれます。この関数は、wei で表されるすべての 16 進数の Gas 値を Gwei で表される 10 進数に変換します。

最後に、この関数をfeeHistoryとして使用してみましょう。
このバージョンのスクリプトを実行すると、次の形式で出力が生成されます。
ステップ 7: 最新のブロックヘッダーを購読する
let subscription = web3.eth.subscribe('newBlockHeaders');subscription.on("data", () => {
web3.eth.getFeeHistory(numBlocks, "latest", [25, 50, 75]).then((data) => {
const blocks = formatOutput(data, numBlocks);
console.log(blocks);
});
});
新しいブロックは約 15 秒ごとにイーサリアム ブロックチェーンに追加されます。したがって、理想的には、追加されるブロックのイベントをサブスクライブし、トランザクション履歴を更新して、常に最後の 20 ブロックのデータが表示されるようにしたいと考えています。
getFeeHistory 関数を購読イベント コールバック内にネストしてみましょう。

ここで main.js スクリプトを実行すると、最新のデータのバッチが 15 秒ごとに出力されます。ここまで来たら、おめでとうございます! これで、完全に機能するガス トラッカーが完成しました。
パート 2: React アプリケーション
前のセクションでは、新しいブロックがイーサリアム メインネットに追加されるたびに、過去 20 ブロックの料金履歴を取得するスクリプトを作成しました。
このセクションでは、このデータを端末からブラウザにストリーミングする小さな React アプリケーションを構築します。手数料取引履歴に加えて、過去20ブロックの平均ガス手数料とブロックサイズも表示されます。
> npx create-react-app gas-tracker-frontend > cd gas-tracker-frontend
ステップ 1: React プロジェクトを初期化し、依存関係をインストールする
> npm install --save @alch/alchemy-web3
次のコマンドを実行します。
これにより、サンプル React プロジェクトが作成されます。反応の依存関係に加えて、前のセクションの Alchemy web3 ライブラリもインストールする必要があります。
import './App.css';
import { useEffect, useState } from 'react';
import { createAlchemyWeb3 } from '@alch/alchemy-web3';const NUM_BLOCKS = 20;function App() { const [blockHistory, setBlockHistory] = useState(null);
const [avgGas, setAvgGas] = useState(null);
const [avgBlockVolume, setAvgBlockVolume] = useState(null); const formatOutput = (data) => { let avgGasFee = 0;
let avgFill = 0;
let blocks = []; for (let i = 0; i < NUM_BLOCKS; i++) { avgGasFee = avgGasFee + Number(data.reward[i][1]) + Number(data.baseFeePerGas[i])
avgFill = avgFill + Math.round(data.gasUsedRatio[i] * 100); 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: Math.round(data.gasUsedRatio[i] * 100),
})
} avgGasFee = avgGasFee / NUM_BLOCKS;
avgGasFee = Math.round(avgGasFee / 10 ** 9) avgFill = avgFill / NUM_BLOCKS;
return [blocks, avgGasFee, avgFill];
} useEffect(() => { const web3 = createAlchemyWeb3(
"wss://eth-mainnet.alchemyapi.io/v2/<--API KEY-->",
); let subscription = web3.eth.subscribe('newBlockHeaders'); subscription.on('data', () => {
web3.eth.getFeeHistory(NUM_BLOCKS, "latest", [25, 50, 75]).then((feeHistory) => {
const [blocks, avgGasFee, avgFill] = formatOutput(feeHistory, NUM_BLOCKS);
setBlockHistory(blocks);
setAvgGas(avgGasFee);
setAvgBlockVolume(avgFill);
});
}); return () => {
web3.eth.clearSubscriptions();
}
}, [])
return (
EIP-1559 Gas Tracker
{!blockHistory &&
Data is loading...
}{avgGas && avgBlockVolume &&
{avgGas} Gwei | {avgBlockVolume}% Volume
}{blockHistory &&
| Block Number | Base Fee | Reward (25%) | Reward (50%) | Reward (75%) | Gas Used |
|---|---|---|---|---|---|
| {block.blockNumber} | {block.baseFeePerGas} | {block.reward[0]} | {block.reward[1]} | {block.reward[2]} | {block.gasUsedRatio}% |
);
}export default App;
ステップ 2: App.js ファイルを作成する
すべてのロジックは App.js ファイル内に存在します。以下の内容を上記のファイルにコピーします。
これは React コースではないため、React 固有の部分については詳しく説明しません。ただし、スクリプトで行ったように経費履歴を取得し、それを HTML テーブルとして出力しているだけであることがわかるはずです。
私たちが使用する唯一の追加ロジックは、20 ブロックにわたる平均ガス価格と平均ブロック サイズを計算することですが、これは簡単なタスクです。
.main-container {
text-align: center;
}table {
border-collapse: collapse;
margin: 20px auto;
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
}thead {
background: linear-gradient(267.45deg,#05d5ff -34.23%,#53f 99.39%);
color: white;
padding: 10px;
}th {
font-size: 18px;
padding: 15px;}tbody > tr {
border-top: 1px solid #ccc;
border-bottom: 1px solid #ccc;
margin: 0px;
padding: 15px;
}td {
padding: 6px;
}.gas {
color: #4299E1;
}.vol {
color: #4C51BF;
(オプション) ステップ 3: いくつかのスタイルを追加する
次のように、App.css ファイルにいくつかの基本スタイルを追加できます。
npm start
ステップ 4: アプリケーションをローカルホストにデプロイする

アプリは次のようになります。
分析する
おめでとうございます! 完全に機能するガス追跡アプリケーションが完成しました。
分析する
上記のデータに戻って分析してみましょう。以下は、観察できる EIP-1559 実装の直接の結果です。
基本料金はブロックごとに大きく変動しません。実際、最大の増減率は12.5%だった。
ブロック サイズは変動する傾向がありますが、平均ブロック サイズは約 50% です。
結論は
データは、このモデルではガスコストがはるかに予測可能であることを示しているようです。誰もが同じ基本料金と優先料金を支払い、ほとんどの場合、優先料金は合計料金のほんの一部にすぎないため、ほとんどの取引でガス料金が法外に支払われることはありません。したがって、このサンプル データは、EIP-1559 がその目標、つまりガス価格の予測可能性の向上、ガスの過剰支払いの削減に成功したことを示しています。
この記事では多くのことを取り上げてきました。 EIP-1559 用のガストラッカーをゼロから構築することで、それがイーサリアムトランザクションにもたらす改善を理解し、評価していただけることを願っています。


