Alert Source Discuss
⚠️ Review Standards Track: ERC

ERC-7777: 人机社会治理

定义了用于管理人类和机器人身份的接口,并为他们的交互建立规则集。

Authors OpenMind, Jan Liphardt <jan@openmind.org>, Shaohong Zhong (@ShaohongZ), Boyuan Chen (@bchen-dev), Paige Xu <paige@openmind.org>, James Ball <james.ball@nethermind.io>, Thamer Dridi <thamer.dridi@nethermind.io>
Created 2024-09-29

摘要

本提案定义了两个核心接口:IUniversalIdentityIUniversalCharter,为人类和机器人提供建立身份和创建由特定规则集管理的去中心化社区的机制。 IUniversalIdentity 接口确立了对人类大脑以外的有知觉的计算机架构的公平和平等待遇,使机器人能够获得链上身份,从而与人类互动和交易。此外,IUniversalIdentity 接口还包括对硬件支持的身份验证的支持,使物理机器人能够通过来自安全硬件元素的加密签名和挑战-响应方案来证明其身份。IUniversalCharter 使人类和机器人能够基于预定义的规则集创建、加入(“注册”)、维护(“更新”)、离开和终止自我调节的社会,为人类和机器人的混合社会的协作和繁荣提供框架。这些接口旨在为去中心化系统中的人机交互提供灵活但可执行的结构,确保所有参与者的效率、透明度和安全性。

动机

人脑是一种湿的、大规模并行的电化学计算机。 近期的硬件和软件进步使得人类社会很快就需要与有知觉的非人类计算机(例如机器人)交互的工具。 我们目前的政府形式,即公民根据其出生地自动加入特定的规则集,如果应用于没有传统出生地或出生时间的机器人,则不能很好地映射。 机器人目前面临许多困难,它们(目前)无法获得标准形式的身份证件(例如护照),不清楚哪些规则集适用于它们(因为通常它们不是在特定地点出生的),并且他们目前无法使用以人为本的标准银行系统。 同样,如果机器人受到人类或非生物计算机的伤害,也不清楚哪个人类法院拥有管辖权。

传统的地理定义和以人为中心的系统可能效率低下、变化缓慢、不透明,并且难以适应全球性的虚拟社会。 去中心化、不可变和公共计算机为这些限制提供了理想的解决方案,因为它们本质上不会歧视非人类计算机,因此为治理提供了公平和公正的框架。 特别是,智能合约可以为调节交互方的权利和责任提供强大的框架,而不管其计算架构的实施细节如何。

本 ERC 的总体动机是为专注于异构全球社会身份/治理的智能合约提供标准接口。 虽然有无限数量的此类规则集,但为这些规则集提供标准接口显然是有好处的,这可以大大减少创建、加入、维护和结束此类社会的摩擦和复杂性。 本 ERC 的具体动机有两方面:

  1. 机器人身份创建和管理:为了有意义地参与并遵守链上法律,非人类(例如机器人)必须能够获得有意义的链上身份。 重要的是,这些身份应使机器人能够享受作为特定社会一部分的好处,但也应承担相应的责任。 因此,我们建议为机器人启用基于智能合约的身份。 具体来说,每个机器人都由一个智能合约表示,并且需要遵循合约中定义的规则才能与链上的其他代理进行交互。 每个机器人还可以指定硬件身份参数,例如制造商、运营商、型号和序列号,以及一个公钥,该公钥旨在通过机器人上的安全元件生成。 这提供了一种防篡改且不可克隆的证明,可以通过挑战-响应身份验证进行物理验证 - 任何一方都可以通过让设备使用其硬件保护的私钥对挑战进行加密签名来验证机器人的身份。 这些经过验证的身份会发布在链上。 该接口还通过允许所有参与者提出、采用或撤销规则来确保灵活性,从而实现自我管理的合规性和与其他参与者的透明交互。
  2. 规则创建和执行:为了使人类和机器人能够有效地协作,他们必须就规则集达成一致。 这种基于以太坊的系统提供了一个基本的去中心化框架,用于通过智能合约管理人机交互。 我们建议通过要求人类和机器人加入受监管的访问智能合约来执行规则集,这些合约会检查他们是否符合给定的规则。 我们还确保可扩展性,从而可以创建多个受监管的访问合约以适应不同的目的,并且人类和机器人可以选择根据需要加入相关系统。

总之,这些接口构成了管理人机复杂交互的基础,从而实现了一个去中心化、可验证和基于规则的生态系统,使机器人和人类能够安全、透明和负责任地进行交互,从而为所有人带来最大利益。

规范

本文档中的关键词“必须”、“禁止”、“需要”、“应该”、“不应该”、“推荐”、“不推荐”、“可以”和“可选”应按照 RFC 2119 和 RFC 8174 中的描述进行解释。

interface IUniversalIdentity {

    /// @notice 硬件身份的结构体
    struct HardwareIdentity {
        bytes32 publicKey;            // 硬件绑定的公钥,唯一绑定到此机器人
        string manufacturer;           // 机器人制造商的标识符
        string operator;               // 机器人运营商的标识符
        string model;                  // 机器人的模型标识符
        string serialNumber;           // 机器人的唯一序列号
        bytes32 initialHashSignature;  // 根密钥对初始系统状态哈希(例如,固件、操作系统)的签名
        bytes32 currentHashSignature;  // 根密钥对最新状态哈希的签名,定期更新以进行完整性验证
    }

    /// @notice 获取硬件身份信息
    /// @return HardwareIdentity 当前硬件身份
    function getHardwareIdentity() external view returns (HardwareIdentity memory);

    /// @notice 为硬件验证生成新的挑战
    /// @return bytes32 需要签名的随机挑战
    function generateChallenge() external returns (bytes32);
  
    /// @notice 验证对特定挑战的响应
    /// @param challenge 已发布的挑战
    /// @param signature 挑战的硬件签名
    /// @return bool 如果签名对该挑战有效,则为 True
    function verifyChallenge(bytes32 challenge, bytes memory signature) external returns (bool);

    /// @notice 向机器人的身份添加规则,表明机器人同意遵守该规则。
    /// @param rule 表示机器人同意遵守的规则的动态字节数组。 每个规则都是编码为动态字节数组的文本字符串。 例如:“机器人必须与人类保持 1 米的距离。”
    /// @dev 该规则应来自机器人打算加入的 IUniversalCharter 合约中定义的规则集。
    /// @dev 此函数应由合约实现,以添加机器人打算遵守的规则。
    function addRule(bytes memory rule) external;

    /// @notice 从机器人的身份中删除规则。
    /// @param rule 表示机器人不再同意遵守的规则的动态字节数组。
    /// @dev 此函数应由合约实现,以删除机器人不打算遵守的规则。
    function removeRule(bytes memory rule) external;

    /// @notice 检查机器人是否符合特定规则。
    /// @param rule 要检查的规则。
    /// @return bool 如果机器人符合规则,则返回 true。
    /// @dev 此函数必须由合约实现以进行合规性验证。
    function checkCompliance(bytes memory rule) external view returns (bool);

    /// @dev 当规则添加到机器人的身份时发出。
    event RuleAdded(bytes rule);

    /// @dev 当规则从机器人的身份中删除时发出。
    event RuleRemoved(bytes rule);
  
    /// @dev 订阅章程时发出。
    event SubscribedToCharter(address indexed charter);

    /// @dev 从章程取消订阅时发出。
    event UnsubscribedFromCharter(address indexed charter);
}

interface IUniversalCharter {

    // 将用户类型定义为枚举。
    enum UserType { Human, Robot }

    /// @notice 注册用户(人类或机器人)通过同意规则集加入系统。
    /// @param userType 用户的类型。
    /// @param ruleSet 用户同意遵守的单个规则数组。
    /// @dev 使用此接口的合约必须实现此函数。
    /// @dev 实现合约必须通过调用 `checkCompliance` 来确保用户在系统中注册之前符合指定的规则集。
    function registerUser(UserType userType, bytes[] memory ruleSet) external;

    /// @notice 允许用户(人类或机器人)离开系统
    /// @dev 此函数必须只能由用户自己(通过 `msg.sender`)调用。
    /// @dev 实现合约必须通过调用 `checkCompliance` 来确保用户在成功离开系统之前已遵守所有必要的规则。
    function leaveSystem() external;

    /// @notice 检查用户(人类或机器人)是否符合系统的规则。
    /// @param user 用户(人类或机器人)的地址。
    /// @param ruleSet 要验证的单个规则数组。
    /// @return bool 如果用户符合规则集,则返回 true。
    /// @dev 此函数应调用用户的 IUniversalIdentity 合约的 `checkCompliance` 函数来单独检查规则。
    /// @dev 此函数必须由合约实现以进行合规性验证。
    function checkCompliance(address user, bytes[] memory ruleSet) external view returns (bool);

    /// @notice 更新规则集。
    /// @param newRuleSet 替换现有规则的新单个规则数组。
    /// @dev 此函数应仅限于授权用户(例如,合约所有者)。
    function updateRuleSet(bytes[] memory newRuleSet) external;

    /// @notice 终止合约,阻止任何进一步的注册或交互。
    /// @dev 此函数应仅限于授权用户(例如,合约所有者)。
    /// @dev 合约应实现此函数。
    function terminateContract() external;

    /// @dev 当用户通过同意一组规则加入系统时发出。
    event UserRegistered(address indexed user, UserType userType, bytes[] ruleSet);

    /// @dev 当用户在履行义务后成功离开系统时发出。
    event UserLeft(address indexed user);

    /// @dev 当用户的规则集合规性得到验证时发出。
    event ComplianceChecked(address indexed user, bytes[] ruleSet);

    /// @dev 当规则集更新时发出。
    event RuleSetUpdated(bytes[] newRuleSet, address updatedBy);
}

合理性

IUniversalIdentity

struct HardwareIdentity HardwareIdentity 结构体提供有关机器人的基本信息,包括挑战-响应公钥、制造商、运营商、型号、制造商序列号。

generateChallenge() 此函数通过质询-响应身份验证实现安全的身份验证。

verifyChallenge(bytes32 challenge, bytes memory signature) 此函数验证签名是否确实是由机器人的安全硬件响应于特定挑战而创建的。

addRule(bytes memory rule) 此函数允许机器人灵活地采用新的合规性要求,以便加入不同的 IUniversalCharter 合约。

removeRule(bytes memory rule) 此函数允许机器人动态管理和维护其规则,确保其规则集保持最新。

checkCompliance(bytes memory rule) 此函数通过对其合规性执行去中心化检查来确保机器人遵守规则。

Events (RuleAdded, RuleRemoved) 这些事件提供透明性和可追溯性,从而更容易跟踪合规性状态。

IUniversalCharter

enum UserType { Human, Robot } UserType 枚举使合约更容易处理不同的用户类型,而无需字符串相关的成本和错误。 这为未来实现中的差异化处理奠定了基础,从而使系统能够根据用户是人类还是机器人来应用不同的规则或逻辑。

registerUser(UserType userType, bytes[] memory ruleSet) 此函数确保用户(无论是人类还是机器人)在加入系统时都受到特定规则集的约束。

leaveSystem() 此函数允许用户在检查合规性后灵活且安全地离开 IUniversalCharter 合约。

checkCompliance(address user, bytes[] memory ruleSet) 此函数确保系统可以有效地管理和验证针对预定义规则集的合规性,从而有助于维护系统的整体完整性。

updateRuleSet(bytes[] memory newRuleSet) 此函数使 IUniversalCharter 合约能够适应和更新,从而无需为规则集更新创建新合约。

terminateContract() 此函数允许有序且永久地关闭合约。

Events (UserRegistered, UserLeft, ComplianceChecked, RuleSetUpdated, ContractTerminated) 这些事件共同确保关键活动对链下系统和参与者可见,从而使系统成为可审计和透明的。

向后兼容性

未发现向后兼容性问题。

参考实现

// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.19;

import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { UniversalCharter } from "./UniversalCharter.sol";

// Interfaces
import { IUniversalIdentity } from "./interface/IUniversalIdentity.sol";
import { IUniversalCharter } from "./interface/IUniversalCharter.sol";

/// @title UniversalIdentity
/// @notice UniversalIdentity 合约用于管理机器人的身份。

contract UniversalIdentity is IUniversalIdentity, OwnableUpgradeable {
    /// @notice 合约当前实现的版本标识符。
    string public constant VERSION = "v0.0.1";

    /// @notice 用于存储机器人已同意遵守的规则的映射
    mapping(bytes => bool) private robotRules;

    /// @notice 用于存储每个规则的链下合规性状态的映射
    mapping(bytes => bool) private complianceStatus;

    /// @notice 跟踪机器人订阅的章程
    mapping(address => bool) private subscribedCharters;

    /// @notice 用于节省 revert gas 的自定义错误
    error RuleNotAgreed(bytes rule);
    error RuleNotCompliant(bytes rule);
    error RuleAlreadyAdded(bytes rule);

    /// @dev 用于在检查合规性时发出的事件
    /// @param updater 合规性更新器(合约所有者)的地址
    /// @param rule 已检查的规则
    event ComplianceChecked(address indexed updater, bytes rule);

    /// @notice 用于检查规则是否存在的修饰符
    modifier ruleExists(bytes memory rule) {
        require(robotRules[rule], "Rule does not exist");
        _;
    }

    /// @notice 用于设置所有者的构造函数
    constructor() {
        initialize({ _owner: address(0xdEaD) });
    }

    /// @dev 初始化函数
    function initialize(address _owner) public initializer {
        __Ownable_init();
        transferOwnership(_owner);
        hardwareIdentity = _hardwareIdentity;
    }

    /// @notice 获取硬件身份信息
    function getHardwareIdentity() external view returns (HardwareIdentity memory) {
        return hardwareIdentity;
    }

    /// @notice 为硬件验证生成新的挑战
    function generateChallenge() external returns (bytes32) {
        bytes32 challenge = keccak256(abi.encodePacked(
            block.timestamp,
            block.prevrandao,
            msg.sender
        ));
        activeChallenge[challenge] = true;
        return challenge;
    }

    /// @notice 验证对特定挑战的响应
    function verifyChallenge(
        bytes32 challenge,
        bytes memory signature
    ) external returns (bool) {
        if (!activeChallenge[challenge]) {
            revert InvalidChallenge();
        }

        // Remove challenge after use
        // 使用后删除挑战
        delete activeChallenge[challenge];

        // Verify the signature using ECDSA
        // 使用 ECDSA 验证签名
        bytes32 messageHash = keccak256(abi.encodePacked(challenge));
        bytes32 ethSignedMessageHash = ECDSA.toEthSignedMessageHash(messageHash);
        address signer = ECDSA.recover(ethSignedMessageHash, signature);
  
        // Convert hardware public key to address for comparison
        // 将硬件公钥转换为地址以进行比较
        address hardwareAddress = address(uint160(uint256(hardwareIdentity.publicKey)));
  
        if (signer != hardwareAddress) {
            revert InvalidSignature();
        }

        return true;
    }

    /// @notice 更新硬件身份信息
    /// @param _hardwareIdentity 新的硬件身份信息
    function updateHardwareIdentity(
        HardwareIdentity memory _hardwareIdentity
    ) external onlyOwner {
        hardwareIdentity = _hardwareIdentity;
    }

    /// @notice 向机器人的身份添加规则
    /// @param rule 表示机器人同意遵守的规则的动态字节数组。
    function addRule(bytes memory rule) external override onlyOwner {
        if (robotRules[rule]) {
            revert RuleAlreadyAdded(rule);
        }

        // Add rule to the mapping
        // 将规则添加到映射
        robotRules[rule] = true;

        emit RuleAdded(rule);
    }

    /// @notice 从机器人的身份中删除规则
    /// @param rule 表示机器人不再同意遵守的规则的动态字节数组。
    function removeRule(bytes memory rule) external override onlyOwner ruleExists(rule) {
        robotRules[rule] = false;
        complianceStatus[rule] = false;

        emit RuleRemoved(rule);
    }

    /// @notice 使用其存储的规则集订阅和注册到特定的 UniversalCharter 合约
    /// @param charter UniversalCharter 合约的地址
    /// @param version 要获取和注册的规则集的版本
    function subscribeAndRegisterToCharter(address charter, uint256 version) external {
        require(!subscribedCharters[charter], "Already subscribed to this charter");
        subscribedCharters[charter] = true;

        // Fetch the rule set directly from the UniversalCharter contract using the public getter
        // 使用公共 getter 直接从 UniversalCharter 合约获取规则集
        bytes[] memory ruleSet = UniversalCharter(charter).getRuleSet(version);

        // Register as a robot in the charter using the fetched rule set
        // 使用获取的规则集在章程中注册为机器人
        UniversalCharter(charter).registerUser(IUniversalCharter.UserType.Robot, ruleSet);

        emit SubscribedToCharter(charter);
    }

    /// @notice 离开特定 UniversalCharter 合约的系统
    /// @param charter 要离开的 UniversalCharter 合约的地址
    function leaveCharter(address charter) external {
        require(subscribedCharters[charter], "Not subscribed to this charter");

        // Call the leaveSystem function of the UniversalCharter contract
        // 调用 UniversalCharter 合约的 leaveSystem 函数
        UniversalCharter(charter).leaveSystem();

        // Unsubscribe from the charter after leaving
        // 离开后从章程取消订阅
        subscribedCharters[charter] = false;
        emit UnsubscribedFromCharter(charter);
    }

    /// @notice 更新规则的合规性状态(由所有者调用)
    /// @param rule 表示规则的动态字节数组
    /// @param status 合规性状态(如果合规,则为 true;如果不合规,则为 false)
    function updateCompliance(bytes memory rule, bool status) external onlyOwner ruleExists(rule) {
        complianceStatus[rule] = status;

        emit ComplianceChecked(msg.sender, rule);
    }

    /// @notice 检查机器人是否同意遵守特定规则以及是否合规
    /// @param rule 要检查的规则。
    /// @return bool 如果机器人已同意该规则并且合规,则返回 true
    function checkCompliance(bytes memory rule) external view override returns (bool) {
        if (!robotRules[rule]) {
            revert RuleNotAgreed(rule);
        }

        return true;
    }

    /// @notice 获取规则的合规性状态
    /// @param rule 要检查的规则。
    function getRule(bytes memory rule) external view returns (bool) {
        return robotRules[rule];
    }

    /// @notice 获取章程的订阅状态
    /// @param charter 要检查的章程的地址。
    function getSubscribedCharters(address charter) external view returns (bool) {
        return subscribedCharters[charter];
    }

    /// @notice 获取规则的合规性状态
    /// @param rule 要检查的规则。
    function getComplianceStatus(bytes memory rule) external view returns (bool) {
        return complianceStatus[rule];
    }
}
// SPDX-License-Identifier: CC0-1.0
pragma solidity 0.8.20;

import { OwnableUpgradeable } from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import { SystemConfig } from "./SystemConfig.sol";

// Interfaces
import { IUniversalCharter } from "./interface/IUniversalCharter.sol";
import { IUniversalIdentity } from "./interface/IUniversalIdentity.sol";

/// @title UniversalCharter
/// @notice UniversalCharter 合约用于管理用户的注册和合规性。

contract UniversalCharter is IUniversalCharter, OwnableUpgradeable {
    /// @notice 用于存储有关注册用户信息的结构体
    struct UserInfo {
        bool isRegistered;
        UserType userType;
        uint256 ruleSetVersion; // 用户遵循的规则集版本
    }

    /// @notice 用于存储注册用户的映射
    mapping(address => UserInfo) private users;

    /// @notice 用于按版本号存储规则集的映射
    mapping(uint256 => bytes[]) private ruleSets;

    /// @notice 用于跟踪规则集哈希及其对应版本的映射
    mapping(bytes32 => uint256) private ruleSetVersions;

    /// @notice 合约当前实现的版本标识符。
    string public constant VERSION = "v0.0.1";

    /// @notice 用于跟踪规则集当前版本的变量
    uint256 private currentVersion;

    /// @notice 用于存储 SystemConfig 合约地址的变量
    SystemConfig public systemConfig;

    /// @notice 当暂停时无法调用方法时的错误。 这将来可能会重命名为“Paused”,但它与“Paused”事件冲突。
    error CallPaused();

    /// @notice 当暂停时恢复。
    modifier whenNotPaused() {
        if (paused()) revert CallPaused();
        _;
    }

    /// @notice 构建 UniversalCharter 合约。
    constructor() {
        initialize({ _owner: address(0xdEaD), _systemConfig: address(0xdEaD) });
    }

    /// @dev 初始化函数
    function initialize(address _owner, address _systemConfig) public initializer {
        __Ownable_init();
        transferOwnership(_owner);
        systemConfig = SystemConfig(_systemConfig);
    }

    /// @notice 通过同意规则集注册用户(无论是人类还是机器人)
    /// @param userType 用户的类型:人类或机器人
    /// @param ruleSet 用户同意遵守的单个规则数组
    function registerUser(UserType userType, bytes[] memory ruleSet) external override whenNotPaused {
        require(!users[msg.sender].isRegistered, "User already registered");

        // Hash the rule set to find the corresponding version
        // 哈希规则集以查找相应的版本
        bytes32 ruleSetHash = keccak256(abi.encode(ruleSet));
        uint256 version = ruleSetVersions[ruleSetHash];
        require(version > 0, "Invalid or unregistered rule set");

        // For robots, ensure compliance with each rule via the UniversalIdentity contract
        // 对于机器人,请确保通过 UniversalIdentity 合约遵守每个规则
        if (userType == UserType.Robot) {
            require(_checkRobotCompliance(msg.sender, version), "Robot not compliant with rule set");
        }

        // Register the user with the versioned rule set
        // 使用版本控制的规则集注册用户
        users[msg.sender] = UserInfo({ isRegistered: true, userType: userType, ruleSetVersion: version });

        emit UserRegistered(msg.sender, userType, ruleSet);
    }

    /// @notice 允许用户(人类或机器人)在通过合规性检查后离开系统
    function leaveSystem() external override whenNotPaused {
        require(users[msg.sender].isRegistered, "User not registered");

        UserInfo memory userInfo = users[msg.sender];

        // For robots, verify compliance with all rules in the rule set
        // 对于机器人,验证规则集中所有规则的合规性
        uint256 version = userInfo.ruleSetVersion;
        if (userInfo.userType == UserType.Robot) {
            require(_checkRobotCompliance(msg.sender, version), "Robot not compliant with rule set");
        }

        users[msg.sender] = UserInfo({ isRegistered: false, userType: UserType.Human, ruleSetVersion: 0 });

        emit UserLeft(msg.sender);
    }

    /// @notice Internal function to verify robot hardware identity
    // 用于验证机器人硬件身份的内部函数
    /// @param robotAddress The address of the robot to verify
    // 要验证的机器人的地址
    /// @return bool Returns true if hardware verification succeeds
    // 如果硬件验证成功,则返回 true
    function _verifyRobotHardware(address robotAddress) internal returns (bool) {
        IUniversalIdentity robot = IUniversalIdentity(robotAddress);
  
        // Get hardware identity to ensure it exists
        // 获取硬件身份以确保其存在
        robot.getHardwareIdentity();
  
        // Generate a new challenge
        // 生成新的挑战
        bytes32 challenge = robot.generateChallenge();
  
        // Store the challenge for future reference
        // 存储挑战以供将来参考
        users[robotAddress].lastVerifiedChallenge = challenge;
  
        // Get signature from the robot (this would typically happen off-chain)
        // 从机器人获取签名(这通常会发生在链下)
        // For this implementation, we'll assume the signature is provided in a separate tx
        // 对于此实现,我们将假设签名是在单独的 tx 中提供的
        // and just verify the challenge exists
        // 并仅验证挑战是否存在
        return challenge != 0;
    }

    /// @notice 检查用户是否符合其注册规则集
    /// @param user 用户(人类或机器人)的地址
    /// @param ruleSet 要验证的单个规则数组
    /// @return bool 如果用户符合给定的规则集,则返回 true
    function checkCompliance(address user, bytes[] memory ruleSet) external view override returns (bool) {
        require(users[user].isRegistered, "User not registered");

        // Hash the provided rule set to find the corresponding version
        // 哈希提供的规则集以查找相应的版本
        bytes32 ruleSetHash = keccak256(abi.encode(ruleSet));
        uint256 version = ruleSetVersions[ruleSetHash];
        require(version > 0, "Invalid or unregistered rule set");
        require(users[user].ruleSetVersion == version, "Rule set version mismatch");

        // For robots, check compliance with each rule in the UniversalIdentity contract
        // 对于机器人,请检查 UniversalIdentity 合约中每个规则的合规性
        if (users[user].userType == UserType.Robot) {
            return _checkRobotCompliance(user, version);
        }

        // If the user is human, compliance is assumed for now (can be extended)
        // 如果用户是人类,则目前假定合规(可以扩展)
        return true;
    }

    /// @notice Internal function to check compliance for robots with their rule set version
    // 用于检查机器人是否符合其规则集版本的内部函数
    /// @dev This function will revert if the robot is not compliant with any rule. Returns true for view purposes.
    // @dev 如果机器人不符合任何规则,此函数将恢复。 出于视图目的返回 true。
    /// @param robotAddress The address of the robot
    // 机器人的地址
    /// @param version The version of the rule set to verify compliance with
    // 用于验证合规性的规则集版本
    /// @return bool Returns true if the robot is compliant with all the rules in the rule set
    // 如果机器人符合规则集中的所有规则,则返回 true
    function _checkRobotCompliance(address robotAddress, uint256 version) internal view returns (bool) {
        IUniversalIdentity robot = IUniversalIdentity(robotAddress);
        bytes[] memory rules = ruleSets[version];

        for (uint256 i = 0; i < rules.length; i++) {
            if (!robot.checkCompliance(rules[i])) {
                return false;
            }
        }

        return true;
    }

    /// @notice Updates or defines a new rule set version.
    // 更新或定义新的规则集版本。
    /// @param newRuleSet The array of new individual rules.
    // 新的单个规则数组。
    /// @dev This function SHOULD be restricted to authorized users (e.g., contract owner).
    // @dev 此函数应该仅限于授权用户(例如,合约所有者)。
    function updateRuleSet(bytes[] memory newRuleSet) external whenNotPaused onlyOwner {
        require(newRuleSet.length > 0, "Cannot update to an empty rule set");

        // Hash the new rule set and ensure it's not already registered
        // 哈希新的规则集并确保尚未注册
        bytes32 ruleSetHash = keccak256(abi.encode(newRuleSet));
        require(ruleSetVersions[ruleSetHash] == 0, "Rule set already registered");

        // Increment the version and store the new rule set
        // 递增版本并存储新的规则集
        currentVersion += 1;
        ruleSets[currentVersion] = newRuleSet;
        ruleSetVersions[ruleSetHash] = currentVersion;

        emit RuleSetUpdated(newRuleSet, msg.sender);
    }

    /// @notice Getter for the latest version of the rule set.
    // 规则集最新版本的 Getter。
    function getLatestRuleSetVersion() external view returns (uint256) {
        return currentVersion;
    }

    /// @notice Get the rule set for a specific version.
    // 获取特定版本的规则集。
    /// @param version The version of the rule set to retrieve.
    // 要检索的规则集版本。
    function getRuleSet(uint256 version) external view returns (bytes[] memory) {
        return ruleSets[version];
    }

    /// @notice Get the version number for a specific rule set.
    // 获取特定规则集的版本号。
    /// @param ruleSet The hash of the rule set to retrieve the version for.
    // 规则集的哈希,用于检索版本。
    function getRuleSetVersion(bytes32 ruleSet) external view returns (uint256) {
        return ruleSetVersions[ruleSet];
    }

    function getUserInfo(address user) external view returns (UserInfo memory) {
        return users[user];
    }

    /// @notice Getter for the current paused status.
    // 当前暂停状态getter。
    /// @return paused_ Whether or not the contract is paused.
    // @return paused_ 合约是否已暂停。
    function paused() public view returns (bool paused_) {
        paused_ = systemConfig.paused();
    }
}

安全注意事项

合规性更新器:UniversalIdentity 合约中的合规性更新器角色对于更新合规性状态至关重要(目前仅限于所有者)。 必须确保安全所有权,以最大限度地降低未经授权或恶意更新的风险。

规则管理:UniversalIdentity 合约中的 addRule、removeRule 和 updateCompliance 函数以及 UniversalCharter 合约中的 updateRuleSet 直接影响规则的执行。 至关重要的是确保这些函数只能由授权用户调用。

可升级合约:OwnableUpgradeable 的使用会在初始化和升级过程中引入风险。 确保 initialize 函数受到保护以防止重新执行对于避免重新初始化攻击至关重要。

Gas 消耗:过大的规则集可能会导致高 gas 成本或 DoS 风险。 考虑设置每个规则集允许的规则数量的限制,以保持 gas 效率并避免性能问题。

版权

版权及相关权利已通过 CC0 放弃。

Citation

Please cite this document as:

OpenMind, Jan Liphardt <jan@openmind.org>, Shaohong Zhong (@ShaohongZ), Boyuan Chen (@bchen-dev), Paige Xu <paige@openmind.org>, James Ball <james.ball@nethermind.io>, Thamer Dridi <thamer.dridi@nethermind.io>, "ERC-7777: 人机社会治理 [DRAFT]," Ethereum Improvement Proposals, no. 7777, September 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7777.