Plasma Cashとは、Karl氏やvitalik氏、Dan氏を中心に提案されたイーサリアムのレイヤー2におけるスケーリングソリューションです。従来のPlasmaを改善することでさらなるスケーリング効果が期待できるとされています。
そこで、当記事ではPlasmaとPlasma Cashの基本的な仕組み、Plasma Cashのメリットや課題点について解説していきます。
Plasmaの基本的な内容を前提として解説していくので、以下のPlasma解説記事も併せて参考にしてください。
参考:プラズマがイーサリアムのスケーラビリティ問題を解決する理由と仕組み
Plasmaとは
Plasma Cashの説明の前に、Plasmaの概念について見ていきましょう。
Plasmaとは下図のようにイーサリアムのブロックチェーンをメインチェーンとして階層上にPlasmaチェーンが成り立つ構造となっています。(以下、この構造に基いてPlasmaチェーンは「親チェーン」と「子チェーン」として表現していきます)
(source: Smart Contracts on Plasma)
Plasmaがない通常の場合は、全てのトランザクションの処理をメインチェーンのみで行い、そこにデータを書き込んでいました。Plasmaではそれぞれの子チェーンにおいてトランザクションを送信し、データの書き込みを行います。そして、それぞれの子チェーンのブロックが追加されるごとにトランザクションのマークル木ルートを親チェーンに記録します。
この親チェーンのブロックが承認されて初めて子チェーンに新たに追加されたブロックは承認されることになるのです。
これを上図のように階層上に繰り返すことで、多くの子チェーンで実行されたトランザクションがイーサリアムのメインチェーンにまとめてハッシュ値として記録されるのでかなりのスケーリング効果が期待できるのです。
つまり、プラズマシステムを大規模にすればするのほどプラズマチェーンの数が水平方向にも垂直方向にも増え、それぞれのチェーンで並列的に実行できるトランザクションの数も増加します。(メインチェーンに書き込むデータサイズや書き込む頻度はプラズマシステムをどれだけ大きくしても変わりません。)
要は、Plasmaを実装することでトランザクションの処理に対するメインチェーンの負担を大幅に軽減することができるということです。
攻撃に対するセキュリティ
まずPlasmaの前提として、子チェーンはネットワーク参加者がオンラインで監視され続ける必要があります。例えば下図のようにアリスやボブが一番下層の子チェーンにトークンを保持している場合は、アリスやボブはその子チェーンから遡る全ての親チェーンを監視する必要があります。
(source: Smart Contracts on Plasma)
もしアリスやボブが自分で監視していない場合は、その子チェーンは攻撃者によって不正にトークンを引き出されたりしても、気づくことができません。オンラインで監視していれば攻撃に対して、ネットワークに不正行為が行われたことを証明(Fraud Proofs)することができるので攻撃成功を回避することができます。
また、アリスやボブが自分で監視していなくても他の誰かによって子チェーンが監視されていれば、攻撃されたときに誰かが代わりに不正行為を申告してくれるはずです。しかし、100%のセキュリティを維持するためには自分自身で自分が利用している子チェーンは監視するべきでしょう。
Plasmaにおける具体的な攻撃としては以下のようなことがあげられます。
- ユーザーが実際より多くのトークンを子チェーンから引き出す攻撃
- 子チェーンで任意のトークンを作る攻撃
- ブロック生成者が任意のトランザクションをコントロールする攻撃
実際より多くのトークンを子チェーンから引き出す攻撃
例えば、アリスが子チェーンに5ETHしかデポジットしないはずなのに10ETHを引き出そうとする攻撃です。この場合、子チェーンを監視しているノードによって不正行為が申告され、攻撃は成功しません。本当にアリスが10ETHを子チェーンにデポジットしているのであれば後述するように「その子チェーンに10ETHを保持している」という証明を行えるはずですが、この証明ができないのであれば不正を行なっている、ということで攻撃は失敗します。
また、ユーザーはトークンを子チェーンから引き出すときに保証金(Security Deposit)をデポジットしなければなりません。不正を行なっておらず、無事引き出しが完了した場合はこの保証金はユーザーの元に返金されます。しかし、もし不正を行なっていた場合は、この保証金はユーザーの元には返金されず、その不正行為を申告した申告者に報酬金として渡されます。
つまり、この報酬金が子チェーンを監視し不正行為を申告することのインセンティブになっているのです。
子チェーンで任意のトークンを作る攻撃
ブロック生成者であるチャーリーが不正なブロックを作り、子チェーンで実際には保持していないはずの100,000ETHを不正に作る攻撃です。この場合も、上述したようにその子チェーンを監視しているユーザーによって不正行為が申告されるはずなので攻撃を成功させることはできません。
さらに、プラズマでは親チェーンに対してその子チェーンにデポジットされているトークン量の総量が記録されるデザインになっています。なので、下図のようにメインチェーンにおいてその子チェーンには5ETHしかデポジットされていないのであれば、チャーリーが不正に作った100,000ETHは存在しないはずなのです。
(source: Smart Contracts on Plasma)
このような場合は、不正行為が申告されていなくでも仕様上、攻撃自体をすることができません。
ただ、5ETH以下であればチャーリーはトークンを不正に作成する攻撃ができてしまいます。このケースでは、前述したように不正行為の申告による攻撃からの保護や後述するExitプロセスで親チェーンへ資産の移動が行われます。
任意のトランザクションをコントロールする攻撃
子チェーンのブロック生成者がユーザーのトランザクションをブロックに含めなかったり、トランザクションを書き換えてしまう攻撃です。例えば、ブロック生成者が自身に有利なトランザクションのみをブロックに記録するような攻撃となります。
子チェーンのコンセンサスアルゴリズムでPoAが採用されていた場合、少数の決められた管理者によってブロックの生成が行われます。(ちなみに、子チェーンはファイナリティが必要なので、PoWではなくPoAやPoSが原則前提となっています。)このPoAの場合、不正なブロックが生成されるチャンスは高くなります。
このような攻撃が行われた場合、その子チェーンに参加するユーザーは攻撃が実現する以前のスナップショットを元に自身の資金を親チェーンに戻すことができます。Plasma Cashにおける資金を引き出す具体的なプロセスは後述します。
Plasma Cashとは
以上のような仕組みで成り立っているPlasmaにもいくつかの解決しなければ大きな課題があります。そのうちのひとつに、ユーザーが子チェーンのデータを全てダウンロードしなければならない、ということがあげられます。これは、ユーザーの二重支払いやブロック生成者の不正なブロック生成などの攻撃を防ぐためです。
例えば、ユーザーが送金をするときにはある特定の子チェーンの特定のブロック高において送金額以上の残高を保持し、かつそのUTXOが複数の受け手に対して送信されていないことを証明する必要があります。(子チェーンはイーサリアムブロックチェーンのようなアカウントベースではなく、ビットコインのようなUTXOベースです。参考:ビットコインのトランザクションにおける「UTXO」を分かりやすく解説)
Plasmaのデザインにおいてこの証明を行うためには、そのトークンの履歴(子チェーンにデポジットされてから、誰から誰に送られてきたか)を参照するために子チェーンのデータを全てダウンロードし、二重支払いを行なっていない証明をする必要があるのです。
これではそれぞれのユーザーが大きなサイズのデータをダウンロードする必要があり、子チェーンが大きくなるほどさらに不便になっていきます。
一方、Plasma Cashでは子チェーンのデータを全てダウンロードする必要はありません。Plasma CashではPlasmaと比べて、はるかに小さなデータサイズで有効性の証明ができるようになるのです。
これは、プラズマチェーンにデポジットするそれぞれのトークンに対して、特有のTokenIDを与えることにより実現されています。アリスがデポジットした3ETHやボブの5ETHはそれぞれ固有のTokenIDが付与されることになります。つまり、プラズマチェーンにデポジットされるトークンはNon-Fungibleになるのです。アリスの3ETHはTokenIDが1であり、ボブの5ETHはTokenIDが2になり、それらはTokenIDで区別されうるのです。
このようにデポジットされたトークンに対して、固有のTokenIDを与えることで子チェーンでのトランザクションを保持するデータ構造を変更することできます。
従来のプラズマでは、プラズマチェーンにはトランザクションのインデックス順にトランザクションをマークル木構造で整理していていました。一方、Plasma Cashではデポジット時に付与したTokenID順にトランザクションをマークル木(あるいはマークル・パトリシア木)で整理しているのです。(ここでいうトランザクションとは通常のイーサリアムトランザクションデータとは異なり、Plasma固有のUTXOに基づいたトランザクションデータであることに注意してください)
これにより、ユーザーは自身のTokenIDとマークル木のインデックス番号を照合するだけで、そのトークンは有効であることが証明できるのです。
例えば、TokenIDが5のトークンが消費された場合、以下のようなマークル木構造において5番目の位置にトランザクションが存在することになります。(消費されていない場合はトランザクションは存在しません)
アリスが子チェーンにデポジットしているTokenIDが1の5ETHを送金する例を考えてみましょう。このTokenIDが1のトークンはその子チェーンで複数回送金されてアリスの元に渡っています。
上述したように、従来のPlasmaではトランザクションを送信するときこの子チェーンを全てダウンロードする必要がありました。Plasma Cashでは、TokenIDが1のマークル・ブランチの履歴を送り手が提示するだけでOKです。他の関係のないTokenIDに関するデータは一切必要ありません。
無事トランザクションの処理が完了すると、そのマークル木のTokenIDの位置にはそのトランザクションが保持されます。つまり、二重支払いをしていない証明をするためにはそのTokenIDの位置が空データであればいいことになります。
また、このようなPlasma Cashのデザインでも子チェーンが伸びてくると証明のためのデータもどんどん大きくなっていきます。長期間運用された子チェーンにおける証明のためのデータが大きくなりすぎないように、1年ごとにスナップショットを取りこのデータサイズを0に戻されます。つまり、1年ごとにトークンは引き出され即時に再びデポジットされることになります。
実際のPlasma CashのユーティリティとしてはDEXのようなハイスループットが求められる環境で非常に有効です。従来のプラズマであれば、DEXを利用するそれぞれのユーザーがプラズマチェーンをダウンロードする必要があったのに対し、Plasma Cashではユーザーは自身のTokenIDの位置にあるマークル・ブランチだけが必要になります。
Plasma Cashのメリット
ここまで解説したきた通り、Plasma Cashではデポジットしたトークンに固有のTokenIDを与えることがPlasmaとの変更点になります。この変更により、Plasmaと比べてPlasma Cashではどのようなメリットが得られるのか見ていきましょう。
検証データの最小化
上述ように、Plasma Cashの最大のメリットはユーザーが保持する子チェーンに関するデータを大幅に削減できることです。ひとりひとりのユーザーが自身が関わっている全ての子チェーンのデータをダウンロードすることは、実際のアプリケーションでは現実的ではありません。Plasma Cashではこの部分が大きく改善されていることになります。
残高更新のための確認が不要に
Plasmaにおいては子チェーンのセキュリティを保つために以下の2段階の確認作業が必要となります。
子チェーンでトランザクションを送信する場合は、その子チェーンでのブロック生成者によってトランザクションのマークル木ルートが親チェーンへトランザクションとして送られます。この確認トランザクションが親チェーンのブロックに取り込まれて初めてプラズマチェーンにおいてそのトランザクションは承認されることになります。
さらに従来のプラズマでは、上記のトランザクションが承認された後、両者の残高を更新するためにトランザクションの送り手は受け手に対して確認メッセージを送る必要があります。
つまり、送り手は親チェーンを監視して、トランザクションが取り込まれたら相手に確認メッセージを送るという確認作業が必要であったのです。例えば、プラズマチェーンにおいてアリスがボブに5ETHを送金する場合はアリスはボブに対して確認メッセージを送らなければならなかったのです。
ボブがアリスからの確認メッセージを受け取って初めて両者のETH残高は更新され、ボブは受け取ったETHを使うことができるようになります。
Plasma Cashではこの残高更新のための確認作業は必要なくなります。なぜなら、デポジットされたときに与えられた固有のTokenIDがなければトークンを引き出すことはできないという制限が存在するからです。これにより、ブロック生成者が任意のトークンを不正に作成することができなくなるのでPlasma Cashにおいては確認作業は必要なくなります。
ここまでが、Plasma Cashの基本的な仕組みとメリットになります。
これらを踏まえて実際に、親チェーンから子チェーンにデポジットする行為、子チェーンでトークンを送金する行為、そして子チェーンから親チェーンにトークンを戻す行為をどのように行なっていくのか見ていきましょう。
Plasma Cashの具体的なプロセス
プラズマチェーンへのデポジット
Plasma Cashにおいて自身が持っているトークンを子チェーンにデポジットするのは、従来のプラズマとほとんど変わりません。親チェーン(メインチェーン)のプラズマコントラクトを実行することで、誰でも子チェーンにデポジットすることができます。
従来のプラズマと違う点は、このときデポジットしたトークンに対して特定のTokenIDが与えられることです。なので、複数のトークンに分割したり、他のトークンと結合させたりすることはできません。
また、デポジットするトークン量が少なすぎるとコントラクトを実行するgasの方が大きくなってしまうのである程度のトークン量は最低限必要になります。
送金
上述したように、子チェーンのトランザクションはTokenID順にマークル木形式で整理されており、そのマークル木ルートはメインチェーンに記録されています。そして、ユーザーは保持しているTokenIDのマークル・ブランチのみを追っていることになります。
なのでPlasma Cashにおいて送金をするときは、受け手はそのTokenIDの情報を一切保持していないことになるので、そのトークンの履歴(以前にどのアドレスからどのアドレスに対して送られてきたか)を相手に提示する必要があります。このトークン履歴はブロックチェーン外のオフラインな方法(例えばWhisperなど)で送信されます。
受け手はこのトークン履歴をチェックすることで何か不正がないか確かめることができるのです。
具体的には、トークンが送金されていない場合、プラズマチェーンのマークル木においてそのTokenIDの位置が存在し、かつ空データであるか、ということをチェックします。(Proof of NonExistence)
これは、子チェーンで二重支払いを防ぐことにとても役立ちます。なぜなら、もし二重支払いをしようとしている場合は、マークル木のそのTokenIDの位置に以前のトランザクションが存在してしまうからです。また、このような設計上、同じブロックにおいて同じTokenIDを持つトークンを2回以上送金することはできないということになります。
親チェーンへ戻す(exit)
トークンをメインチェーンに戻すときは、不正の多くのETHを引き出すことを防ぐために少額の保証金(Security deposit)が必要になります。全てのノードは、あるユーザーの引き出しを監視し、不正を行なっていると判断した場合はネットワークに対して不正申告を行うことができるのです。
例えば、アリスはプラズマチェーンに2ETHしかデポジットしていないのに、5ETHをメインチェーンに戻そうとしたときは、他のユーザーがこの不正を申告し、もし本当に不正が行われていた場合はアリスの保証金を手に入れることができます。
また、トークンを親チェーンに戻すときは、そのトークンの過去2つのトランザクションに対するマークル木証明を提示する必要があります。
なぜ「2つ」なのかというと、例えばユーザーがあるブロックでトランザクションを送信した直後に、ブロック生成者が不正なデータを含めてトークンを引き出してしまうという攻撃が考えられれます。そして、このような攻撃の場合、不正なデータは直近2つのトランザクションの間に含まれるので、ユーザーが子チェーンからトークンを引き出すときは直近2つのトランザクションを提示する必要があるのです。
このトークンを親チェーンに引き出す行為に対する不正行為の申告は以下の3つのタイプがあります。
- 提示された2つのトランザクションのうち一番最近のトランザクションに対する申告
- 提示された2つのトランザクションのうち2番目に新しいトランザクションに対する申告
- 提示された2つのトランザクションよりも過去のトランザクションに対する申告
いずれのタイプも提示されたトランザクションに対応する申告者が保持しているトランザクションを提示することで申告が行われます。つまり、引き出すユーザーのトランザクションと申告者のトランザクションが一致しているのか確認するのです。
タイプ1,2の場合を考えていきましょう。もしブロック生成者が上述したようにユーザーがトランザクションを送信した直後に、不正なexitをした場合、ブロック生成者はexit時のブロック高以降のデータを保持していないことになるので、正当な証明をすることはできません。
タイプ3の場合は、トークン履歴の不正に対する申告になります。申告者はそのTokenIDにおける二重支払いで被害を被ったユーザーであり、そのトークン履歴を保持しているはずなので正しいトランザクションを用いて申告することができます。
逆に、自分自身の関係のないTokenIDの不正行為には関与する必要はありません。
また、ブロック生成者がブロックをブロードキャストせず、ユーザーにトークンの履歴自体を与えないような不正に対しても、Plasma Cashの設計であれば申告を成功させることができます。
Plasma Cashの課題
以上のように、Plasmaのメカニズムにおいてデポジットされたトークンに固有のIDを割り当てることでUX的にかなり改善がされました。しかし、Plasma Cashにおいてもいくつかのデメリットや課題点があり、それらを解決策については現在議論が進められています。
トークンの一部送金
ここまで説明してきたように、Plasma Cashにおいてはデポジットしたトークンに対して固有のTokenIDが割り当てられ、それらは分割したり結合したりすることはできません。つまり、5ETHをデポジットしたときはその「5ETH」をひとつのコインと見なして、2ETHと3ETHに分割したり、他のトークンと合わせて10ETHにしたりすることはできないのです。
これは、デポジットした5ETHのうち3ETHのみを送金したい、といったときに不都合になります。このようなトークンの一部送金の実現方法については現在議論されている段階で以下のような解決策が提案されています。
- 新しいTokenIDをつける
- 欲しい量のトークンを保持している第三者を介して送金を行う
- TokenIDをdecimalに対応
- 確率的ペイメント
- 結合と分割のための新しいトランザクション処理
新しいTokenIDをつける
ユーザーが結合や分割をするときに特定のTokenIDを新しいTokenIDに書き換える”merge/split”トランザクションを定義する方法です。新しいTokenIDに変換されてもトークン量自体は同じであるようにします。
ただ、この方法はPlasma MVPのexitトランザクションと同程度のChallenge期間が必要になります。また、このChallengeはPlasma Cashのexitプロセスと同じ状況として扱うことが可能です。
欲しい量のトークンを保持している第三者を介して送金を行う
例えば、アリスがボブに3ETHを送りたいのに5ETHのコインと少額の0.001ETHのコインしか持っていない場合を考えます。このとき、アリスとボブの間に3ETHと2ETHのコインを持っているチャーリーを介することで実質的にトークンの一部送金が可能になります。具体的な流れを見ていきましょう。
- アリスはチャーリーに5ETHを送る
- チャーリーはボブに3ETHを送る
- チャーリーはアリスに2ETHを送る
- アリスはチャーリーに手数料のための少額な0.001ETHを送る
しかし、このような方法だと特定のコインを持っているユーザーを上手くマッチングすることができるのか、さらにそれぞれの手順で上述したexit時のchallenge期間が必要になるのでかなりの時間がかかってしまう、といった問題があります。
TokenIDをdecimalに対応
分割時にTokenIDをdecimal型に対応させることでそのコインを小さくバラバラできるようにする方法です。
この方法の問題点としては、コインを小さくしすぎると引き出し時のgasと比較してそのコインの価値がほとんどなくなってしまうことがあげられます。
確率的ペイメント(probabilistic payments)
確率的ペイメントとは、例えばアリスが10ETHのコインしか持っていないときボブに5ETHのコインを送金したい場合、50%の確率で10ETHを送金することで実質的に5ETHのコインを送金していると考える方法です。
この方法の問題点は、送金額が確率によって左右されてしまうということです。なので多額の送金には適していません。マイクロペイメントで役に立つ方法であるとされています。
結合と分割のための新しいトランザクション処理
以上のようなさまざまな解決策が提案されていますが理想的には、分割したトークンを子チェーンで送金し、それらの分割されたトークンをひとつにまとめて引き出せるようなトランザクションを定義することです。
しかし、このトランザクションを実現するために有効な解決策は現段階ではまだ考えれらていません。
敵対的Mass Exit問題
敵対的Mass Exit問題とは、攻撃者が子チェーンから親チェーンにトークンを引き出すリクエストを大量に送る攻撃です。引き出しリクエストは順番に処理されていきますので、攻撃者がこのリクエストを大量に送信してしまうと通常のユーザーはなかなかトークンを引き出すことができなくなってしまいます。
そのため、PlasmaやPlasma Cashでは上述したように引き出しの際は保証金もつけることでこの問題を回避しようとしています。不正行為を見つけることができた場合はこの保証金が申告者に報酬金として与えられるのです。このようなインセンティブ設計にすることでMass Exit攻撃を防ごうとしているのです。
しかし、Mass Exit問題は実際はもっと複雑な問題です。例えば、攻撃者が引き出しリクエストを大量に送り、トランザクションを詰まらせ、gasを上昇させます。すると、申告者が申告を行うときに送信するトランザクションで消費されるgasが、申告が成功したときに得られる報酬金と比べて大差がなくなってしまったり、より大きくなってしまうことも考えられます。
こうなると、申告者が不正行為を申告するインセンティブ設計が崩れてしまうのです。つまり、そのPlasmaチェーンが妨害されてしまうことになります。
トークン履歴のデータサイズ削減
Plasma Cashによってnon-existence proofs(TokenIDのポジションにあるマークル・ブランチの履歴)のためのデータサイズは大幅に削減されました。このデータサイズをBloom filterやzk-SNARKsの技術を用いることでさらに削減しようとする提案もされています。
Bloom filterとは、実際にイーサリアムブロックチェーンでログ情報を記録するときにも用いられている技術で、確率的な探索フィルタで欲しいパターンを正確に特定しなくてもパターンを記述できる方法となります。
zk-SNARKsとは、秘匿化技術の一種です。以下の記事で詳しく解説しています。
参考:イーサリアムに導入されたプライバシー保護技術「zk-SNARK」とは
Exitプロセスの最適化
上述したようにトークンを子チェーンから引き出すExitプロセスは、セキュリティを維持するために複雑な仕組みとなっています。さらに、他の巧妙な攻撃に対するセキュリティ効果やユーザーがより素早くExitできるようなプロセスに改善できるように、さまざまな議論がされています。
例えば、理論的には不正なトランザクションの履歴があったとしてもExitプロセスは進めて問題ありません。なぜなら、ユーザーはそれぞれのトークン履歴をチェックするので、その不正なトランザクションに対しては無視すればいいだけだからです。
しかし、巧妙な攻撃に備えてトークン履歴においてトランザクションが有効であるだけでなく、不正なトランザクションがない、ということも証明しなければならない必要性が想定されています。この部分はさらに最適化できることが考えられているのです。