# 系统合约管理 ## 概述 系统合约是区块链底层基础设施的核心组件,负责管理链的基本配置、账户体系、合约生命周期等关键功能。本系统采用模块化的系统合约架构,每个系统合约负责特定的功能领域。 --- ## 系统合约列表 ### 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中继跨链使用指南](TCIP%E4%B8%AD%E7%BB%A7%E8%B7%A8%E9%93%BE%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97.md)) - **主要方法**: - `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 数据结构 ```go type accessControlService struct { // ... 其他字段 queryPolicyMap *sync.Map // map[string]*policy , resourceName -> *policy // ... 其他字段 } ``` #### 2. 策略初始化 在系统初始化时,通过 `initAccessControlService` 函数创建并初始化 queryPolicyMap: ```go 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` 策略: ```go // policyForbidden 策略定义 policyForbidden = newPolicy( protocol.RuleForbidden, // 禁止访问规则 nil, // 无组织列表限制 nil) // 无角色列表限制 // 将敏感方法配置为禁止访问 acs.queryPolicyMap.Store("CONTRACT_MANAGE-INIT_CONTRACT", policyForbidden) ``` #### 4. 查询策略验证流程 当用户发起 QUERY 调用时,系统执行以下验证流程: ```go 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`方法中实现了跨合约调用验证: ```go // 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. 版本检查 ```go if blockVersion >= blockVersion238 { // 执行跨合约调用验证 } ``` #### 2. 合约类型验证 ```go // 检查调用方是否为用户合约 !utils.IsNativeContract(caller.Name) // 检查被调用方是否为系统合约 utils.IsNativeContract(contract.Name) // 检查是否为中继跨合约调用例外 contract.Name != syscontract.SystemContract_RELAY_CROSS.String() ``` #### 3. 特殊场景处理 ```go // EVM合约安装EVM合约的特殊处理 if caller.RuntimeType == common.RuntimeType_EVM && contract.Name == syscontract.SystemContract_CONTRACT_MANAGE.String() && method == syscontract.ContractManageFunction_INIT_CONTRACT.String() { // 验证目标合约的运行时类型 } ``` #### 4. 访问控制验证 ```go // 调用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)