EVM跨链桥部署实战

在本教程中,我们将在WAGMI和Fuji之间架起一座桥梁。这座桥将帮助我们将包裹在wWGM中的原生WGM通证从 WAGMI 链来回转移到 Fuji 链。 使用本指南,您可以在任何基于 EVM 的链之间为任何 ERC20 通证部署一座桥梁。

用熟悉的语言学习 以太坊Web3 DApp开发Java | Php | Python | .Net / C# | Golang | Node.JS | Flutter / Dart

原生通证的包装版本是其挂钩的 ERC20 表示。用 ERC20 标准包装它可以使委托交易等某些流程更加容易。你可以通过将原生通证发送到 打包的通证合约地址来轻松获得打包的ERC20通证。

WAGMI 是一个基于 EVM 的独立测试链,部署在 Avalanche 网络的自定义子网上。

我们将使用Chainsafe的网桥存储库,轻松建立一个强大且安全的EVM跨链网桥。

1、跨链桥的工作流程

WAGMI 和 Fuji 链默认不互连,但是我们可以让它们通信。中继器监视一条链上的事件(通过轮询块),并使用另一条链上的这些事件 执行必要的操作。这样,我们还可以通过使用智能合约将通证从一条链桥接到另一条链。

下面是跨链桥接的工作流程描述 -

  • 用户在 Bridge 合约上存入通证
  • 桥接合约要求 Handler 合约执行存款动作
  • 处理程序合约将存放的通证锁定在保险箱中
  • 桥接合约发出Deposit事件
  • RelayerDeposit从源链接收事件
  • 中继器在目标链上创建一个投票提案来铸造一个新的通证
  • 中继器投票达到阈值后,提案被执行
  • 通证被铸造到收件人的地址

将通证从源链桥接到目标链涉及锁定和铸币方法。而将通证从目标链连接到源链涉及销毁和释放方法。我们不能铸造和燃烧我们无法控制的 通证。因此,需要将它们锁定在源链上的通证保险箱中。并在目标链上生成相应的通证(我们将部署并因此控制它)。

evm-cross-chain

2、部署跨链桥的前置要求

下面列出跟进本教程的要求 -

  • 在 MetaMask 网络上添加WAGMIFuji链
  • 在 WAGMI 网络 (MetaMask) 上导入wWGM代币(资产)。这是地址——0x3Ee7094DADda15810F191DD6AcF7E4FFa37571e4
  • WAGMI Faucet请求1个WGM。
  • Fuji Faucet请求10个AVAX。
  • 向通证地址发送一些WGM通证,以接收相同数量的wWGM. 始终保留一些WGM通证,以支付交易费用。

3、设置部署环境

让我们创建一个新目录deploy-bridge,我们将在其中保存桥代码。我们将使用以下存储库 -

  • ChainSafe/chainbridge-deploy - 这将帮助我们建立桥接合约。代码
  • ChainSafe/chainbridge - 这将帮助我们建立链下中继器。代码

3.1 安装 Chainbridge 命令行工具

使用以下命令,我们可以克隆和安装 Chainbridge 的命令行工具。这将有助于我们建立桥接合约并展示跨链转移。部署桥接合约后, 你可以使用其 ABI 和合约地址来设置你的 UI。

1
2
3
4
git clone -b v1.0.0 --depth 1 https://github.com/ChainSafe/chainbridge-deploy \
&& cd chainbridge-deploy/cb-sol-cli \
&& npm install \
&& make install

这将构建合约并安装cb-sol-cli命令。

3.2 设置环境变量

让我们设置环境变量,这样我们就不需要在每次发出命令时都写入它们的值。移回deploy-bridge目录(主项目目录) 并创建一个新文件configVars。将以下内容放入其中 -

1
2
3
4
5
6
7
8
9
10
SRC_GATEWAY=https://subnets.avax.network/wagmi/wagmi-chain-testnet/rpc
DST_GATEWAY=https://api.avax-test.network/ext/bc/C/rpc

SRC_ADDR="<Your address on WAGMI>"
SRC_PK="<your private key on WAGMI>"
DST_ADDR="<Your address on Fuji>"
DST_PK="<your private key on Fuji>"

SRC_TOKEN="0x3Ee7094DADda15810F191DD6AcF7E4FFa37571e4"
RESOURCE_ID="0x00"
  • SRC_ADDR和DST_ADDR是将部署桥接合约并将充当中继器的地址。
  • SRC_TOKEN是我们要桥接的通证。这是 WGM的包装 ERC20 版本又名 wWGM 的地址。
  • RESOURCE_ID可以是任何东西。它在双方(WAGMI 和 Fuji)上识别我们桥接的 ERC20 通证。
  • 每次我们更改这些配置变量时,都必须更新我们的 bash 环境。根据文件的相对位置运行以下命令。这些变量是临时的, 只存在于当前终端会话中,一旦会话结束就会被刷新。确保将这些环境变量加载到你将在 bash 命令中使用它们的 任何位置(例如$SRC_GATEWAY或$SRC_ADDR)
1
source ./configVars

4、配置源链

我们需要如下设置源链 -

  • 部署Bridge 和 Handler 合约,将$SRC_ADDR设置为默认且唯一的中继器
  • 将wWGM通证注册为网桥上的资源

4.1 部署合约

命令行工具cb-sol-cli将帮助我们部署合约。在加载配置变量的终端会话中运行以下命令。它将添加SRC_ADDR为默认中继器, 用于将事件从 Wagmi 链(源)中继到 Fuji 链(目标)。

部署桥接合约时要注意的最重要参数之一是expiry值。这是一个提议被认为被取消的块数。默认情况下,它设置为100。 在 Avalanche 主网上,使用此值,提案可能会在 3-4 分钟内过期。你应该根据要部署桥接的链选择一个非常大的到期值。否则, 如果没有按时收到限制数量的提案,你的提案将被取消。

你还应该记住这一点,有时在高网络活动期间,交易可能会卡住很长时间。提案交易卡在这种情况下,可能会导致之前的提案被取消。 因此,到期值应该足够大,中继者应该以具有竞争力的最大 gas 价格发布交易。

1
2
3
4
5
6
cb-sol-cli --url $SRC_GATEWAY --privateKey $SRC_PK --gasPrice 25000000000 deploy \
--bridge --erc20Handler \
--relayers $SRC_ADDR \
--relayerThreshold 1 \
--expiry 500 \
--chainId 0

输出将返回已部署合约的(桥接和处理程序)地址。更新configVars文件,添加以下 2 个变量并将它们加载到环境中:

1
2
SRC_BRIDGE="<resulting bridge contract address>"
SRC_HANDLER="<resulting erc20 handler contract address>"

确保使用source命令加载这些环境变量。

4.2 配置桥上资源

运行以下命令将wWGM通证注册为源桥上的资源。

1
2
3
4
5
cb-sol-cli --url $SRC_GATEWAY --privateKey $SRC_PK --gasPrice 25000000000 bridge register-resource \
--bridge $SRC_BRIDGE \
--handler $SRC_HANDLER \
--resourceId $RESOURCE_ID \
--targetContract $SRC_TOKEN

5、配置目标链

我们需要按如下方式设置目标链 -

  • 部署Bridge 和 Handler 合约,设置$DST_ADDR为默认且唯一的中继器
  • 部署代表桥接wWGM通证的可铸可烧 ERC20 合约
  • 将wWGM通证注册为网桥上的资源
  • 将wWGM通证在桥上注册为 mintable/burnable
  • 授予 Handler 合约以铸造新wWGM通证的权限

5.1 部署合约

运行以下命令,在 Fuji 链上部署 Bridge、ERC20 Handler 和wWGM合约。它将再次设置DST_ADDR为将事件从 Fuji 链(目标)中继到 Wagmi 链(源)的默认中继器。对于此示例,两者SRC_ADDR和DST_ADDR代表相同的事物。

1
2
3
4
5
cb-sol-cli --url $DST_GATEWAY --privateKey $DST_PK --gasPrice 25000000000 deploy\
--bridge --erc20 --erc20Handler \
--relayers $DST_ADDR \
--relayerThreshold 1 \
--chainId 1

使用你将通过运行上述命令获得的详细信息更新环境变量。不要忘记加载这些变量。

1
2
3
DST_BRIDGE="<resulting bridge contract address>"
DST_HANDLER="<resulting erc20 handler contract address>"
DST_TOKEN="<resulting erc20 token address>"

5.2 配置桥上资源

运行以下命令将wWGM注册为网桥上的资源。

1
2
3
4
5
cb-sol-cli --url $DST_GATEWAY --privateKey $DST_PK --gasPrice 25000000000 bridge register-resource \
--bridge $DST_BRIDGE \
--handler $DST_HANDLER \
--resourceId $RESOURCE_ID \
--targetContract $DST_TOKEN

5.3 将通证设置为可铸可烧

当收到通证存款时,桥有两种选择 -

  • 将收到的通证锁定在一条链上,并在另一条链上铸造相应的通证
  • 在一条链上烧掉收到的通证,在另一条链上释放对应的通证

我们不能铸造或燃烧任何我们无法控制的通证。虽然我们可以通过将它们放入通证保险箱来锁定和释放这些通证。 桥必须知道它可以烧掉哪个通证。使用以下命令,我们可以将资源设置为可烧录。网桥将根据通证是否可烧来相应地选择操作。

1
2
3
4
cb-sol-cli --url $DST_GATEWAY --privateKey $DST_PK --gasPrice 25000000000 bridge set-burn \
--bridge $DST_BRIDGE \
--handler $DST_HANDLER \
--tokenContract $DST_TOKEN

5.4 授权处理程序铸造新通证

现在让我们允许处理程序在目标链上铸造已部署的 ERC20 (wWGM) 通证。运行以下命令。

1
2
3
cb-sol-cli --url $DST_GATEWAY --privateKey $DST_PK --gasPrice 25000000000 erc20 add-minter \
--minter $DST_HANDLER \
--erc20Address $DST_TOKEN

合约的部署者(此处SRC_ADDR或DST_ADDR)拥有管理员权限。管理员可以添加或删除新的中继者、铸币者、管理员等。 它还可以在目标链上铸币新的 ERC20 通证。你可以使用这些文件cb-sol-cli中提到的选项发出这些命令。除非需要一些干预, 否则当中继者未能按时在目标链上铸造代币时,不应手动使用铸币命令。

6、部署中继器

部署网桥、处理程序、通证等所有链上设置都已完成。但这两条链并不相互连接。我们需要一些链下中继器来在链之间传递消息。 中继者将对一条链上的存款事件进行投票,并提交投票提案以在另一条链上铸造或释放相应的通证。

由于我们将中继器阈值设置为 1,因此在部署网桥和处理程序时,我们只需要来自 1 个中继器的投票提案。但在生产中,我们应该使用 大量阈值较高的中继器,以避免权力集中。

为此,我们将使用 Chainsafe 的中继器。按照下面描述的步骤部署中继器。

6.1 克隆和构建中继器代码

打开一个新的终端会话,同时保持前一个会话加载环境变量。我们也必须在这个会话中加载环境变量。source也可以使用命令 在此会话中加载这些变量。

现在,移动到该deploy-bridge目录并运行以下命令来克隆中继器 repo(在 Go 中实现),并构建其二进制文件。

1
2
3
git clone -b v1.1.1 --depth 1 https://github.com/ChainSafe/chainbridge \
&& cd chainbridge \
&& make build

这将在chainbridge/build目录中创建一个二进制文件chainbridge.

6.2 配置中继器

中继器需要一些配置,如源链、目标链、网桥、处理程序地址等。运行以下命令。它将制作一个config.json包含所需详细信息的文件。 你可以根据需要更新这些详细信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
echo "{
\"chains\": [
{
\"name\": \"WAGMI\",
\"type\": \"ethereum\",
\"id\": \"0\",
\"endpoint\": \"$SRC_GATEWAY\",
\"from\": \"$SRC_ADDR\",
\"opts\": {
\"bridge\": \"$SRC_BRIDGE\",
\"erc20Handler\": \"$SRC_HANDLER\",
\"genericHandler\": \"$SRC_HANDLER\",
\"gasLimit\": \"1000000\",
\"maxGasPrice\": \"50000000000\",
\"http\": \"true\",
\"blockConfirmations\":\"0\"
}
},
{
\"name\": \"Fuji\",
\"type\": \"ethereum\",
\"id\": \"1\",
\"endpoint\": \"$DST_GATEWAY\",
\"from\": \"$DST_ADDR\",
\"opts\": {
\"bridge\": \"$DST_BRIDGE\",
\"erc20Handler\": \"$DST_HANDLER\",
\"genericHandler\": \"$DST_HANDLER\",
\"gasLimit\": \"1000000\",
\"maxGasPrice\": \"50000000000\",
\"http\": \"true\",
\"blockConfirmations\":\"0\"
}
}
]
}" >> config.json

检查并确认config.json文件中的详细信息。

在上面的命令中,可以看到blockConfirmations设置为0. 这对于像 Avalanche 这样的网络非常有效,因为一旦提交,区块就会得到确认。 不像其他链,比如以太坊,需要 20-30 个区块确认。因此,请谨慎使用此配置,具体取决于你使用的链类型。

如果基于未确认的区块铸造或释放相应的通证,可能会导致严重问题。

6.3 设置密钥

让中继器访问你的密钥。使用这些密钥,中继者将提议存款事件并执行提议。它将要求设置密码以加密这些密钥。每次启动中继器时, 它都会要求输入此密码。

1
2
3
./build/chainbridge accounts import --privateKey $SRC_PK

./build/chainbridge accounts import --privateKey $DST_PK

7、跨链桥测试

设置现已完成 - 链上和链下。现在我们只需要启动中继器并测试网桥。出于测试目的,我们将用于cb-sol-cli在桥上进行存款交易。 但是你可以制作前端并使用 ABI 将其与网桥集成。

7.1 启动中继器

运行以下命令启动中继器。它将打印与我们的网桥相关的所有事件的日志,这些事件发生在两条链上。所以保持中继器运行并在另一个 终端会话中执行下一个命令。

1
./build/chainbridge --config config.json --verbosity trace --latest

7.2 授权处理程序支配我的通证

现在,让我们在 WAGMI 桥上存入通证。但在此之前,我们需要批准处理程序代表我们(此处)使用(锁定或销毁)通证SRC_PK。 此处的金额以 Wei 为单位(1 以太 (WGM) = 10^18 Wei)。我们将批准 0.1 wWGM。

1
2
3
4
cb-sol-cli --url $SRC_GATEWAY --privateKey $SRC_PK --gasPrice 25000000000 erc20 approve \
--amount 100000000000000000 \
--erc20Address $SRC_TOKEN \
--recipient $SRC_HANDLER

7.3 将通证存入跨链桥

一旦获得批准,我们就可以发送存款交易。现在让我们在桥上存入 0.1 wWGM。处理程序将从我们的地址(此处SRC_PK)锁定(转移到 通证保险箱)0.1 wWGM,并将目标链上的新通证铸造给接收者(此处DST_ADDR)。

1
2
3
4
5
6
cb-sol-cli --url $SRC_GATEWAY --privateKey $SRC_PK --gasPrice 25000000000 erc20 deposit \
--amount 100000000000000000 \
--dest 1 \
--bridge $SRC_BRIDGE \
--recipient $DST_ADDR \
--resourceId $RESOURCE_ID

该交易会将 0.1 wWGM 转移到通证保险箱并发出一个Deposit事件,该事件将被中继器捕获。在此事件之后,它将向目标链发送投票提案。 由于阈值为 1,桥将执行提案,并将新的 wWGM 铸造到收件人的地址。这是中继器输出的屏幕截图。

evm-cross-chain

同样,我们可以将代币转回 WAGMI 链。

8、结束语

与上述过程类似,你可以在任意 2 个基于 EVM 的链之间部署一座桥。我们使用命令行工具进行审批和存款。这可以进一步扩展以构建 与桥集成的前端。目前,它依赖于单个中继器,这是不安全的。我们需要大量的中继器和高门槛来避免任何形式的中心化。

可以通过阅读 ChainSafe 的Chainbridge文档来了解有关这些合约和实现的更多信息。


原文链接:Deploying Cross-Chain EVM <-> EVM Bridge

汇智网翻译整理,转载请标明出处