Optimism 中文力量

2025年06月23日更新 11 人订阅
专栏简介 Superscan:超级链生态系统的终极区块浏览器 Retro Funding 5: OP Stack Optimism 第 6 季 超超600 ETH奖励,Onchain Summer 正在进行 Optimism 中文周刊 #24 什么是欺诈证明 OP Labs | 无需许可的故障证明上线,OP Stack 进入第 1 阶段 OP Labs |故障证明系统已适用于 OP Stack OP Labs|基线权力下放 统一的超级链:互操作性 OP Labs|故障证明深入研究的第二部分:Cannon 从上层的视角看看 OP Chain 的架构和工作流程 OP Labs|游戏开始了:为 OP Stack 的故障证明系统设计模块化争议游戏 索尼进军区块链领域 — Soneium 加入超级链 解密超级链 —— 如何与 Optimism 集体共享收益 Optimism 治理体系概述 当 OP Stack 进化成 OP “超级链”概念 OP Labs|从 EIP 到以太坊主网:4844 的集体胜利 OP Labs | 开源且功能完备的欺诈证明为 OP Sepolia 测试网带来无需许可的验证 Retro Funding: 从大范围到小范围的轮次转变 Retro Funding 6 : 治理 从以太坊或 OP 主网铸造 NFT 以太坊 L2 治理机制的比较分析 OP Labs | 对 OP Stack 故障证明系统中的诚实行为和参与度进行激励 活跃投票者的链上行为指标是什么? Optimism 徽章持有者链上活动分析 欢迎 Unichain 加入超级链 欢迎 Ink 加入超级链 OP 超级链的崛起 我们共同的 Optimism Optimism Retro Funding 投票机制对恶意行为的抵抗能力 构建以太坊的未来:超级链和原生互操作性 Retro Funding 2025 Super Accounts: 加速超级链上的有意义的贡献 Optimism 与 Uniswap 共同提出的 ERC-7802 是什么? 迈向跨链的未来:打破链间壁垒 以太坊互操作性论坛 :团结一致迎接互操作性的未来 Optimism 第 7 季指南 Optimism:2024 年回顾 OP 残酷共学第一周学习回顾 Optimism 第 7 季资助现已开放 跨超级链的协作分析 Optimism Retro Funding:Dev-tooling Optimism Retro Funding:Onchain Builders 任务详情 新产品介绍:Superchain.Eco 欢迎 Celo 加入 Superchain 生态系统 Superchain 互操作性资产正式落地:USDT0 率先实现全链部署 Superseed 主网现已上线 Superchain.Eco 上的机会信息流介绍 SuperStacks:Superchain 上的全新奖励方式 Superchain 残酷共学成果展:从Rollup原理到 OP 测试链搭建实战 Celo Public Goods Superseed 的 SUPR 现已上线 PeerDAS 与 2025 年的 48 Blob 目标 Superchain|如何赚取 SuperStacks XP 超级账户 1.2:活动、金库及贡献成就徽章 Lisk Surge 在 2025 年,Superchain 的有效衡量指标有哪些? 在 2025 年,Superchain 的有效衡量指标有哪些? 在 2025 年,Superchain 的有效衡量指标有哪些? 在 2025 年,Superchain 的有效衡量指标有哪些? 在 2025 年,Superchain 的有效衡量指标有哪些? 在2025年,Superchain的有效衡量指标有哪些? Optimism 第八季治理:新阶段 Optimism 追加200万赏金至协议升级,助力Superchain互操作 使用 Relayer.sol 进行端到端的多链测试

使用 Relayer.sol 进行端到端的多链测试

原文|End-to-EndMultichainTestingwithRelayer.solRelayer.sol为你的Forge测试环境带来了原生的多链端到端测试能力。通过继承抽象的Relayer测试辅助类,你的测试可以:启动多个网络的分叉(fork)、真实地发送L2ToL2

Screenshot-2025-06-18-at-3.09.38---PM (1).png

原文|End-to-End Multichain Testing with Relayer.sol

Relayer.sol 为你的 Forge 测试环境带来了原生的多链端到端测试能力。通过继承抽象的 Relayer 测试辅助类,你的测试可以:启动多个网络的分叉(fork)、真实地发送 L2ToL2CrossDomainMessenger 事件、并在同一个 forge test 流程中完成消息的中继传输——无需额外的 relayer 或脚本粘合。在本文中你将学到如何:

  • 使用 Supersim 节点运行的 RPC 接口配置多链分叉
  • 在多个链上部署合约并进行交互
  • 用一次调用中继所有消息(或只中继部分)
  • 和普通单元测试一样,断言目标链上的状态变化

Superchain Interop(超级链互操作)有望彻底改变去中心化应用开发的范式。它将实现低延迟、无缝的跨链消息传递与资产桥接,而为了构建适应这一未来的应用,你需要升级自己的跨链测试工作流。

为什么你的测试中需要一个 relayer?

超级链的跨链交互流程是事件驱动的:

某个合约调用 L2ToL2CrossDomainMessenger.sendMessage(),消息器发出 SentMessage 事件,然后一个链下 relayer 监听该事件并向目标链发送执行交易——只有这样,消息载荷才会真正执行。

Relayer.sol 将这一 relayer 逻辑直接内嵌到 Forge 中,无需不稳定的 sleep 等待,也不需要手动 cast 命令,非常适合本地 CI 流程中的自动化测试。

最终,Relayer.sol 将跨链测试从“分别跑两个测试套件,然后祈祷桥接成功”转变为“在 Forge 内部验证:这个消息确实在链 B 上成功执行了”。它去除了外部依赖,减少了样板代码,并使你的测试环境更加贴近主网现实。

image (4).png

Relayer.sol 极大简化了跨链测试流程

项目设置

1. 添加互操作库

forge install ethereum-optimism/interop-lib

Relayer.sol 位于 repo https://github.com/ethereum-optimism/interop-lib 的 src/test/Relayer.sol 下。

2. 启动 Supersim 并将 Foundry 指向它

安装 Supersim

brew install ethereum-optimism/tap/supersim      # macOS/Linux

启动一个原版超级链

supersim 

Supersim 启动三个本地 anvil 节点,预先部署 Superchain 互作合约,并公开 JSON-RPC 端点:

Chain  链 ID RPC URL  RPC 网址
L1(主网) 900 http://127.0.0.1:8545
L2-A 901 http://127.0.0.1:9545
L2-B 902 http://127.0.0.1:9546

有关 Supersim 以及自定义本地开发工作流程的各种方式的更多信息,请查看 Supersim 文档 。

在 foundry.toml 中告诉 Foundry 这些 RPC

[rpc_endpoints]
l2a = "<http://127.0.0.1:9545>"
l2b = "<http://127.0.0.1:9546>"

需要测试网? 如果您想尝试互作的测试网,请跳过 Supersim,或者通过更改 foundry.toml 以指向这些测试网端点,将您的项目从本地开发升级到测试网(请参阅文档以获取最新的端点):

[rpc_endpoints]
devnet0 = "<https://interop-alpha-0.optimism.io>"
devnet1 = "<https://interop-alpha-1.optimism.io>"

编写跨链的测试

以下是参考 CrossChainIncrementer.t.sol 测试的精简版本:

contract IncrementerTest is Relayer {
    /**
     * 0. Constructor – pass Supersim RPC URLs to Relayer so it can map
     *    chainIds ↔ forkIds under the hood.
     */
    constructor() Relayer(_rpcUrls()) {}

    function _rpcUrls() internal view returns (string[] memory urls) {
        urls = new string[](2);
        urls[0] = vm.rpcUrl("l2a"); // source
        urls[1] = vm.rpcUrl("l2b"); // destination
    }

    // 1. Fork identifiers
    uint256 l2aFork;
    uint256 l2bFork;

    // ──────────────── 2. Contract handles ────────────────
    Counter src;              // lives on l2a fork
    Counter dst;              // lives on l2b fork

    function setUp() public {
        // Foundry forks
        l2aFork = vm.createFork(vm.rpcUrl("l2a"));
        l2bFork = vm.createFork(vm.rpcUrl("l2b"));

        // 2. Deploy contracts on each chain
        vm.selectFork(l2aFork);
        src = new Counter();

        vm.selectFork(l2bFork);
        dst = new Counter();
    }

    function testIncrementAcrossChains() public {
        // 3. Build a message on the source chain
        vm.selectFork(l2aFork);
        L2ToL2CrossDomainMessenger(payable(CDM_ADDR)).sendMessage(
            address(dst),
            abi.encodeCall(dst.increment, ()),
            100_000
        );

        // 4. Relay everything that was just logged
        relayAllMessages();

        // 5. Assert on the destination chain
        vm.selectFork(l2bFork);
        assertEq(dst.count(), 1);
    }
}

让我们来了解一下这里发生了什么。

第 1 步:分叉网络

vm.createFork 会克隆远程链的状态;vm.selectFork 用于切换当前激活的链分叉。请保留返回的 ID —— 在你跨链切换时将会用到它们。

第 2 步:自动记录日志

Relayer 构造函数调用 vm.recordLogs() 表示每个触发的事件都会被捕获。你无需手动添加这一逻辑,只需继承这个辅助类即可!

第 3 步:发出互操作消息

L2ToL2CrossDomainMessenger.sendMessage 为您提供开箱即用的重放保护和域绑定。完全按照您在链上的方式使用它。

第 4 步:在测试中中继

  • relayAllMessages() 通过 vm.getRecordedLogs() 获取日志缓冲区,筛选出 SentMessage 事件,并在对应的目标分叉上重新执行每条消息。
  • 需要更多控制?你可以将 vm.log[] 的一个切片传给 relayMessages(),手动决定哪些事件需要中继。

第 5 步:断言状态

一旦消息中继完成,切换回目标分叉(再次调用 vm.selectFork("l2a")),然后像普通单元测试一样进行断言。由于所有操作都是在同一进程中同步执行的,不会出现竞态条件或轮询循环的问题。、

要查看此测试模式的实际效果,请查看此处 !

高级用法

细粒度中继

有时你只想中继部分事件。由于 SentMessage 日志中不包含来源链的信息,你需要手动传入生成这些日志的 sourceChainId

Vm.Log[] memory logs = vm.getRecordedLogs();
relayMessages(slice(logs, 1, 3), 901); // 仅中继第二条和第三条消息

这个功能在你需要缓存日志并进行中继以外的操作时特别有用。因为 vm.getRecordedLogs() 每次调用都会清空缓冲区,你可以先获取一次,存储下来,然后对原始事件进行自定义断言、解码、模糊测试等操作,最后将相同的切片(或过滤后的子集)传入 relayMessages()。这允许你仅中继感兴趣的消息,重复中继以测试重放保护机制,或保留日志用于覆盖率统计 —— 无需额外的链上事件,也不会丢失数据。

Promise 测试(实验性)

Interop 库还提供了一个 Promise 原语,用于保障消息交付的语义;早期测试套件可见于 Promise.t.sol。未来该辅助模块将添加更多原生的 Promise 工具!

常见陷阱

  • 缺少预部署合约:如果你在本地节点运行,且没有部署 messenger 合约,则会回退。建议使用 Supersim 或 devnet 测试网络。
  • 日志缓冲区被消费vm.getRecordedLogs() 每次调用都会清空缓冲区。如需多次使用,请务必缓存结果。

整合应用

只需不到 40 行模板代码,你就能实现真实、确定性的多链测试,几秒内运行完成:

supersim &         # 一次性启动 Supersim
forge test -vvvv   # 所有消息都在本地中继并测试

在幕后,Forge 会:

  1. fork 两条 L2 链(使用 Supersim)
  2. 执行源链上的交易
  3. 在目标链 fork 上重放日志
  4. 断言目标链的状态变化(后置条件)

这一切都发生在 EVM 内部,无需依赖外部基础设施 —— 这就是 Relayer.sol 的强大之处。用它试一试,打破几条跨链消息,在上线前让你的逻辑变得坚不可摧。祝你测试愉快!

延伸阅读

在加密行业,尤其是 OP Labs,我们的工作独一无二。尽管面临的挑战巨大,复杂性惊人,但有时,简单的流程就能带来质的飞跃。

OP Labs 正在招聘愿意在技术与安全的最前沿工作的优秀人才。如果你想加入一个世界级的团队,参与世界级的项目,欢迎联系我们


Join us

微信公众号: Optimism 中文

Twitter: https://x.com/Optimismzh

Telegramhttps://t.me/optimism_cn

Medium: https://medium.com/@optimismcn

微信群:公众号后台回复 【加群】


点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论