paint-brush
使用 Truffle L2 Boxes 桥接区块链网络经过@johnjvester
677 讀數
677 讀數

使用 Truffle L2 Boxes 桥接区块链网络

经过 John Vester10m2022/12/22
Read on Terminal Reader

太長; 讀書

构建在 L1 和 L2 之间互操作的 dapp 可能很困难。让我们看看使用 Optimism Bridge Truffle Box 作为连接以太坊和 Optimism 的简单方法。
featured image - 使用 Truffle L2 Boxes 桥接区块链网络
John Vester HackerNoon profile picture


众所周知,许多区块链存在可扩展性和拥塞问题。这些问题具有广泛的影响,从交易时间变慢到交易费用增加和用户体验下降。


一种解决方案是使用L2 (第二层)链使 web3 成为链。以太坊 L2,如OptimismArbitrumPolygon ,建立在以太坊网络之上,但比以太坊更快、更便宜。


然而,作为权衡,它们通常不如以太坊安全。这就是为什么 L2 处理日常用户活动,同时仍然依赖以太坊 L1 作为安全和去中心化结算和数据可用性层的幕后基础。


这是一个很好的解决方案——但是,仅在以太坊上就有很多 L2;每一个都是独立的网络,具有自己的细微差别和经验。


构建和使用在这些网络和以太坊 L1 之间互操作和移动的 dapp 可能是乏味、困难的,并且对用户和开发人员来说体验不佳。


我们需要的是让 web3 成为一种多链体验,消费者不需要知道他们正在使用哪个链(坦率地说,不关心),开发人员可以依赖任何网络最好地支持他们的 dapps 的需求.


通过转移到这个多链区块链互联网,web3 成为每个相关人员的更好体验。


不幸的是,允许 dapps 在链之间移动是一项艰巨的技术挑战。在本文中,我们将研究一种解决方案——使用 Infura RPC 端点和 Truffle Boxes 构建并无缝桥接这些网络。


具体来说,我们将使用 Optimism Bridge Truffle Box在以太坊 Goerli 测试网上创建一个项目,并桥接到 Optimism Goerli。

使用 Infura 和 Truffle Boxes 运行多链 Dapp

松露盒

作为我们示例解决方案的核心,我们将依赖Truffle Boxes——来自 ConsenSys 的“快捷”样板(例如合约、库、模块,甚至是功能齐全的 dapp),您可以使用它们来构建 dapp。


对于多链解决方案,它们构建在许多 L2 网络的Infura RPC 节点之上。


如上所述,我们将特别依赖Optimism Bridge Truffle Box 。这个盒子有从 L1 和 L2 与 Optimism 桥交互所需的所有合约,以及一组用于部署、调用函数和在层之间传递消息/值的迁移。


它甚至有一个帮助脚本,可以完成我们需要看到的一切。我们只需要将它拆箱即可获得我们需要的一切!据 Trufflesuite.com 称,该盒子包括:


  • “通过 Optimism 桥发送消息的 L1 合约
  • 从以太坊向 Optimism 发送消息的迁移
  • 通过 Optimism 桥发送消息的 L2 合约
  • 从 Optimism 向以太坊发送消息的迁移
  • 自动编译合约、运行迁移和发送消息的脚本
  • 自动通过桥发送 ETH 和 DAO 的脚本”


注:桥接器是一种允许独立的区块链相互通信、发送代币、NFT 等的工具。

先决条件

在开始之前,我们需要满足以下先决条件:


  • Node.js及其包管理器 NPM。
  • 使用以下终端命令验证我们是否安装了 Node.js:

node -v && npm -v

第 1 步 — 创建 Infura 帐户以访问网络

满足先决条件后,请访问 Infura 网站以登录(或注册一个新帐户)。


成功注册后,页面重定向到 Infura 仪表板,我们可以在其中创建新的 API 密钥,如下所示。


单击“创建新密钥”按钮并填写所需信息。


创建 API 密钥后,您的项目 ID 将显示在仪表板上的 API 密钥部分下,如下所示。复制并保存在某个地方;您将在本教程的后面部分需要它。


第 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 truffle-config.ovm.js文件期望 .env 文件中存在一个 GOERLI_MNEMONIC 值,用于在 Ethereum Goerli 和 Optimism Goerli 测试网上运行命令,以及一个 INFURA_KEY 以连接到网络。


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


将 <your-infura-key> 替换为我们之前从 Infura 仪表板获得的信息。 (注意:切勿与任何人共享您的私钥(助记词),并妥善保管)。并将 <your-wallet-mnemonic> 替换为您的助记符,如下所示:


要从 Metamask 中检索助记符,请在您的 Metamask 上单击下面显示的图标。



接下来,点击导出私钥按钮复制助记词。


Git 忽略此项目中的 .env 文件以帮助保护您的私人数据。避免向 GitHub 泄露您的私钥是一种良好的安全做法。

第 3 步 — 使用 Truffle L2 框桥接

当我们打开项目时,我们项目的所有必需合同和脚本都已为我们创建。在下一步中,让我们通过各个合同和迁移来了解网络之间如何进行桥接和交互。


合约contract/ethereum/GreeterL1.sol向您展示了如何通过 Optimism 桥从 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使用上述合约从以太坊向 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 发送到以太坊。


 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` ); };


在脚本目录中,我们还有goerli_bridge_message.mjsgoerli_bridge_value.js来自动化编译合约、运行迁移和发送消息的过程。

Step 4 — 完成以太坊歌尔里与Optimism歌尔里合约的编译、迁移和桥接

接下来,我们将实际部署我们的合约到 Goerli。 helper脚本方便了以太坊歌尔里和Optimism歌尔里之间消息的编译、迁移和桥接。


在这些网络上,我们需要测试网 ETH 才能使用它。要接收一些,请使用水龙头。我们还需要将 Optimism 附加组件添加到您的 Infura 帐户。


接下来,我们将运行以下命令来启动项目。


 npm run deploy 


下面是一个 URL,用于在完成迁移后确认(通过 Etherscan)桥接消息。


第 4 次迁移完成后,将提供用于通过 Etherscan 确认桥接消息的链接。


第 5 步 — 使用 Block Explore 验证项目是否在 Goerli 测试网上成功

我们已经成功地设置、安装、构建、部署并完成了我们之前拆箱的项目。接下来,我们将在歌尔力以太坊测试网上验证该项目。


前往Goerli Etherscan区块浏览器并粘贴部署时在我们的 CLI 上显示的 txn 地址 0xbcc1746a9ebbfcfb71665225c1a353a8c8dc9a1aa528a3babcb5b046d615a353。



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


结论

如果我们希望用户和开发人员的体验不断改善,多链 web3 世界至关重要。为了实现这一目标,我们需要让 dapp 能够在链之间快速无缝地进行通信的方法。


希望我们使用 Optimism Bridge Truffle Box 演示的示例向您展示了一种相对简单快捷的入门方法。要了解更多信息,请查看官方文档


祝你有美好的一天!