本記事は生成AIと共同で執筆しています。事実関係は可能な範囲で公式ドキュメント等と照合していますが、誤りが含まれている可能性があります。重要な判断を行う前にご自身でも一次情報をご確認ください。

Monad は、Ethereum 向けに書かれたプログラムがそのまま動くブロックチェーンです。EVM(Ethereum Virtual Machine、Ethereum のプログラム実行環境)との互換性があるためで、この点が設計全体の前提になっています。公開されている資料では、毎秒 1 万件の処理、300ms のブロック間隔、600ms のファイナリティ(取引が確定して覆らなくなるまでの時間)を掲げています。本番として稼働するネットワーク(メインネット)は 2025 年 11 月 24 日に公開されたとされています。

「Ethereum と同じものが動く」と「速い」は、普通は両立しにくい組み合わせです。互換性を保つということは、既存の仕組みをそのまま引き継ぐということなので、速度の面で制約になる部分も一緒に引き継ぐことになります。Monad はこの制約の中で、外から見える振る舞いを変えずに、内部の段取りを組み替えるという方針を取っています。

以下では、その組み替えのうち主なものを 3 つ取り上げます。前提知識は仮定しません。

合意と実行という 2 つの仕事

ブロックチェーンは、世界中に散らばったコンピュータ(ノード)が、同じ帳簿を持ち続けるための仕組みです。誰か一人が管理しているわけではないので、「次にどの取引を、どの順番で帳簿に書くか」を、参加者全員で毎回決めなければなりません。この合意形成をコンセンサスと呼びます。

帳簿への書き込みは 1 件ずつではなく、一定数の取引をひとまとめにした単位で行われます。このまとまりをブロックと呼び、ブロックが順につながっていく形をとることからブロックチェーンという名前がついています。

ここで、各ノードがやることは大きく 2 つあります。順番を決めること(合意)と、決まった順番どおりに取引を処理して残高を書き換えること(実行)です。

多くのチェーンでは、この 2 つを 1 回の手順の中で交互に行います。順番を決め、実行し、その結果を全員で突き合わせて一致を確認し、また次の順番を決める、という進み方です。結果の突き合わせまで含めて合意するため、実行が終わらないと次に進めません。

公開されている Monad の資料では、Ethereum におけるこの配分が具体的な数字で説明されています。ブロックの間隔は 12 秒ありますが、そのうち実行に割り当てられる時間はおよそ 100ms とされています。残りは合意やデータの伝播に使われます。実行に使える時間が短ければ、1 ブロックに詰め込める処理の量もそれに応じて制限されます。

設計 1 — 合意と実行を別のレーンに分ける

Monad は、この 2 つを同じ手順の中に置くのをやめています。合意の段階では順序だけを決め、実行はその後ろで別に進めます。公式ドキュメントでは「ノードは、取引を実行することなく、公式な順序についての合意に達する」と説明されています。この方式は非同期実行と呼ばれています。

合意と実行の関係を上下 2 段で比較した図です。上段「交互に行う場合(Ethereum の例)」では、1 ブロック 12 秒という細長い枠の中に、左端に「実行 約 100ms」という小さな枠があり、残りの大部分を「合意・伝播・その他」が占めています。右下に「実行に回せるのはブロック時間のごく一部」と注記されています。下段「レーンを分ける場合(Monad の非同期実行)」では、「合意レーン:順序だけを決める」と「実行レーン:決まった順序を実行する」という 2 本の帯が上下に並び、その右側にそれぞれ「ブロック間隔 300ms で次々に確定」「実行はブロック時間をまるごと使える」と対応づけられています。図の下部に、実行は合意より D ブロック(現時点で 3)遅れて進み、ブロックには D ブロック前の状態ルートが載る、と記されています。

順序さえ決まっていれば、各ノードが正しく動作している限り、実行の結果は誰がやっても同じになります。であれば、全員がその場で結果を突き合わせる必要はない、という考え方です。合意のレーンは順序を決めることに専念できるので速く回り、実行のレーンは合意の完了を待たずに進められるようになります。

ここで注意したいのは、実行に使える時間の絶対量が大きく増えるわけではない点です。公式ドキュメントの表現は「実行にブロック時間をまるごと割り当てられる」ですが、Monad のブロック間隔は 300ms なので、Ethereum の 12 秒がそのまま実行に回るという話ではありません。変わるのは、ブロックあたりの時間のうち実行に充てられる割合と、実行が合意の進行を止めなくなることです。

結果をまったく突き合わせないわけでもありません。実行は合意より一定のブロック数(資料では D と表記され、現時点では 3)だけ遅れて進み、新しいブロックには D ブロック前の時点の状態を表す値(状態ルート)が載せられます。少し前の時点についてなら結果は出そろっているので、そこで答え合わせができるという構成です。あるノードの実行結果が他とずれていれば、この時点で検出されます。

この設計の副作用として、取引を送ってから「確定した」と分かるタイミングと、「実行結果が全員で照合済み」になるタイミングがずれます。順序の確定は速い一方、状態ルートによる照合はブロック数個ぶん後ろになります。

設計 2 — 先に走らせてから、ぶつかった分だけやり直す

順序が決まっていても、その順番どおりに 1 件ずつ処理していたのでは、待ち時間が積み上がります。ただし、単純に同時並行で処理すると結果が変わってしまう場合があります。前の取引が書き換えた残高を後の取引が読む、という依存関係があるためです。

Monad はここで楽観的実行という方法を取っています。依存関係があるかどうかを先に調べるのではなく、とりあえず全部同時に走らせてしまい、後から突き合わせる、という順序です。

並列実行の方式を上下 2 段で示した図です。上段「順番に実行する」では、取引 1 → 取引 2 → 取引 3 が矢印で一列につながれ、右に「前が終わるまで次は始まらない」と注記されています。下段「先に走らせる(楽観的実行)」では、取引 1・2・3 の 3 つの箱が縦に並んで同時に走り、その右の「読んだ値と書かれた値を突き合わせる」という箱に集まります。そこから 2 本に分かれ、上は「取引 1・2 はそのまま採用」、下は「取引 3 は古い値を読んでいたのでやり直し」となります。両者はさらに右の「結果は順番に実行した場合と同じになる」という箱に合流します。図の下部に、やり直しでも署名から送信者を復元する処理や読み込み済みの値は使い回されるため、まるごと最初からやり直すわけではない、と記されています。

突き合わせの方法は、ある取引が実行中に読んだ値と、それより前の取引が書いた値を比較する、というものです。食い違いがあれば、その取引は古い値を読んでいたことになるので、正しい状態でやり直します。

これで最終的な結果が順番どおりに実行した場合と一致するのは、突き合わせと確定を先頭の取引から順に進めるからです。ある取引を確定させる時点では、それより前の取引はすべて確定しています。そこで読んだ値が一致していれば、順番に実行したときに読むはずの値と同じものを読んだことになるので、出てくる結果も同じになります。一致しなければやり直し、やり直した結果がさらに後ろの取引の読んだ値を変えていれば、その取引もやり直します。これを繰り返した先が、順番に実行した場合と同じ状態になります。

やり直しは無駄に見えますが、公式ドキュメントでは、そこまでに済ませた作業のうち再利用できるものは使い回すと説明されています。署名から送信者のアドレスを復元する処理(署名リカバリ)は計算量が大きいものの取引の内容だけで決まるため、やり直しの際に繰り返す必要がありません。読み込んだ状態もメモリ上に残っています。

重要なのは、この工夫が外から見える結果を変えない点です。ドキュメントには「ブロック内の取引を実行した結果は、Monad と Ethereum で同一である」とあり、ブロックの構造自体も「線形に順序づけられた取引の集合」という Ethereum と同じ形が保たれています。並列に動いているのは内部の処理であって、取引の順番や結果ではありません。

なお、この方式が効くかどうかは、どんな取引が多いかに依存すると考えられます。多くの取引が同じ場所を読み書きする状況では、やり直しの割合が増えて並列化の効果が薄れることになります。この点について実測はしていないので、どの程度かは分かりません。

設計 3 — 直前のブロックが捨てられないようにする

3 つ目は、コンセンサスそのものの改良です。Monad が使っているのは MonadBFT というプロトコルで、論文(arXiv:2502.20692)として公開されています。BFT はビザンチン耐障害(Byzantine Fault Tolerant)の略で、参加者の一部が故障したり嘘をついたりしても全体としては正しく動く、という性質を指します。

MonadBFT が扱っている問題は、テールフォーキング(tail-forking)と呼ばれます。これは処理速度を上げるための工夫から生まれた副作用です。

ブロックを作る担当者は順番に交代していきます。速度を上げるため、工程をずらして重ねる設計が広く使われています。具体的には、あるブロックへの賛成票を集めて「多数の賛成を得た」という証明にまとめる作業を、そのブロックを作った本人ではなく、次の担当者の仕事にします。工程が重なるぶん、全体としては速く進みます。

その代わり、自分のブロックが認められるかどうかが、次の担当者に委ねられることになります。次の担当者がその作業をしなければ、賛成多数を得ていたブロックでも成立せずに終わります。

ブロックが捨てられる問題と、その解決を上下 2 段で示した図です。上段「次の担当者に裁量がある場合」では、「A のブロック(賛成多数)」から「B のブロック(賛成多数)」へ矢印が伸び、その先が × 印で断ち切られ、「C が B の票を集めず別の枝を作る」という箱につながっています。下に「B のブロックは消える。書いた側の報酬も、含まれていた取引も失われる」と注記されています。下段「再提案が義務づけられている場合(MonadBFT)」では、「全員が『最後に投票した提案』を申告」→「申告のうち最も新しいものが特定される」→「次の担当者はそれを出し直す」という 3 段が矢印でつながれています。その下に、賛成多数のブロックには必ず賛成した人が申告側にも含まれるため申告から漏れないこと、次の担当者に「捨てる」という選択肢が残らないこと、ただし提案者自身が同じ順番に矛盾する提案を複数出した場合は保証の対象外であることが記されています。

問題は、これが意図的にもできることです。直前のブロックを成立させずに捨てれば、そこに入っていた取引は宙に浮きます。捨てた側は、それらの取引を自分のブロックに好きな順番で入れ直せます。取引の並び順を操作して利益を得る行為は MEV(Maximal Extractable Value、最大抽出可能価値)と呼ばれ、この形の操作はその一種にあたります。ブロックを作った側から見れば、正しく仕事をしたのに報酬を失うことになります。

MonadBFT の対処は、次の担当者から選択の余地をなくすというものです。あるビュー(担当者 1 人分の番)が時間切れで失敗したとき、各参加者は自分が最後に賛成した提案を申告します。次の担当者は、申告のうち最も新しいものを出し直します。何を提案するかを選べないため、特定のブロックを狙って捨てることができません。

取りこぼしの危険があるのは、まだ次の担当者に引き継がれていない末尾のブロックだけなので、最も新しい申告を出し直せば足ります。テールフォーキングの「テール」は、この末尾を指しています。

これが機能する理由は、参加者の数の関係にあります。全体を 3f+1 人とします。f は故障や不正がありうる人数の上限で、この人数構成は、不正が f 人まで混じっても合意できる最小の形として使われるものです。賛成多数を得たブロックには 2f+1 人が賛成しており、担当交代の申告にも 2f+1 人が参加します。足すと 4f+2 人ぶんになり、全体の 3f+1 人を f+1 人ぶん超えます。超過分は同じ人を二重に数えているところなので、両方に加わった人が少なくとも f+1 人いることになります。不正な参加者は多くても f 人ですから、この f+1 人のうち少なくとも 1 人は正直な参加者です。その人は自分が賛成した提案をそのまま申告するため、賛成多数を得たブロックが申告から漏れることはありません。

なお、出し直しが常に必要になるわけではありません。論文では、賛成多数の証明をその場で構成できる場合や、対象のブロックがそもそも賛成多数を得られなかったことを別の証明書で示せる場合には、出し直しを省いて新しいブロックを提案してよいとされています。省略できるのは、いずれも「取りこぼしが起きていない」ことが確認できる場合に限られます。

保証にはもう一つ条件があります。論文では、提案者自身が同じ順番に対して矛盾する提案を複数出した場合は対象外である、と明示されています。この行為は署名の残る証拠になるため、預けた資産を没収する仕組みの対象にできる、というのが前提の置き方です。

確定は 2 段階に分かれている

確定のタイミングについては、公式ドキュメントと論文で数え方が異なります。

公式ドキュメントの MonadBFT のページでは、暫定的な確定が 1 スロット(300ms)、撤回できない確定が 2 スロット(600ms)とされています。冒頭に挙げた 600ms は後者にあたります。

論文のほうは、担当者が提案を出した時点を起点として数えています。賛成多数の証明が 1 つ揃った時点が暫定的な確定で 1.5 往復、続けてもう 1 つ揃うと撤回できない確定になり 2.5 往復です。ここでの 1 往復は、提案が参加者に届き、その返答が戻るまでの一巡を指します。起点の取り方が違うため、この 1.5 / 2.5 往復と、上の 300ms / 600ms は直接は対応しません。

段階が 2 つに分かれていること自体は、どちらの数え方でも共通しています。暫定的な確定が覆るのは、設計 3 で触れた矛盾する提案が行われた場合に限られるとされています。

アプリケーション側は、どちらの時点で動き出すかを選べるという整理になっています。論文では、売買や価格更新のように速さが重要なものは暫定的な確定で動き、他のチェーンとの資産の橋渡しや暗号資産取引所の入出金のように決済として確実性が要るものは撤回できない確定を待つ、という使い分けが例として挙げられています。

互換性の側

ここまでは速度側の話ですが、Monad の主張のもう半分は互換性です。公式ドキュメントでは、EVM のバイトコード(プログラムがコンピュータ向けに変換された形式)互換と、Ethereum の RPC(Remote Procedure Call、外部のプログラムから機能を呼び出すための仕組み)API 互換の両方が挙げられています。前者は既存のプログラムがそのまま動くこと、後者は既存の開発ツールやウォレットがそのまま繋がることを意味します。

これは移行のコストに直結します。動かすプログラムも、周辺のツールも書き直さずに済むのであれば、試すための障壁が低くなります。ここまで見てきた 3 つの設計が、いずれも「外から見える結果は変えずに内部の段取りだけを変える」形になっているのは、この互換性を保つためだと読めます。

このほか、ブロックの配布には RaptorCast、状態の保存には MonadDb という独自の仕組みが使われています。公開されている情報では、実装は C++ と Rust で書かれ、GPL-3.0 のもとで公開されているとされています。

確認していないこと

この記事は公開資料を読んで整理したもので、ノードを動かして数字を確かめたわけではありません。毎秒 1 万件、300ms、600ms はいずれも公式資料に掲げられた値であり、どのような条件で測られたものかまでは確認していません。300ms についても、資料によっては最小のブロック時間として説明されています。

また、非同期実行や楽観的実行のような設計は、条件が揃ったときの性能と、条件が崩れたときの振る舞いが別々に効いてきます。前者は数字で示されていますが、後者については、実際の負荷のもとでどうなるかを外から判断する材料がありませんでした。

参考