共享有效性排序(Validity Sequencing)

本文介绍了一种共享有效性排序的新架构,旨在增强乐观 Rollup 之间的原子跨链互操作性。通过引入共享排序器,支持跨链操作和条件执行,解决了当前乐观 Rollup 设计中的中心化与互操作性问题。该设计促进了一种统一的原生资产层,支持更灵活的多 Rollup 生态系统。

介绍

以太坊扩展的未来之一是一个有成千上万的 rollup的世界。今天,主流的 rollup 是乐观 rollup,大多数 rollup-as-a-service 公司也在构建乐观 rollup。

目前乐观 rollup 设计面临两个主要问题:

  • Rollup 依赖于中心化的排序器,这是软审查和 MEV 租金中心化的一个途径。
  • 在乐观 rollup 之间没有良好的原子互操作性解决方案。由于乐观 rollup 安全模型中的 7 天挑战期,一个乐观 rollup 不能在不等待欺诈证明窗口结束的情况下验证另一个的状态。因此,现有的跨 rollup 桥接和互操作性设计(任意消息传递)在本质上是中心化和异步的。

已提出共享、去中心化的排序器集合作为去中心化 rollup 排序器角色的一种方式。但现有设计仅执行交易排序,因此只解决了第一个问题,而没有解决原子跨 rollup 互操作性问题。

在这篇文章中,我们提出了一种共享的排序器架构,能够实现原子跨 rollup 互操作性。共享有效性排序解锁了一个可以服务于整个 rollup 生态系统的原生资产统一层。

背景

考虑两个乐观 rollup A 和 B。为了清晰起见,该设计推广到 NNN 个 rollup,但我们使用 2 个 rollup 来描述系统。

在当前的环境中,针对 A 和 B 的两个排序器独立地承诺对两个 rollup 的交易排序。

目标是使 A 和 B 之间能够实现原子跨链操作。具体而言,A 上的交易 aia_iai​ 仅在 B 上相应交易 bjb_jbj​ 被包含并成功时才能包含并成功(不回滚)。

使用上述原语的经典示例是对两个 rollup 之间共享代币的 burnmint。从 rollup A 向 rollup B 连接共享代币的用户需要确保 rollup A 上的 burn 交易仅在 rollup B 上的 mint 交易成功时才能成功。否则,资金可能会丢失(例如,如果 burn 成功但 mint 不成功)或被错误铸造(例如,如果 burn 由于用户余额不足而回滚,但 mint 仍然被包含)。

请注意,在不执行交易 aia_iai​ 的情况下,无法知道该交易是否会成功执行,或者其成功是否需要满足跨域条件。没有某种程度的执行在排序器层面,很可能无法实现跨 rollup 原子性。

现有的共享排序器设计不需要排序器执行交易,因此仅通过条件包含启用了一种弱形式的互操作性。由不执行的共享排序器提供的原子交易包含并不支持原子代币桥接,因为代币铸造/销毁的不变性无法以与底层欺诈证明机制相同的安全性强制执行。一般而言,原子条件交易执行是一种比原子交易包含更具表现力的原语。

共享有效性排序

在这里,我们描述共享有效性排序,这是一种能够实现乐观 rollup 之间原子跨链互操作性的共享排序器设计。该设计有三个关键组成部分:

  • 共享排序器接受跨链操作的方法
  • 共享排序器的区块构建算法,用于处理这些跨链操作,同时尊重原子性和条件执行的保证
  • 在相关的 rollup 之间的共享欺诈证明,以强制执行这些跨链操作的保证

为了简单起见,我们概述一个能够实现两个 rollup 之间原子 burnmint 操作的系统:当且仅当 rollup B 上的相应 mint 成功时,rollup A 上的 burn 成功。之后,我们将系统推广到任意的跨 rollup 消息传递。

使用系统合约的跨链操作

目前,rollup 通过设定系统合约来实现特定的 rollup 功能,例如 L1 和 L2 之间的双向消息传递以及其他特殊预编译合约。我们建议添加一个系统合约,使得其他智能合约能够触发跨链操作。

contract MintBurnSystemContract {
    uint256 burnNonce = 0;

    // 包含所有 `burn` 操作的树
    MerkleTree burnTree;

    uint256 mintNonce = 0;

    // 包含所有 `mint` 操作的树
    MerkleTree mintTree;

    // 任何合约/EOA 均可以在链 A 上调用此函数,此时将触发
    // 排序器在链 B 上调用 `mint`
    function burn(address sender, address token, uint256 amount) external {
        IERC20(token).transferFrom(sender, amount);

        // 注意 msgHash 仅在 `transferFrom` 成功时插入到 burnTree 中,否则整个 `burn` 交易将回滚。
        bytes32 msgHash = keccak256(abi.encode(sender, token, amount, burnNonce++));
        burnTree.insert(msgHash);

        emit SystemContractBurn(sender, token, amount, burnNonce);
    }

    // 仅排序器可以调用此函数
    function mint(address sender, address token, uint256 amount) external onlySequencer {
        IERC20(token).mint(sender, amount);

        bytes32 msgHash = keccak256(abi.encode(sender, token, amount, mintNonce++));
        // 注意 msgHash 仅在 `mint` 成功时插入到 mintTree 中,否则整个 `mint` 交易将回滚。
        mintTree.insert(msgHash);

        emit SystemContractMint(sender, token, amount, mintNonce);
    }
}

该合约的副本在两个 rollup 上均存在,用于原生代币的原子桥接。 在 rollup A 上,burnTree 包含所有包含的 burn 操作。 在 rollup B 上,mintTree 包含所有包含的 mint 操作。 所希望的不变性是 A 上的 burnTree 与 B 上的 mintTree 相同,或者等价地说,它们的 Merkle 根相等。

Mint Burn 结构

使用共享有效性排序的区块构建

在此设计下,rollup A 和 B 共享一个排序器。该共享排序器负责将交易批次和声明的状态根发布到 L1,以供两个 rollup 使用。共享排序器可以是一个中心化排序器,例如当前生产中的 rollup 排序器,或者来自去中心化网络的领导者。

我们施加的唯一要求是,共享排序器必须在同一交易中为两个 rollup 发布交易批次和声明的状态根。虽然不同的 rollup 可以选择不同的交易排序和区块构建方法,但我们对区块构建器的修改应与大多数排序机制兼容。

共享排序器接收交易并为 A 和 B 构建区块。对于 A 上的每个交易,排序器执行该交易并检查其是否与 MintBurnSystemContract 交互。如果交易成功执行并与 burn 函数交互,共享排序器尝试在 B 上执行相应的 mint 交易。如果 mint 交易成功,共享排序器将 burn 交易和 mint 交易都包含;然后,如果 mint 交易失败,共享排序器将排除这两个交易。

上述区块构建修改是对现有区块构建算法的简单扩展。它仅要求共享排序器为两个 rollup 构建区块,并且排序器执行交易并将条件触发的交易从一个 rollup 插入到另一个。

共享欺诈证明

乐观 rollup 最重要的部分是有效的、无需许可的欺诈证明;这就是 rollup 如何从底层 L1 中继承安全性(今日,Optimism 没有欺诈证明,而 Arbitrum 有白名单欺诈证明)。我们已经描述了共享排序器如何条件性地包含它同时排序的两个链上的交易。现在我们再描述一下欺诈证明如何强制执行条件包含。

欺诈证明是在 L1 上的一种机制,用于确保 rollup 排序器诚实地处理交易并更新状态。扩展现有欺诈证明机制以确保排序器诚实地处理跨链操作并正确包含这些条件交易既简单又优雅。

上述的 MintBurnSystemContract 维护了一个包含一个 rollup 上所有 burn 交易以及它们在另一个 rollup 上对应 mint 交易的 Merkle 树。条目仅在交易成功时才进入 Merkle 树。因此,为了确保 rollup A 上所有 burn 交易在 rollup B 上有对应的 mint 交易,只需检查 A 上的 burnTree 的 Merkle 根是否与 B 上的 mintTree 的 Merkle 根匹配。

只需对 rollup A 和 B 的现有欺诈证明机制进行小幅修改。 如果 A 上的 burnTree 的根不匹配 B 上的 mintTree 的根,就认为排序不当,责任排序器可以受到惩罚。

另一种强制执行跨链原子性保证的机制是,接受 rollup 交易批次的 L1 智能合约还要求在批次提交时提供 Merkle 证明,证明 A 上的 burnTree 的根与 B 上的 mintTree 的根匹配。

超越 Mint 和 Burn 的推广

我们已经概述了共享有效性排序,仅包含 mintburn 函数。但它可以很容易推广到任意消息传递和多个 rollup 之间的条件交易执行。可以调用跨 rollup 操作,强制执行的不变性是,所有触发的合约调用都成功并被包含,或者它们都不成功。

contract GeneralSystemContract {
    uint256 triggerNonce = 0;
    MerkleTree triggerTree;

    uint256 actionNonce = 0;
    MerkleTree actionTree;

    address crossChainSender = address(0);

    // 任何合约/EOA 均可在链 A 上调用此函数,触发
    // 排序器调用链 B 上的 `action`
    function trigger(address addr, bytes calldata_, uint256 gasLimit) external {
        bytes32 msgHash = keccak256(
            abi.encode(msg.sender, addr, calldata_, gasLimit, triggerNonce++)
        );
        triggerTree.insert(msgHash);

        emit SystemContractTrigger(msg.sender, addr, calldata_, gasLimit, triggerNonce);
    }

    // 仅排序器可以调用此函数
    function action(
        address sender,
        address addr,
        bytes calldata_,
        uint256 gasLimit
    ) external onlySequencer {
        crossChainSender = sender; // 设置 crossChainSender
        (bool status, bytes data) = addr.call{gas:gasLimit}(calldata_);
        require(status == true); // 要求调用成功
        bytes32 msgHash = keccak256(
            abi.encode(sender, addr, calldata_, gasLimit, actionNonce++)
        );
        actionTree.insert(msgHash);

        emit SystemContractAction(sender, addr, calldata_, gasLimit, actionNonce);
        crossChainSender = address(0); // 重置 crossChainSender
    }

    // 允许触发的操作获取源链上的原始 msg.sender
    function messageSender() external returns(address) {
        require(crossChainSender != address(0));
        return crossChainSender;
    }
}

共享有效性排序的特性

与单体链的比较

通过共享有效性排序支持原子跨 rollup 交易的一组 rollup 在逻辑上可以被视为一个大型链,有多个分片。与单体 rollup 相比,具有以下好处:

  • 每个单独 rollup 的本地费用市场
  • 一套锁定的定价机制:跨 rollup 操作有效地在两个链上获取锁定
  • 开箱即用的分片:可以选择信任某些分片并验证其他分片
  • 支持不同的执行环境,例如时间为特定用例优化的应用链

这些都是今天与单体 rollup 的差异点。与支持并行执行和弱本地费用市场的高性能基础层 Solana 相比,最大的区别在于原生支持不同的执行环境和与以太坊路线图的兼容性。然而,在共享有效性排序下,将多个 rollup 结合起来形成单一分片状态机相对于从第1天开始设计支持并行性基础层而言是一种粗糙且低效的实现。吞吐量、费用和最终确定时间始终会受到以太坊的限制。

排序器和节点需求

与仅排序交易而不执行它们的共享排序器设计相比,共享有效性排序对共享排序器负载更大。共享排序器需要执行所有交易,以便访问当前状态并确定是否触发其他交易的执行。请注意,跨不同 rollup 的执行仍然可以默认实现分片。

rollup A 的完整节点操作员还必须为 rollup B 运行完整节点,因为 A 的有效性不仅依赖于 A 的有效状态转换,还依赖于跨 rollup 状态 (A + B) 的有效性。为了验证 A 的有效性,节点操作员还必须验证跨 rollup 状态(A + B)的有效性,这要求验证 B 的有效性。

主权性

该模型将 rollup A 和 B 的有效性耦合在一起,因为它们各自状态的有效性现在相互依赖。对于 rollup 作出耦合以实现组合性而言,这是一个意见化的决定。它们的应用的主权性要比如果部署在单体链上的场景大,但比如果它们是应用链的场景小。我们将在未来的文章中探讨这些模型之间的权衡。

应用主权

对 ZK Rollup 的应用

ZK rollup 天生具有异步互操作性,因为它们可以直接验证彼此的 ZK 证明。但实现原子互操作性仍然有其好处,包括更好的用户体验和同步组合性。

尽管该共享有效性排序设计是为乐观 rollup 创建的,但可稍作修改以适用于 ZK rollup。MintBurnSystemContract 和排序器区块构建算法保持不变。共享欺诈证明被提议的替代机制所替代,即接受交易批次的 L1 智能合约和验证 rollup 状态转换的 ZK 证明现在还必须验证 A 上的 burnTree 的根与 B 上的 mintTree 的根相匹配。

在本设计下,ZK rollup 的 A 的完整节点操作员不需要为 B 运行完整节点。为了验证跨 rollup 不变性,它可以仅验证 B 的状态转换证明,并使用 Merkle 证明获取 B 的 MintBurnSystemContract 状态。

结论

在这篇文章中,我们描述了共享有效性排序这一共享排序器设计,它能够实现 rollup 之间的原子互操作性。在该设计下,排序器除了排序交易之外,还负责执行交易,从而在增加排序器和节点操作员负担的同时,加强了跨链不变性的执行。 通过选择与其他 rollup 共享有效性,rollup 能够获得原子互操作性及其相关好处(如统一的原生资产层)。该系统推广到多个 rollup,包括 ZK rollup。

共享有效性排序及其权衡可能对某些 rollup 生态系统来说是合理的。如果你希望与我们合作,请联系 collaborators@umbraresearch.xyz

  • 原文链接: umbraresearch.xyz/writin...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
umbraresearch
umbraresearch
Umbra Research is exploring novel ideas in blockchain research.