ブロックチェーン間でじゃんけんをしよう!

さっそくですが

ブロックチェーン間でじゃんけんゲームをしてみませんか? ルールは簡単で、N個のチェーンにじゃんけんのコントラクトを実装し、お互いに通信しながらじゃんけんを実施し、最後に結果を取得します。なんだか、とっても簡単な話に聞こえますよね?

それではやってみましょう!

目的

本記事では、ブロックチェーン間でじゃんけんをすることを通して、クロスチェーンメッセージを使ったアプリケーションの開発体験を垣間見ることを目的としています。といっても、プログラミングや開発を主軸とした話ではないので、身構える必要はありませんよー

舞台設定

舞台は次のように設定します。

  • 開発者はN個のチェーンにコントラクトを実装し、「ある時間になったら」じゃんけんゲームを始めるように定義します。一人の開発者が勝手にコントラクトを整備して、勝手にじゃんけんさせるという異様な光景を想定してください。

  • 簡単のためにセッションIDは考えません。要は、じゃんけんは一回限りで、あいこになっても再戦しません。一回じゃんけんしたら、二度とじゃんけんをしません。

  • ブロックチェーン間のコミュニケーション手段として、汎用クロスチェーンメッセージングプロトコル(以下CCMPとします)を使用します。具体例をあげるなら、LayerZeroなんかが有名でしょうか。

そして、コントラクトは次のような動きをします。

  • 時間が来たら、まず自分の手を考えます。簡単のために、コントラクトは手を出すためにランダムな値(注)を生成し、3で割った余りで自分の手を考えます。例えば、1余ったらグー、2余ったらチョキ、割り切れたらパーといった感じです。

  • そしたら、コントラクトはCCMPを使って対戦相手のチェーンに自分の手を知らせます。

  • それと同時に、コントラクトは対戦相手のチェーンから手の情報を受け取ります。「出た手の組み合わせによって勝敗状況はどうなるのか」ということはじゃんけんのルールから自明なので、全員の手がわかったら勝敗がわかります。繰り返しますが、あいこになっても再戦しません。

  • 一人の開発者がコントラクトを実装するので、自分の手を秘匿化する必要はありません。つまり、後出しじゃんけんされるリスクは考えません。

条件が出そろいました! メッセージのやり取りについて、もうちょっと深く考えてみましょう。

注: ブロックチェーンは基本的にランダムな値の生成に対応してないのですが、ここは簡単のために…

メッセージの伝達回数

CCMPの機能

ここで使用するCCMPは、次のような機能を有するとします。

  • あらゆるチェーンに対応している。

  • メッセージングは二者間のチェーンで行われる。それは双方向ではなく、手紙のように一方的なやり取りである。

  • 宛先がメッセージを受け取れなかった場合、送信者に未到達エラーを通知する機能がある。

  • メッセージを送信するごとにガス代がかかる。

伝達回数を見積もる

すべてのチェーンが互いに対等な立場だとします。

つまり、ゲームを取り仕切るゲームマスターのような存在は考えないものとします。ある特定のチェーンに注目したとき、そのチェーンは何回メッセージを送ることになるのでしょうか。

じゃんけんのためのメッセージの伝達回数.
じゃんけんのためのメッセージの伝達回数.

このように、自分以外のチェーンにメッセージを送るので、そのチェーンはN-1回メッセージを送ることになります。このようなチェーンは合計N個存在するので、このゲームにおけるメッセージの伝達回数はN(N-1)回です。Nの2乗の項が出てきてしまったので、チェーンが増えれば増えるほど、ガス代が跳ね上がることが予想されます。

これを解決するには、ゲームマスターを設定します。つまり、対戦者はゲームマスターのチェーンに自分の手を提出し、ゲームマスターからはじき出される結果を受け取るという算段です。これにより、メッセージの伝達回数はNの2乗から線形に削減されます。

ゲームマスターを設定すると、メッセージの伝達回数は高々Nの整数倍となる.
ゲームマスターを設定すると、メッセージの伝達回数は高々Nの整数倍となる.

じゃんけんの途中で離席してしまう場合

離席とは

ここで、じゃんけんの途中で離席してしまう困ったチェーンがいることを考えましょう。具体的には、じゃんけんをしている途中で、ネットワークがダウンしてしまうような状況です。そのような場合でも、じゃんけんは成立するのでしょうか。

離席の影響を考える

すべてのチェーンが互いに対等な立場だとします。(ゲームマスターの存在はいったん忘れてください!)

この場合、どういった状況になると困るのかを考えたいのですが、その前にこの一文を思い出しましょう。

  • 宛先がメッセージを受け取れなかった場合、送信者に未到達エラーを通知する機能がある。(CCMPの機能の節より)

よって、メッセージが到達しなかった場合は、宛先のチェーンが離席したと考えることができるので、送信元のチェーンは離席したチェーン抜きでゲームを続行できます。離席したチェーンの存在がわかったらみんなに通知できればなおよいですね。(その分ガス代がかかりますが)

しかしながら、そもそもメッセージを送信しなかったチェーンを、ほかのチェーンはどのように離席状態であると判断するのでしょうか。これには、「ある時間経過してもメッセージを送ってこないチェーンは、離席したものと考える」という処理を実装する必要があります。そうしないと、一向に離席判定を下すことができません。

と、ここである懸念が浮かんでくる方がいるのではないでしょうか。例えば、自分の手を対戦相手に続けて送信している途中で離席(障害)が発生してしまった場合です。チェーンA~Eの5人がじゃんけんをする途中で、Aが離席してしまう場合を考えてみましょう。そうすると、次のような困ったことが起こる可能性があります。

チェーンAが一部に自分の手の情報を送って離席してしまうと、混乱が生じる.
チェーンAが一部に自分の手の情報を送って離席してしまうと、混乱が生じる.

この図は、「チェーンAが対戦相手の手の情報を知ってから、自分の手の情報を送り始める」という状況を考えています。このとき、導びかれるゲームの結果がチェーンによって異なってしまいます。とてもじゃんけんゲームが成立しているとはいいがたい状況です。こうならないようにするためには、ゲームの結果が一致しているかどうかを、すべてのチェーン間で合意を取ることで解消できますが、そうしたらまた余計なガス代がかかってしまいます。また、もし結果が一致してなかったとしたら、ゲームを無効にして切り戻すのか、多数決をとって強引に結果を決めるのか、開発者はあらかじめ決めておかなければなりません。

以上のように、障害のようなイレギュラーな状態を考慮すると、クロスチェーンのやり取りに原子性(やり取りが完結するか、問題等が起きたら元の状態に戻るかの二択しかない性質)をもたせつつ、アプリケーションとして表現するのは大変そうであることが伺えます。

将来の拡張性

あなたはさらに開発を進め、セッションIDを導入し、じゃんけんの再戦機能を作ることができました。もし今後魅力的なチェーンが出てきて、そのチェーンにもじゃんけんに参加できるようにしたくなった場合、何をする必要があるでしょうか。

答えは、「既にある全てのチェーンのコントラクトに手を加える必要がある」です。既存のコントラクトには、新しく追加されたチェーンとやり取りする機能を追加しなければなりません。大変ですね。

まとめ

以上のように、クロスチェーンメッセージングを用いたアプリケーションは、機能を豪華にすればするほど、より多くのチェーンに対応すればするほど、必要なメッセージの数が爆発的に増えてしまうという欠点があります。なぜなら、チェーン間で状態の同期をとらなければならないからです。また、将来の拡張性に目を向けた際、必要な工数も膨れ上がる傾向にあります。

例えば、チェーンAにあるトークンと、チェーンBにあるトークンと、チェーンCにあるトークンを担保に、チェーンDでお金を借りるにはどうしたらよいのでしょうか? オラクルに基づき、各チェーンに担保として預けた資産の価値を確認し、お金を借りる(ことを許可する)機能を作るのは大変であることが予想されます。(それ以外にも、レンディングプロトコルには様々な機能がありますよね)

そのため、クロスチェーンメッセージングを用いたアプリケーションは、以下のようなものに限られるのが現状です。

  • 2つ(や小数)のチェーンが相互作用するようなアプリケーション(ブリッジとか)

  • 1つのチェーンがほぼすべての状態を管理するようなアプリケーション(この記事だと、ゲームマスターがいるじゃんけんゲームのような)

このように、クロスチェーンメッセージングは魅力あるソリューションなのですが、開発者の負担が大きいってことを下記ツイートよりも上手に伝えたかったのであります!

ちなみに、ぼくがアンバサダーをやってるZetaChainのオムニチェーンスマートコントラクトという機能では、このような問題を解決できるとされているみたいですよ?

参考文献

なし

Subscribe to hashigo
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.