メインコンテンツへスキップ

SQLでイーサリアムの基礎的なトピックについて学ぶ

SQL
クエリ
トランザクション
初級
Paul Apivat
2021年5月11日
14 分の読書

イーサリアムに関するチュートリアルの多くはデベロッパー向けのものですが、データアナリストや、クライアント/ノードを実行することなくオンチェーンのデータを確認したい人々を対象とする学習リソースは多くありません。

このチュートリアルは、Dune Analytics (opens in a new tab)が提供するインターフェースを用いて、オンチェーンのデータに対して構造化問い合わせ言語(SQL)のクエリを実行することで、トランザクション、ブロック、ガスといったイーサリアムの基本的なコンセプトについての理解を深めるものです。

オンチェーンのデータは、イーサリアムやイーサリアム・ネットワークに関する理解を深めるのに役立つだけでなく、コンピュータ処理能力の経済学といった現在のイーサリアムが直面している課題(例:ガス代の上昇)や、より重要性が高いスケーリング・ソリューションに関する議論について、基本的な事項を理解する土台となるものです。

トランザクション

イーサリアムのユーザーの体験は、ユーザーが管理するアカウント、またはETH残高を持つエンティティを初期化することから始まります。 アカウントには、ユーザー管理アカウントとスマートコントラクトの2種類があります(ethereum.orgを参照)。

どのアカウントも、Etherscan (opens in a new tab)Blockscout (opens in a new tab)のようなブロックエクスプローラーで表示できます。 ブロックエクスプローラーは、イーサリアム上のデータポータルです。 このポータルから、ブロックのデータ、トランザクション、マイナー、アカウント、および他のオンチェーンのアクティビティをリアルタイムで確認できます(こちらをご覧ください)。

しかし、外部のブロックエクスプローラーが提供する情報と直接照合したい場合は、オンチェーンのデータに対するクエリを実行したいと思うかもしれません。 Dune Analytics (opens in a new tab)は、SQLに関する一定の知識を持つ人なら誰でもこの機能を利用できるようにします。

参考までに、イーサリアム財団(EF)のスマートコントラクトアカウントはBlockscout (opens in a new tab)で閲覧できます。

注意すべき点として、EFのアカウントを含むすべてのアカウントは、トランザクションの送受信に使用できる公開アドレスを持つということが挙げられます。

Etherscanのアカウント残高は、通常のトランザクションと内部トランザクションで構成されています。 内部トランザクションは、その名前とは裏腹に、チェーンの状態を変更する_実際の_トランザクションではありません。 これらは、コントラクトの実行によって開始される値の転送です(ソース (opens in a new tab))。 内部トランザクションは署名を持たないためブロックチェーンには含まれず、Dune Analyticsでクエリを実行することができません。

したがって、このチュートリアルでは通常のトランザクションのみを取り上げます。 通常のトランザクションに対しては、以下のようにクエリを実行します。

1WITH temp_table AS (
2SELECT
3 hash,
4 block_number,
5 block_time,
6 "from",
7 "to",
8 value / 1e18 AS ether,
9 gas_used,
10 gas_price / 1e9 AS gas_price_gwei
11FROM ethereum."transactions"
12WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
13ORDER BY block_time DESC
14)
15SELECT
16 hash,
17 block_number,
18 block_time,
19 "from",
20 "to",
21 ether,
22 (gas_used * gas_price_gwei) / 1e9 AS txn_fee
23FROM temp_table
すべて表示

これにより、Etherscanのトランザクションページで提供されるのと同一の情報が返されます。 比較のために、2つのソースを以下に示します。

Etherscan

Etherscan トランザクション エクスプローラー ビューのスクリーンショット

Blockscout上のEFのコントラクトページ。 (opens in a new tab)

Dune Analytics

Dune Analytics クエリ ダッシュボードのスクリーンショット

ダッシュボードはこちら (opens in a new tab)にあります。 テーブルをクリックすると、クエリを確認できます(上記も参照してください)。

トランザクションの内訳

送信されたトランザクションには、以下のようないくつかの情報が含まれています(ソース):

  • 受信者: 受信アドレス(クエリでは「to」)
  • 署名: 送信者の秘密鍵がトランザクションに署名しますが、SQLでクエリできるのは送信者の公開アドレス(「from」)です。
  • : これは転送されたETHの量です(etherの列を参照)。
  • データ: ハッシュ化された任意のデータです(data列を参照)
  • ガスリミット – トランザクションで消費できるガスユニットの最大量。 ガスユニットは、計算ステップを示します
  • maxPriorityFeePerGas - マイナーへのチップとして含めることができるガスの最大量
  • maxFeePerGas - トランザクションに支払う意思のあるガスの最大額(baseFeePerGasとmaxPriorityFeePerGasを含む)

イーサリアム財団の公開アドレスへのトランザクションについて、これらの具体的な情報を次のようにクエリできます:

1SELECT
2 "to",
3 "from",
4 value / 1e18 AS ether,
5 data,
6 gas_limit,
7 gas_price / 1e9 AS gas_price_gwei,
8 gas_used,
9 ROUND(((gas_used / gas_limit) * 100),2) AS gas_used_pct
10FROM ethereum."transactions"
11WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
12ORDER BY block_time DESC
すべて表示

ブロック

各トランザクションは、イーサリアム仮想マシン(EVM)の状態を変更します(ソース)。 トランザクションは、ネットワークにブロードキャストされ、検証を経てブロックに追加されます。 各トランザクションには、ブロック番号が関連付けられています。 データを見るには、特定のブロック番号でクエリすることができます。ブロック番号: 12396854は、執筆時点(2021/11/5)でイーサリアム財団のトランザクションの中で最も新しいブロックです。

さらに、次の2つのブロックに対してクエリを実行すると、各ブロックが1つ前のブロックのハッシュ(親ハッシュ)を含んでいることが確認でき、ブロックチェーンがどのように形成されるかを理解できます。

各ブロックには、親ブロックへの参照が含まれています。 これは、以下のhash列とparent_hash列の間に示されます(ソース):

parent_hash

Dune Analyticsでのクエリ (opens in a new tab)はこちらです:

1SELECT
2 time,
3 number,
4 hash,
5 parent_hash,
6 nonce
7FROM ethereum."blocks"
8WHERE "number" = 12396854 OR "number" = 12396855 OR "number" = 12396856
9LIMIT 10
すべて表示

時間、ブロック番号、難易度、ハッシュ、親ハッシュ、およびノンスをクエリすることでブロックを調べることができます。

このクエリがカバーしていないのは、_トランザクションのリスト_と_ステート・ルート_のみで、これらには以下の別のクエリが必要です。 フルノードまたはアーカイブノードは、すべてのトランザクションと状態遷移を保存しますので、クライアントはいつでもチェーンの状態をクエリすることができます。 これには大容量のストレージが必要になりますので、チェーンデータと状態データを分離することができます:

  • チェーンデータ(ブロックおよびトランザクションのリスト)
  • 状態データ(各トランザクションによる状態遷移の結果)

ステート・ルートは後者に分類され_暗黙的_なデータ(オンチェーンで保存されない)ですが、チェーンデータは明示的であり、チェーン自体に保存されます(ソース (opens in a new tab))。

このチュートリアルでは、Dune Analyticsを使ってSQLでクエリ_できる_オンチェーンのデータに焦点を当てます。

すでに述べたように、各ブロックにはトランザクションのリストが含まれているので、特定のブロックに絞り込んでクエリを実行できます。 最新ブロック「12396854」を試してみましょう:

1SELECT * FROM ethereum."transactions"
2WHERE block_number = 12396854
3ORDER BY block_time DESC`

DuneでのSQL出力はこちらです:

Ethereum トランザクションのリストのスクリーンショット

この1つのブロックがチェーンに追加されると、イーサリアム仮想マシン(EVM)の状態が変化します。 一度に数十、時には数百ものトランザクションが検証されます。 このブロックの場合、222件のトランザクションが含まれていました。

実際に成功した件数を調べるには、成功したトランザクションをカウントするフィルターを追加します。

1WITH temp_table AS (
2 SELECT * FROM ethereum."transactions"
3 WHERE block_number = 12396854 AND success = true
4 ORDER BY block_time DESC
5)
6SELECT
7 COUNT(success) AS num_successful_txn
8FROM temp_table

ブロック12396854では、計222件のトランザクションのうち、204件が正常に検証されました:

成功したイーサリアムトランザクションのスクリーンショット

トランザクションリクエストは毎秒数十回発生しますが、ブロックがコミットされるのはおよそ15秒に1回です(ソース)。

約15秒ごとに1つのブロックが生成されることを確認するには、1日に含まれる合計の秒数(86400秒)を15で割ることで、1日に生成される平均ブロック数(およそ5760)が分かります。

イーサリアムで1日あたりに生成されたブロック数(2016年〜現在)のグラフはこちらです:

毎日のイーサリアムブロック生成を示すグラフ

この期間に毎日生成されたブロックの平均数は約5,874です:

毎日のイーサリアムブロック生成を示すグラフ

クエリは、次のように行います。

1# 2016年以降に毎日生成されたブロック数を可視化するクエリ
2
3SELECT
4 DATE_TRUNC('day', time) AS dt,
5 COUNT(*) AS block_count
6FROM ethereum."blocks"
7GROUP BY dt
8OFFSET 1
9
10# 1日あたりの平均ブロック生成数
11
12WITH temp_table AS (
13SELECT
14 DATE_TRUNC('day', time) AS dt,
15 COUNT(*) AS block_count
16FROM ethereum."blocks"
17GROUP BY dt
18OFFSET 1
19)
20SELECT
21 AVG(block_count) AS avg_block_count
22FROM temp_table
すべて表示

2016年から現在までに1日に生成されたブロック数の平均は、この数字をわずかに上回る5,874です。 あるいは、86,400秒を平均ブロック数5,874で割ると14.7秒となり、およそ15秒に1つのブロックが生成されていることになります。

ガス

ブロックのサイズは制限されています。 ブロックの最大サイズは動的で、ネットワーク需要に応じて12,500,000から25,000,000ユニットの間で変動します。 ブロックサイズが任意に大きくなることで、フルノードのディスクスペースや処理速度に負荷がかかることを防ぐため、制限が必要となります(ソース)。

ブロックのガスリミットを理解する一つの方法として、トランザクションをバッチ処理するために利用できるブロックスペースの供給量と考えることができます。 ブロックのガスリミットは、クエリを実行して2016年から現在までを可視化できます:

時間の経過に伴うイーサリアムの平均ガス制限を示すグラフ

1SELECT
2 DATE_TRUNC('day', time) AS dt,
3 AVG(gas_limit) AS avg_block_gas_limit
4FROM ethereum."blocks"
5GROUP BY dt
6OFFSET 1

そして、イーサリアムチェーン上での計算(トランザクションの送信、スマートコントラクトの呼び出し、NFTのミントなど)の支払いに毎日使用される実際のガスがあります。 これは、利用可能なイーサリアムのブロックスペースに対する需要です:

毎日使用されるイーサリアムガスを示すグラフ

1SELECT
2 DATE_TRUNC('day', time) AS dt,
3 AVG(gas_used) AS avg_block_gas_used
4FROM ethereum."blocks"
5GROUP BY dt
6OFFSET 1

また、これら2つのグラフを並べて比較することで、需要と供給がどのように一致するかを確認できます。

gas_demand_supply

したがって、利用可能な供給量を前提として、ガス価格はイーサリアムのブロックスペースへの需要の関数として理解できます。

最後に、イーサリアムチェーンの1日あたりの平均ガス価格をクエリすることもできますが、クエリ時間が非常に長くなるため、イーサリアム財団によってトランザクションごとに支払われた平均ガス量にクエリを絞り込みます。

イーサリアム財団の毎日のガス使用量を示すグラフ

長年にわたるイーサリアム財団のアドレスへのすべてのトランザクションで支払われたガス価格を見ることができます。 クエリは、次のとおりです。

1SELECT
2 block_time,
3 gas_price / 1e9 AS gas_price_gwei,
4 value / 1e18 AS eth_sent
5FROM ethereum."transactions"
6WHERE "to" = '\xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
7ORDER BY block_time DESC

まとめ

このチュートリアルでは、オンチェーンのデータをクエリして理解することで、イーサリアムの基本的な概念とイーサリアムブロックチェーンの仕組みを理解します。

このチュートリアルで使用されたすべてのコードを含むダッシュボードはこちら (opens in a new tab)にあります。

データを使ってWeb3をさらに探求したい方は、Twitterで私を見つけてください (opens in a new tab)

最終更新: 2026年2月26日

このチュートリアルは役に立ちましたか?