系统合约管理
概述
系统合约是区块链底层基础设施的核心组件,负责管理链的基本配置、账户体系、合约生命周期等关键功能。本系统采用模块化的系统合约架构,每个系统合约负责特定的功能领域。
系统合约列表
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- 从白名单中删除节点IDNODE_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- 为候选人设置关联的节点IDGET_NODE_ID- 查询候选人关联的节点IDREAD_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- 退还虚拟机执行过程中未消耗的GasFROZEN_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- 从黑名单中移除交易IDGET_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 方式调用,这导致以下问题:
垃圾数据问题: QUERY 调用虽然不产生区块数据,但会在节点内部产生临时数据和日志
资源浪费: 频繁的 QUERY 调用消耗节点计算和存储资源
安全风险: 恶意用户可能通过 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版本之前,用户合约可以自由调用系统合约,这导致以下问题:
安全风险: 恶意用户合约可能通过跨合约调用操纵系统合约
状态混乱: 配置变更交易可能与其他交易混合在同一区块中
审计困难: 系统合约调用路径复杂,难以追踪和审计
性能影响: 系统合约调用可能影响区块链的整体性能
设计目标
隔离系统合约调用,确保配置变更交易的独立性
保持必要的跨合约调用功能(如中继跨合约)
支持以太坊兼容的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)