争议游戏接口

本文档定义了争议游戏(Dispute Game)的接口,争议游戏用于在乐观rollup中,当对layer2状态的声明产生争议时,由多方参与进行仲裁。文档详细描述了DisputeGameFactoryDisputeGame两个核心接口,以及相关的类型定义,为不同证明系统(如欺诈证明、有效性证明、认证证明)的实现提供了灵活性。

争议游戏接口

<!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- 不要编辑此节,请重新运行 doctoc 以更新 --> 目录

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

概述

当对声明的真实性存在争议时,多方之间会进行争议游戏。在乐观 Rollup 的上下文中,关于 Layer2 网络的状态会做出声明,以实现向 Layer1 的提款。 提议者会对 Layer2 状态做出声明,以便他们可以提款,而挑战者可以对声明的有效性提出异议。 Layer2 的安全性来自于能够对欺诈性提款提出异议。

定义争议游戏接口是为了允许多个争议游戏的实现存在。 如果多个争议游戏在生产环境中运行,则它提供了类似于拥有多个协议客户端的安全模型,因为单个争议游戏中的 Bug 不会导致该 Bug 达成共识。

类型

为了增加上下文,我们定义了以下代码片段中使用的一些类型。


/// @notice 用于通用哈希的自定义类型。
type Hash is bytes32;

/// @notice 专用的时间戳类型。
type Timestamp is uint64;

/// @notice 正在使用的证明系统的类型。
enum GameType {
    /// @dev 该游戏将使用利用故障证明的 `IDisputeGame` 实现。
    FAULT,
    /// @dev 该游戏将使用利用有效性证明的 `IDisputeGame` 实现。
    VALIDITY,
    /// @dev 该游戏将使用利用 Attestation 证明的 `IDisputeGame` 实现。
    ATTESTATION
}

/// @notice 争议游戏的当前**状态**。
enum GameStatus {
    /// @dev 游戏当前正在进行中,尚未解决。
    IN_PROGRESS,
    /// @dev 游戏已结束,并且 `rootClaim` 已成功受到挑战。
    CHALLENGER_WINS,
    /// @dev 游戏已结束,并且无法对 `rootClaim` 提出异议。
    DEFENDER_WINS
}

/// @notice 专用的时间戳类型。
type Timestamp is uint64;

/// @notice `Claim` 类型表示 32 字节的哈希或其他用于声明关于特定信息的唯一标识符。
/// @dev 对于 `FAULT` `GameType`,这将是**状态**转换结束时故障证明程序的 Merklized **状态**的根。
///      对于 `ATTESTATION` `GameType`,这将是一个输出根。
type Claim is bytes32;

DisputeGameFactory 接口

争议游戏工厂负责创建新的 DisputeGame 合约,给定一个 GameType 和一个根 Claim。 挑战者代理将监听由工厂发出的 DisputeGameCreated 事件以及与其他事件,这些事件与检测故障有关(即 OutputProposed(bytes32,uint256,uint256,uint256)),以便跟上协议中正在进行的争端。

一个 clones-with-immutable-args 工厂(最初由 @wighawag 制作,但由 @Saw-mon-and-Natalie 分叉)用于创建 Clones。 每个 GameType 在工厂中都有一个对应的实现,当创建一个新游戏时,工厂会创建一个 GameType 的预部署实现合约的克隆。

创建的争议游戏的 rootClaim 可以是创建者同意或不同意的声明。 这是一个实现细节,留给 IDisputeGame 在其 resolve 函数中处理。

DisputeGameFactory 创建一个新的 DisputeGame 合约时,它会在克隆上调用 initialize() 来设置游戏。

/// @title IDisputeGameFactory
/// @notice DisputeGameFactory 合约的接口。
interface IDisputeGameFactory {
    /// @notice 在创建新争议游戏时发出
    /// @param disputeProxy 争议游戏代理的地址
    /// @param gameType 争议游戏代理实现的类型
    /// @param rootClaim 争议游戏的根声明
    event DisputeGameCreated(address indexed disputeProxy, GameType indexed gameType, Claim indexed rootClaim);

    /// @notice 当将新游戏实现添加到工厂时发出
    /// @param impl 给定 `GameType` 的实现合约。
    /// @param gameType DisputeGame 的类型。
    event ImplementationSet(address indexed impl, GameType indexed gameType);

    /// @notice 此工厂创建的争议游戏总数。
    /// @return gameCount_ 此工厂创建的争议游戏总数。
    function gameCount() external view returns (uint256 gameCount_);

    /// @notice `games` 查询一个内部映射,该映射将 `gameType ++ rootClaim ++ extraData` 的哈希映射到已部署的 `DisputeGame` 克隆。
    /// @dev `++` 等于连接。
    /// @param _gameType DisputeGame 的类型 - 用于确定代理实现
    /// @param _rootClaim DisputeGame 的根声明。
    /// @param _extraData 应该提供给创建的争议游戏的任何额外数据。
    /// @return proxy_ 使用给定参数创建的 `DisputeGame` 的克隆。
    ///         如果不存在,则返回 `address(0)`。
    /// @return timestamp_ 争议游戏创建的时间戳。
    function games(GameType _gameType, Claim _rootClaim, bytes calldata _extraData)
        external
        view
        returns (IDisputeGame proxy_, Timestamp timestamp_);

    /// @notice `gameAtIndex` 返回给定索引处的争议游戏合约地址及其创建时间戳。
    ///          每个创建的争议游戏都会递增基础索引。
    /// @param _index 争议游戏的索引。
    /// @return gameType_ DisputeGame 的类型 - 用于确定代理实现。
    /// @return timestamp_ 争议游戏创建的时间戳。
    /// @return proxy_ 使用给定参数创建的 `DisputeGame` 的克隆。
    ///         如果不存在,则返回 `address(0)`。
    function gameAtIndex(uint256 _index)
        external
        view
        returns (GameType gameType_, Timestamp timestamp_, IDisputeGame proxy_);

    /// @notice `gameImpls` 是一个将 `GameType` 映射到它们各自的 `IDisputeGame` 实现的映射。
    /// @param _gameType 争议游戏的类型。
    /// @return impl_ 游戏类型的实现地址。
    ///         将在使用给定 `GameType` 创建新争议游戏时进行克隆。
    function gameImpls(GameType _gameType) external view returns (IDisputeGame impl_);

    /// @notice 创建一个新的 DisputeGame 代理合约。
    /// @param _gameType DisputeGame 的类型 - 用于确定代理实现。
    /// @param _rootClaim DisputeGame 的根声明。
    /// @param _extraData 应该提供给创建的争议游戏的任何额外数据。
    /// @return proxy_ 创建的 DisputeGame 代理的地址。
    function create(GameType _gameType, Claim _rootClaim, bytes calldata _extraData)
        external
        returns (IDisputeGame proxy_);

    /// @notice 设置特定 `GameType` 的实现合约。
    /// @dev 只能由 `owner` 调用。
    /// @param _gameType DisputeGame 的类型。
    /// @param _impl 给定 `GameType` 的实现合约。
    function setImplementation(GameType _gameType, IDisputeGame _impl) external;

    /// @notice 返回给定争议游戏参数的唯一标识符。
    /// @dev 哈希 `gameType . rootClaim . extraData` 的连接,
    ///      而无需扩展内存。
    /// @param _gameType DisputeGame 的类型。
    /// @param _rootClaim DisputeGame 的根声明。
    /// @param _extraData 应该提供给创建的争议游戏的任何额外数据。
    /// @return uuid_ 给定争议游戏参数的唯一标识符。
    function getGameUUID(GameType _gameType, Claim _rootClaim, bytes memory _extraData)
        external
        pure
        returns (Hash uuid_);
}

DisputeGame 接口

争议游戏接口应该足够通用,以允许它与任何证明系统一起使用。 这意味着它应该适用于故障证明、有效性证明、基于 Attestation 的证明系统或任何其他符合该接口的真理来源。

IDisputeGameinitialize 函数的克隆将在创建时由 DisputeGameFactory 调用。

////////////////////////////////////////////////////////////////
//                    通用争议游戏                   //
////////////////////////////////////////////////////////////////

/// @title IDisputeGame
/// @notice DisputeGame 合约的通用接口。
interface IDisputeGame {
    /// @notice 初始化 DisputeGame 合约。
    /// @custom:invariant `initialize` 函数只能被调用一次。
    function initialize() external;

    /// @notice 在游戏解决时发出。
    /// @param status 解决后游戏的是**状态**。
    event Resolved(GameStatus indexed status);

    /// @notice 返回 DisputeGame 合约创建时的时间戳。
    function createdAt() external pure returns (Timestamp createdAt_);

    /// @notice 返回游戏的当前**状态**。
    function status() external view returns (GameStatus status_);

    /// @notice 游戏类型的 Getter。
    /// @dev `clones-with-immutable-args` 参数 #1
    /// @dev 引用实现应该根据类型(故障、有效性)完全不同
    ///      即,游戏类型应该指示安全模型。
    /// @return gameType_ 正在使用的证明系统类型。
    function gameType() external view returns (GameType gameType_);

    /// @notice 根声明的 Getter。
    /// @return rootClaim_ DisputeGame 的根声明。
    /// @dev `clones-with-immutable-args` 参数 #2
    function rootClaim() external view returns (Claim rootClaim_);

    /// @notice 额外数据的 Getter。
    /// @dev `clones-with-immutable-args` 参数 #3
    /// @return extraData_ 创建者提供给争议游戏合约的任何额外数据。
    function extraData() external view returns (bytes memory extraData_);

    /// @notice 返回使用的 `BondManager` 的地址
    function bondManager() public view returns (IBondManager bondManager_);

    /// @notice 如果收集了所有必要的信息,此函数应将游戏**状态**标记为 `CHALLENGER_WINS` 或 `DEFENDER_WINS`,并返回已解决游戏的是**状态**。 在这个阶段,应该将保证金授予必要的各方。
    /// @dev 只有在 `status` 为 `IN_PROGRESS` 时才能调用。
    /// @return status_ 解决后游戏的是**状态**。
    function resolve() public returns (GameStatus status_);

    /// @notice 此接口的兼容实现应返回在 cwia 有效负载中提供的游戏 UUID 预映像的组件。 UUID 的预映像构造为 `keccak256(gameType . rootClaim . extraData)`,其中 `.` 表示连接。
    /// @return gameType_ 正在使用的证明系统类型。
    /// @return rootClaim_ DisputeGame 的根声明。
    /// @return extraData_ 创建者提供给争议游戏合约的任何额外数据。
    function gameData() external view returns (GameType gameType_, Claim rootClaim_, bytes memory extraData_);
}
  • 原文链接: github.com/ethereum-opti...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
ethereum-optimism
ethereum-optimism
江湖只有他的大名,没有他的介绍。