系统合约管理

概述

系统合约是区块链底层基础设施的核心组件,负责管理链的基本配置、账户体系、合约生命周期等关键功能。本系统采用模块化的系统合约架构,每个系统合约负责特定的功能领域。


系统合约列表

1. 链配置管理合约 (CHAIN_CONFIG)

  • 功能描述: 管理区块链的核心配置参数

  • 主要方法:

    • CORE_UPDATE - 更新链核心配置(如基础运行参数)

    • BLOCK_UPDATE - 更新区块相关配置(如区块大小、出块间隔)

    • TRUST_ROOT_ADD - 添加信任根证书/公钥

    • TRUST_ROOT_UPDATE - 更新已存在的信任根配置

    • TRUST_ROOT_DELETE - 删除指定信任根

    • TRUST_MEMBER_ADD - 添加信任成员(如节点、组织)

    • TRUST_MEMBER_DELETE - 删除指定信任成员

    • NODE_ID_ADD - 添加共识节点ID到白名单

    • NODE_ID_UPDATE - 更新节点ID关联信息

    • NODE_ID_DELETE - 从白名单中删除节点ID

    • NODE_ORG_ADD - 添加节点所属组织信息

    • NODE_ORG_UPDATE - 更新节点组织关联配置

    • NODE_ORG_DELETE - 删除节点与组织的关联关系

    • CONSENSUS_EXT_ADD - 添加共识扩展配置(如自定义共识参数)

    • CONSENSUS_EXT_UPDATE - 更新共识扩展配置

    • CONSENSUS_EXT_DELETE - 删除指定共识扩展配置

    • PERMISSION_ADD - 添加资源访问权限策略

    • PERMISSION_UPDATE - 更新已存在的权限策略

    • PERMISSION_DELETE - 删除指定权限策略

    • PERMISSION_LIST - 查询所有权限策略列表

    • GET_CHAIN_CONFIG - 查询当前链的完整配置信息

    • GET_CHAIN_CONFIG_AT - 查询指定区块高度对应的链配置

    • UPDATE_VERSION - 更新链配置版本号

    • ENABLE_OR_DISABLE_GAS - 启用或禁用链上Gas计费机制

    • SET_INVOKE_BASE_GAS - 设置合约调用的基础Gas费用

    • SET_INVOKE_GAS_PRICE - 设置合约调用的Gas单价

    • SET_INSTALL_BASE_GAS - 设置合约部署的基础Gas费用

    • SET_INSTALL_GAS_PRICE - 设置合约部署的Gas单价

    • SET_ACCOUNT_MANAGER_ADMIN - 设置账户管理器的管理员地址

    • ALTER_ADDR_TYPE - 修改链上地址编码格式(如从短地址切换为长地址)

    • ENABLE_ONLY_CREATOR_UPGRADE - 启用仅合约创建者可升级合约的限制

    • DISABLE_ONLY_CREATOR_UPGRADE - 禁用仅合约创建者可升级的限制

    • MULTI_SIGN_ENABLE_MANUAL_RUN - 启用多签交易手动触发执行机制

    • VM_SUPPORT_LIST_ADD - 添加虚拟机支持的合约类型/指令集

    • VM_SUPPORT_LIST_DEL - 从虚拟机支持列表中删除指定类型/指令集

2. 链查询合约 (CHAIN_QUERY)

  • 功能描述: 提供链配置信息的查询接口

  • 主要方法:

    • GET_BLOCK_BY_HEIGHT - 根据区块高度查询区块基本信息

    • GET_BLOCK_WITH_TXRWSETS_BY_HEIGHT - 根据高度查询区块及包含的交易读写集

    • GET_BLOCK_BY_HASH - 根据区块哈希查询区块基本信息

    • GET_BLOCK_WITH_TXRWSETS_BY_HASH - 根据哈希查询区块及交易读写集

    • GET_BLOCK_BY_TX_ID - 根据交易ID查询包含该交易的区块

    • GET_TX_BY_TX_ID - 根据交易ID查询交易详情

    • GET_LAST_CONFIG_BLOCK - 查询最新的配置变更区块

    • GET_LAST_BLOCK - 查询链上最新区块的完整信息

    • GET_CHAIN_INFO - 查询链的基础信息(如链ID、当前高度、共识算法)

    • GET_NODE_CHAIN_LIST - 查询当前节点已加入的链列表

    • GET_FULL_BLOCK_BY_HEIGHT - 根据高度查询包含完整交易数据的区块

    • GET_BLOCK_HEIGHT_BY_TX_ID - 根据交易ID查询其所在区块的高度

    • GET_BLOCK_HEIGHT_BY_HASH - 根据区块哈希查询对应的区块高度

    • GET_BLOCK_HEADER_BY_HEIGHT - 根据高度查询区块头信息(不含交易数据)

    • GET_ARCHIVED_BLOCK_HEIGHT - 查询已归档的区块高度范围

    • GET_ARCHIVE_STATUS - 查询区块归档功能的启用状态及配置

    • GET_MERKLE_PATH_BY_TX_ID - 根据交易ID查询其在区块默克尔树中的证明路径

    • GET_LAST_BLOCK_HEIGHT - 查询链上最新区块的高度

3. 证书管理合约 (CERT_MANAGE)

  • 功能描述: 管理节点和用户的数字证书

  • 主要方法:

    • CERT_ADD - 添加证书(如用户证书、节点证书)到链上存储

    • CERTS_DELETE - 批量删除指定证书

    • CERTS_FREEZE - 冻结指定证书(使其暂时失效)

    • CERTS_UNFREEZE - 解冻已冻结的证书

    • CERTS_REVOKE - 吊销指定证书(永久失效)

    • CERT_ALIAS_ADD - 为证书添加别名(便于快速查询)

    • CERT_ALIAS_UPDATE - 更新证书的别名信息

    • CERTS_ALIAS_DELETE - 删除证书的指定别名

    • CERTS_QUERY - 查询符合条件的证书列表(如按所有者、状态)

    • CERTS_ALIAS_QUERY - 根据别名查询对应的证书信息

4. 多签合约 (MULTI_SIGN)

  • 功能描述: 实现多签名管理功能

  • 主要方法:

    • REQ - 发起多签交易请求

    • VOTE - 对多签交易请求进行投票(同意/拒绝)

    • QUERY - 查询多签交易的状态(如投票进度、结果)

    • TRIG - 触发已达成投票阈值的多签交易执行

    • REQ_V2 - 发起V2版本的多签交易请求(扩展功能)

    • VOTE_V2 - 对V2版本多签交易进行投票

    • TRIG_V2 - 触发V2版本多签交易执行

5. 合约管理合约 (CONTRACT_MANAGE)

  • 功能描述: 管理用户合约的生命周期

  • 主要方法:

    • INIT_CONTRACT - 初始化(部署)新合约

    • UPGRADE_CONTRACT - 升级已部署的合约(替换代码/配置)

    • FREEZE_CONTRACT - 冻结合约(禁止调用)

    • UNFREEZE_CONTRACT - 解冻已冻结的合约

    • REVOKE_CONTRACT - 吊销合约(永久禁用并清理资源)

    • GET_CONTRACT_INFO - 查询指定合约的详情(如地址、版本、状态)

    • GET_CONTRACT_LIST - 查询链上所有已部署的合约列表

    • GRANT_CONTRACT_ACCESS - 授予某账户调用指定合约的权限

    • REVOKE_CONTRACT_ACCESS - 撤销某账户调用指定合约的权限

    • VERIFY_CONTRACT_ACCESS - 验证某账户是否具有调用指定合约的权限

    • GET_DISABLED_CONTRACT_LIST - 查询所有已冻结/吊销的合约列表

    • INIT_NEW_NATIVE_CONTRACT - 部署新的原生合约(系统级合约)

6. DPoS ERC20合约 (DPOS_ERC20)

  • 功能描述: DPoS共识相关的ERC20代币管理(仅限于DPoS共识)

  • 主要方法:

    • GET_BALANCEOF - 查询指定账户的ERC20代币余额

    • TRANSFER - 转账ERC20代币给指定账户

    • MINT - 铸造新的ERC20代币(仅管理员权限)

    • GET_OWNER - 查询ERC20代币合约的所有者(管理员)地址

    • GET_DECIMALS - 查询ERC20代币的小数位数

    • GET_TOTAL_SUPPLY - 查询ERC20代币的总发行量

7. DPoS质押合约 (DPOS_STAKE)

  • 功能描述: DPoS共识中管理DPoS质押功能(仅限于DPoS共识)

  • 主要方法:

    • GET_ALL_CANDIDATES - 查询所有DPoS共识候选人列表

    • GET_VALIDATOR_BY_ADDRESS - 根据地址查询验证人节点的详情

    • DELEGATE - 将代币质押给指定候选人/验证人

    • GET_DELEGATIONS_BY_ADDRESS - 查询指定账户的所有质押记录

    • GET_USER_DELEGATION_BY_VALIDATOR - 查询指定账户对某验证人的质押详情

    • UNDELEGATE - 从指定验证人处解除质押(赎回代币)

    • READ_EPOCH_BY_ID - 根据周期ID查询DPoS共识周期的详情

    • READ_LATEST_EPOCH - 查询最新的DPoS共识周期信息

    • SET_NODE_ID - 为候选人设置关联的节点ID

    • GET_NODE_ID - 查询候选人关联的节点ID

    • READ_MIN_SELF_DELEGATION - 查询候选人的最小自质押额度要求

    • READ_EPOCH_VALIDATOR_NUMBER - 查询每个共识周期的验证人数量上限

    • READ_EPOCH_BLOCK_NUMBER - 查询每个共识周期包含的区块数量

    • READ_SYSTEM_CONTRACT_ADDR - 查询DPoS相关系统合约的地址

    • READ_COMPLETE_UNBOUNDING_EPOCH_NUMBER - 查询解除质押所需的共识周期数

8. 归档管理合约 (ARCHIVE_MANAGE)

  • 功能描述: 管理区块数据的归档和恢复

  • 主要方法:

    • ARCHIVE_BLOCK - 将指定区块归档(迁移至低成本存储)

    • RESTORE_BLOCK - 从归档中恢复指定区块数据

9. 跨链交易合约 (CROSS_TRANSACTION)

  • 功能描述: 处理代理跨链交易(从v2.3.8开始不再支持,跨链相关可参考:TCIP中继跨链使用指南

  • 主要方法:

    • EXECUTE - 执行跨链交易(触发跨链数据传输)

    • COMMIT - 提交跨链交易结果(确认执行成功)

    • ROLLBACK - 回滚跨链交易(执行失败时恢复状态)

    • READ_STATE - 查询跨链交易的状态(如执行中、成功、失败)

    • SAVE_PROOF - 存储跨链交易的有效性证明(如对方链的区块证明)

    • READ_PROOF - 查询跨链交易的有效性证明

    • ARBITRATE - 仲裁跨链交易纠纷(如双花、执行不一致)

10. 公钥管理合约 (PUBKEY_MANAGE)

  • 功能描述: 管理公钥信息

  • 主要方法:

    • PUBKEY_ADD - 添加公钥到链上(如账户公钥、节点公钥)

    • PUBKEY_DELETE - 删除链上存储的指定公钥

    • PUBKEY_QUERY - 查询指定账户/节点对应的公钥

11. 账户管理合约 (ACCOUNT_MANAGER)

  • 功能描述: 管理账户体系和Gas费用

  • 主要方法:

    • SET_ADMIN - 设置账户管理器的管理员地址

    • GET_ADMIN - 查询账户管理器的管理员地址

    • RECHARGE_GAS - 为账户充值Gas(用于支付交易/合约调用费用)

    • CHARGE_GAS - 从账户扣除Gas费用(执行交易时触发)

    • GET_BALANCE - 查询账户的Gas余额

    • REFUND_GAS - 退还账户未使用的Gas费用

    • REFUND_GAS_VM - 退还虚拟机执行过程中未消耗的Gas

    • FROZEN_ACCOUNT - 冻结账户(禁止转账、调用合约等操作)

    • UNFROZEN_ACCOUNT - 解冻已冻结的账户

    • ACCOUNT_STATUS - 查询账户状态(如正常、冻结、吊销)

    • CHARGE_GAS_FOR_MULTI_ACCOUNT - 为多个账户批量扣除Gas费用

    • SET_CONTRACT_METHOD_PAYER - 设置合约方法的Gas支付者(指定由某账户代付)

    • UNSET_CONTRACT_METHOD_PAYER - 取消合约方法的代付配置

    • GET_CONTRACT_METHOD_PAYER - 查询合约方法的代付账户

    • GET_TX_PAYER - 查询某笔交易的Gas支付者

12. 中继跨链合约 (RELAY_CROSS)

  • 功能描述: 中继跨链功能

  • 主要方法:

    • SAVE_GATEWAY - 存储跨链网关信息(如对方链的接入点)

    • UPDATE_GATEWAY - 更新跨链网关配置

    • GET_GATEWAY_NUM - 查询已配置的跨链网关数量

    • GET_GATEWAY - 查询指定跨链网关的详情

    • GET_GATEWAY_BY_RANGE - 按索引范围查询跨链网关列表

    • SAVE_CROSS_CHAIN_INFO - 存储跨链交易的基础信息(如链ID、交易ID)

    • UPDATE_CROSS_CHAIN_TRY - 更新跨链交易的重试次数及状态

    • UPDATE_CROSS_CHAIN_RESULT - 更新跨链交易的执行结果

    • DELETE_ERROR_CROSS_CHAIN_TX_LIST - 删除执行失败的跨链交易列表

    • UPDATE_CROSS_CHAIN_CONFIRM - 更新跨链交易的确认状态(如多网关确认)

    • UPDATE_SRC_GATEWAY_CONFIRM - 更新源链网关的确认状态

    • GET_CROSS_CHAIN_INFO - 查询指定跨链交易的详情

    • GET_CROSS_CHAIN_INFO_BY_RANGE - 按索引范围查询跨链交易列表

    • GET_NOT_END_CROSS_CHAIN_ID_LIST - 查询未完成的跨链交易ID列表

    • SET_CROSS_ADMIN - 设置跨链功能的管理员地址

    • DELETE_CROSS_ADMIN - 删除跨链功能的管理员

    • IS_CROSS_ADMIN - 验证某地址是否为跨链功能管理员

    • SAVE_SYNC_CROSS_CHAIN_INFO - 存储同步型跨链交易的信息

13. 交易管理合约 (TRANSACTION_MANAGER)

  • 功能描述: 管理交易相关功能

  • 主要方法:

    • ADD_BLACKLIST_TX_IDS - 将交易ID加入黑名单(禁止执行/上链)

    • DELETE_BLACKLIST_TX_IDS - 从黑名单中移除交易ID

    • GET_BLACKLIST_TX_IDS - 查询交易黑名单列表


核心合约详细说明

链配置管理合约 (ChainConfigContract)

链配置管理合约是系统中最核心的合约之一,负责管理区块链的各种配置参数:

核心配置管理

  • 交易调度超时: 控制区块调度的最大时间

  • 交易验证超时: 控制交易验证的最大时间

  • 发送者分组: 优化交易冲突处理

  • 冲突位窗口: 动态调整交易执行容量

  • Gas优化: 启用Gas费用优化

区块配置管理

  • 交易时间戳验证: 启用交易时间戳验证

  • 交易超时: 设置交易超时时间

  • 区块容量: 设置区块最大交易数量

  • 区块大小: 设置区块最大大小

  • 区块间隔: 设置出块间隔

账户管理合约 (AccountManager)

账户管理合约负责管理账户体系和Gas费用系统:

账户管理功能

  • 管理员设置: 设置Gas费用管理员

  • 账户状态管理: 冻结和解冻账户

  • 余额查询: 查询账户Gas余额

Gas费用管理

  • Gas充值: 为账户充值Gas

  • Gas扣除: 执行合约时扣除Gas

  • Gas退还: 退还多余的Gas

  • 批量操作: 支持批量Gas管理

合约管理合约 (ContractManager)

合约管理合约负责管理用户合约的完整生命周期:

合约生命周期管理

  • 合约安装: 安装新的用户合约

  • 合约升级: 升级现有合约版本

  • 合约冻结: 临时禁用合约

  • 合约解冻: 恢复合约使用

  • 合约吊销: 永久禁用合约


系统合约查询策略限制(v2.3.8版本新增)

背景与问题

在 v2.3.8 版本之前,系统合约(如 INIT_CONTRACT)可以通过 QUERY 方式调用,这导致以下问题:

  1. 垃圾数据问题: QUERY 调用虽然不产生区块数据,但会在节点内部产生临时数据和日志

  2. 资源浪费: 频繁的 QUERY 调用消耗节点计算和存储资源

  3. 安全风险: 恶意用户可能通过 QUERY 方式探测系统合约状态

技术实现

1. queryPolicyMap 数据结构

type accessControlService struct {
    // ... 其他字段
    queryPolicyMap        *sync.Map // map[string]*policy , resourceName -> *policy
    // ... 其他字段
}

2. 策略初始化

在系统初始化时,通过 initAccessControlService 函数创建并初始化 queryPolicyMap:

func initAccessControlService(hashType, authType string, addressType config.AddrType,
    store protocol.BlockchainStore, log protocol.Logger) *accessControlService {
    acService := &accessControlService{
        // ... 其他初始化
        queryPolicyMap:            &sync.Map{},  // 初始化查询策略映射
        // ... 其他初始化
    }
    return acService
}

3. 敏感方法限制配置

对于 INIT_CONTRACT 等敏感系统合约方法,系统配置了 policyForbidden 策略:

// policyForbidden 策略定义
policyForbidden = newPolicy(
    protocol.RuleForbidden,  // 禁止访问规则
    nil,                     // 无组织列表限制
    nil)                     // 无角色列表限制

// 将敏感方法配置为禁止访问
acs.queryPolicyMap.Store("CONTRACT_MANAGE-INIT_CONTRACT", policyForbidden)

4. 查询策略验证流程

当用户发起 QUERY 调用时,系统执行以下验证流程:

func (acs *accessControlService) verifyPrincipalPolicy(principal, refinedPrincipal protocol.Principal, p *policy) (bool, error) {
    endorsements := refinedPrincipal.GetEndorsement()
    rule := p.GetRule()
    
    switch rule {
    case protocol.RuleForbidden:
        // FORBIDDEN规则:直接拒绝访问
        return false, fmt.Errorf("authentication fail: [%s] is forbidden to access", 
            refinedPrincipal.GetResourceName())
    // ... 其他规则处理
    }
}

具体限制效果

对 INIT_CONTRACT 的限制

  • 调用方式: 禁止通过 QUERY 交易类型调用

  • 错误信息: 返回 “authentication fail: [CONTRACT_MANAGE-INIT_CONTRACT] is forbidden to access”

  • 影响范围: 只影响 QUERY 调用,不影响正常的 INVOKE 调用

其他受限制的系统合约方法

除了 INIT_CONTRACT,以下敏感方法也受到类似限制:

  • 链配置修改方法

  • 证书管理敏感操作

  • 合约管理的安装/升级操作


系统合约跨合约调用策略限制(v2.3.8版本新增)

v2.3.8版本引入了系统合约跨合约调用策略限制机制,旨在增强区块链平台的安全性和稳定性。该机制限制了用户合约对系统合约的直接调用,确保配置变更交易能够保持独立的区块状态。

问题背景

在v2.3.8版本之前,用户合约可以自由调用系统合约,这导致以下问题:

  1. 安全风险: 恶意用户合约可能通过跨合约调用操纵系统合约

  2. 状态混乱: 配置变更交易可能与其他交易混合在同一区块中

  3. 审计困难: 系统合约调用路径复杂,难以追踪和审计

  4. 性能影响: 系统合约调用可能影响区块链的整体性能

设计目标

  • 隔离系统合约调用,确保配置变更交易的独立性

  • 保持必要的跨合约调用功能(如中继跨合约)

  • 支持以太坊兼容的EVM合约部署模式

  • 提供版本兼容性支持

核心验证逻辑

txSimContextImpl.verifyCallContract方法中实现了跨合约调用验证:

// above v238, user callers are not allowed to call native contracts expect relay cross
// contract, to ensure that one configuration-change transaction remains a separate block.
// Special, we also allow an evm contract to install an evm contract, because this is a common behavior in Ethereum

if blockVersion >= blockVersion238 && !utils.IsNativeContract(caller.Name) &&
    utils.IsNativeContract(contract.Name) && contract.Name != syscontract.SystemContract_RELAY_CROSS.String() {
    // 独立判断EVM合约安装EVM合约的情况
    installEvmByEvm := false
    if caller.RuntimeType == common.RuntimeType_EVM &&
        contract.Name == syscontract.SystemContract_CONTRACT_MANAGE.String() &&
        method == syscontract.ContractManageFunction_INIT_CONTRACT.String() {
        // 检查要安装的合约是否为EVM类型
        if runtime, ok := parameters[syscontract.InitContract_CONTRACT_RUNTIME_TYPE.String()]; ok {
            strRuntime := string(runtime)
            if runtimeInt, okk := common.RuntimeType_value[strRuntime]; okk && 
                common.RuntimeType(runtimeInt) == common.RuntimeType_EVM {
                installEvmByEvm = true
            }
        }
    }
    
    if !installEvmByEvm {
        return errors.New("cannot call native contract by user caller")
    }
}

限制规则详解

1. 基本限制规则

  • 适用版本: v2.3.8及以上版本(blockVersion >= blockVersion238)

  • 调用方限制: 调用方必须是非原生合约(用户合约)

  • 被调用方限制: 被调用方必须是原生系统合约

  • 例外情况: 中继跨合约调用(RELAY_CROSS)不受限制

2. 特殊例外情况

允许EVM合约安装EVM合约,这是为了保持与以太坊生态的兼容性:

  • 调用方: 必须是EVM类型合约

  • 被调用方: 必须是合约管理系统合约(CONTRACT_MANAGE)

  • 调用方法: 必须是初始化合约方法(INIT_CONTRACT)

  • 目标合约: 要安装的合约必须是EVM类型

验证流程

1. 版本检查

if blockVersion >= blockVersion238 {
    // 执行跨合约调用验证
}

2. 合约类型验证

// 检查调用方是否为用户合约
!utils.IsNativeContract(caller.Name)

// 检查被调用方是否为系统合约
utils.IsNativeContract(contract.Name)

// 检查是否为中继跨合约调用例外
contract.Name != syscontract.SystemContract_RELAY_CROSS.String()

3. 特殊场景处理

// EVM合约安装EVM合约的特殊处理
if caller.RuntimeType == common.RuntimeType_EVM &&
    contract.Name == syscontract.SystemContract_CONTRACT_MANAGE.String() &&
    method == syscontract.ContractManageFunction_INIT_CONTRACT.String() {
    // 验证目标合约的运行时类型
}

4. 访问控制验证

// 调用verifyPolicy进行最终的权限验证
return s.verifyPolicy(contract, method, blockVersion)

系统合约限制分类

限制类型 合约名称 说明
完全受限 CHAIN_CONFIG 链配置管理
完全受限 CERT_MANAGE 证书管理
完全受限 ACCESS_CONTROL 权限管理
完全受限 MULTI_SIGN 多签合约
部分受限 CONTRACT_MANAGE 普通用户合约调用受限
不受限制 RELAY_CROSS 中继跨合约调用

完全受限的系统合约

  • 链配置管理(CHAIN_CONFIG)

  • 证书管理(CERT_MANAGE)

  • 权限管理(ACCESS_CONTROL)

  • 多签合约(MULTI_SIGN)

部分受限的系统合约

  • 合约管理(CONTRACT_MANAGE)

    • 受限:普通用户合约调用

    • 例外:EVM合约安装EVM合约

不受限制的系统合约

  • 中继跨合约(RELAY_CROSS)