paint-brush
Truffle L2 ボックスを使用してブロックチェーン ネットワークをブリッジする@johnjvester
677 測定値
677 測定値

Truffle L2 ボックスを使用してブロックチェーン ネットワークをブリッジする

John Vester10m2022/12/22
Read on Terminal Reader

長すぎる; 読むには

L1 と L2 の間で相互運用する dapp を構築するのは難しい場合があります。 Ethereum と Optimism を橋渡しする簡単な方法として、Optimism Bridge Truffle Box の使用を見てみましょう。
featured image - Truffle L2 ボックスを使用してブロックチェーン ネットワークをブリッジする
John Vester HackerNoon profile picture


多くのブロックチェーンがスケーラビリティと輻輳の問題を抱えていることはよく知られています。これらの問題は、取引時間の遅延から取引手数料の増加、ユーザー エクスペリエンスの低下まで、幅広い影響をもたらします。


1 つの解決策は、web3 をL2 (レイヤー 2) チェーンを使用したマルチチェーンにすることです。 OptimismArbitrumPolygonなどの Ethereum L2 は、Ethereum ネットワークの上に構築されますが、Ethereum よりも高速で安価です。


ただし、トレードオフとして、イーサリアムよりも安全性が低いことがよくあります。そのため、L2 は日々のユーザー アクティビティを処理しながら、安全で分散化された決済とデータ可用性レイヤーの舞台裏の基盤として Ethereum L1 に依拠しています。


これは優れたソリューションですが、イーサリアムだけでも多くの L2 が存在します。それぞれが独自のニュアンスと経験を持つスタンドアロン ネットワークです。


これらのネットワークと Ethereum L1 の間で相互運用および移動する dapps を構築して使用することは、ユーザーと開発者にとって退屈で困難であり、貧弱な経験になる可能性があります。


私たちが必要としているのは、web3 がマルチチェーンエクスペリエンスになることです。そこでは、消費者は自分が使用しているチェーンを知る必要がなく (率直に言って気にしません)、開発者は dapps のニーズを最もよくサポートするネットワークに依存できます。 .


このブロックチェーンのマルチチェーンインターネットに移行することで、web3 は関係者全員にとってより良いエクスペリエンスになります。


残念ながら、dapps がチェーン間を移動できるようにすることは、技術的に困難な課題です。この記事では、Infura RPC エンドポイントと Truffle Box を使用して構築し、これらのネットワークをシームレスにブリッジする 1 つのソリューションを見ていきます。


具体的には、 Optimism Bridge Truffle Boxを使用して、Ethereum Goerli テストネット上にプロジェクトを作成し、Optimism Goerli にブリッジします。

Infura と Truffle Box を使用したマルチチェーン Dapp の実行

トリュフボックス

サンプル ソリューションの中核として、dapp の構築に使用できる ConsenSys の「ショートカット」ボイラープレート (コントラクト、ライブラリ、モジュール、さらには完全に機能する dapps など) であるTruffle Boxesに依存します。


マルチチェーン ソリューションの場合、L2 ネットワークの多くでInfura RPC ノードの上に構築されます。


上で述べたように、特にOptimism Bridge Truffle Boxに依存します。このボックスには、L1 と L2 の両方から Optimism ブリッジと対話するために必要なすべてのコントラクトと、デプロイ、関数の呼び出し、およびレイヤー間でのメッセージ/値の受け渡しのための一連の移行が含まれています。


これには、すべての動作を確認するために必要なすべてを実行するヘルパー スクリプトもあります。箱から出して必要なものをすべて入手するだけです。 Trufflesuite.com によると、ボックスには次のものが含まれています。


  • 「Optimism ブリッジを介してメッセージを送信する L1 コントラクト
  • Ethereum から Optimism にメッセージを送信する移行
  • Optimism ブリッジを介してメッセージを送信する L2 コントラクト
  • Optimism から Ethereum にメッセージを送信する移行
  • コントラクトのコンパイル、移行の実行、メッセージの送信を自動化するスクリプト
  • ブリッジを介した ETH と DAO の送信を自動化するスクリプト」


注:ブリッジは、独立したブロックチェーンが相互に通信し、トークンや NFT などを送信できるようにするツールです。

前提条件

始める前に、次の前提条件が必要です。


  • Node.jsとそのパッケージ マネージャー NPM。
  • 次のターミナル コマンドを使用して、Node.js がインストールされていることを確認します。

node -v && npm -v

ステップ 1 — ネットワークにアクセスするための Infura アカウントを作成する

前提条件を満たしたら、Infura Web サイトにアクセスしてログイン(または新しいアカウントにサインアップ) します。


サインアップに成功すると、以下に示すように、ページが Infura ダッシュボードにリダイレクトされ、そこで新しい API キーを作成できます。


「Create a New Key」ボタンをクリックし、必要な情報を入力します。


API キーを作成すると、以下に示すように、プロジェクト ID がダッシュボードの API KEY セクションの下に表示されます。コピーしてどこかに保管してください。このチュートリアルの後半で必要になります。


ステップ 2 — セットアップとインストール

次に、 Truffle Optimism Bridge Boxを設定します。次のコマンドを使用して、選択した任意のディレクトリで unbox コマンドを実行できます。


 npx truffle unbox optimism-bridge <DIRECTORY_NAME>


<DIRECTORY_NAME> を任意のディレクトリ名に置き換えます。または、Truffle をグローバルにインストールして unbox コマンドを実行することもできます。


 npm install -g truffle truffle unbox optimism-bridge <DIRECTORY_NAME> 



このコマンドは、ボックス化解除プロセスの一部として npm install をダウンロードして実行する必要があります。


次に、次のコマンドを実行して、ディレクトリを作成したばかりの新しいディレクトリに変更します。


 cd truffle-bridge-demo


注: truffle-bridge-demo は、作成されたディレクトリの名前です。


以下に示すようなものがあるはずです。


dotenv npm パッケージがインストールされましたが、ボックス化解除後に作成される .env ファイルにいくつかの情報を追加する必要があります。


truffle-config.ovm.jsファイルは、Ethereum Goerli および Optimism Goerli テストネットでコマンドを実行するために GOERLI_MNEMONIC 値が .env ファイルに存在すること、およびネットワークに接続するための INFURA_KEY が存在することを想定しています。


 GOERLI_MNEMONIC="<your-wallet-mnemonic>" INFURA_KEY="<your-infura-key>"


<your-infura-key> を Infura ダッシュボードから取得した情報に置き換えます。 (: 秘密鍵 (ニーモニック) を誰とも共有せず、安全に保管してください)。以下に示すように、 <your-wallet-mnemonic> をニーモニックに置き換えます。


メタマスクからニーモニックを取得するには、メタマスクの下に表示されているアイコンをクリックします。



次に、[秘密鍵のエクスポート] ボタンをクリックして、ニーモニックをコピーします。


Git は、このプロジェクトの .env ファイルを無視して、個人データを保護します。秘密鍵を GitHub に開示しないようにすることは、優れたセキュリティ プラクティスです。

ステップ 3 — Truffle L2 ボックスを使用したブリッジ

プロジェクトを開封すると、プロジェクトに必要なすべてのコントラクトとスクリプトが作成されました。この次のステップでは、個々のコントラクトと移行について説明し、ネットワーク間でブリッジングと相互作用がどのように発生するかを理解しましょう。


コントラクトcontract/ethereum/GreeterL1.solは、楽観主義ブリッジを介して L1 から L2 にメッセージを送信する方法を示しています。


 //SPDX-License-Identifier: Unlicense // This contract runs on L1, and controls a Greeter on L2. pragma solidity ^0.8.0; import { ICrossDomainMessenger } from "@eth-optimism/contracts/libraries/bridge/ICrossDomainMessenger.sol"; contract GreeterL1 { address crossDomainMessengerAddr = 0x5086d1eEF304eb5284A0f6720f79403b4e9bE294; address greeterL2Addr = 0xC0836cCc8FBa87637e782Dde6e6572aD624fb984; function setGreeting(string calldata _greeting) public { bytes memory message; message = abi.encodeWithSignature("setGreeting(string)", _greeting); ICrossDomainMessenger(crossDomainMessengerAddr).sendMessage( greeterL2Addr, message, 1000000 // within the free gas limit amount ); } // function setGreeting } // contract GreeterL1


移行migrations/3_set_L2_greeting.jsは、上記のコントラクトを使用して、Ethereum から Optimism にメッセージを送信します。


 var Greeter = artifacts.require("GreeterL1"); /** * Set L2 Greeting * Run this migration on L1 to update the L1 greeting. */ module.exports = async function (deployer) { console.log("Updating the L2 Greetings contract from L1! 👋👋"); const instance = await Greeter.deployed(); const tx = await instance.setGreeting("👋 Greetings from Truffle!"); console.log(`🙌 Greeter txn confirmed on L1! ${tx.receipt.transactionHash}`); console.log(`🛣️ Bridging message to L2 Greeter contract...`); console.log( `🕐 In about 1 minute, check the Greeter contract "read" function: https://goerli-optimism.etherscan.io/address/0xC0836cCc8FBa87637e782Dde6e6572aD624fb984#readContract` ); };


次に、 contracts/optimism/GreeterL2.solコントラクトは、Optimism ブリッジを介して反対方向 (L2->L1) にメッセージを送信します。


 //SPDX-License-Identifier: Unlicense // This contract runs on L2, and controls a Greeter on L1. pragma solidity ^0.8.0; import { ICrossDomainMessenger } from "@eth-optimism/contracts/libraries/bridge/ICrossDomainMessenger.sol"; contract GreeterL2 { address crossDomainMessengerAddr = 0x4200000000000000000000000000000000000007; address greeterL1Addr = 0x7fA4D972bB15B71358da2D937E4A830A9084cf2e; function setGreeting(string calldata _greeting) public { bytes memory message; message = abi.encodeWithSignature("setGreeting(string)", _greeting); ICrossDomainMessenger(crossDomainMessengerAddr).sendMessage( greeterL1Addr, message, 1000000 // irrelevant here ); } // function setGreeting } // contract GreeterL2


移行migrations/4_set_L1_greeting.jsは、上記のコントラクトを使用して、Optimism から Ethereum にメッセージを送信します。


 require("dotenv").config(); const sdk = require("@eth-optimism/sdk"); const ethers = require("ethers"); const Greeter = artifacts.require("GreeterL2"); const goerliMnemonic = process.env["GOERLI_MNEMONIC"]; const infuraKey = process.env["INFURA_KEY"]; const sleep = (milliseconds) => { return new Promise((resolve) => setTimeout(resolve, milliseconds)); }; /** * Set L1 Greeting * Run this migration on L1 to update the L1 greeting. */ module.exports = async function (deployer) { const newGreeting = "👋 Greetings from Truffle!"; //<---- CHANGE THIS VALUE TO YOUR NAME!!! const instance = await Greeter.deployed(); console.log("Updating the L1 Greetings contract from L2! 👋"); const tx = await instance.setGreeting(newGreeting); const txHash = tx.receipt.transactionHash; console.log(`🙌🙌 Greeter txn confirmed on L2! ${txHash}`); console.log( `🛣️ Bridging message to L1 Greeter contract.\n 🕐 This will take at least 1-5 min...` ); // Set providers for Optimism sdk const l1Provider = new ethers.providers.JsonRpcProvider( "https://goerli.infura.io/v3/" + infuraKey ); const l2Provider = new ethers.providers.JsonRpcProvider( "https://optimism-goerli.infura.io/v3/" + infuraKey ); // Connect an L1 signer const wallet = ethers.Wallet.fromMnemonic(goerliMnemonic); const l1Signer = wallet.connect(l1Provider); // Initialize sdk messenger const crossChainMessenger = new sdk.CrossChainMessenger({ l1ChainId: 5, l2ChainId: 420, l1SignerOrProvider: l1Signer, l2SignerOrProvider: l2Provider, }); let statusReady = false; // Sleep for 1 min during L2 -> L1 bridging await sleep(60000); // 60 seconds // Poll the L1 msg status while (!statusReady) { let status = null; status = await crossChainMessenger.getMessageStatus(txHash); statusReady = status == sdk.MessageStatus.READY_FOR_RELAY; if (!statusReady) { console.log( "Message not yet received on L1.\n 🕐 Retrying in 10 seconds..." ); await sleep(10000); // 10 seconds } } console.log("📬 Message received! Finalizing..."); // Open the message on L1 finalize = await crossChainMessenger.finalizeMessage(txHash); console.log( `🎉 Message finalized. Check the L1 Greeter contract "read" function: https://goerli.etherscan.io/address/0x7fA4D972bB15B71358da2D937E4A830A9084cf2e#readContract` ); };


scripts ディレクトリには、 goerli_bridge_message.mjsgoerli_bridge_value.jsもあり、コントラクトのコンパイル、移行の実行、およびメッセージの送信のプロセスを自動化します。

ステップ 4 — Ethereum Goerli と Optimism Goerli の間のコントラクトの完全なコンパイル、移行、ブリッジング

次に、実際にコントラクトを Goerli にデプロイします。ヘルパースクリプトは、Ethereum Goerli と Optimism Goerli の間のメッセージのコンパイル、移行、ブリッジングを容易にします。


これらのネットワークでは、テストネット ETH を使用する必要があります。一部を受け取るには、蛇口を使用します。 Optimism アドオンを Infura アカウントに追加する必要もあります。


次に、次のコマンドを実行してプロジェクトを開始します。


 npm run deploy 


以下は、移行が完了した後にブリッジされたメッセージを (Etherscan 経由で) 確認するための URL です。


4 回目の移行が完了すると、Etherscan を介してブリッジされたメッセージを確認するためのリンクが提供されます。


ステップ 5 — Block Explore を使用して Goerli テストネットでプロジェクトが正常に動作することを確認する

以前に箱から出したプロジェクトのセットアップ、インストール、ビルド、デプロイ、およびウォークスルーに成功しました。次に、Goerli Ethereum テストネットでプロジェクトを検証します。


Goerli Etherscanブロック エクスプローラーに移動し、展開時に CLI に表示された txn アドレス 0xbcc1746a9ebbfcfb71665225c1a353a8c8dc9a1aa528a3babcb5b046d615a353 を貼り付けます。



https://goerli-optimism.etherscan.io/tx/0xbcc1746a9ebbfcfb71665225c1a353a8c8dc9a1aa528a3babcb5b046d615a353


結論

ユーザーと開発者のエクスペリエンスを改善し続けるには、マルチチェーンの web3 ワールドが不可欠です。そしてそれを達成するには、dapps がチェーン間で迅速かつシームレスに通信する方法が必要です。


Optimism Bridge Truffle Box を使用して説明した例で、比較的簡単かつ迅速に開始する方法を示していただければ幸いです。詳細については、公式ドキュメントをご覧ください。


本当に素晴らしい一日を!