GMOインターネットTopへTOP研究開発トピックスブログ成長とキャリアプラン参加プロジェクト採用情報2020.01.09Plasmaフレームワークのアーキテクチャの紹介TweetPocketこんにちは。次世代システム研究室のL.W.です。Plasmaフレームワークというと、システムとしてどのような仕組みだかっていう疑問を持つ方がいるかと思います。今回はオーバービューで、plasma-rust-frameworkのOSSをベースに、Plasmaの仕組みを覗いていきましょう。Plasmaフレームワークは、少なくとも三つのコンポーネントが必要です。クライアント(Client)エンドユーザ、オペレーター、イーサリアムのスマートコントラクトと対話(インターアクション)する機能を持つコンポーネントです。ウォレット管理、トランザクション管理、ステート管理、スマートコントラクトとのやり取り(deposit、Exit、Challengeなど)、自分と関わるデータのローカル保持などを行います。オペレーター(Operator)クライアント、イーサリアムのスマートコントラクトと対話(インターアクション)する機能を持つコンポーネントです。TreeのRootをイーサリアムに提出します。全てのデータをローカルに保持し、フルノードの存在となります。Contract)レイヤ1でデプロイされます。disputeロジック実現できたので、レイヤ1と同様のセキュルティーが裏付けます。クライアント(Plasma-Client)全体的な構図は以下のようとなります。RPCサービスを提供します。これらのリクエストを満たすためには、他のさまざまなRPCメソッドを呼び出します。ウォレットアカウントの作成、トークンの残高の表示、支払履歴の表示、送金、スワップのトランザクションの作成などのエンドユーザーからのリクエストは想定されます。RpcClientRpcClientは、他のクライアントおよびオペレーターとのインターアクションを行います。Treeの存在証明などを求めたりなどを行います。Channelクライアントの場合、他のクライアント同士とのメッセージ交換などを行います。Rollupなど)を抽象化し、同じ枠組みで扱えるものとなります。Runtime(L2)を分けられています。Runtimeのインターアクションにより、イーサリアム並みのセキュルティー性は裏付けられます。Runtimeで送信されたクレームをローカル情報(各種DB情報)によってtrueまたはfalseに評価することもできます。簡単にまとめると、このRuntimeで、さまざまな機能をサポートし、ステート、トランザクション、サイン、存在証明の履歴などの情報の保存と更新などを行います。OVMはあくまでバーチャルマシンであり、バーチャルマシンの役目はインストラクションを実行することです。そのためには、OVMはインストラクションのベースインターフェイスを定義する必要があります。OVMはレイヤ2からのクレームとそのクレームの紛争に完全に基づいているため、そのインストラクションはすべて「入力NがルールセットSに従って有効かどうかを判断する」という形式に従う必要があります。RuntimeにはOVMならではのプロパティ(Property)、ステート(StateUpdate)、トランザクション(Transaction)の概念が定められています。L1のスマートコントラクトのアドレス。対応するコントラクトはインプットを真/偽か判定できます。レイヤ2のローカル情報であり、判定される対象となります。メタデータ(トランザクションの性質を定義する)}StateUpdateとTransactionの関係ownershipの場合を例として挙げます。EventWatcherEventWatcherは、Ethereumのさまざまな重要なイベントを監視します。他のコンポーネントは、EventWatcherに特定のイベントを監視するようにリクエストでき、イベントが発生するたびに通知されます。イベントを見逃したり、同じイベントをコンポーネントに複数回通知したりしないように設計されています。クライアントには、オペレーターのブロック提出したイベント(BlockSubmitted)、他のクライアントのExitのリクエストしたイベント(ExitStarted)などを監視しないといけないです。オペレーターには、クライアントのExitのリクエストしたイベント(ExitStarted)、入金デポジットしたイベント(Deposited)などを監視しないといけないです。ContractWrapperContractWrapperは、イーサリアムのスマートコントラクトの単純なラッパーです。各コンポーネントはイーサリアムとのインターアクションはContractWrapper経由となります。Rustフレームワークでは、LevelDBは使われています。LevelDBはkey-value型のデータストアの一つです。イーサリアムもこれを利用します。イメージとして、以下のようになります。データシリアライズするために、RLPエンコーディングを採用しました。Treeの存在証明のCRUDは頻繁に行われるなので、設計では工夫されました。StateDBステート(ブロック番号、トークンアドレス、プロパティ)に関する情報を保存します。Property,}上の「StateUpdateとTransactionの関係」の例では、StateDBの変化は以下のようとなります。TransactionDBトランザクション(トークンアドレス、レンジ、パラメータ、サイン、メタデータ)に関する情報を保存します。Metadata,}上の「StateUpdateとTransactionの関係」の例では、TransactionDBの変化は以下のようとなります。Treeを採用しました。ステート)を保存します。StateUpdate,}上の「StateUpdateとTransactionの関係」の例では、Range(0,5)のステートをUTXOとしてDBに更新する。SignedByDB署名されたメッセージ情報(パブリックキー、メッセージ、署名)を保存します。Bytes,}トランザクション毎にSignedByDBを追加します。WalletManagerエンドユーザー向けに、ウォレットを管理するコンポーネントです。Keyのインポートなどを行います。Keyのペアを保存します。KeyEventDBイーサリアム発火したイベントと関する情報を保存します。オペレーター(Plasma-Operator)全体的な構図は以下のようとなります。RpcServerクライアントのリクエストに応じて、レスポンスを送ります。誠実なオペレーターの場合、正しいトランザクション、ステートの含めたブロックコンテンツを送付します。Tree存在証明を送ったり、クライアントからのトランザクションをブロードキャストしたりすることもあります。Treeを構築したりします。TreeのRootを提出します。ContractにRootはきちんと登録されたら、BlockManagerはブロックコンテンツをDBに永久に保存します。BlockDBブロックに関する情報を保存します。Tree}送金のシナリオAliceはBobに5ETHを送金することとします。クライアントのAliceサイド1.Aliceは送金アカウントを作ります。WalletManagerとWalletDBモジュールが使われます。RuntimeモジュールからStateDBで5ETHあるいは5ETH以上の持つState(UTXO)を検索します。検索結果がない場合、送金不能となります。検索結果が出たら、このStateをUTXOとしてトランザクションを新規に作成します。Keyでトランザクションを署名し、RpcClientモジュールを通して、オペレーターに送ります。オペレーターサイド1.トランザクションのチェック処理、保持処理を行います。このトランザクションはオーナー本人からの署名だか、二重払いないかをチェックを行います。RuntimeモジュールよりStateDB、TransactionDB、SignedByDBを更新します。不正が発見できれば、廃棄します。同時ににこのトランザクションとこのトランザクションの含めたのステートをBlockManagerモジュールによりBlockDBで一時的に保持されます。2.トランザクションのブロードキャストを行います。受け取る側のBobを受信できるように、このトランザクションをブロードキャストを行います。Treeを構築します。Contractに提出します。BlockDBで一時的に保持されたトランザクションとステートをクリアします。クライアントのBobサイド1.イベントが監視されて、オペレーターにブロックコンテンツをリクエストします。EventWatcherモジュールにより、BlockSubmittedというイベントを監視できたら、RpcClientモジュールよりブロックコンテンツをリクエストします。2.トランザクションのチェック処理を行います。トランザクションの正しさとトランザクションの含めたステートの履歴をチェック処理を行います。)、取引は失敗となります。3.ローカルDBのアップデートを行いますライトクライアントの場合、自分と関わるトランザクション、存在証明情報だけをローカルに保持します。ライトクライアントではない場合、全てのトランザクション、存在証明情報をローカルに保持します。Rustはこのケースに該当します。)StateDB、TransactionDB、RangeAtBlockDB、SignedByDBをアップデートをします。4.取引は成立となります。ファイナリティとみなされる場合、取引は成立となります。いう案でファイナリティを短縮できる研究は進んでいます。Smart-Contract)レイヤ1が得意なことだけにレイヤ1を活用し、スマートコントラクトは明確に定義されたルールセットに基づいて、不変で全会一致のコンセンサスを達成することです。Contractではレイヤ2のクレームの裁定に使用する明確なルールセットが定義されています。裁判官のように、ルールが常に守られていることを保証するためにすべてを積極的に監督することより、ルールが守られていないという主張(クレーム)を遡及的に処理するために使用する方がはるかに効率的です。全体的な構図は以下のようとなります。ソースはまだ未完成かと思いますが、こちらも解読中です。ロジックは複雑ですが、セキュリティー問題が伴っているかと思います。監査(Audit)はどのようにしますか、興味深いですね。今回はスマートコントラクトの詳しい解説を割愛させて頂きます。TreeのRootをスマートコントラクトのストレージに保持します。同時にPlasmaチェーンのブロック番号を割振りします。イーサリアムのブロックに無事に含めば、BlockSubmittedのようなイベントを発火します。depositETHあるいはERC-20を入金します。入金金額により、Rangeを割振りします。源のステートを生成します。CheckpointFinalizedのようなイベントを発火します。finalizeExitExitのプロパティのクレームのステータスはTrueと判定できれば、イーサリアムのアカウントに出金します。ExitFinalizedのようなイベントを発火します。finalizeCheckpointCheckpointのプロパティのクレームのステータスはTrueと判定できれば、あるRangeの履歴を確定します。CheckpointFinalizedのようなイベントを発火します。challenge不正クレームにチャレンジします。claimPropertyあるプロパティ(例えば、Exit)をクレームします。スマートコントラクトのストレージでこのクレームのステータスがUndecided、True、False三つがありますが、この場合、ステータスをUndecidedに初期化されます。decideClaimToTrue/decideClaimToFalseスマートコントラクトのストレージでこのクレームのステータスをTrue、Falseに設定します。decideTrue/decideFalseローカル情報をインプットとして、Predicateに送ります。Predicateは関係するプロパティはTrueかFalseか判定できます。判定結果により、UniversalAdjudicationContractコントラクトのsetPredicateDecision方法を呼び出す。setPredicateDecisionスマートコントラクトのストレージでこのクレームのステータスをTrueかFalseかに設定します。isValidChallengeチャレンジしようとするプロパティはルールに従うかチェックを行います。Treeに含められるか検証します。ローカル保持した存在証明でTreeを再構築し、TreeのRootはストレージで保持されたRootと一致かチェックを行います。Rustはまだ開発中に見えますが、Todoもまだ沢山が残っています。読めない部分もあれば、こちらの理解間違い部分もありますが、皆さんのこのOSSへの理解に一助となれば幸いと思います。contractの進展を見守って行き、心得ができれば、また共有します。さいごに次世代システム研究室では、グループ全体のインテグレーションを支援してくれるアーキテクトを募集しています。インフラ設計、構築経験者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ募集職種一覧からご応募をお願いします。皆さんのご応募をお待ちしています。