如何使用TruffleL2Box桥接区块链网络

译者 | 李睿

审校 | 孙淑娟

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

一种解决方案是使用L2(第二层)区块链使Web3成为多链。以太坊L2(例如Optimism、Arbitrum和Polygon)构建在以太坊网络之上,但比以太坊更快,更便宜。然而,作为一种权衡,它们通常不如以太坊安全。这就是L2处理日常用户活动,同时仍然依赖以太坊L1作为安全、去中心化结算和数据可用性层的幕后基础的原因。

这是一个很好的解决方案,仅以太坊上就有许多L2,每个L2都是一个独立的网络,有自己的细微差别和体验。构建和使用在这些网络和以太坊L1之间互操作和移动的dApp可能是乏味和困难的,而且对用户和开发人员来说也是糟糕的体验。

现在需要的是Web3成为一种多链体验,消费者不需要知道他们使用的是哪条区块链(坦率地说不在乎),开发者可以依赖任何最支持他们dApp需求的网络。通过转移到区块链的多链互联网,Web3为每个参与者提供了更好的体验。

不幸的是,允许dApp在区块链之间移动是一项艰巨的技术挑战。本文将研究一种解决方案——使用Infura RPC端点和Truffle Box进行构建,并无缝地桥接这些网络。具体来说, 将使用Optimism Bridge的Truffle Box在以太坊Goerli测试网上创建一个项目,并连接到Optimism Goerli。

使用Infura和Truffle Boxes运行多链dApp

Truffle Boxes

作为示例解决方案的核心,将依赖于来自ConsenSys的“快捷”样板文件(例如合约、库、模块,甚至是功能齐全的dApp),企业可以使用它们来构建自己的dApp。对于多链解决方案,它们构建在许多L2网络的Infura RPC节点之上。

如上所述,特别依赖Optimism Bridge的Truffle Box。Truffle Box包含L1和L2与Optimism Bridge交互所需的所有合约,以及一组用于在层之间部署、调用函数和传递消息/值的迁移。它甚至有一个辅助脚本,可以完成需要的所有操作。只需要打开Truffle Box就能得到需要的一切! Truffle Box包括:

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

注:桥接(Bridge)是一种工具,允许独立的区块链彼此通信,并发送令牌、NFT等。

先决条件

在开始之前,需要具备以下先决条件:

  • Node.js及其包管理器NPM。

使用以下终端命令验证已经安装了Node.js:

node -v && npm -v
  • Infura帐户
  • MetaMask账户
  • 基本了解JavaScript和Solidity

步骤1:创建用于访问网络的Infura帐户  

在完成先决条件后,登录Infura网站(或注册新帐户)。

在成功注册之后,页面重定向到Infura仪表板,在那里可以创建一个新的API密钥,如下图所示:

点击“Create a New Key”按钮,填写所需信息。

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

步骤2:设置和安装  

接下来,将设置Truffle Optimism Bridge Box。可以使用以下命令在选择的任何目录中运行unbox命令。

npx truffle unbox optimism-bridge 

用选择的目录名替换。或者,可以全局安装Truffle并运行unbox命令。

npm install -g truffle
truffle unbox optimism-bridge

该命令应该下载并运行npminstall作为unbox过程的一部分。

现在,运行以下命令将目录更改为刚刚创建的新目录。

cd truffle-bridge-demo

注:truffle-bridge-demo是创建的目录的名称。

应该得到类似于下面所示的结果。

.dotenv npm包已经安装,但是需要在开箱后创建的.env文件中添加一些信息。truulu -config.ovm.js文件期望在.env文件中存在一个GOERLI_MNEMONIC值,用于在以太坊Goerli和Optimism Goerli测试网上运行命令,并期望INFURA_KEY连接到网络。

GOERLI_MNEMONIC=""
INFURA_KEY=""

替换为之前从Infura仪表板中获得的信息。【注意:永远不要与任何人分享私钥(助记符),并妥善保管】。将替换为助记符,如下所示:

要从Metamask中检索助记符,单击Metamask上所示的图标。

接下来,单击Export Private Key按钮复制助记符。

Git忽略了这个项目中的.env文件,以帮助保护私有数据。避免将私钥泄露给GitHub是一个很好的安全实践。

步骤3:使用Truffle L2 Boxes桥接

当打开项目的盒子时,创建了项目的所有必要合同和脚本。在下一步中,我们将详细介绍各个合约和迁移,以理解桥接和交互是如何在网络之间发生的。

合约contract/ethereum/GreeterL1.sol展示了如何通过Optimism bridge将消息从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使用上面的合约从以太坊发送消息给optimistic。

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 bridge向另一个方向(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.mjs和goerli_bridge_value.js来自动化编译合约、运行迁移和发送消息的过程。

步骤4:完成Ethereum Goerli和Optimism Goerli之间的合约编译、迁移和桥接

接下来,将把合约部署到Goerli。助手脚本促进了Ethereum Goerli和Optimism Goerli之间的编译、迁移和桥接消息。在这些网络上,需要测试网ETH来使用它。还需要将Optimism插件添加到Infura帐户。

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

npm run deploy

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

在第四次迁移完成后,将提供一个通过Etherscan确认桥接消息的链接。

步骤5:用块资源管理器在Goerli测试网上验证项目是否成功

已经成功地设置、安装、构建、部署了前面打开的项目。接下来,将在Goerli Ethereum测试网上验证该项目。

转到Goerli Etherscan块资源管理器,并粘贴txn地址

0xbcc1746a9ebbfcfb71665225c1a353a8c8dc9a1aa528a3babcb5b046d615a353,该地址在部署时在CLI上显示。

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

结论

如果希望用户和开发人员的体验持续改善,那么多链Web3世界是至关重要的。为了实现这一点,需要让dApp在区块链之间快速无缝地通信。希望使用Optimism Bridge Truffle Box的例子能给一个相对简单快速的入门方法。要了解更多信息,可以查看官方文档。

原文标题:​​Using Truffle L2 Boxes to Bridge Blockchain Networks​​,作者:John Vester

网页题目:如何使用TruffleL2Box桥接区块链网络
网页链接:http://www.shufengxianlan.com/qtweb/news31/476781.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联