Solana仮想マシン(SVM)は、さまざまなLayer-2(L2)ソリューションの実行レイヤーとして広く採用されつつあります。ただし、SVMの元の設計における重要な制限事項は、そのグローバルステートルートの不透明性です。これは、ロールアップシステムにとって重要な課題を提起しており、グローバルステートルートが完全性を確保し、不正証明を可能にし、クロスレイヤー操作をサポートするために不可欠であるということです。
ロールアップでは、提案者は定期的にL2ステートルート(Merkleルート)をレイヤー1(L1)に提出し、L2チェーンのためのチェックポイントを確立します。これらのチェックポイントにより、任意のアカウントステートの含有証明が可能となり、1つのチェックポイントから別のチェックポイントまでのステートレス実行が可能となります。詐欺証明はこのメカニズムに依存しており、参加者は紛争中に有効な入力を検証するための含有証明を提供できます。さらに、Merkleツリーは、ユーザーが引き出しトランザクションの含有証明を生成できることにより、正規のブリッジのセキュリティを向上させ、L2とL1の間の信頼できるインタラクションを保証します。
これらの課題に対処するために、SOONネットワークSVMの実行レイヤーにMerkleツリーを導入し、クライアントが包含証明を提供できるようにします。SOONは、固有のエントリを使用してProof-of-Historyと統合し、状態ルートを直接SVMベースのブロックチェーンに埋め込むことができます。この革新により、SOONスタックは、セキュリティ、拡張性、およびユーティリティが向上した新しいSVMベースのロールアップをサポートできます。
Solanaは常に高いスループットをコア目標として設計されており、その革新的なパフォーマンスを達成するためには、特に初期の開発段階で意図的な設計のトレードオフが必要でした。これらのトレードオフの中で、Solanaがどのようにしていつメルクライズするかという点に関する最も影響力のある決定の一つがありました。
最終的に、この決定は、クライアントがグローバルステートやトランザクションの包含、および簡易支払い検証(SPV)を証明する際に、大きな課題を生み出しました。 SVMステートをメルカライズした状態を一貫してハッシュ化するルートがないことは、軽量クライアントやロールアップなどのプロジェクトにとって相当な難しさをもたらします。
他のチェーンでマークライゼーションがどのように行われているかを見て、その後、Solanaのプロトコルアーキテクチャによって提示される課題を特定しましょう。
ビットコインでは、取引はブロックに格納されます。マークルツリー、そのルートが保存されているブロックのヘッダービットコインプロトコルは、トランザクションの入出力(およびその他のメタデータ)をハッシュします。取引ID(TxID). ビットコイン上の状態を証明するために、ユーザーは単純にMerkle証明を計算して、TxIDをブロックのMerkleルートと照合することができます。
この検証プロセスは、Tx IDが一意であり、それは一意の入力と出力のセットに対応し、それらはアドレスの状態の変更を反映しているため、状態を検証します。 Bitcoinトランザクションにはアドレスの状態の変更が含まれていることに注意してください。Taprootスクリプト,検証中に確認できるトランザクション出力を生成する、通常はトランザクションの入力とスクリプトの証人データを使用してスクリプトを再実行し、その出力と照合を行うことがあります。
Bitcoinに類似して、EthereumはMerkleツリーから派生したカスタムデータ構造を使用して取引を保存します。マークルパトリシアトライ(MPT)。このデータ構造は、大規模なデータセットに対する迅速な更新と最適化を目的として設計されています。これは、イーサリアムがビットコインよりもはるかに多くのインプットとアウトプットを管理する必要があるためです。
ザ Ethereum仮想マシン(EVM) はグローバル・ステート・マシンとして機能します。この評価基板 (EVM) は基本的に、実行可能ファイルをサポートする巨大な分散コンピューティング環境ですスマートコントラクト, それぞれがグローバルメモリ内で独自のアドレススペースを確保します。その結果、Ethereum上で状態を検証したいクライアントは、トランザクションの結果(ログ、リターンコードなど)だけでなく、トランザクションの結果としてのグローバルステートの変更も考慮する必要があります。
幸いにも、EVMは、各ブロックヘッダーにそのルートを格納する3つの重要なトライ構造を巧妙に利用しています。
トランザクションが与えられた場合、クライアントはトランザクションのトライルートを評価することでブロックへの含まれ具合を証明し(ビットコインのように)、レシートトライを評価することでその結果を確認し、状態トライを評価することでグローバル状態の変更を確認できます。
Solanaの高いスループットの理由の1つは、Ethereumが持っているマルチツリー構造を持っていないという事実です。Solanaのリーダーは、ブロックを作成する際にMerkleツリーを計算しますが、EVM内のそれらとは異なる構造になっています。残念ながら、そこにSVMベースのロールアップの問題があります。
Solanaは、取引をエントリと呼ばれるものにマークライズし、スロットごとに複数のエントリが存在することがあります。したがって、ブロックごとに複数の取引ルートがあります。さらに、Solanaはアカウント状態のMerkleルートをエポックごとに1回だけ(約2.5日ごとに)計算し、このルートは元帳上では利用できません。
実際、SolanaブロックヘッダにはまったくMerkleルートが含まれていません。代わりに、それらには前のものと現在のものが含まれています。ブロックハッシュ, これはSolanaのを通じて計算されますProof of History(PoH)アルゴリズム。 PoHは、バリデータに連続して「tick」を登録することを要求し、ブロックエントリを再帰的にハッシュ化する必要があります。これらのエントリには、空であるか、トランザクションのバッチを含むことができます。 PoHアルゴリズムの最終的なtick(ハッシュ)は、そのブロックのブロックハッシュです。
Proof of Historyの問題は、状態をブロックハッシュから証明することが非常に難しくなるということです。Solanaは、経過時間の概念を維持するためにPoHハッシュをストリーミングするように設計されています。トランザクションルートは、トランザクションを含むPoH tickにのみ利用可能であり、ブロック全体ではなく、いかなるエントリにも状態ルートは格納されていません。
しかし、クライアントが使用できる別のハッシュが存在します: 銀行ハッシュ。スロットハッシュとも呼ばれることがあり、銀行ハッシュは利用可能です SlotHashes sysvarアカウントは、クライアントによってクエリされる可能性があります。銀行ハッシュは、少数の入力から各ブロック(スロット)ごとに作成されます。
誰もが見ることができるように、銀行ハッシュは複数のハッシュ入力でオーバーロードされており、これにより取引や状態に関する情報を証明しようとするクライアントにとって複雑さが増しています。さらに、1つの「エポックアカウントハッシュ」を実行した銀行の銀行ハッシュだけが、その特定のルートが含まれています。さらに、SlotHashesシステム変数アカウントは、最後の512個の銀行ハッシュに切り捨てられます。
SOONネットワークEthereumの上にあるSVM L2です。SOONにmerklizationを統合する際、安定性のために、車輪の再発明よりも確立された解決策を使用することを優先しました。使用するデータ構造やハッシュアルゴリズムを決定する際、それらがL1契約との互換性を考慮しました。Optimism Stack,彼らがSolanaアーキテクチャにシームレスに統合できる能力、および彼らがSolanaのアカウントモデルの下で高いパフォーマンスを達成できるかどうか。
アカウント数が増えるにつれて、Merkle Patricia Trie(MPT)ストレージモデルが基づくLSM-ツリーより多くのディスクの読み書き増幅を引き起こし、パフォーマンスの低下につながる可能性があります。最終的に、私たちは統合することに決めました。Erigon MPT優れたRustの作業をもとに構築することで、rETHチームに加えて、Solanaアカウントモデルへのサポートを追加する。
以前に述べたように、SOONの状態トライはSolanaアカウントをサポートするために構築されたMPTです。そのため、各葉ノードのデータとして機能するSVM互換のアカウントタイプを定義しています。
struct TrieSolanaAccount {
lamports: u64,
データ:Vec
executable: bool,
rent_epoch:u64,
owner: Pubkey,
}
MPTモジュールがSVMアカウントの最新状態をリアルタイムで購読できるようにするために、アカウント通知機能を導入しました。銀行ステージ中、アカウント通知機能はMPTモジュールにアカウントの状態変化を通知し、MPTはこれらの変更をトライ構造に増分的に更新します。
MPTモジュールは、50スロットごとにサブツリーのみを更新し、スロットの終わりに状態ルートを計算しません。このアプローチは2つの理由から採用されています。まず、すべてのスロットで状態ルートを計算するとパフォーマンスに大きな影響を与えます。第二に、状態ルートは、プロポーザが提出するときだけ必要とされます。outputRootしたがって、それは提案者の提出頻度に基づいて定期的に計算する必要があります。
outputRoot = keccak256(version, state_root, withdraw_root, l2_block_hash)
SOON MPTモジュールは、同時に2種類のトライ構造を維持します:グローバル状態のための状態トライと引き出しトランザクションのための引き出しトライ。提案者は、状態ルートと引き出しルートからoutputRootを定期的に生成し、L1に提出します。
現在、SOONは、450スロットごとに状態ルートと引き出しルートを計算し、L2ブロックチェーンに追加します。その結果、ネットワーク内の他のノード間でのMPTデータの整合性を確保できます。ただし、Solanaブロック構造にはブロックヘッダーが含まれていないため、状態ルートを格納する場所がありません。Solanaブロックチェーンの基本構造を詳しく見て、その後、SOONがUniqueEntryを導入して状態ルートを格納する方法を探ってみましょう。
Solanaブロックチェーンは、PoHモジュールによって生成されるスロットで構成されています。スロットには複数のエントリが含まれ、それぞれのエントリにはティックとトランザクションが含まれています。ネットワークおよびストレージレイヤーでは、スロットは次のように保存および送信されます シュレッド最小単位として。シュレッドはエントリに変換および変換できます。
pub struct Entry {
前のエントリIDからのハッシュ数。
pub num_hashes: u64,
/// SHA-256ハッシュnum_hashes
前のエントリーIDの後。
pub hash: ハッシュ,
/// エントリーIDが前に観察されたトランザクションの順不同リスト
///生成されました。 以前のエントリIDの前に観察されている可能性がありますが、
/// このリストに再度追加され、台帳の確定的な解釈を確保します。
pub transactions: Vec
}
PoHによって生成されたブロックチェーン構造に従い、シュレッド構造を維持し、Solanaの既存のストレージ層、ネットワーク層、およびRPCフレームワークを再利用することができました。L2ブロックチェーンに追加データを格納するために、UniqueEntryを導入しました。この特性により、エントリペイロードをカスタマイズし、データの独立した検証ルールを定義することができます。
pub const UNIQUE_ENTRY_NUM_HASHES_FLAG: u64 = 0x8000_0000_0000_0000;
/// ユニークエントリーは特別なエントリータイプです。データを保存する必要があるときに便利です
/// blockstore but do not want to verify it.
///
のレイアウトnum_hashes
is:
/// |…1 ビット…|…63 ビット…|
/// \ _ _/
/// \ \
/// フラグ カスタムフィールド
pub trait UniqueEntry: Sized {
fn encode_to_entries(&self) -> Vec
fn decode_from_entries(
entries: impl IntoIterator<Item = Entry>,
) -> Result
}
pub fn unique_entry(custom_field:u64、ハッシュ:ハッシュ)->エントリ{
エントリー {
num_hashes: num_hashes(custom_field), hash, transactions: vec![],
}
}
pub fn num_hashes(custom_field: u64) -> u64 {
assert!(custom_field < (1 << 63));
UNIQUE_ENTRY_NUM_HASHES_FLAG | custom_field
}
pub fn is_unique(entry: &Entry) -> bool {
entry.num_hashes & UNIQUE_ENTRY_NUM_HASHES_FLAG != 0
}
UniqueEntryでは、num_hashesはビットレイアウトとして使用され、最初のビットフラグはEntryとUnique Entryを区別するために使用され、続く63ビットはペイロードタイプを定義するために使用されます。ハッシュフィールドは、必要なカスタムデータを含むペイロードとして機能します。
3つのユニークなエントリを使用して、スロットハッシュ、ステートルート、および取り消しハッシュを格納する例を見てみましょう。
/// MPTルートユニークエントリ。
pub struct MptRoot {
pub slot: スロット,
pub state_root: B256,
pub withdrawal_root: B256,
}
impl UniqueEntry for MptRoot {
fn encode_to_entries(&self) -> Vec
let slot_entry = unique_entry(0, slot_to_hash(self.slot)); let state_root_entry = unique_entry(1, self.state_root.0.into(); let withdrawal_root_entry = unique_entry(2, self.withdrawal_root.0.into()); vec![slot_entry, state_root_entry, withdrawal_root_entry]
}
FN decode_from_entries(
entries: impl IntoIterator
) -> Result
let mut entries = entries.into_iter(); let entry = entries.next().ok_or(UniqueEntryError::NoMoreEntries)?; let slot = hash_to_slot(entry.hash); let entry = entries.next().ok_or(UniqueEntryError::NoMoreEntries)?; let state_root = B256::from(entry.hash.to_bytes()); let entry = entries.next().ok_or(UniqueEntryError::NoMoreEntries)?; let withdrawal_root = B256::from(entry.hash.to_bytes(); Ok(MptRoot { slot, state_root, withdrawal_root, })
}
}
UniqueEntryはnum_hashesの意味を再定義するため、PoH検証段階で処理できません。したがって、検証プロセスの開始時には、まずユニークなエントリをフィルタリングし、ペイロードタイプに基づいたカスタム検証フローに直します。残りの通常のエントリは、元のPoH検証プロセスを通過します。
ネイティブブリッジは、レイヤー2ソリューションの重要なインフラストラクチャの一部であり、L1とL2の間のメッセージ伝達を担当しています。L1からL2へのメッセージは預入れトランザクションと呼ばれ、一方、L2からL1へのメッセージは引き出しトランザクションと呼ばれています。
預金取引は、通常、派生パイプラインまた、ユーザーは L1 で 1 つのトランザクションを送信するだけで済みます。ただし、引き出しトランザクションはより複雑であり、ユーザーはプロセスを完了するために3つのトランザクションを送信する必要があります。
出金トランザクションの含意証明は、L2での出金が行われたことを保証し、標準的なブリッジのセキュリティを大幅に向上させます。
OPスタックでは、ユーザーの引き出しトランザクションのハッシュが、対応する状態変数に格納されています。OptimismPortal契約。その後、eth_getProof RPCインターフェースを使用して、特定の引き出しトランザクションに対する包含証明をユーザーに提供します。
EVMとは異なり、SVM契約データは勘定科目のデータ項目に保存され、すべてのタイプの口座が同じ階層レベルに存在します。
SOONはネイティブブリッジプログラムを導入しました:Bridge1111111111111111111111111111111111111。ユーザーが引き出しトランザクションを開始するたびに、ブリッジプログラムは各引き出しトランザクションに対してグローバルにユニークなインデックスを生成し、このインデックスをシードとして新しいプログラム派生アカウント(PDA)に対応する引き出しトランザクションを保存します。
pub struct WithdrawalTransaction {
/// 出金カウンター
pub nonce: U256,
/// ユーザーは引き出したい
pub sender: Pubkey,
/// L1のユーザーアドレス
pub target: アドレス,
///ラムポートでの引き出し金額
pub value: U256,
/// L1のガス制限
pub gas_limit: U256,
/// L1での引き出しコールデータ
データを公開します:L1WithdrawalCalldata,
}
PDAのdataフィールドに出金取引を保存するためにWithdrawalTransaction構造を定義しました。
この設計はOPスタックと同様に機能します。出力ルートが引き出しトランザクションをL1に提出されると、ユーザーは引き出しトランザクションの包含証明をL1に提出してチャレンジ期間を開始することができます。
提案者がoutputRootをL1に提出すると、L2の状態が確定したことを意味します。もしチャレンジャーが提案者が間違った状態を提出したことを検知した場合、彼らは橋の資金を保護するためにチャレンジを開始することができます。
障害証明を構築する際の最も重要な側面の1つは、ブロックチェーンが状態S1から状態S2に状態レスに移行することを可能にすることです。これにより、L1の仲裁契約がプログラムの命令を状態レスに再生して仲裁を行うことができます。
ただし、このプロセスの開始時には、チャレンジャーは、状態S1の初期入力がすべて有効であることを証明しなければなりません。これらの初期入力には、参加アカウントの状態(lamports、データ、オーナーなど)が含まれます。EVMとは異なり、SVMは自然にアカウントの状態を計算から分離します。AnzaのSVM APITransactionProcessingCallbackトレイトを通じてアカウントをSVMに渡すことができます。以下に示すように。
pub trait TransactionProcessingCallback {
fn account_matches_owners(&self、account:&Pubkey、owners:&[Pubkey]) -> Option
fn get_account_shared_data(&self、pubkey:&Pubkey) -> Option
fn add_builtin_account(&self、_name:&str、_program_id:&Pubkey) {}
}
したがって、私たちは、挑戦プログラムの入力の妥当性を検証するために、入力アカウントの包含証明とともに状態S1のみを使用する必要があります。
SOONは、SVMエコシステムの開発において重要なマイルストーンをマークしています。メルクライゼーションを統合することで、SOONはSolanaのグローバルステートルートの不足に対処し、故障証明の含有証明、安全な引き出し、およびステートレス実行などの重要な機能を可能にしています。
さらに、SOONのSVM内のメルクル化設計は、Solana自体が現在は軽量クライアントをサポートしていないにもかかわらず、SVMベースのチェーン上で軽量クライアントを可能にすることができます。設計の一部がメインチェーンに軽量クライアントをもたらすのに役立つ可能性さえあります。
状態管理にMerkle Patricia Tries(MPT)を使用することで、SOONはEthereumのインフラと整合し、SVMベースのL2ソリューションを進化させます。この革新により、セキュリティ、拡張性、互換性が向上し、分散型アプリケーションの成長が促進され、SVMエコシステムが強化されます。
Solana仮想マシン(SVM)は、さまざまなLayer-2(L2)ソリューションの実行レイヤーとして広く採用されつつあります。ただし、SVMの元の設計における重要な制限事項は、そのグローバルステートルートの不透明性です。これは、ロールアップシステムにとって重要な課題を提起しており、グローバルステートルートが完全性を確保し、不正証明を可能にし、クロスレイヤー操作をサポートするために不可欠であるということです。
ロールアップでは、提案者は定期的にL2ステートルート(Merkleルート)をレイヤー1(L1)に提出し、L2チェーンのためのチェックポイントを確立します。これらのチェックポイントにより、任意のアカウントステートの含有証明が可能となり、1つのチェックポイントから別のチェックポイントまでのステートレス実行が可能となります。詐欺証明はこのメカニズムに依存しており、参加者は紛争中に有効な入力を検証するための含有証明を提供できます。さらに、Merkleツリーは、ユーザーが引き出しトランザクションの含有証明を生成できることにより、正規のブリッジのセキュリティを向上させ、L2とL1の間の信頼できるインタラクションを保証します。
これらの課題に対処するために、SOONネットワークSVMの実行レイヤーにMerkleツリーを導入し、クライアントが包含証明を提供できるようにします。SOONは、固有のエントリを使用してProof-of-Historyと統合し、状態ルートを直接SVMベースのブロックチェーンに埋め込むことができます。この革新により、SOONスタックは、セキュリティ、拡張性、およびユーティリティが向上した新しいSVMベースのロールアップをサポートできます。
Solanaは常に高いスループットをコア目標として設計されており、その革新的なパフォーマンスを達成するためには、特に初期の開発段階で意図的な設計のトレードオフが必要でした。これらのトレードオフの中で、Solanaがどのようにしていつメルクライズするかという点に関する最も影響力のある決定の一つがありました。
最終的に、この決定は、クライアントがグローバルステートやトランザクションの包含、および簡易支払い検証(SPV)を証明する際に、大きな課題を生み出しました。 SVMステートをメルカライズした状態を一貫してハッシュ化するルートがないことは、軽量クライアントやロールアップなどのプロジェクトにとって相当な難しさをもたらします。
他のチェーンでマークライゼーションがどのように行われているかを見て、その後、Solanaのプロトコルアーキテクチャによって提示される課題を特定しましょう。
ビットコインでは、取引はブロックに格納されます。マークルツリー、そのルートが保存されているブロックのヘッダービットコインプロトコルは、トランザクションの入出力(およびその他のメタデータ)をハッシュします。取引ID(TxID). ビットコイン上の状態を証明するために、ユーザーは単純にMerkle証明を計算して、TxIDをブロックのMerkleルートと照合することができます。
この検証プロセスは、Tx IDが一意であり、それは一意の入力と出力のセットに対応し、それらはアドレスの状態の変更を反映しているため、状態を検証します。 Bitcoinトランザクションにはアドレスの状態の変更が含まれていることに注意してください。Taprootスクリプト,検証中に確認できるトランザクション出力を生成する、通常はトランザクションの入力とスクリプトの証人データを使用してスクリプトを再実行し、その出力と照合を行うことがあります。
Bitcoinに類似して、EthereumはMerkleツリーから派生したカスタムデータ構造を使用して取引を保存します。マークルパトリシアトライ(MPT)。このデータ構造は、大規模なデータセットに対する迅速な更新と最適化を目的として設計されています。これは、イーサリアムがビットコインよりもはるかに多くのインプットとアウトプットを管理する必要があるためです。
ザ Ethereum仮想マシン(EVM) はグローバル・ステート・マシンとして機能します。この評価基板 (EVM) は基本的に、実行可能ファイルをサポートする巨大な分散コンピューティング環境ですスマートコントラクト, それぞれがグローバルメモリ内で独自のアドレススペースを確保します。その結果、Ethereum上で状態を検証したいクライアントは、トランザクションの結果(ログ、リターンコードなど)だけでなく、トランザクションの結果としてのグローバルステートの変更も考慮する必要があります。
幸いにも、EVMは、各ブロックヘッダーにそのルートを格納する3つの重要なトライ構造を巧妙に利用しています。
トランザクションが与えられた場合、クライアントはトランザクションのトライルートを評価することでブロックへの含まれ具合を証明し(ビットコインのように)、レシートトライを評価することでその結果を確認し、状態トライを評価することでグローバル状態の変更を確認できます。
Solanaの高いスループットの理由の1つは、Ethereumが持っているマルチツリー構造を持っていないという事実です。Solanaのリーダーは、ブロックを作成する際にMerkleツリーを計算しますが、EVM内のそれらとは異なる構造になっています。残念ながら、そこにSVMベースのロールアップの問題があります。
Solanaは、取引をエントリと呼ばれるものにマークライズし、スロットごとに複数のエントリが存在することがあります。したがって、ブロックごとに複数の取引ルートがあります。さらに、Solanaはアカウント状態のMerkleルートをエポックごとに1回だけ(約2.5日ごとに)計算し、このルートは元帳上では利用できません。
実際、SolanaブロックヘッダにはまったくMerkleルートが含まれていません。代わりに、それらには前のものと現在のものが含まれています。ブロックハッシュ, これはSolanaのを通じて計算されますProof of History(PoH)アルゴリズム。 PoHは、バリデータに連続して「tick」を登録することを要求し、ブロックエントリを再帰的にハッシュ化する必要があります。これらのエントリには、空であるか、トランザクションのバッチを含むことができます。 PoHアルゴリズムの最終的なtick(ハッシュ)は、そのブロックのブロックハッシュです。
Proof of Historyの問題は、状態をブロックハッシュから証明することが非常に難しくなるということです。Solanaは、経過時間の概念を維持するためにPoHハッシュをストリーミングするように設計されています。トランザクションルートは、トランザクションを含むPoH tickにのみ利用可能であり、ブロック全体ではなく、いかなるエントリにも状態ルートは格納されていません。
しかし、クライアントが使用できる別のハッシュが存在します: 銀行ハッシュ。スロットハッシュとも呼ばれることがあり、銀行ハッシュは利用可能です SlotHashes sysvarアカウントは、クライアントによってクエリされる可能性があります。銀行ハッシュは、少数の入力から各ブロック(スロット)ごとに作成されます。
誰もが見ることができるように、銀行ハッシュは複数のハッシュ入力でオーバーロードされており、これにより取引や状態に関する情報を証明しようとするクライアントにとって複雑さが増しています。さらに、1つの「エポックアカウントハッシュ」を実行した銀行の銀行ハッシュだけが、その特定のルートが含まれています。さらに、SlotHashesシステム変数アカウントは、最後の512個の銀行ハッシュに切り捨てられます。
SOONネットワークEthereumの上にあるSVM L2です。SOONにmerklizationを統合する際、安定性のために、車輪の再発明よりも確立された解決策を使用することを優先しました。使用するデータ構造やハッシュアルゴリズムを決定する際、それらがL1契約との互換性を考慮しました。Optimism Stack,彼らがSolanaアーキテクチャにシームレスに統合できる能力、および彼らがSolanaのアカウントモデルの下で高いパフォーマンスを達成できるかどうか。
アカウント数が増えるにつれて、Merkle Patricia Trie(MPT)ストレージモデルが基づくLSM-ツリーより多くのディスクの読み書き増幅を引き起こし、パフォーマンスの低下につながる可能性があります。最終的に、私たちは統合することに決めました。Erigon MPT優れたRustの作業をもとに構築することで、rETHチームに加えて、Solanaアカウントモデルへのサポートを追加する。
以前に述べたように、SOONの状態トライはSolanaアカウントをサポートするために構築されたMPTです。そのため、各葉ノードのデータとして機能するSVM互換のアカウントタイプを定義しています。
struct TrieSolanaAccount {
lamports: u64,
データ:Vec
executable: bool,
rent_epoch:u64,
owner: Pubkey,
}
MPTモジュールがSVMアカウントの最新状態をリアルタイムで購読できるようにするために、アカウント通知機能を導入しました。銀行ステージ中、アカウント通知機能はMPTモジュールにアカウントの状態変化を通知し、MPTはこれらの変更をトライ構造に増分的に更新します。
MPTモジュールは、50スロットごとにサブツリーのみを更新し、スロットの終わりに状態ルートを計算しません。このアプローチは2つの理由から採用されています。まず、すべてのスロットで状態ルートを計算するとパフォーマンスに大きな影響を与えます。第二に、状態ルートは、プロポーザが提出するときだけ必要とされます。outputRootしたがって、それは提案者の提出頻度に基づいて定期的に計算する必要があります。
outputRoot = keccak256(version, state_root, withdraw_root, l2_block_hash)
SOON MPTモジュールは、同時に2種類のトライ構造を維持します:グローバル状態のための状態トライと引き出しトランザクションのための引き出しトライ。提案者は、状態ルートと引き出しルートからoutputRootを定期的に生成し、L1に提出します。
現在、SOONは、450スロットごとに状態ルートと引き出しルートを計算し、L2ブロックチェーンに追加します。その結果、ネットワーク内の他のノード間でのMPTデータの整合性を確保できます。ただし、Solanaブロック構造にはブロックヘッダーが含まれていないため、状態ルートを格納する場所がありません。Solanaブロックチェーンの基本構造を詳しく見て、その後、SOONがUniqueEntryを導入して状態ルートを格納する方法を探ってみましょう。
Solanaブロックチェーンは、PoHモジュールによって生成されるスロットで構成されています。スロットには複数のエントリが含まれ、それぞれのエントリにはティックとトランザクションが含まれています。ネットワークおよびストレージレイヤーでは、スロットは次のように保存および送信されます シュレッド最小単位として。シュレッドはエントリに変換および変換できます。
pub struct Entry {
前のエントリIDからのハッシュ数。
pub num_hashes: u64,
/// SHA-256ハッシュnum_hashes
前のエントリーIDの後。
pub hash: ハッシュ,
/// エントリーIDが前に観察されたトランザクションの順不同リスト
///生成されました。 以前のエントリIDの前に観察されている可能性がありますが、
/// このリストに再度追加され、台帳の確定的な解釈を確保します。
pub transactions: Vec
}
PoHによって生成されたブロックチェーン構造に従い、シュレッド構造を維持し、Solanaの既存のストレージ層、ネットワーク層、およびRPCフレームワークを再利用することができました。L2ブロックチェーンに追加データを格納するために、UniqueEntryを導入しました。この特性により、エントリペイロードをカスタマイズし、データの独立した検証ルールを定義することができます。
pub const UNIQUE_ENTRY_NUM_HASHES_FLAG: u64 = 0x8000_0000_0000_0000;
/// ユニークエントリーは特別なエントリータイプです。データを保存する必要があるときに便利です
/// blockstore but do not want to verify it.
///
のレイアウトnum_hashes
is:
/// |…1 ビット…|…63 ビット…|
/// \ _ _/
/// \ \
/// フラグ カスタムフィールド
pub trait UniqueEntry: Sized {
fn encode_to_entries(&self) -> Vec
fn decode_from_entries(
entries: impl IntoIterator<Item = Entry>,
) -> Result
}
pub fn unique_entry(custom_field:u64、ハッシュ:ハッシュ)->エントリ{
エントリー {
num_hashes: num_hashes(custom_field), hash, transactions: vec![],
}
}
pub fn num_hashes(custom_field: u64) -> u64 {
assert!(custom_field < (1 << 63));
UNIQUE_ENTRY_NUM_HASHES_FLAG | custom_field
}
pub fn is_unique(entry: &Entry) -> bool {
entry.num_hashes & UNIQUE_ENTRY_NUM_HASHES_FLAG != 0
}
UniqueEntryでは、num_hashesはビットレイアウトとして使用され、最初のビットフラグはEntryとUnique Entryを区別するために使用され、続く63ビットはペイロードタイプを定義するために使用されます。ハッシュフィールドは、必要なカスタムデータを含むペイロードとして機能します。
3つのユニークなエントリを使用して、スロットハッシュ、ステートルート、および取り消しハッシュを格納する例を見てみましょう。
/// MPTルートユニークエントリ。
pub struct MptRoot {
pub slot: スロット,
pub state_root: B256,
pub withdrawal_root: B256,
}
impl UniqueEntry for MptRoot {
fn encode_to_entries(&self) -> Vec
let slot_entry = unique_entry(0, slot_to_hash(self.slot)); let state_root_entry = unique_entry(1, self.state_root.0.into(); let withdrawal_root_entry = unique_entry(2, self.withdrawal_root.0.into()); vec![slot_entry, state_root_entry, withdrawal_root_entry]
}
FN decode_from_entries(
entries: impl IntoIterator
) -> Result
let mut entries = entries.into_iter(); let entry = entries.next().ok_or(UniqueEntryError::NoMoreEntries)?; let slot = hash_to_slot(entry.hash); let entry = entries.next().ok_or(UniqueEntryError::NoMoreEntries)?; let state_root = B256::from(entry.hash.to_bytes()); let entry = entries.next().ok_or(UniqueEntryError::NoMoreEntries)?; let withdrawal_root = B256::from(entry.hash.to_bytes(); Ok(MptRoot { slot, state_root, withdrawal_root, })
}
}
UniqueEntryはnum_hashesの意味を再定義するため、PoH検証段階で処理できません。したがって、検証プロセスの開始時には、まずユニークなエントリをフィルタリングし、ペイロードタイプに基づいたカスタム検証フローに直します。残りの通常のエントリは、元のPoH検証プロセスを通過します。
ネイティブブリッジは、レイヤー2ソリューションの重要なインフラストラクチャの一部であり、L1とL2の間のメッセージ伝達を担当しています。L1からL2へのメッセージは預入れトランザクションと呼ばれ、一方、L2からL1へのメッセージは引き出しトランザクションと呼ばれています。
預金取引は、通常、派生パイプラインまた、ユーザーは L1 で 1 つのトランザクションを送信するだけで済みます。ただし、引き出しトランザクションはより複雑であり、ユーザーはプロセスを完了するために3つのトランザクションを送信する必要があります。
出金トランザクションの含意証明は、L2での出金が行われたことを保証し、標準的なブリッジのセキュリティを大幅に向上させます。
OPスタックでは、ユーザーの引き出しトランザクションのハッシュが、対応する状態変数に格納されています。OptimismPortal契約。その後、eth_getProof RPCインターフェースを使用して、特定の引き出しトランザクションに対する包含証明をユーザーに提供します。
EVMとは異なり、SVM契約データは勘定科目のデータ項目に保存され、すべてのタイプの口座が同じ階層レベルに存在します。
SOONはネイティブブリッジプログラムを導入しました:Bridge1111111111111111111111111111111111111。ユーザーが引き出しトランザクションを開始するたびに、ブリッジプログラムは各引き出しトランザクションに対してグローバルにユニークなインデックスを生成し、このインデックスをシードとして新しいプログラム派生アカウント(PDA)に対応する引き出しトランザクションを保存します。
pub struct WithdrawalTransaction {
/// 出金カウンター
pub nonce: U256,
/// ユーザーは引き出したい
pub sender: Pubkey,
/// L1のユーザーアドレス
pub target: アドレス,
///ラムポートでの引き出し金額
pub value: U256,
/// L1のガス制限
pub gas_limit: U256,
/// L1での引き出しコールデータ
データを公開します:L1WithdrawalCalldata,
}
PDAのdataフィールドに出金取引を保存するためにWithdrawalTransaction構造を定義しました。
この設計はOPスタックと同様に機能します。出力ルートが引き出しトランザクションをL1に提出されると、ユーザーは引き出しトランザクションの包含証明をL1に提出してチャレンジ期間を開始することができます。
提案者がoutputRootをL1に提出すると、L2の状態が確定したことを意味します。もしチャレンジャーが提案者が間違った状態を提出したことを検知した場合、彼らは橋の資金を保護するためにチャレンジを開始することができます。
障害証明を構築する際の最も重要な側面の1つは、ブロックチェーンが状態S1から状態S2に状態レスに移行することを可能にすることです。これにより、L1の仲裁契約がプログラムの命令を状態レスに再生して仲裁を行うことができます。
ただし、このプロセスの開始時には、チャレンジャーは、状態S1の初期入力がすべて有効であることを証明しなければなりません。これらの初期入力には、参加アカウントの状態(lamports、データ、オーナーなど)が含まれます。EVMとは異なり、SVMは自然にアカウントの状態を計算から分離します。AnzaのSVM APITransactionProcessingCallbackトレイトを通じてアカウントをSVMに渡すことができます。以下に示すように。
pub trait TransactionProcessingCallback {
fn account_matches_owners(&self、account:&Pubkey、owners:&[Pubkey]) -> Option
fn get_account_shared_data(&self、pubkey:&Pubkey) -> Option
fn add_builtin_account(&self、_name:&str、_program_id:&Pubkey) {}
}
したがって、私たちは、挑戦プログラムの入力の妥当性を検証するために、入力アカウントの包含証明とともに状態S1のみを使用する必要があります。
SOONは、SVMエコシステムの開発において重要なマイルストーンをマークしています。メルクライゼーションを統合することで、SOONはSolanaのグローバルステートルートの不足に対処し、故障証明の含有証明、安全な引き出し、およびステートレス実行などの重要な機能を可能にしています。
さらに、SOONのSVM内のメルクル化設計は、Solana自体が現在は軽量クライアントをサポートしていないにもかかわらず、SVMベースのチェーン上で軽量クライアントを可能にすることができます。設計の一部がメインチェーンに軽量クライアントをもたらすのに役立つ可能性さえあります。
状態管理にMerkle Patricia Tries(MPT)を使用することで、SOONはEthereumのインフラと整合し、SVMベースのL2ソリューションを進化させます。この革新により、セキュリティ、拡張性、互換性が向上し、分散型アプリケーションの成長が促進され、SVMエコシステムが強化されます。