ブロックチェーンのMempool:未確認トランザクションがブロックに取り込まれる仕組み
はじめに:トランザクションの「待ち行列」とは
ブロックチェーンにおけるトランザクションは、作成されネットワークに送信された後、すぐにブロックに取り込まれて確定するわけではありません。すべてのノードがそのトランザクションを認識し、検証し、そして最終的にブロックに含めるための選定プロセスを経る必要があります。この、まだどのブロックにも含まれていないが、ネットワーク上のノードによって認識・保持されている「未確認」状態のトランザクションが一時的に集まる場所を、一般的に「Mempool」(Memory Poolの略)と呼びます。
Mempoolは、各ブロックチェーンノードが独自に管理する領域であり、分散システムにおける一時的なデータバッファのような役割を果たします。これは、リレーショナルデータベースにおけるトランザクションログや、メッセージキューシステムに似た側面を持ちますが、非中央集権的なネットワーク構造ゆえの独自の特徴や技術的な考慮事項が存在します。
本記事では、このブロックチェーンのMempoolがどのような技術的な仕組みで機能し、未確認トランザクションがそこから選ばれて新しいブロックに取り込まれるまでのプロセスについて、Webエンジニアの視点から詳しく解説します。
Mempoolの役割と基本概念
Mempoolは、ブロックチェーンネットワークに参加する各ノードが個別に管理するメモリ上のデータ構造です。その主な役割は以下の通りです。
- 未確認トランザクションの一時保管: ネットワークを通じて受信した、まだブロックに含まれていない有効なトランザクションを一時的に保持します。
- トランザクションの検証: 受信したトランザクションが、プロトコルのルールに従っているか(構文、署名、二重支払いなど)を検証します。無効なトランザクションはMempoolには追加されず、破棄されます。
- ノード間での共有: 検証済みの有効なトランザクションを、P2Pネットワークを通じて他のノードに中継(Gossip)します。これにより、ネットワーク全体で同じ(あるいは非常に近い)トランザクションのセットを認識できるようになります。
Mempoolは中央集権的な単一のデータベースではなく、ネットワーク上の各ノードがそれぞれ独立して管理しています。したがって、ノードごとにMempoolの内容が完全に一致するとは限りません。ネットワーク遅延やノードの設定(Mempoolの最大サイズなど)によって、含まれるトランザクションやその順序が異なる場合があります。
Mempoolにおけるトランザクションの技術的な管理
ノードは、ネットワークからトランザクションを受信するたびに、いくつかの技術的なチェックを実行します。
- 基本的な構文チェック: トランザクションのフォーマットが正しいか。
- 署名検証: 送信者が秘密鍵で正しく署名しているか。これは公開鍵暗号と電子署名の技術が利用されます。
- インプット/アウトプットの検証(UTXOモデルの場合): 参照しているUTXO(Unspent Transaction Output)が存在し、まだ使用されていないか。また、そのUTXOを送信者が所有しているか。
- 残高の検証(アカウントモデルの場合): 送信者のアカウントに残高があり、送金額と手数料を支払えるか。
- 二重支払いチェック: 同じインプット(UTXOモデル)や、同じナンス(アカウントモデル、Ethereumなど)を持つトランザクションが既にMempoolにあるか、またはチェーン上に存在するか。
これらの検証にパスしたトランザクションのみが、そのノードのMempoolに追加されます。
Mempool内では、トランザクションは通常、手数料(Fee/Gas Price)に基づいて優先順位付けられます。これは、後述するブロック生成者が手数料の高いトランザクションを優先的にブロックに含めようとするためです。多くのノードは、手数料の高いトランザクションから優先的に他のノードに中継したり、Mempoolの容量制限に達した場合に手数料の低いトランザクションから削除したりするメカニズムを持っています。
Mempool内のトランザクション管理を疑似コードでイメージすると、以下のような構造が考えられます(実際のデータ構造や実装は各ブロックチェーンクライアントによって異なります)。
// Mempoolデータ構造のイメージ
mempool = {
transaction_hash_1: {
tx_data: { ... }, // トランザクションの内容
fee_per_byte: ..., // 手数料率 (手数料 / サイズ)
received_time: ... // 受信時刻
},
transaction_hash_2: { ... },
...
}
// 新しいトランザクションを受信した際の処理のイメージ
function handle_new_transaction(tx):
if validate_transaction(tx): // 署名、残高、二重支払いなどを検証
add_to_mempool(tx)
gossip_transaction(tx) // 他ノードへ中継
else:
discard_transaction(tx) // 無効なトランザクションは破棄
// ブロック生成者がトランザクションを選択する際のイメージ
function select_transactions_for_block(mempool, max_block_size):
candidate_txs = list(mempool.values())
sort(candidate_txs, by: descending fee_per_byte) // 手数料率でソート
selected_txs = []
current_size = 0
for tx in candidate_txs:
if current_size + size(tx) <= max_block_size:
selected_txs.append(tx)
current_size += size(tx)
else:
break // ブロックサイズ上限に達したら終了
return selected_txs
ブロック生成とMempoolからの選択
ブロックチェーンにおける新しいブロックは、合意形成アルゴリズム(Proof of WorkやProof of Stakeなど)によって選ばれた特定のノード(マイナーやバリデーター)によって生成されます。このブロック生成プロセスにおいて、生成者は自身のMempoolの中から、新しいブロックに含めるトランザクションを選択します。
トランザクションの選択基準は、ブロックチェーンのプロトコルや、生成者のインセンティブ(主にトランザクション手数料)によって異なりますが、最も一般的なのは「最大の手数料収入を得られるようにトランザクションを選択する」という基準です。そのため、手数料率(トランザクションサイズあたりの手数料)の高いトランザクションほど、優先的にブロックに取り込まれる傾向があります。
生成者は、Mempool内のトランザクションを手数料率などでソートし、自身の生成するブロックの最大サイズ制限に収まるように、リストの上位から順にトランザクションを選んでいきます。選択されたトランザクションのリストが、新しいブロックのトランザクションデータとして含まれます。
新しいブロックが生成され、ネットワーク上で検証・承認され、チェーンに追加されると、そのブロックに含まれていたトランザクションはもはや「未確認」ではなくなります。各ノードは、新しいブロックを受信・検証し、そのブロックに含まれるトランザクションを自身のMempoolから削除します。これにより、Mempoolは常に最新の未確認トランザクションのセットを反映するように更新されます。
Mempoolの変動性と影響
Mempoolの内容は、ネットワークのアクティビティ(トランザクションの送信頻度)、ブロック生成の速度、各ノードの設定などによって常に変動しています。
- ネットワークの混雑: トランザクションの送信数が、ブロックが処理できる上限を超える場合、Mempoolに滞留するトランザクションが増加します。これにより、トランザクションがブロックに取り込まれるまでの時間が長くなり、より高い手数料を支払わなければ優先的に処理されにくくなります。
- 手数料の変動: ネットワークの混雑状況は、トランザクション手数料の相場に直接影響します。Mempoolが混雑していれば手数料が高騰し、空いていれば手数料は低下します。
- ノード間の非同期性: P2Pネットワークの性質上、新しいトランザクションやブロックの情報はネットワーク全体に瞬時に伝播するわけではありません。この時間差により、異なるノードのMempoolの内容や、ブロック生成者が参照するMempoolの状態に一時的な違いが生じます。これは、いわゆる「Mempool Watcher」と呼ばれる、Mempool内のトランザクションを監視して取引機会を見つけるような技術(例: MEV - Miner Extractable Value)の可能性を生み出す要因の一つでもあります。
エンジニアとしてブロックチェーンアプリケーションを開発する際には、Mempoolの状態を理解することが重要です。例えば、トランザクションの送信時には、現在のネットワークの混雑状況を考慮して適切な手数料を設定する必要があります。また、スマートコントラクトのイベント監視などを行う場合、トランザクションがMempoolに入った時点(未確認)と、ブロックに取り込まれて確定した時点(確認済み)で状態が変わることを考慮する必要があります。
まとめと次のステップ
本記事では、ブロックチェーンにおける未確認トランザクションの一時保管場所であるMempoolの技術的な仕組みについて解説しました。Mempoolは、各ノードが独自に管理する検証済みのトランザクションプールであり、P2Pネットワークを通じて共有され、ブロック生成者が新しいブロックに含めるトランザクションを選択する際のソースとなります。その状態はネットワークの混雑状況や手数料に影響を与え、ブロックチェーンシステム全体のパフォーマンスやユーザー体験に深く関わっています。
Mempoolの理解は、トランザクションがどのように処理され、ブロックチェーンの状態がどのように変化していくのかを把握する上で不可欠です。
次の学習ステップとしては、以下のトピックを掘り下げてみることをお勧めします。
- トランザクションの具体的な構造: UTXOモデルとアカウントモデルにおけるトランザクションの内部形式の詳細。
- 合意形成アルゴリズム: Proof of WorkやProof of Stakeにおいて、ブロック生成者がどのように選ばれ、Mempoolからトランザクションを選択してブロックを構築するかの詳細なプロセス。
- P2Pネットワークの技術: トランザクションやブロックがノード間でどのように効率的に伝播・共有されるのか(Gossipプロトコルなど)。
- トランザクション手数料(Gas/Fee)の計算: 手数料がどのように決まり、Mempoolにおける優先順位付けにどう影響するか。
これらの技術要素を学ぶことで、ブロックチェーンシステム全体の理解がさらに深まるでしょう。