跳转至主要内容

阅读时间 38 分钟

概述

Hyperliquid 将两层架构整合到一个统一的状态下:HyperCore 是一个通过签名操作访问的超低延迟订单簿引擎;HyperEVM 则是一个完全兼容 EVM 的网络,支持标准的 Solidity 开发。

Chainlink CCIP 通过“销毁与铸造”机制,实现了跨链资产的桥接。在 Hyperliquid 中,HyperCore (HIP-1) 资产与其 HyperEVM 表示形式之间的转换由原生协议流程处理。

在本指南中,您将使用 Foundry 对对应于 HIP-1 资产的 HyperEVM 代币进行包装,并利用 CCIP 将该代币在 HyperEVM 和 BNB Smart Chain(BSC)之间进行跨链桥接。

您将负责的工作内容


  • 为与 HIP-1 资产关联的 HyperEVM 代币创建一个包装合约
  • 在 HyperEVM 和 BSC 上部署和配置 CCIP 代币池
  • 在链上验证我们已部署的代币和资金池合约
  • 使用 Foundry 脚本在 HyperEVM 和 BSC 之间执行 CCIP 转账

您需要准备的物品


免责声明

在本指南中,我们将使用各条链的主网(MAINNETS)。这是因为在撰写本文时,Chainlink CCIP 尚未在 HyperEVM 测试网(Testnet)上推出。请谨慎操作,仅使用您能够承受损失的资金。

搭建开发环境

我们将使用Foundry来编译、部署智能合约并与之交互。如果您尚未安装 Foundry,可以在终端中运行以下命令进行安装:

curl -L https://foundry.paradigm.xyz | bash

请按照屏幕上的说明操作,之后您就可以使用该 foundryup 用于安装 Foundry 的命令。请确保在新的终端会话中执行此命令,以便反映对您的 PATH 变量。

foundryup

我们需要在本地创建一个新文件夹,用于存放本指南中的项目。我们将该文件夹命名为hyperevm_ccip,但您可以根据自己的喜好随意命名。请在终端中运行以下命令创建该文件夹,然后使用代码编辑器进入该文件夹。在本指南中,我们将使用 VS Code。

forge init hyperevm_ccip
cd hyperevm_ccip
code .

此时,您的设置应该大致如下所示:

太好了!我们的 Foundry 项目结构现已搭建完成。接下来,创建一个 .env 位于项目文件夹根目录下的文件。我们将在此处存储环境变量,例如私钥和 RPC URL。该文件的格式如下: .env 文件应如下所示:

HYPEREVM_RPC="您的_HYPEREVM_RPC_URL"
BSC_RPC="您的 BSC RPC 网址"
PRIVATE_KEY="您的私钥"
ETHERSCAN_API_KEY="您的_etherscan_api_key"

我们稍后将讨论这些变量的具体含义以及如何获取它们。下一步是删除默认的 src/Counter.sol 合同和 script/Counter.s.sol Foundry 为我们生成的脚本。本指南中将不会使用这些文件。此外,您还可以在终端中运行以下命令来删除这些文件:

rm src/Counter.sol
rm script/Counter.s.sol

您还需要配置 foundry.toml 在项目文件夹的根目录下创建一个文件,其中包含 Solidity 编译器的重要设置以及我们将要使用的 import 语句的重新映射。以下是你的 foundry.toml 文件应如下所示:

[个人资料.默认]
src = "src"
out = "out"
= ["lib"]
优化器 = true
优化器运行次数 = 200

重映射 = [
'@chainlink/contracts-ccip/=node_modules/@chainlink/contracts-ccip/',
'@chainlink/contracts/=node_modules/@chainlink/contracts/',
]

fs_permissions = [{ 访问 = "读写", 路径 = "./" }]

在此文件中,我们添加了 优化器 用于优化智能合约部署的设置。该 fs_permissions 该条目允许 Foundry 在项目目录中读写文件。该 重新映射 这些条目是本指南中将要使用的 Chainlink 合约包的路径。接下来我们将安装这些包。

安装依赖项

在本指南中,我们将使用两个 Chainlink 合约包: @chainlink/contracts-ccip 以及 @chainlink/contracts. 第一个包包含我们将要交互的核心 CCIP 合约,以及我们将要部署的 CCIP 代币池合约。第二个包包含定制的 ERC20 符合 Chainlink 跨链转账要求的合约。

此外,我们还将安装 @layerzerolabs/hyperliquid-composer 该包将用于提高我们在 HyperEVM 上交易的 gas 限制。HyperEVM 具有一个 多块架构 该网络由两类区块组成:一类是 gas 限制为 200 万 gas 单位的小区块,另一类是 gas 限制为 3000 万 gas 单位的大区块。小区块的区块间隔为 1 秒,而大区块的区块间隔为 1 分钟。默认情况下,HyperEVM 上的账户只能发送符合小区块 gas 限制的交易。通过此套餐,我们将能够使账户发送具有更高 gas 限制的交易,以便纳入大区块中。

要安装这些软件包,请使用您喜欢的软件包管理器输入以下命令:

npm 安装 @chainlink/contracts-ccip @chainlink/contracts @layerzerolabs/hyperliquid-composer

太好了!您已成功安装了本指南中将要使用的依赖项。接下来,我们将讨论需要在我们的 .env 文件。

环境变量

Quicknode 端点

首先,我们需要获取 HyperEVM 和 BSC 的相应 RPC 端点。您可以从以下位置获取这些信息: Quicknode。只需注册免费试用,创建一个新的多链端点,然后复制每条链的 HTTPS URL。将相应的 URL 粘贴到 HYPEREVM_RPC 以及 BSC_RPC 您中的变量 .env 文件。

Etherscan API

接下来,请前往您的个人资料页面 Etherscan 然后转到“API 密钥”选项卡。如果您还没有账户,请创建一个 这里. 在此处,您将创建一个 API 密钥,该密钥将帮助您在链上验证智能合约。复制该 API 密钥,并将其粘贴到 ETHERSCAN_API_KEY 您中的变量 .env 文件。

Etherscan API v2
Etherscan 已将其 API 升级至 v2 版本。当您在 Etherscan 上创建 API 密钥时,该密钥也可用于 Etherscan 支持的多条链,包括 HyperEVM 和 BSC。因此,您无需为每条链分别创建 API 密钥。

私钥

最后,打开您的 MetaMask,复制其中一个账户的私钥。如需了解如何获取私钥,请参阅这篇简短的 指南. 将此私钥粘贴到 PRIVATE_KEY 您中的变量 .env 文件。

至此,您中的所有环境变量 .env 该文件现在应已填充完毕。此设置过程的最后一步是将相应的网络添加到我们的 MetaMask 钱包中。

将网络添加到 MetaMask

我们将把 HyperEVM 主网和币安智能链(Binance Smart Chain)主网添加到我们的 MetaMask 钱包中。添加这些网络的最简单方法是前往 hyperevmscan.io 以及 bscscan.com 然后点击 添加 页面左下角的按钮。这将把这些网络添加到您的 MetaMask 钱包中:

恭喜!您已成功为本指南搭建了开发环境。下一步,我们将把一个 HIP-1 资产从 HyperCore 桥接到 HyperEVM。

从 HyperCore 过渡到 HyperEVM

接下来,您将把一项 HIP-1 资产从 HyperCore 桥接到 HyperEVM。此过程涉及将 HIP-1 资产转换为其对应的 HyperEVM 代币形式。在本指南中,我们将使用 Hyperliquid 的原生生态系统代币:HYPE。请前往Hyperliquid 交易界面,并使用MetaMask登录以开始操作。

如果您目前还没有 HYPE 代币,可以通过将 USDC 从 Arbitrum 主网存入 Hyperliquid,然后在交易界面的现货市场将其兑换为 HYPE 来获取:

Hyperliquid 交易界面

提醒
本指南中,我们使用的是各条链的主网。这是因为在撰写本文时,Chainlink CCIP 尚未在 HyperEVM 测试网上线。请谨慎操作,仅使用您能够承受损失的资金。

获得一定数量的HYPE后,您可以将其桥接到HyperEVM。操作时,请点击页面底部图表下方的“转入/转出EVM”按钮。只需输入您要桥接的HYPE数量,然后点击“确认”即可。

将 HYPE 与 HyperEVM 连接起来

将 HYPE 与 HyperEVM 连接起来

太好了!您已成功将 HYPE 从 HyperCore 桥接到 HyperEVM。现在,您应该能在 MetaMask 中看到 HyperEVM 网络上的 HYPE 余额。接下来,我们将创建一个符合 Chainlink 跨链转账要求的 HYPE 包装合约。

为 HYPE 创建一个包装合约

为了利用 Chainlink CCIP 在 HyperEVM 和 BSC 之间实现 HYPE 的跨链转移,我们需要创建一个符合 Chainlink 跨链转移要求的包装合约。这包括在 HyperEVM 上创建一个新的 ERC20 代币合约来包装现有的 HYPE 资产,以及在 BSC 上创建一个相应的 ERC20 代币合约。

我们将创建一个 Quicknode 炒作热潮 符号为 的代币 qWHYPE. 输入以下命令,在 src 项目目录下的文件夹中,并将以下代码粘贴到该文件夹内。

touch src/qWHYPE.sol

理解包装合约

让我们来分析一下 qWHYPE.sol 合同。该合同导入了 BurnMintERC20 来自的合同 @chainlink/contracts 该合约提供了铸造和销毁代币所需的功能。当用户向合约存入 HYPE 时,合约会向其地址铸造等值的 qWHYPE 代币。反之,当用户提取 qWHYPE 代币时,合约会销毁这些代币,并将相应数量的 HYPE 转回用户的地址。

该特定合约将部署在HyperEVM网络上。在BSC上,我们将部署基础版 BurnMintERC20 直接部署该合约,因为它不需要任何额外功能。我们将在下一节中使用脚本部署这两个合约。

《铸造字体的脚本编写》

我们将编写几个 Foundry 脚本,用于部署智能合约并与之交互。本节将分为几个部分,详细介绍每个脚本。我们将创建以下脚本,并按此顺序执行它们:

脚本名称描述
DeployTokens.s.sol在 HyperEVM 上部署 qWHYPE 合约及其基础合约 BurnMintERC20 BSC上的合约
DeployPools.s.sol在 HyperEVM 和 BSC 上部署 CCIP 代币池合约
SetupAdmin.s.sol在每条链的 CCIP 合约上注册并配置管理员角色
ConfigurePools.s.sol配置我们的 CCIP 代币池,以便它们之间进行跨链转账
DepositAndTransferTokens.s.sol向 qWHYPE 合约存入少量 HYPE 以铸造 qWHYPE 代币,然后执行跨链转账至 BSC
TransferTokens.s.sol从任一方向执行 qWHYPE 代币的跨链转账

先决条件

在编写脚本之前,我们需要一种方法来追踪已部署的合约地址,并需要一个文件来存储脚本中将要使用的常用常量。

执行以下命令以创建相应的文件:

touch script/Constants.s.sol
mkdir -p script/output
touch script/output/deployments.json

我们将使用 deployments.json 用于跟踪每条链上已部署合约地址的文件。

以下是 Constants.s.sol 文件应如下所示:

点击展开代码
// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import {Script} from "forge-std/Script.sol";

contract Constants is Script {

struct CCIPConstants {
uint64 chainSelector;
address router;
address rmnProxy;
address tokenAdminRegistry;
address registryModuleOwnerCustom;
string nativeCurrencySymbol;
}

function getCCIPConstants(uint256 chainId) public pure returns (CCIPConstants memory) {
if(chainId == 999) {
return CCIPConstants({
chainSelector: 2442541497099098535,
router: 0x13b3332b66389B1467CA6eBd6fa79775CCeF65ec,
rmnProxy: 0x07f15e9813FBd007d38CF534133C0838f449ecFA,
tokenAdminRegistry: 0xcE44363496ABc3a9e53B3F404a740F992D977bDF,
registryModuleOwnerCustom: 0xbAb3aBB5F29275065F2814F1f4B10Ffc1284fFEf,
nativeCurrencySymbol: "HYPE"
});
} else if (chainId == 56) {
return CCIPConstants({
chainSelector: 11344663589394136015,
router: 0x34B03Cb9086d7D758AC55af71584F81A598759FE,
rmnProxy: 0x9e09697842194f77d315E0907F1Bda77922e8f84,
tokenAdminRegistry: 0x736Fd8660c443547a85e4Eaf70A49C1b7Bb008fc,
registryModuleOwnerCustom: 0x47Db76c9c97F4bcFd54D8872FDb848Cab696092d,
nativeCurrencySymbol: "BNB"
});
}
revert("Chain not supported");
}
}

脚本菜单

该脚本将部署 qWHYPE HyperEVM 上的合约及其基础 BurnMintERC20 BSC 上的合约。在 剧本 项目目录下名为 DeployTokens.s.sol 并将下面的代码粘贴到其中。

点击展开代码

创建文件:

touch script/DeployTokens.s.sol

将以下代码粘贴到文件中:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.24;

import {Script, console} from "forge-std/Script.sol";
import {qWHYPE} from "../src/qWHYPE.sol";
import {BurnMintERC20} from "@chainlink/contracts/src/v0.8/shared/token/ERC20/BurnMintERC20.sol";

contract DeployTokens is Script {
string internal constant OUTPUT_PATH = "script/output/deployments.json";

/// forge script script/DeployTokens.s.sol:DeployTokens
function run() external {
// Load env vars
bytes memory hyperevm = bytes(vm.envString("HYPEREVM_RPC"));
bytes memory bsc = bytes(vm.envString("BSC_RPC"));
uint256 pk = vm.envUint("PRIVATE_KEY");

// Check if env vars are set
require(hyperevm.length != 0, "HYPEREVM_RPC not set");
require(bsc.length != 0, "BSC_RPC not set");

// print deployer address
address deployer = vm.addr(pk);
console.log("Deployer address:", deployer);

// Deploy on both chains
address hyperAddr = deployOn(hyperevm, deployer, pk);
address bscAddr = deployOn(bsc, deployer, pk);

// Write deployed addresses to JSON file
string memory obj = vm.serializeString("deployments", "qWHYPE_hyperevm", vm.toString(hyperAddr));
obj = vm.serializeString("deployments", "qWHYPE_bsc", vm.toString(bscAddr));
vm.writeJson(obj, OUTPUT_PATH);
}

function deployOn(bytes memory rpc, address deployer, uint256 pk) internal returns (address) {
vm.selectFork(vm.createFork(string(rpc)));
vm.startBroadcast(pk);
string memory chainName = getChainName(block.chainid);
address tokenAddr = address(block.chainid == 999 ? new qWHYPE() : new BurnMintERC20("Quicknode Wrapped HYPE", "qWHYPE", 18, 0, 0));
console.log("\nDeployed qWHYPE to:", tokenAddr, "on", chainName);
BurnMintERC20(tokenAddr).grantMintAndBurnRoles(deployer);
console.log("Granted minter and burner roles on", chainName, "qWHYPE to:", deployer);
vm.stopBroadcast();
return tokenAddr;
}

function getChainName(uint256 chainId) internal pure returns (string memory) {
if (chainId == 56) return "\x1b[36mBSC Mainnet\x1b[0m";
else if (chainId == 999) return "\x1b[32mHyperEVM Mainnet\x1b[0m";
else revert("Unsupported chain ID");
}
}

了解 DeployTokens 脚本

在此脚本中,我们首先加载 RPC URL 和私钥的环境变量。然后,我们定义一个 deployOn 该函数接受 RPC URL、部署者地址和私钥作为参数。该函数会创建指定区块链的分叉,使用提供的私钥开始广播交易,并部署 qWHYPE 合约(在 HyperEVM 上)或基础合约 BurnMintERC20 合约(在 BSC 上)。部署完成后,该合约会向部署者地址授予已部署代币合约的铸造和销毁权限。

运行脚本

既然我们已经编写好了所有必要的脚本,就可以按顺序执行它们,以部署和配置我们的 CCIP 代币池,并执行 qWHYPE 代币的跨链转账。

此前,我们讨论过 Hyperliquid 的多区块架构:较小的区块最多使用 2M gas,而较大的区块最多可使用 30M gas。我们的合约部署交易肯定会超过 2M gas 的限制,因此我们需要先启用账户使用较大区块的功能。要实现这一点,请在终端中执行以下命令:

源文件 .env
npx @layerzerolabs/hyperliquid-composer set-block --size--network 主网 --私钥 $PRIVATE_KEY
信息

我们建议不要在命令行中直接传递私钥,因为它可能会被保存在您的 shell 历史记录中。请务必使用环境变量或安全的方法来处理敏感信息!


警告

如果您的钱包尚未在 HyperCore 上注册,此命令可能会因以下原因失败: 该用户或 API 钱包不存在。 请确保您已在 Hyperliquid 上完成充值或交易,以注册您的钱包。如果您按照 从 HyperCore 过渡到 HyperEVM 没错,您的钱包已经注册成功了!

太好了!我们的账户现在可以使用更大的区块了。接下来,我们将使用 DeployTokens.s.sol 脚本:

forge 脚本 script/DeployTokens.s.sol:DeployTokens --broadcast --验证 --验证器 etherscan

该命令将把我们的代币部署到 HyperEVM 和 BSC 两个网络上。您将在终端中看到部署进度,并在交易确认后看到交易哈希值。该 --广播 该标志表示我们希望将交易发送到网络,而 --验证 以及 --验证器 etherscan 部署完成后,flags 会自动在 hyperevmscan.io 和 bscscan.com 上验证我们的合约。您还会注意到您的 deployments.json 文件中已填入了已部署合约的地址。您的终端输出应类似如下:

部署输出

接下来,我们将使用 DeployPools.s.sol 脚本:

forge 脚本 script/DeployPools.s.sol:DeployPools --broadcast --验证 --验证器 etherscan

该命令将把我们的代币池部署到 HyperEVM 和 BSC 两个网络上。与上一步类似,您将在终端中看到部署进度,并在交易确认后看到交易哈希。该 deployments.json 该文件将更新为已部署的池地址。您的终端输出应类似如下:

池部署输出

接下来,我们将使用 SetupAdmin.s.sol 使用以下命令编写脚本并配置我们的资源池: ConfigurePools.s.sol 脚本。我们可以使用以下命令依次执行这两个脚本:

forge 脚本 script/SetupAdmin.s.sol:SetupAdmin --broadcast
forge 脚本 script/ConfigurePools.s.sol:ConfigurePools --broadcast

与上一步骤一样,一旦交易得到确认,您将看到类似的终端输出,其中包含交易哈希值。

我们的首次跨链转账

最后,我们将使用……将 qWHYPE 代币从 HyperEVM 跨链转账至 BSC。 DepositAndTransferTokens.s.sol 脚本:

forge 脚本 script/DepositAndTransferTokens.s.sol:DepositAndTransferTokens --broadcast

该命令将向 HyperEVM 存入 HYPE 以铸造 qWHYPE,随后将 qWHYPE 代币转至 BSC。交易确认后,您将在终端中看到转账进度及交易哈希。您还将看到该转账的 CCIP 消息 ID,可用于在Chainlink CCIP 浏览器上追踪转账状态。您的终端将输出如下所示的消息 ID:

传输输出 显示 CCIP 消息 ID 的终端输出

让我们验证一下是否 qWHYPE 代币已成功存入 BSC 网络。请打开您的 MetaMask 钱包,切换至 BSC 网络,然后导入该 qWHYPE 使用您在 deployments.json 包含密钥的文件 qWHYPE_bsc. 如果您在导入代币时需要帮助,请按照 MetaMask 的指南操作 这里. 您应该会在钱包中看到 0.01 qWHYPE 代币的余额,这表明跨链转账已成功!


MetaMask 余额

向任意方向转移

TransferTokens.s.sol 该脚本可用于在 HyperEVM 和 BSC 之间双向转移 qWHYPE 代币。您可以通过传递以下任一参数来指定转移方向: to-bscto-hyperevm 作为运行脚本时的参数。例如,若要将 qWHYPE 代币从 BSC 转入 HyperEVM,请运行以下命令:

forge 脚本 script/TransferTokens.s.sol:TransferTokens --broadcast --sig 'run(string)' 'to-hyperevm'

输出结果将与我们的首次跨链转账类似,显示交易哈希和 CCIP 消息 ID。将该消息 ID 粘贴到Chainlink CCIP 浏览器中,现在将显示反向的转账记录:

CCIP Explorer 反向

结论

恭喜!您已成功掌握如何使用 Chainlink CCIP 在 Hyperliquid 上进行代币跨链桥接。您已部署了自己的 ERC-20 代币,设置了 CCIP 代币池,并在 HyperEVM 与 BSC 之间完成了 qWHYPE 代币的跨链转账。

下一步

既然您已经拥有了一个可正常运行的跨链桥,就可以进一步优化和定制您的配置了。以下是一些建议:


  • Hyperliquid Bridge UI:使用 React 或 Vue.js 等框架为您的桥接器构建一个用户友好的界面。这样,用户无需使用命令行工具,即可轻松与您的桥接器进行交互。
  • 速率限制: 在您的代币池中实施速率限制,以防止滥用并确保公平使用。您可以在 ConfigurePools.s.sol 脚本。
  • 实现更多链:扩展您的桥接方案,以支持 Chainlink CCIP 支持的其他链。您可以按照本指南中概述的相同步骤,在其他链上部署和配置代币池。请在CCIP 目录中查看通道和支持的链。
  • 包装其他 HIP-1 资产:您可以按照与处理 HYPE 时类似的流程,在 Hyperliquid 上为其他 HIP-1 资产创建并部署额外的包装代币。唯一的区别在于,需要为每种资产分别创建一个包装 ERC-20 合约。这将使用户能够在 HyperEVM 与其他链之间桥接更广泛的资产。

更多资源


如果您遇到困难或有任何疑问,欢迎在我们的Discord 频道中提出。请关注我们的X账号(@Quicknode)或Telegram 公告频道,随时了解最新动态。

我们 ❤️ 您的反馈!

如果您对本文档有任何反馈或疑问,请告诉我们。我们非常期待您的反馈!

分享本指南