【完全保存版】LayerZeroの簡易テストを実行しよう!
0 はじめに
本日は、LayerZeroの「OmniCounter」というテストを実際に行います。
一つのコントラクトから別のコントラクトに「LZEndpoint」コントラクトを通じて、メッセージが送られます。
では、やっていきましょう。
1 やってみよう
1 git clone
まずは、下のように、git cloneを行い、フォルダを移動します。
git clone https://github.com/LayerZero-Labs/solidity-examples.git
cd solidity-examples
こちらのGithubです。
2 コメントアウトを行う
次に、「.npmrc」ファイルを開き、下のように、コメントアウトします。
ここは、npmのレジストリに、認証トークンを使ってアクセスするためのものです。
今回は、特に使わないため、コメントアウトしました。
3 依存関係のインストール
次に、依存関係をインストールします。
yarn install
4 テストの実施
今回は、こちらの、「OmniCounter.test.js」を実行していきます。
なお、"Omni" はラテン語で「すべて」や「全体」という意味を持つようです。
では、実際に実行してみましょう。
npx hardhat test test/contracts/examples/OmniCounter.test.js
しばらくすると、このように、コンパイル済みのコントラクトが出てきました。
そして、下のように、「OmniCounter」が成功したようです。
また、下に、デプロイされたコントラクトと使用されたメソッドが表示されています。
「LZEndpointMock」「OmniCounter」というコントラクトがデプロイされました。
「setDestLzEndpoint」「incrementCounter」「setTrustedRemote」関数が使われています。
2 コードを読んでみよう
1 インポートについて
では、実際に見てみましょう。
まずは、こちらで、インポートを行なっています。
chaiライブラリからexpect関数を取り出していますね。
2 describeについて
「describe」でテストスイートを定義しています。
これは「Mocha」の関数です。
3 beforeEachについて
次に、「beforeEach」でテストの実行前の処理を定義しています。
こちらも「Mocha」の関数です。
4 チェーンIDの設定
まずは、chainIdを123と設定しています。
5 LZEndpointMockのデプロイ
次に、「LZEndpointMock」コントラクトを上のチェーンIDでデプロイしています。
ちなみに、「LZEndpointMock」コントラクトはこちらです。
こちらは、その名の通り、LayerZeroEndpointのモックです。
「blocking」の説明にあるように、特定の送信者からの宛先チェーンへのメッセージを順序付けて送付するようです。
6 OmniCounterのデプロイ
次に、こちらで、「OmniCounter」のコントラクトがデプロイされています。
ちなみに、「OmniCounter」のコントラクトはこちらです。
こちらは、LayerZeroEndpointを使って、クロスチェーンの通信を行い、その通信を使用してカウンターの値を増やすことを目的としています。
7 目的先エンドポイントの設定
(この部分、若干自信がないです。違いましたら修正します。)
次に、「setDestEndpoint」関数で、最終的に経由するLayerZeroEndpointを設定しているようです。
つまり、イメージとしては、このようになりました。
こちらは、次の記事である、「PingPong」コントラクトの方がわかりやすいかもしれません。
そちらは、EndPointが2つ存在しているからです。
内容は、こちらのように、mappingとなっています。
8 信頼できるリモートコントラクトの設定
そして、下の部分で、「setTrustedRemote」関数を実行しています。
こちらでは、送付先のチェーンIDとどこからどこに向かうのかを規定しています。
具体的な内容は、こちらになります。
「trustedRemoteLookup」と言うマッピングでパスを設定しています。
つまり、このようになると考えられます。
チェーンID 123の場合は、Bに向かうことが示されます。
これにより、下のような流れができます。
AがチェーンID:123を実行する場合、中のmappingでそのリモートがBであることがわかります。
そして、接続している、「LZEndpointMock」を確認すると、Bに行くEndPointは自分自身です。
そのため、そのまま他のEndPointを経由せずにメッセージを送ります。
9 itについて
「it」で単一のテストケースを定義しています。
「Mocha」の関数です。
10 初期値の確認
まずは、下のように、それぞれが持っているcounterの初期値が0であることが確認されます。
下のような状態です。
11 omniCounterの関数の実行
そこで、下のように、「omniCounterA」で「incrementCounter」関数を実行します。
具体的な中身としては、下のように、「_lzSend」関数が実行されています。
12 送付関数について
さらに確認すると、「_lzSend」関数がこちらになります。
送付先として、あらかじめ「trustedRemoteLookup」mappingで指定した宛先が使われています。
これにより、今回は、「omniCounterB」に向かうことがわかりました。
13 メッセージの受信について
では、メッセージを受けて、何をしているのかを見てみましょう。
具体的には、「OmniCounter」コントラクトの「_nonblockingLzReceive」関数が実行されています。
まずは、こちらになります。
そして、それを実行しているのが、「NonblockingLzApp」コントラクトの「nonblockingLzReceive」関数です。
このような関係性です。
そして、それは「_blockingLzReceive」関数内の「excessivelySafeCall」関数で実行されています。
このようになりました。
さらに、「_blockingLzReceive」関数は「LzApp」コントラクトの「lzReceive」関数で実行されていました。
このようになりました。
このようにして、受け取る側では、最終的に、「_nonblockingLzReceive」関数が実行されていました。
以上です。