一般的に、ゲームはループベースのシステムに基づいています。ゲームループは、ユーザーの入力の処理、ゲームの状態の更新、ゲームワールドのレンダリングなどのステップを繰り返し行うプロセスです。このループはゲームの実行中に継続的に行われ、通常は 1 秒間に数十回から数百回実行され、ゲームワールドの滑らかさを保つために必要です。
しかし、ブロックチェーンのアーキテクチャはプッシュベースです。ブロックチェーンは分散型のデータベースであり、ネットワーク上のノードが情報を共有・保存します。ノードが新しいトランザクション(送金、契約呼び出しなど)を生成すると、そのトランザクションはネットワークにプッシュされ、他のノードはそのトランザクションを受け取り、検証してブロックチェーンに追加します。これは受動的なプロセスであり、ノードは新しいトランザクションをアクティブに検索するのではなく、ネットワーク上の他のノードからの新しいトランザクションを待ちます。そのため、ブロックチェーンのアーキテクチャはプッシュベースと呼ばれています。
したがって、フルチェーンゲームでクロックサイクルのあるループシステムを実現することは非常に重要です。なぜなら、「自治世界」では、いくつかの NPC や仮想環境が時間とともに自動的に進化することを望んでいるからです。ブロックチェーンにプッシュされたトランザクションの入力に従って受動的に進化するのではなく、という意味です。
@therealbytes は、OP スタックをベースにした Tick-Optimism というコンセプトの検証チェーン(クロックサイクルを持つチェーン)を開発しました。これは、自動的に Tick する Conway のライフゲームの実装を実行します。以下では、彼がどのように実現したのかについて説明します。
翻訳を簡単にするために、"tick" を「滴答」と直訳します。これは「ループサイクル」という意味です。
Ticking-Optimism は、Optimism Bedrock rollup アーキテクチャに基づいた「滴答チェーン」の概念実装です。
滴答チェーンでは、「滴答コントラクト」という特別なスマートコントラクトがあり、各ブロックでプロトコルによって自動的に呼び出されます。これにより、他のスマートコントラクトが特定の時間や間隔で自動的にトリガーされることが可能になり、ユーザーがトランザクションを送信する必要がありません。
実装方法#
Optimism の新しいモジュラーロールアップアーキテクチャである Optimism Bedrock は、「デポジットトランザクション」という新しいトランザクションタイプを導入しました。通常のトランザクションとは異なり、デポジットトランザクションは次の特徴があります。
- Layer 1 のブロックから来ます。
- 署名の検証は必要ありません。
- L1 で L2 のガスを購入するため、L2 のガスは返金されません。
元の Bedrock では、デポジットトランザクションは 2 つの目的で使用されます。
- L1 に直接送信されるトランザクションを実行する。
- 各ブロックで事前にデプロイされた L2 コントラクトに L1 のプロパティ(番号、タイムスタンプ、ハッシュなど)を設定する。
後者の場合、トランザクションはロールアップノードによって作成されます。トランザクションはガスを支払わず、使用されるガスはガスプールから差し引かれません。
Ticking-Optimism は、ロールアップノードを変更し、「滴答トランザクション」と呼ばれるものを作成しました。これは同じ方法で機能しますが、L1 のプロパティを設定するのではなく、アドレス 0x42000000000000000000000000000000000000A0 に事前にデプロイされたコントラクトの tick () 関数を呼び出します。このコントラクトは、目標変数を設定することで別のコントラクトを呼び出すことができます。
動機#
Ticking-Optimism のパワーを示すために、マップ上で複数の NPC(非プレイヤーキャラクター)が移動するゲームを想像してみてください。滴答チェーンがない場合、2 つの主要な設計方法があります。
-
遅延更新(Lazy updating)。クライアントでは、NPC は連続的に移動しているように見えますが、その位置はユーザーが相互作用するトランザクションがチェーンに送信されたときにのみ更新されます。その後、コントラクトは最後のチェーン上の更新とそれ以降のブロック数に基づいて NPC の新しい位置を計算します。
-
手動の滴答(Manual ticking)。更新関数を定義し、マップ上の各 NPC の位置を設定し、外部アカウントが定期的にそれを呼び出す。
滴答チェーンを使用すると、手動の滴答と同様の解決策が得られますが、滴答コントラクトが自動的に更新関数を呼び出すため、手動で呼び出す必要はありません。
手動の滴答と比較して、自動の滴答の利点は次のとおりです。
- 更新がプロトコルによって保証されます。
- 更新はブロック内のすべてのトランザクションの前に実行され、前に置かれることはありません。なぜなら、それはプロトコル自体の一部だからです。
- 更新トランザクションは通常のガス市場に参加しません。
ただし、自動の滴答にはカスタムのブロックチェーンが必要です。更新の頻度が同じ場合、手動と自動の滴答はノードの計算リソース要件が同じです。一方、遅延更新は通常よりも安価です。なぜなら、チェーン上の更新がより小さく、少ないからです。
さらに、更新する必要のある状態が増えるにつれて、滴答トランザクションの計算コストも増加します。これは開発者に追加のプレッシャーをかけ、コストがチェーンがサポートできる範囲を超えないようにアプリケーションを設計する必要があります。
これらの大きな欠点があるにもかかわらず、自動の滴答は遅延更新よりも特定のタイプのアプリケーションに適しています。
- 状態が常に明示的で最新であること
滴答により、スマートコントラクトは更新される動的な状態に恒定のコストでアクセスできます。この状態は、オープンな形式の式で更新されます。
状態(上記の例では NPC の位置)は常に恒定で比較的低いガスコストでチェーン上から読み取ることができます。ただし、現在の状態を計算するコストは、前回の更新以降のブロック数の増加に伴って増加する場合があります。
一定の速度で移動するエンティティの位置を更新している場合、最後に設定された位置と前回の更新以降のブロック数から、任意のブロックでの位置を計算できます。この操作のコストは、更新間のブロック数の増加に伴って増加しません。
一方、更新する状態が Conway のライフゲーム(または三体の重力シミュレーション)のようなものである場合、更新のコストは前回の更新以降のステップ数に比例して増加します。これは問題です。なぜなら、それはユーザーが支払いたいコストやチェーンがサポートできるコストを超える可能性があるからです。
-
クライアントの役割が異なる
遅延更新を使用する場合、更新ロジックはスマートコントラクトとクライアントの両方で実装する必要があります。滴答を使用する場合、ブロックチェーン上でのみ実装する必要があり、クライアントは単純にチェーン上のイベントに反応するだけです。 -
コードがよりシンプルで監査しやすい
遅延更新では、開発者は更新ロジックを多くの関数やスマートコントラクトに分散させ、各関数は特定のトランザクションが実行されたときにのみトリガーされます。対照的に、滴答メソッドでは定期的にトリガーされる更新関数だけが必要です。後者は状態の一貫性と完全性を維持するのがより簡単になります。
また、新しい遅延更新状態(例えば、新しいタイプの NPC)を追加するたびに、すべての更新関数を変更して考慮する必要があります。これにより、コードベースがより複雑になり、問題が発生しやすくなります。
- ユーザーは更新コストを支払いません
遅延更新のコストは通常大きく変動し、ユーザーはトランザクションを作成して、ほとんどの更新の負担を他の人に押し付けることができます。滴答を使用すると、すべての操作のコストが比較的安定し、MEV 攻撃の影響を受けにくくなります。
Conway のライフゲームのデモンストレーション
私は滴答チェーンのデモンストレーションを構築し、対話型バージョンの Conway のライフゲームを実行しています。チェーンは変更され、実行エンジン内のセルオートマトンロジックが最適化され、スマートコントラクトのバイトコードで実装されたより大きなゲームボードを可能にしています。
デモのソースコード:https://github.com/therealbytes/ticking-conway
デモのビデオ:
オリジナルの記事:https://therealbytes.substack.com/p/presenting-ticking-optimism
オリジナルの著者:@therealbytes
日本語訳:@hicaptainz