はじめに
Monadは高性能なEthereum互換のL1です。Monadは分散化とスケーラビリティのトレードオフにおいて、効率のフロンティアを大きく進歩させます。
Monadは4つの主要な領域での最適化を導入し、1秒あたり10,000トランザクション(tps)のスループットを持つブロックチェーンを実現します。
Monadの改善は、既存のボトルネックに対処しつつ、アプリケーション開発者(完全なEVMバイトコード互換性)とユーザー(Ethereum RPC API互換性)のためにシームレスな互換性を保持します。その結果、Ethereumの豊富なツールセットや応用暗号研究が、改善されたスループットとスケールを享受しつつ、Monadにシームレスに統合できます。
- アプリケーション(Ethereum用に構築された任意のdapp)
- 開発者ツール(例:Hardhat、Apeworx、Foundry)
- ウォレット(例:MetaMask)
- 分析/インデキシング(例:Etherscan、Dune)
Monadクライアントは、パフォーマンスに焦点を当てて構築され、C++およびRustで一から書かれています。後続のページでは、Monadの主要な変更点とユーザー向けのインターフェースについて概観します。
ユーザー向けMonad
Monadは、高性能なEthereum互換のL1であり、ユーザーにポータビリティとパフォーマンスの両方の最良のものを提供します。
ポータビリティの観点から、MonadはEthereumバーチャルマシン(EVM)の完全なバイトコード互換性を提供するため、Ethereum用に構築されたアプリケーションをコード変更なしでMonadに移植でき、MetaMaskやEtherscanのようなインフラをシームレスに使用できる完全なEthereum RPC互換性を提供します。
パフォーマンスの観点から、Monadは1秒間のブロックタイムと1秒間のファイナリティを提供しながら、1日に10億トランザクション、すなわち1秒あたり10,000トランザクションのスループットを提供します。これにより、Monadは既存のブロックチェーンよりもはるかに多くのユーザーをサポートし、はるかにインタラクティブな体験を提供できるとともに、トランザクションあたりのコストを大幅に削減できます。
Monadの馴染みやすい点は何ですか?
ユーザーの観点から見ると、MonadはEthereumと非常に似ている動作をします。同じウォレット(例:MetaMask)やブロックエクスプローラー(例:Etherscan)を使用してトランザクションに署名したり、トランザクションを表示したりできます。Ethereum用に構築された同じアプリケーションをコード変更なしでMonadに移植できるため、Ethereumからの多くのお気に入りのアプリをMonadで使用できると予想されます。Monadのアドレス空間はEthereumと同じなので、既存のキーを再利用できます。
Ethereumと同様に、Monadはリニアブロックとブロック内のトランザクションのリニアな順序付けを特徴とします。
Ethereumと同様に、Monadは分散型のバリデータセットによって維持されるプルーフ・オブ・ステークネットワークです。誰でもノードを実行してトランザクション実行を独立して検証でき、ハードウェア要件を最小限に抑えるために細心の注意が払われています。
Monadの異なる点は何ですか?
Monadは、Ethereumバーチャルマシンに並列実行とスーパースカラーパイプラインを導入することにより、卓越した性能を実現します。
並列実行とは、複数のコアとスレッドを利用して作業を戦略的に並行して実行しつつ、結果を元の順序でコミットする実践のことです。トランザクションは「内部的に」並行して実行されますが、ユーザーや開発者の視点からは連続して実行されているように見えます。一連のトランザクションの結果は、トランザクションが一つずつ実行された場合と常に同じです。
スーパースカラーパイプラインとは、作業の段階を作成し、その段階を並行して実行する実践のことです。シンプルな図がその物語を語ります。
4回の洗濯をする際、素朴な戦略は、最初の洗濯物を洗い、乾燥させ、畳み、収納するまで完了させてから、2回目に取り掛かることです。パイプライン戦略は、1回目の洗濯物が乾燥機に入ったときに2回目の洗濯を開始することです。パイプライニングは、複数のリソースを同時に利用することで、より効率的に作業を完了させます。
Monadは、状態の保存、トランザクション処理、分散合意における既存のボトルネックに対処するためにパイプライニングを導入します。特に、Monadは以下の4つの主要な領域でパイプライニングと他の最適化を導入しています:
- MonadBFT(追加の研究改善を備えたパイプライン化されたHotStuff合意)
- 遅延実行(合意と実行の間のパイプライニングを通じて実行予算を大幅に増加させる)
- 並列実行
- MonadDb(高性能状態バックエンド)
C++とRustで一から書かれたMonadのクライアントは、これらのアーキテクチャ上の改善を反映しており、真に世界的な採用にスケールできる分散型アプリのプラットフォームを結果としています。
なぜこれが重要なのか?
分散型アプリは、いくつかの重要な利点を持つ集中型サービスの代替品です:
- オープンAPI/コンポーザビリティ:分散型アプリは他の分散型アプリによってアトミックに呼び出すことができ、開発者は既存のコンポーネントを積み重ねることでより複雑な機能を構築できます。
- 透明性:アプリのロジックは純粋にコードを通じて表現されるため、誰でも副作用のためのロジックをレビューできます。状態は透明で監査可能であり、DeFiの予備証明はデフォルトです。
- 検閲耐性と信頼性の中立性:誰でも許可のないネットワークにトランザクションを送信したり、アプリケーションをアップロードしたりすることができます。
- グローバルリーチ:インターネットにアクセスできる人なら誰でも、銀行口座のない人/銀行サービスが不十分な人を含め、重要な金融サービスにアクセスできます。
しかし、分散型アプリは意図した影響レベルに到達するためには、安価で高性能なインフラが必要です。毎日活動しているユーザー(DAU)が100万人で、ユーザー1人あたり1日10トランザクションの単一アプリは、1日あたり1000万トランザクション、または100tpsが必要になります。既存のEVM互換のL1およびL2のスループットと分散化をまとめた便利なウェブサイトL2Beatを一見すると、現在のEVMブロックチェーンがそのレベルのスループットをサポートしていることはありません。
Monadは、EVM互換ブロックチェーンネットワークのパフォーマンスを大幅に向上させ、今後数年間でEthereumの標準となることを期待されるいくつかの革新を開拓しています。
Monadを使うことで、開発者、ユーザー、研究者はEVMのために構築された既存のアプリケーション、ライブラリ、および応用暗号研究の豊富な資源を再利用することができます。
Monadをどのように使用しますか?
Monadの最初の公開テストネットは、数ヶ月以内にライブになります。
それが行われたら、Ethereum互換ウォレットに適切なRPC URLとChainIdを追加し、他のEthereum互換ネットワークと同様にMonadを使用し始めることができます。それまでは、お待ちください!
開発者向けMonad
Monadは、秒間10,000トランザクション、1秒のブロック時間、およびシングルスロットの最終確定を持つ、Ethereum互換のレイヤー1ブロックチェーンです。
MonadのEthereumバーチャルマシンの実装は、上海フォークに準拠しており、Monad実行環境での歴史的なEthereumトランザクションのシミュレーションは同一の結果を生み出します。また、Monadは完全なEthereum RPC互換性を提供するため、ユーザーはMetaMaskやEtherscanのような馴染みのあるツールを使用してMonadと対話できます。
Monadは、いくつかの主要な革新の導入を通じてこれらのパフォーマンスの改善を達成しています:
- MonadBFT(追加の研究改善を備えたパイプライン化されたHotStuff合意)
- 遅延実行(合意と実行の間のパイプライニングを大幅に増やすことで実行予算を大幅に増加させる)
- 並列実行
- MonadDb(高性能状態バックエンド)
Monadには並列実行とパイプライニングが特徴ですが、Monad内のブロックはリニアであり、各ブロック内のトランザクションはリニアに順序付けられていることに注意することが重要です。
トランザクション形式
属性 | 説明 |
---|---|
アドレス空間 | Ethereumと一致 ECDSAを使用した20バイトのアドレス |
トランザクション形式 | Ethereumと一致 EIP-2718に準拠し、RLPでエンコードされます。アクセスリスト(EIP-2930)はサポートされていますが、必須ではありません。 |
ウォレットの互換性 | MonadはMetamaskのような標準的なEthereumウォレットと互換性があります。必要な変更は、RPC URLとChainIdを変更することだけです。 |
スマートコントラクト
MonadはEVMバイトコードをサポートし、Ethereumとバイトコードが等価です。すべてのオペコード(上海フォーク時点)がサポートされています。
コンセンサス
属性 | 説明 |
---|---|
シビル耐性メカニズム | プルーフ・オブ・ステーク(PoS) |
委任 | 許可されている(プロトコル内) |
コンセンサスメカニズムとパイプライニング | MonadBFTは、部分的に同期された条件下でトランザクションの順序と含まれる内容について合意に達するためのリーダーベースのアルゴリズムです。一般的には、HotStuffの派生であり、追加の研究改善が施されています。
MonadBFTは、一般的なケースで線形通信オーバーヘッドを持つパイプライン化された2フェーズのBFTアルゴリズムです。ほとんどのBFTアルゴリズムと同様に、通信はフェーズごとに進行します。各フェーズで、リーダーは署名されたメッセージを投票者に送信し、投票者は署名された返答を送り返します。パイプライニングにより、ブロック |
ブロック時間 | 1秒 |
ファイナリティ | シングルスロット。2/3のステーク重みがブロック提案にYESと投票したら、それは最終確定されます。 |
Mempool | Mempoolが存在します。トランザクションはイレイジャ符号化され、効率のためにブロードキャストツリーを使用して伝達されます。 |
スパム耐性 | ユーザーはブロックへの組み込み(運搬コスト)とトランザクションの実行(実行コスト)のために料金を支払います。 |
コンセンサス参加者 | 直接のコンセンサス参加者はブロック提案に投票し、リーダーとして機能します。直接参加するためには、ノードは少なくとも |
トランザクションのハッシュ化 | 効率のために、ブロック提案はトランザクションをハッシュのみで参照します。ノードがトランザクションを持っていない場合、隣のノードからハッシュでトランザクションをリクエストします。 |
遅延実行と運搬コスト | Monadでは、コンセンサスと実行がパイプライン方式で行われます。ノードはその順序の実行に先立って、公式のトランザクション順序についてコンセンサスに達します(遅延実行);実行の結果はコンセンサスの前提条件ではありません。
実行がコンセンサスの前提条件であるブロックチェーンでは、実行のための時間予算はブロック時間の小さな割合です。コンセンサスと実行をパイプライン化することで、Monadはコンセンサスと実行の両方に全ブロック時間を費やすことができます。
ブロック提案は、トランザクションハッシュの順序付けられたリストと、 |
状態の決定論 | 最終確定はコンセンサス時に発生します。この時点でトランザクションの公式な順序が確立され、結果は任意のフルノードにとって完全に決定論的であり、通常、その新しいブロックのトランザクションを1秒未満で実行します。
状態メルクルルートの |
実行
各ブロックの実行フェーズは、そのブロックについてのコンセンサスが得られた後に始まり、ノードは後続のブロックについてのコンセンサスを進めることができます。
並列実行
トランザクションはリニアに順序付けられており、実行の仕事は、そのトランザクションのリストを連続して実行することで得られる状態に到達することです。素朴なアプローチは、トランザクションを次々に実行することです。もっと良い方法はありますか?はい、あります!
Monadは並列実行を実装しています:
- 実行者は、トランザクションを実行するための仮想マシンです。Monadは多くの実行者を並行して実行します。
- 実行者はトランザクションを取り、結果を生成します。結果とは、トランザクションの入力と出力のリストであり、入力は実行の過程でSLOADされた(ContractAddress、Slot、Value)のタプル、出力はトランザクションの結果としてSSTOREされた(ContractAddress、Slot、Value)のタプルです。
- 結果は当初、保留状態で生成されます。その後、トランザクションの元の順序でコミットされます。結果がコミットされると、その出力が現在の状態を更新します。結果がコミットされる番になったとき、Monadはその入力が現在の状態とまだ一致するかを確認します。一致しない場合、Monadはトランザクションを再スケジュールします。この並行制御の結果、Monadの実行は、トランザクションが連続して実行された場合と同じ結果を生成することが保証されます。
- トランザクションが再スケジュールされると、必要な入力の多くまたはすべてがキャッシュされるため、再実行は一般的に比較的安価です。再実行に際して、トランザクションが前回の実行で行ったのと異なる一連の入力を生成する可能性があることに注意してください。
MonadDb:高性能状態バックエンド
全てのアクティブな状態はMonadDbに保存されます。これは、メルクルトライデータの保存に最適化された、ソリッドステートドライブ(SSD)用のストレージバックエンドです。アップデートはバッチ処理され、メルクルルートを効率的に更新できるようになっています。
MonadDbはインメモリキャッシングを実装し、効率的な非同期読み書きのためにasioを使用します。ノードには最適なパフォーマンスのために32 GBのRAMが必要です。
Ethereumとの比較:ユーザーの視点
属性 | Ethereum | Monad |
---|---|---|
トランザクション/秒
(スマートコントラクトの呼び出しと転送) | ~10 | ~10,000 |
ブロックタイム | 12秒 | 1秒 |
ファイナリティ | 2エポック(12-18分) | シングルスロット(1秒) |
バイトコード標準 | EVM(上海フォーク) | EVM(上海フォーク) |
RPC API | ||
Cryptography | ECDSA | ECDSA |
アカウント | ECDSAの下での公開鍵のkeccak-256の最後の20バイト | ECDSAの下での公開鍵のkeccak-256の最後の20バイト |
コンセンサスメカニズム | Gasper(Casper-FFG最終確定ガジェット + LMD-GHOSTフォーク選択ルール) | MonadBFT(追加の研究改善を備えたパイプライン化されたHotStuff) |
Mempool | Yes | Yes |
トランザクションの順序付け | リーダーの裁量(実際にはPBS) | リーダーの裁量(デフォルト動作:優先ガスオークション) |
シビル耐性メカニズム | PoS | PoS |
委任の許可 | No ; LSTを通じた疑似委任 | Yes |
ハードウェア要件(フルノード) | 4コアCPU 16GB RAM 1 TB SSD 25Mbit/s 帯域幅 | 16コアCPU 32GB RAM 2TB SSD 100Mbit/s 帯域幅 |
技術的な議論
コンセプト
パイプライニング
パイプライニングは、タスクを一連の小さなタスクに分割し、それらを並列に処理することで並列性を実装する技術です。
パイプライニングは、コンピュータプロセッサ内で、同じクロックレートで一連の命令を順次実行するスループットを増加させるために使用されます。(プロセッサでスループットを増加させるために使用される他の技術もあります。)命令レベルの並列性(ILP)についての詳細はこちらで読むことができます。
パイプライニングの簡単な例:
4回の洗濯をする際、素朴な戦略は、最初の洗濯物を洗い、乾燥させ、畳み、収納してから2回目に取り掛かることです。パイプライン戦略では、1回目の洗濯物が乾燥機に入ったときに2回目の洗濯を開始します。パイプライニングは、複数のリソースを同時に利用することで、作業をより効率的に行います。
Asynchronous I/O (非同期I/O)
非同期I/Oは、通信が進行中でもCPUが同時に実行を続けられるようにする入出力処理の形式です。
ディスクとネットワークはCPUよりも桁違いに遅いです。I/O操作を開始して結果を待つのではなく、データが必要になることが分かったらすぐにCPUがI/O操作を開始し、I/O操作の結果に依存しない他の命令の実行を続けることができます。
説明のために大まかな比較をいくつか示します。
デバイス | レイテンシー | 帯域幅 |
---|---|---|
CPU L3 キャッシュ | 10ns | >400 GB/秒 |
メモリ | 100ns | 100GB/秒 |
ディスク(NVMe SSD) | 400us | 380MB/秒 |
通信網 | 50~200ミリ秒 | 1 Gb/秒(125 MB/秒) |
(fioによる報告による実際のディスク統計で、サイズ2KBのランダム読み取りで約190k IOPS)
幸いなことに、SSDドライブは操作を同時に実行できるため、CPUは同時に複数のリクエストを開始し、実行を続け、その後ほぼ同時に複数の操作の結果を受け取ることができます。
一部のデータベース(例:lmdb / mdbx)は、ディスクへの読み書きにメモリマップドストレージを使用しています。残念ながら、メモリマップドストレージはカーネル(mmap)によって実装されており、非同期ではないため、操作が完了するのを待っている間、実行がブロックされます。
非同期i/oについての詳細はこちらで読むことができます。
なぜブロックチェーンなのか?
「何」そして「なぜ」のためのシンプルな精神モデル。
ブロックチェーンは、多様な参加者の間の分散型合意であり、二つのことに関しています。
- トランザクションの公式な順序(台帳)
- 口座残高やさまざまなプログラムの状態を含む、世界の公式の状態。
Ethereumのような現代のブロックチェーンでは、トランザクションは残高の転送、新しいプログラムの作成、既存のプログラムに対する関数呼び出しで構成されます。これまでの全てのトランザクションの集約結果が現在の状態を生み出し、これが(1)についての合意が(2)についての合意を意味する理由です。
ブロックチェーンシステムには、現在同期している分散ノードセットが、それぞれが適用すべき新しいトランザクションリストについて互いに通信して合意する方法を記述した一連のプロトコルルールがあります。帰納法はノードを同期させます:彼らは同じ状態から始め、同じトランザクションを適用するため、新しいトランザクションリストを適用した終わりには、彼らはまだ一貫した状態を持っています。(このエッセイでは、そのようなノードシステムがどのように合意を達成するかの詳細は無視しますが、さらなる詳細についてはMonadのコンセンサスメカニズムのドキュメントを参照してください。)
共有グローバル状態は、分散型アプリの開発を可能にします。ブロックチェーン上に存在するアプリ、つまりブロックチェーンシステムの各ノード上に。分散型アプリは、コードの塊(および永続的でアプリ固有の状態)であり、任意のユーザーがそのアプリ上の関数を指すトランザクションを提出することによって呼び出すことができます。ブロックチェーン内の各ノードは、呼び出されたバイトコードを正確に実行する責任があり、複製が各ノードを正直に保ちます。
アプリの例
分散型アプリは、中央集権的に実装されることが期待されるかもしれない機能を実装できます。たとえば、非常にシンプルな分散型アプリの例は、バーチャルバンクです(通常、暗号ではレンディングプロトコルと呼ばれます)。
物理的な世界で、銀行は預金を受け入れ、より高い利率でそれらを貸し出すビジネスです。銀行は高利率と低利率の差額を稼ぎます;借り手は何か経済的に生産的なことをするためのローンを得ます;そして、あなたは預金に対して利息を稼ぎます。みんな勝ちです!
バーチャルバンクは、単純に預金、引き出し、借入、返済の4つの主要なメソッドを持つアプリです。これらのメソッドの各ロジックは、主に預金とローンが正しく追跡されていることを保証するための簿記です:
class VirtualBank:
def deposit(sender, amount):
# transfer amount from sender to myself (the bank)
# do internal bookkeeping to credit the sender
def withdraw(sender, amount):
# ensure the sender had enough on deposit
# do internal bookkeeping to debit the sender
# transfer amount from myself (the bank) to sender
def borrow(sender, amount):
# ...
def repay(sender, amount);
# ...
イーサリアムまたはMonadでは、誰かがこの仮想銀行のコードを作成してアップロードできます。そうすれば、誰もがそれを貸し借りに利用できるようになり、自国で銀行サービスにアクセスするよりもはるかに簡単になる可能性があります。
この簡単な例は、分散型アプリの威力を示しています。他にも注目すべき利点がいくつかあります。
- オープンAPI / コンポーザビリティ : 分散型アプリは他の分散型アプリからアトミックに呼び出すことができるため、開発者は既存のコンポーネントを積み重ねることにより、より複雑な機能を構築できます。
- 透明性 : アプリのロジックはコードのみで表現されるため、誰でもロジックの副作用を確認できます。状態は透明で監査可能です。 DeFiでは準備金の証明がデフォルトです。
- 検閲耐性と信頼できる中立性 : 誰でもトランザクションを送信したり、許可のないネットワークにアプリケーションをアップロードしたりできます。
- グローバルなリーチ : インターネットにアクセスできる誰もが、銀行口座を持たないユーザーや銀行口座を持たないユーザーも含め、重要な金融サービスにアクセスできます。
Monadを選ぶ理由 : 分散化+パフォーマンス
分散化が重要
ブロックチェーンにはいくつかの主要なコンポーネントがあります。
- 台帳に追加する取引に関する合意を達成するためのコンセンサスメカニズム
- アクティブ状態を維持するための実行/保存システム
これらのコンポーネントのパフォーマンスを向上させるには、例えば、全てのノードが物理的に互いに近い位置にあることを要求する(コンセンサスのオーバーヘッドを節約するため)や、膨大な量のRAMを要求する(多くの、または全ての状態をメモリ内に保持するため)など、手を抜く方法もありますが、それは分散化に対して重大なコストとなります。
そして重要なのは分散化です!
なぜブロックチェーンなのか?で説明したように、分散型共有グローバル状態により、単一の共有された客観的な真実の情報源に依存しながら、多くの関係者が調整できるようになります。分散化がこの問題の鍵となります。少数のノードオペレーターのグループ (極端な場合には単一のオペレーター!) によって維持されるブロックチェーンでは、信頼性のなさ、信頼できる中立性、検閲への耐性などの利点は得られません。
あらゆるブロックチェーンネットワークにとって、分散化が主な関心事である必要があります。パフォーマンスの向上は、分散化を犠牲にして実現されるべきではありません。
今日のパフォーマンスのボトルネック
イーサリアムの現在の実行制限(1秒あたり1.25Mガス)は控えめに設定されていますが、それにはいくつかの正当な理由があります。
- 非効率的なストレージアクセスパターン
- シングルスレッド実行
- 実行なしではコンセンサスを進めることができないため、実行予算が非常に限られている
- 州の成長と、州の成長が将来の州へのアクセスコストに及ぼす影響に関する懸念
Monadは、アルゴリズムの改善とアーキテクチャの変更を通じてこれらの制限に対処し、今後数年でイーサリアムの標準になることが期待されるいくつかの革新を先駆的に行っています。実質的なパフォーマンスを向上させながら、高度な分散性を維持することが重要な考慮事項です。
最適化を通じてこれらのボトルネックに対処する
Monadは、4つの主要な領域でパイプライン処理やその他の最適化を可能にし、優れたイーサリアム仮想マシンのパフォーマンスを可能にし、分散化とスケーラビリティのトレードオフを大幅に前進させます。後続のページでは、次の主要な改善分野について説明します。
コンセンサス
MonadBFT
パイプライン化された2フェーズHotStuffコンセンサス
MonadBFTは、ビザンチンアクターの存在下で部分同期条件下でトランザクションの順序付けに関する合意を達成するための高性能コンセンサス メカニズムです。これは、Jolteon / DiemBFT / Fast-HotStuffで提案された改良点を備えたHotStuffの派生製品であり、リーダータイムアウトの場合に二次通信の複雑さを利用することで3ラウンドから2ラウンドに削減されます。
MonadBFTは、楽観的な応答性を備えたパイプライン化された2フェーズBFTアルゴリズムであり、一般的な場合には線形通信オーバーヘッドがあり、タイムアウトの場合には二次通信が行われます。ほとんどのBFTアルゴリズムと同様、通信は段階的に進行します。各フェーズで、リーダーは署名付きメッセージを有権者に送信し、有権者は次のリーダーに署名付きの回答を送信します。パイプライン処理により、ブロックのクォーラム証明書(QC)またはタイムアウト証明書(TC)がk
ブロックの提案に便乗できるようになります。k+1.
簡単な事実
属性 | 説明 |
---|---|
シビル耐性のメカニズム | プルーフ・オブ・ステーク (PoS) |
ブロックタイム | 1秒 |
ファイナリティ | シングルスロット |
委任が許可される | はい |
Mempool
Shared Mampoolを参照してください。
コンセンサスプロトコル
MonadBFTは、ラウンドで進行するパイプライン化されたコンセンサスメカニズムです。以下の説明は、プロトコルの高レベルで直感的な理解を示します。
通常のように、n = 3f+1
ノードが存在するとします。ここで、 はf
ビザンチン ノードの最大数です。つまり、2f+1
ノードの (つまり 2/3) が非ビザンチンです。以下の説明では、すべてのノードが等しいステーク ウェイトを持つものとして扱います。実際には、すべてのしきい値はノード数ではなくステークの重みで表すことができます。
- 各ラウンドで、リーダーは新しいブロックと、前のラウンドの QC または TC (これについては後ほど詳しく説明します) を送信します。
- 各バリデータは、そのブロックがプロトコルに準拠しているかどうかを確認し、同意した場合は、署名付きの賛成票を次のラウンドのリーダーに送信します。そのリーダーは、バリデーターからの YES 投票を (しきい値署名を介して) 集約することで QC (クォーラム証明書) を導き出します
2f+1
。この場合の通信は線形であることに注意してください。リーダーはブロックをバリデーターに送信し、バリデーターは投票を次のリーダーに直接送信します。 k
各バリデータは、ラウンドの QC を受信するとk+1
(つまり、ラウンドのリーダーからの通信でk+2
)、ラウンドで提案されたブロックを確定します。具体的には:
あるいは、バリデーターが事前に指定された時間内に有効なブロックを受信しない場合、署名付きタイムアウト メッセージをすべてのピアにマルチキャストします。このタイムアウト メッセージには、バリデーターが観察した最高の QC も含まれています。いずれかのバリデーターがタイムアウト メッセージを蓄積すると2f+1
、これらを (やはりしきい値署名を介して) TC (タイムアウト証明書) に組み立て、次のリーダーに直接送信します。
ラウンド のリーダーであるアリスはk
、新しいブロックを全員に送信します (ラウンド の QC または TC とともにk-1
、これは重要ではないので無視しましょう)。
2f+1
バリデーターが Bob (ラウンド のリーダー) に投票を送信してそのブロックに YES 投票した場合k+1
、ブロックにはk+1
ラウンド の QC が含まれますk
。ただし、k
この時点でラウンドの QC を確認しただけでは、ラウンド内のブロックが保存されたことをバリデーターのヴァレリーが知るには十分ではありませんk
。(たとえば) ボブが悪意を持ってブロックをヴァレリーに送信しただけである可能性があるためです。ヴァレリーができることは、ブロックに投票し、チャーリー (ラウンドのリーダー)k+1
に投票を送ることだけです。k+2
2f+1
バリデーターがブロックで YES に投票した場合k+1
、チャーリーはラウンドの QCk+1
とラウンドのブロック提案を公開しますk+2
。ヴァレリーはこのブロックを受け取るとすぐに、ラウンドからのブロックk
(アリスのブロック) が確定したことを知ります。
ボブが、round で無効なブロック提案を送信するかk+1
、少数のバリデータに送信するなど、悪意のある行動をとったとします2f+1
。次に、少なくともf+1
バリデーターがタイムアウトになり、次に他の非ビザンチンバリデーターがタイムアウトをトリガーし、少なくとも 1 つのバリデーターがラウンドの TC を生成するようになりますk+1
。次に、チャーリーは提案書でラウンドの TC を公開しますk+1
(ラウンドに利用できる QC がないため、提案を行うためにはそうする必要がありますk+1
)。
このコミット手順を 2 チェーン コミット ルールと呼びます。これは、バリデーターが 2 つの隣接する認証済みブロック および を確認するとすぐにB
、その先祖すべてをB'
コミットできるためです。B
参考文献:
- マオファン・イン、ダリア・マルキ、マイケル・K・ライター、ガイ・ゴラン・グエタ、イッタイ・エイブラハム。HotStuff: ブロックチェーンの視点から見る BFT コンセンサス、2018 年。
- モハマド・M・ジャラルザイ、牛建宇、チェン・フェン、ファンユー・ガイ。Fast-HotStuff: 高速かつ復元力のある HotStuff プロトコル、2020 年。
- ラティ・ゲラシヴィリ、レフテリス・ココリス=コギアス、アルベルト・ソンニーノ、アレクサンダー・シュピーゲルマン、卓倫翔。Jolteon と同上: 非同期フォールバックによるネットワーク適応型の効率的なコンセンサス。 arXiv プレプリント arXiv:2106.10362、2021。
- ディエムチーム。DiemBFT v4: Diem ブロックチェーンのステート マシン レプリケーション。 2021年。
BLS マルチシグネチャ
証明書(QC および TC)は、secp256k1曲線上のECDSA署名のベクトルとして単純に実装できます。これらの証明書は明示的であり、構築と検証が簡単です。ただし、証明書のサイズは署名者の数に比例します。投票メッセージを除くほぼすべてのコンセンサス メッセージに証明書が含まれるため、スケーリングに制限が生じます。
BLS12-381曲線上のペアリングベースのBLSシグネチャは、スケーリングの問題の解決に役立ちます。署名は段階的に1つの署名に集約できます。単一の有効な集約署名を検証すると、公開鍵に関連付けられたステークがすべてメッセージに署名していることが証明されます。
BLS署名はECDSA署名よりもはるかに低速です。したがって、パフォーマンス上の理由からMonadBFTは、BLS署名が集約可能なメッセージ タイプ(投票とタイムアウト)でのみ使用される混合署名スキームを採用しています。メッセージの整合性と信頼性は、引き続きECDSA署名によって提供されます。
Shared Mempool
Mempool
保留中のユーザートランザクションは、確定されたブロックに含まれるまで、各バリデーターのmempoolに保存されます。保留中のトランザクションは、トランザクションを消去コーディングし、効率化のためにブロードキャストツリー経由で通信することにより、他のバリデータmempoolと共有されます。
トランザクションのハッシュ化
MonadBFTは、任意のペイロードについて合意に達する効率的な手段です。ただし、ブロックの伝播は依然として重大なボトルネックです。たとえば、500バイトのトランザクションを含む10,000トランザクションのブロックは5MBになります。このサイズのブロックでは、検証ノードに過度の帯域幅要件が課せられます。
この問題を軽減するために、ブロック提案ではトランザクションをハッシュのみで参照します。ハッシュは32バイトであるため、大幅な節約になります。このため、すべてのバリデータmempoolは、提案に投票したりブロックをコミットしたりするときに、独自のmempoolにトランザクションを持つ必要があります。バリデーターのmempoolに送信されたトランザクションは、トランザクションを消去コーディングし、効率性を高めるためにブロードキャストツリー経由で通信することによって、他のバリデーターのmempoolと共有されます。
遅延実行 (Deferred Execution)
Monadブロックチェーンの新しい側面の1つは、実行がコンセンサスから切り離されていることです。
要約すると、コンセンサスはMonadノードがトランザクションの正式な順序について合意に達するプロセスであり、実行はそれらのトランザクションを実際に実行して状態を更新するプロセスです。
Monadのコンセンサスでは、ノードはトランザクションの正式な順序について合意に達しますが、リーダーや検証ノードがまだトランザクションを実行している必要はありません。
つまりリーダーは、結果の状態ルートをまだ知ることなく順序付けを提案し、検証ノードは(たとえば)ブロック内のすべてのトランザクションが元に戻さずに実行されるかどうかを知らずに、ブロックの妥当性について投票します。
どうすればいいの?そしてなぜMonadはこんなことをするのでしょうか?
その答えはMonadの設計の基礎であり、これによりMonadは大幅な高速化を実現し、単一シャードのブロックチェーンを数百万のユーザーに拡張できるようになります。
実行とコンセンサスのインターリーブは非効率的です
イーサリアムでは、実行は合意の前提条件であるため、ノードがブロックに関して合意に達すると、(1)ブロック内のトランザクションのリストと、(2)実行後のすべての状態を要約するマークル ルートの両方について合意することになります。そのトランザクションのリスト。その結果、リーダーは提案を共有する前に、提案されたブロック内のすべてのトランザクションを実行する必要があり、検証ノードは投票で応答する前にそれらのトランザクションを実行する必要があります。
このパラダイムでは、実行にかかる時間は非常に限られています。これは、実行を2回実行し、コンセンサスを得るための複数ラウンドのクロスグローブコミュニケーションに十分な時間を残しておく必要があるためです。さらに、実行するとコンセンサスがブロックされるため、ガス制限は非常に控えめに選択し、最悪のシナリオでも予算内ですべてのノードで計算が完了するようにする必要があります。
決定的な順序付けは状態の決定論を意味する
ここに明らかだが重要な洞察があります:トランザクションの公式な順序が与えられた場合、真の状態は完全に決定されます。真実を明らかにするには実行が必要ですが、真実はすでに決定されています。
Monadは、この洞察を利用して、コンセンサス前にノードが実行する必要があるという要件を取り除きます。ノードの合意は、公式な順序についてのみです;各ノードはブロックN
のトランザクションを独立して実行しながら、ブロックN+1
についてのコンセンサスを開始します。
これにより、実行がコンセンサスに追いつく必要があるだけなので、フルブロック時間に相当するガス予算が可能になります。さらに、このアプローチは、実行が平均でコンセンサスに追いつく必要があるだけなので、正確な計算時間の変動に対してより寛容です。
遅延メルクルルートは依然としてステートマシンのレプリケーションを保証する
上記に対する主な反論は以下の通りです。
- もしノードの1つが悪意を持っており、コンセンサスで指定された正確なトランザクションを実行しない場合はどうなるか?(例えば、特定のトランザクションを省略するか、または状態変数を任意の値に設定するかもしれません。)
- もしノードが実行中にミスを犯した場合はどうなるか?
これらの懸念に対処するため、Monadではブロック提案にD
ブロック遅延のメルクルルートを含めます。ここでD
はシステム全体のパラメーターです(現在は10になることが予想されます)。この遅延メルクルルートの結果:
- ネットワークがブロック
N
についてコンセンサス(2/3多数決)に達した後、ネットワークはブロックN-D
の公式な結果がメルクルルートM
に根ざした状態であることに同意したことを意味します。軽量クライアントは、ブロックN-D
での状態変数値のメルクル証明をフルノードに問い合わせることができます。 - ブロック
N-D
で実行エラーがあるノードは、ブロックN
からコンセンサスから外れます。これはそのノードにブロックN-D-1
の終了状態へのロールバックを引き起こし、その後ブロックN-D
のトランザクションの再実行(メルクルルートが一致することを期待して)、その後ブロックN-D+1
、N-D+2
などのトランザクションの再実行が続きます。
Ethereumのアプローチは、コンセンサスを利用してステートマシンのレプリケーションを非常に厳格に強制します:ノードがコンセンサスに達した後、大多数が公式の順序とその順序から生じる状態について同意していることを知ります。しかし、この厳格性は非常に限られたスループットという大きなコストを伴います。Monadはこの厳格性を少し緩和し、大きな効果を上げています。
ファイナリティについて
MonadBFTでは、ファイナリティは単一スロット(1 秒)であり、フルノードを使用している場合、実行結果の遅れは通常1秒未満です。これを少し開梱してみましょう。
Monad のファイナリティは単一スロット(1 秒)です。トランザクションを送信すると、単一ブロック後に(他のすべてのトランザクションの中で)トランザクションの正式な注文が表示されます。ネットワークの大多数による悪意のあるアクションがない限り、順序が変更される可能性はありません。これにより、モナドのファイナリティはイーサリアムよりも大幅に速くなります(2 エポック、別名 12.8 分)。
トランザクションの実行結果(成功したか失敗したか? その後の残高はどうなったか?) は通常、フル ノードではファイナリティよりも1秒未満遅れます。 トランザクションの結果をすぐに知る必要がある人(たとえば、注文のステータスを知りたい高頻度トレーダー)は、フル ノードを実行できます。 Monadは、フルノードのコストを最小限に抑えるように設計されています。詳細については、「ハードウェア要件」を参照してください。
フルノードを実行せずにトランザクションの結果を安全にクエリしたい人は誰でも、マークルプルーフを使用して残高をフルノードにクエリしながらライトクライアントを実行できます。この場合、クエリにはマークルルート遅延(D=10
ブロック、つまり10秒)だけ遅れが生じます。現在、ほとんどのユーザーはソフトウェア(ブラウザ)ウォレットまたはブロックエクスプローラーを使用してブロックチェーンの状態を表示していることに注意してください。これらの使用パターンにはどちらもライトクライアントは含まれません。
一部の読者は、マークルルート遅延(D=10
ブロック)とファイナリティを誤って混同し、ファイナリティが10ブロックであると誤って仮定する可能性があります。それは真実ではない。公式のトランザクション順序は1ブロック後に決定され、その後は超多数によるビザンチン的な振る舞いがなければ再組織化は行われません。
運送コストと準備金残高
モチベーション
実行の延期は、実行とコンセンサスを並行して行うことができるため、非常に強力であり、実行にかかる時間の予算を大幅に拡大します。
明らかな反対意見は次のとおりです。コンセンサスノードには最新の状態のビューがないのに、ガスをすべて使い果たしたアカウントからのトランザクションを誤って含めることを何が防ぐのでしょうか?これにより、サービス拒否ベクトルが作成されます。
これを防ぐために、Monadはネットワーク上で実行されるトランザクションのコスト (輸送コスト) を導入し、コンセンサス時に更新される各アカウントの準備金残高を維持し、準備金残高に対して輸送コストを請求します。
送料
Monadでは、ネットワーク上でトランザクションをブロック単位で伝送するのに料金がかかります (伝送コスト)。実行費用とは別にかかる費用です。
送料はスパム防止のため必要です。コストは最小限ですが、ネットワークリソースを利用するコストが反映されます。
トランザクションがコンセンサスに含まれている (そして送料が請求されている) ものの、指定されたガス制限に対して実行バジェットが不十分である可能性があります。その場合、実行時にトランザクションは失敗しますが、失敗した時点までガスがチャージされます。これはイーサリアムと何ら変わらないことに注意してください。アカウント内のイーサが不十分な状態でトランザクションを送信すると、イーサが使い果たされて失敗します。DOSベクトルの実行を防ぐには、ガスを障害点までチャージする必要があります。
リザーブ残高
各アドレスについて、ノードは次の2つのバランスを維持します。
- 輸送費の支払いに使用されるリザーブバランス
- 実行残高、トランザクション実行の支払いに使用されます
トランザクションがブロック(コンセンサス)に含まれる場合、送料はリザーブ残高に請求されます。実行時に実行残高から差し引かれ(ダブルチャージ)、D
ブロックの遅延期間(10秒)経過後に積立残高に返金されます。
リザーブは事実上、「進行中の」注文の予算です。これは、支払いが行われたトランザクションのみがブロックに含まれるようにするために存在します。リザーブ残高はリアルタイムで(つまり、コンセンサスが発生すると)減少すると考えることができます。ノードの完全な状態の表示には遅れがありますが、準備金残高は常に最新の支出を反映しています。
目標積立残高
目標リザーブ残高はアカウントごとのパラメーターです。デフォルトは運送費の大きな倍数(200倍)になることが予想されているため、ユーザーは問題なく大量の機内注文を送信できます。
同じEOAから大量のインフライト注文を送信すると予想されるユーザーは、組み込まれたスマート コントラクトを操作することで目標の準備金残高を変更できます。準備金残高の変更は実行として扱われます。つまり、遅延期間が経過した後にのみ準備金残高に反映されます。
Execution
並列実行 (Parallel Execution)
Monadはトランザクションを並列に実行します。最初はこれがEthereumに存在する実行セマンティクスと異なるように思えるかもしれませんが、実際にはそうではありません。MonadのブロックはEthereumのブロックと同じです - トランザクションのリニアに順序付けられたセットです。ブロック内のトランザクションを実行する結果は、MonadとEthereumの間で同一です。
楽観的実行
基本レベルで、Monadは楽観的実行を使用します。これは、Monadがブロック内の前のトランザクションが完了する前にトランザクションの実行を開始することを意味します。時には(常にではありませんが)これにより実行が正しくなくなります。
ブロック内でこの順序である2つのトランザクションを考えてみましょう。
- トランザクション1はアカウントAの残高を読み取り更新します(例えば、アカウントBからの転送を受け取ります)。
- トランザクション2もアカウントAの残高を読み取り更新します(例えば、アカウントCへの転送を行います)。
これらのトランザクションが並列に実行され、トランザクション2がトランザクション1の完了前に実行を開始した場合、アカウントAの読み取り残高は、順番に実行された場合と異なる可能性があります。これにより実行が不正確になる可能性があります。
楽観的実行がこれを解決する方法は、トランザクション2の実行中に使用された入力を追跡し、それらをトランザクション1の出力と比較することです。もし異なっていれば、トランザクション2が実行中に誤ったデータを使用したことが検出され、正しいデータで再実行する必要があることを意味します。
Monadはトランザクションを並列に実行しますが、各トランザクションの更新された状態は、上記の条件をチェックするために順次統合されます。
関連するコンピュータサイエンスのトピックには、楽観的並行制御(OCC)とソフトウェアトランザクショナルメモリ(STM)があります。
楽観的実行の影響
楽観的実行の単純な実装では、ブロック内の先行するトランザクションが完了するまで、トランザクションを再実行する必要があることが検出されません。その時点で、すべての先行トランザクションの状態更新が統合されているため、トランザクションが2回目の楽観的実行のために失敗することはありません。
状態に依存しないトランザクション実行のステップがあります。例として、署名回復がありますが、これは高価な計算です。この作業は、トランザクションを再実行する際に繰り返す必要はありません。
さらに、統合に失敗したためにトランザクションを再実行する場合、多くの場合、アクセスされるアカウントやストレージは変わりません。この状態はメモリ内にキャッシュされているため、これも再度繰り返す必要のない高価な作業です。
スケジュール設定
楽観的実行の単純な実装は、プロセッサに利用可能なリソースがあるときに次のトランザクションの実行を開始しようとします。ブロック内にお互いに依存する長い「チェーン」のトランザクションが存在するかもしれません。これらのトランザクションを並列に実行すると、多くの失敗が発生する可能性があります。
トランザクション間の依存関係を事前に決定することで、Monadは必要なトランザクションが完了したときにのみトランザクションを実行のためにスケジュールすることで、この無駄な努力を避けることができます。Monadにはこのような予測を試みる静的コードアナライザーがあります。良い場合、Monadは多くの依存関係を事前に予測できますが、最悪の場合、Monadは素朴な実装に戻ります。
今後の作業
トランザクションの再実行を回避する方法は他にもあり、現在検討中です。
MonadDb
MonadDbは、ブロックチェーンの状態を保存するためのカスタムデータベースです。
ほとんどのEthereumクライアントは、B-Tree(例はLMDB)またはLSM-Tree(例はLevelDBおよびRocksDB)データ構造として実装されたキー/値データベースを使用します。ただし、イーサリアムは状態を保存するためにマークル パトリシアトライ(MPT)データ構造を使用します。これにより、あるデータ構造が異なるタイプの別のデータ構造に埋め込まれる、次善のソリューションが得られます。MonadDbは、Patricia Trieデータ構造をディスク上とメモリ内の両方でネイティブに実装します。
Monadは複数のトランザクションを並行して実行します。あるトランザクションがディスクから状態を読み取る必要がある場合、その操作が完了するのを待ってブロックするべきではありません。代わりに、読み取りを開始し、その間に別のトランザクションの作業を開始する必要があります。したがって、この問題にはデータベースの非同期 i/o (async i/o) が必要です。上記のキーと値のデータベースには、適切なasync i/oサポートがありません(ただし、この領域では改善するための取り組みがいくつかあります)。MonadDbは、async i/o(Linux ではio_uring )の最新のカーネルサポートを最大限に活用します。これにより、作業を非同期に実行しようとして保留中のi/o要求を処理するために多数のカーネル スレッドを生成する必要がなくなります。
MonadDbは、高価なオーバーヘッドを追加するファイルシステムのバイパスなど、i/oに関連するその他の最適化を数多く行います。
Monadのトランザクションのライフサイクル
トランザクションの送信
トランザクションのライフサイクルは、ユーザーが署名済みトランザクションを準備し、それをRPCノードに送信することから始まります。
トランザクションは通常、アプリケーションのフロントエンドによって準備され、署名のためにユーザーのウォレットに提示されます。ほとんどのウォレットはeth_estimateGas
RPC呼び出しを行ってこのトランザクションのガス制限を設定しますが、ユーザーはウォレットでこれをオーバーライドすることもできます。ユーザーは通常、トランザクションのガス価格(ガス単位あたりのNativeTokenの数)を選択するように求められます。
ユーザーがウォレットでの署名を承認した後、署名されたトランザクションはeth_sendTransaction
またはeth_sendRawTransaction
API呼び出しを使用してRPCノードに送信されます。
Monadでは、ガス制限はキャリッジガスと実行ガスの合計であることに注意してください。キャリッジガスは一定です。
Mempoolの伝播
RPCノードは保留中のトランザクションをコンセンサスに参加している他のMonadノードに転送します。保留中のトランザクションのセットは口語的に「mempool」と呼ばれます。mempoolの動作の詳細については、Mempoolを参照してください。
スパム防止の理由から、ノードはリザーブ残高に十分なガスがある場合にのみトランザクションをmempoolに追加します。
ブロックの包含
MonadBFTは、回転リーダーメカニズムを使用してブロックを生成します。各ラウンドで、リーダーは保留中のトランザクションのリストからブロックを組み立てます。ブロックに含めるトランザクションを選択した後、リーダーは輸送費を使用して準備金残高を減算します。
MonadBFTで説明したように、ブロックはネットワークを通じて伝播されます。このブロックのクォーラム証明書(QC)は、その後のコンセンサスラウンドで伝播されます(つまり、次のリーダーによって送信されます)。QCを確認した後、投票ノードは相互に投票を送信します。ノードがステークウェイトの2/3の賛成票を確認すると、そのブロックが確定します。
ブロックが完了すると、トランザクションはブロックチェーンの歴史の中で正式に「発生」したことになります。順序が決まっているので、その真理値(成功か失敗か、実行直後の結果はどうなるか)が決まります。
ローカル実行
ノードはブロックを終了するとすぐに、そのブロックからトランザクションの実行を開始します。効率上の理由から、トランザクションは楽観的に並列実行されますが、結果は常に元の順序でコミットされるため、トランザクションが直列に実行されたかのようになります。
結果のクエリ
ユーザーは、任意の RPC ノードで eth_getTransactionByHash
または eth_getTransactionReceipt
を呼び出すことで、トランザクションの結果をクエリできます。 RPC ノードは、ノード上でローカルに実行が完了するとすぐに戻ります。
その他の情報
アカウント
MonadのアカウントはEthereumアカウントと同じです。アカウントは同じアドレス(ECDSAを使用した20バイトのアドレス)を使用します。イーサリアムと同様に、外部所有アカウント(EOA)と契約アカウントがあります。
取引
Monadのトランザクション形式はEthereumに一致します。つまり、EIP-2718に準拠しており、トランザクションはRLPでエンコードされます。
アクセスリスト(EIP-2930)はサポートされていますが、必須ではありません。
ブロックとトランザクションの直線性
ブロック内のトランザクションと同様に、ブロックも線形です。並列処理は効率性を目的としてのみ利用されます。一連のトランザクションの実際の結果や最終状態には決して影響しません。
ガス (Gas)
Gas (おそらく、より明確に「計算ユニット」と名付けられている)は、イーサリアムと同様に機能します。つまり、各オペコードには一定量のガスがかかります。オペコードごとのガスコストはモナドのイーサリアムと同じですが、これは将来変更される可能性があります。
ユーザーがトランザクションを送信すると、ガス制限(この関数呼び出しがエラーになる前に消費できるガスの最大ユニット数)とガス価格(ガス単位あたりのネイティブ トークン単位の入札)が含まれます。 。
デフォルトのMonadクライアントのリーダーは、優先ガスオークション(PGA)を使用してトランザクションを注文します。つまり、ガス価格の降順でトランザクションを注文します。将来的には、トランザクションの順序付けに別のメカニズムが登場する可能性があります。順序の選択は、下流で起こるすべてのことと直交しています。順序の有効な選択はMonadプロトコルに組み込まれていません。
Monadの使う
ノードの実行
ハードウェア要件
Monadフルノードを実行するには、次のハードウェア要件が想定されます。
- CPU : 16コアCPU
- メモリ : 32GB RAM
- ストレージ : 2TB NVMe SSD
- 帯域幅 : 100Mb/秒
Developing on Monad
推奨リソース
MonadはEVMバイトコードと完全に互換性があり、上海フォークの時点でサポートされているすべてのオペコードとプリコンパイルを備えています。Monadは、標準のEthereum JSON-RPCインターフェイスも保持します。
そのため、イーサリアムメインネットの開発リソースのほとんどはMonadでの開発に適用されます。
このページでは、イーサリアム用の分散アプリの構築を開始するための最小限のリソースセットを提案します。子ページには追加の詳細やオプションが表示されます。
Solidityはイーサリアムスマートコントラクトで最も人気のある言語であるため、このページのリソースはSolidityに焦点を当てています。代わりに、VyperまたはHuffのリソースを参照してください。スマートコントラクトは構成可能であるため、元々1つの言語で作成されたコントラクトは引き続き別の言語のコントラクトを呼び出すことができることに注意してください。
IDE
- RemixはインタラクティブなSolidity IDEです。これは、追加のツールをインストールすることなく、Solidityスマートコントラクトのコーディングとコンパイルを開始する最も簡単かつ迅速な方法です。
- VSCode + Solidity拡張機能
基本的な堅牢性
- CryptoZombiesは、EVM上でdAppを構築するための優れたエンドツーエンドの入門書です。これまでコーディングをしたことがない人から、ブロックチェーン開発を検討している他の分野の経験豊富な開発者まで、あらゆる人にリソースとレッスンを提供します。
- Solidity by Exampleでは、簡単な例を通じて概念を段階的に紹介します。すでに他の言語の基本的な経験がある開発者に最適です。
中間の固さ
- Solidity Languageの公式ドキュメントは、EVM環境を中心としたスマート コントラクトとブロックチェーンの基本をエンドツーエンドで説明しています。Solidity Languageのドキュメントに加えて、EVMへのデプロイメント用にコードをコンパイルする基本と、EVMへのスマートコントラクトのデプロイメントに関連する基本コンポーネントについても説明します。
- Solidity Patternsリポジトリは、コードテンプレートのライブラリとその使用法の説明を提供します。
- Uniswap V2コントラクトは、プロフェッショナルでありながら理解しやすいスマートコントラクトであり、運用中のSolidity dAppの概要を提供します。契約のガイド付きウォークスルーはここにあります。
- Cookbook.devは、ライブ編集、ワンクリックデプロイ、コードに関する質問に役立つAIチャット統合を備えたインタラクティブなサンプルテンプレートコントラクトのセットを提供します。
- OpenZeppelinは、ERC20、ERC712、ERC1155 などの一般的なEthereumトークン展開用のカスタマイズ可能なテンプレートコントラクトライブラリを提供します。これらはガス最適化されていないことに注意してください。
高度な堅牢性
- SolmateリポジトリとSoladyリポジトリは、SolidityまたはYulを利用してガス最適化されたコントラクトを提供します。
- YulはSolidityの中間言語であり、一般にEVMのインラインアセンブリと考えることができます。これは完全に純粋なアセンブリではなく、制御フロー構造を提供し、スタックの内部動作を抽象化しながら、生のメモリバックエンドを開発者に公開します。Yulは、高性能のガス最適化EVMコードを構築するためにEVMの生メモリバックエンドを利用する必要がある開発者を対象としています。
- Huffは、EVMアセンブリとして最も正確に説明されます。Yulとは異なり、Huffは制御フロー構造を提供したり、プログラムスタックの内部動作を抽象化したりしません。Huffを利用できるのはパフォーマンス重視の最上位のアプリケーションだけですが、HuffはEVMが最下位レベルの命令をどのように解釈するかを学ぶための優れた教育ツールです。
ローカルノード
開発者は、パラメータを変更して1ノードのEthereumネットワークを実行して、ブロックチェーンとの対話をテストできると便利だと考えることがよくあります。
- Anvilは、Foundryツールキットにパッケージ化されたローカルEthereumノードです。
- Hardhat Networkは、Hardhatツールキットにパッケージ化されたローカルEthereumノードです。
インストールは、次のセクションで説明する各ツールキットのインストールの一部として行うのが最も簡単です。
ツールキット
開発者は、外部の依存関係(つまりパッケージ管理)を整理し、単体テストと統合テストを整理し、(ローカルノード、テストネット、メインネットに対して)導入手順を定義し、ガスコストを記録する、より広範なフレームワークのコンテキストでプロジェクトを構築することが役立つと感じることがよくあります。 、など。
Solidity開発用の最も人気のある2つのツールキットを次に示します。
- Foundryは、開発とテストの両方のためのSolidityフレームワークです。Foundryは依存関係の管理、プロジェクトのコンパイル、テストの実行、デプロイを行い、コマンドラインやSolidityスクリプト経由でチェーンを操作できるようにします。Foundryユーザーは通常、スマートコントラクトとテストをSolidity言語で作成します。
- Hardhatは、JavaScriptテスト フレームワークと組み合わせたSolidity開発フレームワークです。Foundryと同様の機能が可能であり、Foundry以前はEVM開発者にとって主要なツールチェーンでした。
Ethereum RPC APIとの対話
dAppのフロントエンドは通常、JavaScriptまたはPythonを使用して読み取りまたは書き込みクエリをRPCノードに送信します。Web開発者はブロックチェーンをバックエンドサーバーとほぼ同等にみなすことができるため、このコードは通常「クライアント側」と呼ばれます。
いくつかのライブラリは、RPCノードにクエリまたはトランザクションを送信するための標準メソッドを提供します。
- Python :
- JavaScript :
フロントエンドを作成する簡単な例を次に示します : create-eth-app 。
テストネット
Monad Testnetは今後数か月以内に開発者向けに提供される予定ですが、バイトコードおよびRPCがEVMと互換性があるため、Monadへのデプロイを希望する開発者はEthereumのTestnetを予備的に使用できます。
さらに詳しく知るには
EVMの動作
EVMの動作仕様
- Notes on the EVM : EVMの簡単な技術仕様といくつかの動作例
- EVM : From Solidity to bytecode, memory and storage : Peter RobinsonとDavid Hyland-Woodによる90分間の講演
- EVM illustrated : メンタルモデルを確認するための優れた図のセット
- EVM Deep Dives : The Path to Shadowy Super-Coder
オペコードリファレンス • evm.codes : オペコードリファレンス(ガスコストを含む)およびバイトコード実行を段階的に実行するためのインタラクティブなサンドボックス
Solidityストレージのレイアウト
EVMにより、スマートコントラクトは32バイトワード( 「ストレージ スロット」 )にデータを保存できますが、リストやマッピングなどの複雑なデータ構造がどのように構成されるかについての詳細は、実装の詳細として高レベル言語に残されます。Solidityには以下で説明するように、変数をストレージスロットに割り当てる特定の方法があります。
その他のSolidityリソース
「推奨リソース」で説明した以外のリソースをいくつか紹介します。
チュートリアル • Ethernaut : パズルを解いて学ぶ
ベストプラクティス/パターン
テスト
- Echidna : ファズテスト
- Slither : 脆弱性検出のための静的分析
- Solidity-coverage : Solidity テストのコードカバレッジ
スマートコントラクトのアーカイブ
- Smart contract sanctuary : Etherscanで検証された契約
- EVM function signature database
オンチェーンでのデバッグ
トランザクションのイントロスペクション/トレース
- Tenderly
- EthTx Transaction Decoder
- https://openchain.xyz/
- Bloxy
- https://github.com/naddison36/tx2uml : UML図を生成するためのOSツール
- https://github.com/apeworx/evm-trace : トレースツール
コントラクトの逆コンパイル
- https://oko.palkeo.com/ : Panoramixデコンパイラーのホストされたバージョン
その他の言語
Vyper言語
VyperはEVM用の人気のあるプログラミング言語であり、論理的にはSolidityに似ており、構文的にはPythonに似ています。
Vyperのドキュメントでは、Vyper言語のインストール、言語構文、コーディング例、コンパイルについて説明しています。
Pythonのようなエクスペリエンスを求める一般的なEVM開発者は、プログラミング言語としてVyperを使用し、テストおよびデプロイメントフレームワークとしてPython言語を活用するApeWorxを使用することをお勧めします。ApeWorxでは、Pandasなどのテスト結果の分析に一般的なPythonライブラリを使用することもできます。
VyperおよびApeWorxは、Webブラウザを使用したインタラクティブな環境を提供するJupyterと併用できます。EVMのスマートコントラクト開発のためにVyperおよびJupyterを使用するためのクイックセットアップガイドは、ここにあります。
Vyperリソース
- Vyper by Example
- Snekmate : ガスに最適化されたスマート コントラクトビルディングブロックのVyperライブラリ
- Curve Contracts : Vyperの最も顕著な使用例
Huff言語
Huffは、EVMアセンブリとして最も正確に説明されます。Yulとは異なり、Huffは制御フロー構造を提供したり、プログラムスタックの内部動作を抽象化したりしません。Huffを利用できるのはパフォーマンス重視の最上位のアプリケーションだけですが、HuffはEVMが最下位レベルの命令をどのように解釈するかを学ぶための優れた教育ツールです。
Huffリソース
- Huff Resourcesは追加のリソースを提供します。
オフィシャルリンク
ウェブサイト : https://monad.xyz/
Twitter : https://twitter.com/monad_xyz
Substack : https://monadlabs.substack.com/
Discord : https://discord.gg/monad
Copyright Notice
*Reprinted with permission from Neafs Organization Gitbook by 0xneaf, 2024.