436 lines
15 KiB
Plaintext
436 lines
15 KiB
Plaintext
// charter-std/src/constitution_interface.charter
|
||
// NAC公链 Charter 智能合约宪法接口
|
||
// Issue #70 | 版本: 1.0 | 2026-03-07
|
||
//
|
||
// 本文件定义 Charter 合约访问宪法层的标准接口:
|
||
// - 宪法条款查询接口(A44-A52)
|
||
// - 节点共享合规验证绑定
|
||
// - 跨辖区资源分配查询
|
||
// - 辖区身份验证接口
|
||
|
||
// ============================================================
|
||
// 标准库导入(Charter 原生)
|
||
// ============================================================
|
||
|
||
import std::types::{ Address, Hash, Bytes48, Uint16, Uint64, Bool, String }
|
||
import std::acc20::{ AssetId, AssetRecord }
|
||
import std::cr::{ ConstitutionalReceipt, DualConstitutionalReceipt }
|
||
import std::jurisdiction::{ JurisdictionId, JurisdictionProof }
|
||
|
||
// ============================================================
|
||
// 宪法条款查询接口
|
||
// ============================================================
|
||
|
||
/// 宪法条款层级
|
||
enum ClauseTier {
|
||
Eternal, // 永恒级(索引1-100)
|
||
Strategic, // 战略级(索引101-1000)
|
||
Tactical, // 战术级(索引1001+)
|
||
}
|
||
|
||
/// 宪法条款记录
|
||
struct ConstitutionalClause {
|
||
clause_index: Uint64,
|
||
title: String,
|
||
tier: ClauseTier,
|
||
is_active: Bool,
|
||
effective_from: Uint64,
|
||
clause_hash: Bytes48,
|
||
}
|
||
|
||
/// 节点共享宪法条款(A44-A52)
|
||
struct NodeSharingClause {
|
||
clause_index: Uint64,
|
||
name: String,
|
||
tier: ClauseTier,
|
||
// 条款核心谓词(CNNL形式化表达)
|
||
predicate_hash: Bytes48,
|
||
// 违规处理动作
|
||
violation_action: String,
|
||
is_active: Bool,
|
||
}
|
||
|
||
// ============================================================
|
||
// 宪法接口(内置合约,地址 0x0000...CONST)
|
||
// ============================================================
|
||
|
||
/// NAC宪法内置合约接口
|
||
/// 合约地址:0x0000000000000000000000000000000000000001
|
||
interface IConstitution {
|
||
|
||
// --- 条款查询 ---
|
||
|
||
/// 查询宪法条款是否激活
|
||
/// @param clause_index 条款索引(如 A44 = 44)
|
||
/// @returns 条款是否处于激活状态
|
||
fn is_clause_active(clause_index: Uint64) -> Bool
|
||
|
||
/// 获取条款详情
|
||
/// @param clause_index 条款索引
|
||
/// @returns 条款记录(不存在时 panic)
|
||
fn get_clause(clause_index: Uint64) -> ConstitutionalClause
|
||
|
||
/// 获取节点共享条款(A44-A52)
|
||
/// @param clause_index 条款索引(44-52)
|
||
/// @returns 节点共享条款记录
|
||
fn get_node_sharing_clause(clause_index: Uint64) -> NodeSharingClause
|
||
|
||
// --- 节点共享合规验证(A44)---
|
||
|
||
/// 验证节点是否满足物理共享逻辑隔离要求(A44)
|
||
/// @param node_did 节点DID
|
||
/// @param container_id 容器实例ID(不能为空)
|
||
/// @param network_namespace 网络命名空间(不能为空)
|
||
/// @returns 是否合规
|
||
fn verify_node_sharing_isolation(
|
||
node_did: String,
|
||
container_id: String,
|
||
network_namespace: String,
|
||
) -> Bool
|
||
|
||
// --- 跨辖区双CR验证(A45)---
|
||
|
||
/// 验证跨辖区交易的双CR(A45)
|
||
/// @param source_cr 源辖区宪法收据
|
||
/// @param target_cr 目标辖区宪法收据
|
||
/// @returns 双CR是否有效
|
||
fn verify_dual_cr(
|
||
source_cr: ConstitutionalReceipt,
|
||
target_cr: ConstitutionalReceipt,
|
||
) -> Bool
|
||
|
||
/// 获取当前区块的 jurisdiction_merkle_root(A45)
|
||
/// @returns 当前区块的辖区默克尔树根(无跨辖区交易时返回零哈希)
|
||
fn get_jurisdiction_merkle_root() -> Bytes48
|
||
|
||
// --- 资源配额查询(A46)---
|
||
|
||
/// 查询辖区当前资源配额(A46)
|
||
/// @param jurisdiction 辖区ID
|
||
/// @returns (cpu_share, memory_share, bandwidth_share, storage_share) 定点数1e4
|
||
fn get_jurisdiction_quota(jurisdiction: JurisdictionId) -> (Uint64, Uint64, Uint64, Uint64)
|
||
|
||
/// 检查辖区是否超出资源配额(A46)
|
||
/// @param jurisdiction 辖区ID
|
||
/// @returns 是否超出配额
|
||
fn is_quota_exceeded(jurisdiction: JurisdictionId) -> Bool
|
||
|
||
// --- 节点身份辖区绑定(A47)---
|
||
|
||
/// 验证节点DID的辖区绑定(A47)
|
||
/// @param node_did 节点DID
|
||
/// @param jurisdiction 声明的辖区ID
|
||
/// @returns 绑定是否有效
|
||
fn verify_node_jurisdiction_binding(
|
||
node_did: String,
|
||
jurisdiction: JurisdictionId,
|
||
) -> Bool
|
||
|
||
/// 验证节点加载的插件哈希是否已授权(A47)
|
||
/// @param node_did 节点DID
|
||
/// @param plugin_hash 插件哈希(SHA3-384)
|
||
/// @returns 插件是否已授权
|
||
fn verify_plugin_hash_authorized(
|
||
node_did: String,
|
||
plugin_hash: Bytes48,
|
||
) -> Bool
|
||
|
||
// --- WASM沙箱验证(A48)---
|
||
|
||
/// 验证插件是否在WASM沙箱中执行(A48)
|
||
/// @param plugin_hash 插件哈希
|
||
/// @returns 是否在WASM沙箱中执行
|
||
fn verify_wasm_sandbox_execution(plugin_hash: Bytes48) -> Bool
|
||
|
||
/// 检查插件哈希是否已上链(A48)
|
||
/// @param plugin_hash 插件哈希
|
||
/// @returns 是否已上链
|
||
fn is_plugin_hash_on_chain(plugin_hash: Bytes48) -> Bool
|
||
|
||
// --- CEE集群查询(A49)---
|
||
|
||
/// 获取支持指定辖区的CEE节点列表(A49)
|
||
/// @param jurisdiction 辖区ID
|
||
/// @returns CEE节点DID列表
|
||
fn get_cee_nodes_for_jurisdiction(jurisdiction: JurisdictionId) -> Array<String>
|
||
|
||
/// 获取负载最低的CEE节点(A49,用于跨辖区交易路由)
|
||
/// @param source_jurisdiction 源辖区
|
||
/// @param target_jurisdiction 目标辖区
|
||
/// @returns 最优CEE节点DID(无可用节点时返回空字符串)
|
||
fn get_optimal_cee_node(
|
||
source_jurisdiction: JurisdictionId,
|
||
target_jurisdiction: JurisdictionId,
|
||
) -> String
|
||
|
||
// --- 争议状态查询(A50)---
|
||
|
||
/// 查询辖区间是否存在未解决争议(A50)
|
||
/// @param jurisdiction_a 辖区A
|
||
/// @param jurisdiction_b 辖区B
|
||
/// @returns 是否存在未解决争议
|
||
fn has_pending_dispute(
|
||
jurisdiction_a: JurisdictionId,
|
||
jurisdiction_b: JurisdictionId,
|
||
) -> Bool
|
||
|
||
// --- CSNP路由验证(A51)---
|
||
|
||
/// 验证CSNP辖区感知路由是否启用(A51)
|
||
/// @returns 是否启用
|
||
fn is_csnp_jurisdiction_routing_enabled() -> Bool
|
||
|
||
// --- 存储加密验证(A52)---
|
||
|
||
/// 验证存储节点是否满足加密要求(A52)
|
||
/// @param storage_node_did 存储节点DID
|
||
/// @returns 是否满足A52要求
|
||
fn verify_storage_encryption_compliance(storage_node_did: String) -> Bool
|
||
}
|
||
|
||
// ============================================================
|
||
// 示例合约:使用宪法接口的 RWA 资产跨辖区转移合约
|
||
// ============================================================
|
||
|
||
/// RWA资产跨辖区转移合约(集成A44-A52宪法条款)
|
||
contract RwaAssetCrossJurisdictionTransfer {
|
||
|
||
// 宪法内置合约地址
|
||
const CONSTITUTION_ADDRESS: Address = 0x0000000000000000000000000000000000000001
|
||
|
||
// 状态变量
|
||
state {
|
||
owner: Address,
|
||
asset_id: AssetId,
|
||
source_jurisdiction: JurisdictionId,
|
||
target_jurisdiction: JurisdictionId,
|
||
transfer_status: TransferStatus,
|
||
source_cr: ConstitutionalReceipt,
|
||
target_cr: ConstitutionalReceipt,
|
||
initiated_at: Uint64,
|
||
}
|
||
|
||
enum TransferStatus {
|
||
Pending,
|
||
CrVerified,
|
||
Completed,
|
||
Failed,
|
||
}
|
||
|
||
// 构造函数
|
||
constructor(
|
||
asset_id: AssetId,
|
||
source_jurisdiction: JurisdictionId,
|
||
target_jurisdiction: JurisdictionId,
|
||
) {
|
||
self.owner = msg.sender
|
||
self.asset_id = asset_id
|
||
self.source_jurisdiction = source_jurisdiction
|
||
self.target_jurisdiction = target_jurisdiction
|
||
self.transfer_status = TransferStatus::Pending
|
||
self.initiated_at = block.timestamp
|
||
}
|
||
|
||
/// 提交双CR并验证(A45)
|
||
/// 调用者必须提供源辖区和目标辖区的宪法收据
|
||
fn submit_dual_cr(
|
||
source_cr: ConstitutionalReceipt,
|
||
target_cr: ConstitutionalReceipt,
|
||
) -> Bool {
|
||
// 仅资产所有者可提交
|
||
require(msg.sender == self.owner, "仅资产所有者可提交双CR")
|
||
require(self.transfer_status == TransferStatus::Pending, "转移状态不正确")
|
||
|
||
// 调用宪法内置合约验证双CR(A45)
|
||
let constitution = IConstitution(CONSTITUTION_ADDRESS)
|
||
let is_valid = constitution.verify_dual_cr(source_cr, target_cr)
|
||
|
||
if !is_valid {
|
||
self.transfer_status = TransferStatus::Failed
|
||
emit DualCrVerificationFailed(self.asset_id, block.timestamp)
|
||
return false
|
||
}
|
||
|
||
// 检查辖区间是否有未解决争议(A50)
|
||
let has_dispute = constitution.has_pending_dispute(
|
||
self.source_jurisdiction,
|
||
self.target_jurisdiction,
|
||
)
|
||
require(!has_dispute, "A50: 辖区间存在未解决争议,转移被暂停")
|
||
|
||
// 检查目标辖区资源配额(A46)
|
||
let quota_exceeded = constitution.is_quota_exceeded(self.target_jurisdiction)
|
||
require(!quota_exceeded, "A46: 目标辖区资源配额已超出,请稍后重试")
|
||
|
||
self.source_cr = source_cr
|
||
self.target_cr = target_cr
|
||
self.transfer_status = TransferStatus::CrVerified
|
||
|
||
emit DualCrVerified(self.asset_id, self.source_jurisdiction, self.target_jurisdiction)
|
||
return true
|
||
}
|
||
|
||
/// 执行跨辖区转移(A45验证通过后)
|
||
fn execute_transfer(recipient: Address) -> Bool {
|
||
require(msg.sender == self.owner, "仅资产所有者可执行转移")
|
||
require(self.transfer_status == TransferStatus::CrVerified, "双CR未验证")
|
||
|
||
let constitution = IConstitution(CONSTITUTION_ADDRESS)
|
||
|
||
// 验证接收方节点的辖区绑定(A47)
|
||
// 注:实际实现中需要通过 nac_lens 查询接收方节点DID
|
||
|
||
// 验证CSNP路由是否启用(A51)
|
||
let routing_enabled = constitution.is_csnp_jurisdiction_routing_enabled()
|
||
require(routing_enabled, "A51: CSNP辖区感知路由未启用,无法执行跨辖区转移")
|
||
|
||
// 执行ACC-20资产转移(NAC原生标准)
|
||
// 注:使用 std::acc20 而非 ERC-20
|
||
let transfer_result = acc20::transfer_cross_jurisdiction(
|
||
self.asset_id,
|
||
self.owner,
|
||
recipient,
|
||
self.source_cr,
|
||
self.target_cr,
|
||
)
|
||
|
||
if transfer_result {
|
||
self.transfer_status = TransferStatus::Completed
|
||
emit TransferCompleted(
|
||
self.asset_id,
|
||
self.owner,
|
||
recipient,
|
||
self.source_jurisdiction,
|
||
self.target_jurisdiction,
|
||
block.timestamp,
|
||
)
|
||
} else {
|
||
self.transfer_status = TransferStatus::Failed
|
||
emit TransferFailed(self.asset_id, block.timestamp)
|
||
}
|
||
|
||
return transfer_result
|
||
}
|
||
|
||
// 事件定义
|
||
event DualCrVerificationFailed(asset_id: AssetId, timestamp: Uint64)
|
||
event DualCrVerified(
|
||
asset_id: AssetId,
|
||
source_jurisdiction: JurisdictionId,
|
||
target_jurisdiction: JurisdictionId,
|
||
)
|
||
event TransferCompleted(
|
||
asset_id: AssetId,
|
||
from: Address,
|
||
to: Address,
|
||
source_jurisdiction: JurisdictionId,
|
||
target_jurisdiction: JurisdictionId,
|
||
timestamp: Uint64,
|
||
)
|
||
event TransferFailed(asset_id: AssetId, timestamp: Uint64)
|
||
}
|
||
|
||
// ============================================================
|
||
// 示例合约:节点共享注册合约(A44/A47)
|
||
// ============================================================
|
||
|
||
/// 节点共享注册合约
|
||
/// 用于在链上记录节点的物理共享状态和辖区绑定
|
||
contract NodeSharingRegistry {
|
||
|
||
const CONSTITUTION_ADDRESS: Address = 0x0000000000000000000000000000000000000001
|
||
|
||
state {
|
||
admin: Address,
|
||
// 节点DID → 共享节点记录
|
||
nodes: Map<String, SharedNodeOnChain>,
|
||
// 辖区 → 节点DID列表
|
||
jurisdiction_nodes: Map<JurisdictionId, Array<String>>,
|
||
total_nodes: Uint64,
|
||
}
|
||
|
||
struct SharedNodeOnChain {
|
||
node_did: String,
|
||
jurisdiction: JurisdictionId,
|
||
physical_host_id: String,
|
||
container_id: String,
|
||
network_namespace: String,
|
||
plugin_hashes: Array<Bytes48>,
|
||
is_active: Bool,
|
||
registered_at: Uint64,
|
||
jurisdiction_proof_hash: Bytes48,
|
||
}
|
||
|
||
constructor() {
|
||
self.admin = msg.sender
|
||
self.total_nodes = 0
|
||
}
|
||
|
||
/// 注册共享节点(A44 + A47 双重验证)
|
||
fn register_shared_node(
|
||
node_did: String,
|
||
jurisdiction: JurisdictionId,
|
||
physical_host_id: String,
|
||
container_id: String,
|
||
network_namespace: String,
|
||
plugin_hashes: Array<Bytes48>,
|
||
jurisdiction_proof_hash: Bytes48,
|
||
) -> Bool {
|
||
let constitution = IConstitution(CONSTITUTION_ADDRESS)
|
||
|
||
// A44: 验证节点逻辑隔离
|
||
let isolation_ok = constitution.verify_node_sharing_isolation(
|
||
node_did,
|
||
container_id,
|
||
network_namespace,
|
||
)
|
||
require(isolation_ok, "A44: 节点未满足逻辑隔离要求")
|
||
|
||
// A47: 验证节点辖区绑定
|
||
let binding_ok = constitution.verify_node_jurisdiction_binding(node_did, jurisdiction)
|
||
require(binding_ok, "A47: 节点辖区绑定验证失败")
|
||
|
||
// A47: 验证所有插件哈希已授权
|
||
for hash in plugin_hashes {
|
||
let authorized = constitution.verify_plugin_hash_authorized(node_did, hash)
|
||
require(authorized, "A47: 存在未授权的辖区规则插件")
|
||
}
|
||
|
||
// A48: 验证插件在WASM沙箱中执行
|
||
for hash in plugin_hashes {
|
||
let wasm_ok = constitution.verify_wasm_sandbox_execution(hash)
|
||
require(wasm_ok, "A48: 插件必须在WASM沙箱中执行")
|
||
|
||
let on_chain = constitution.is_plugin_hash_on_chain(hash)
|
||
require(on_chain, "A48: 插件哈希必须已上链验证")
|
||
}
|
||
|
||
// 记录节点信息
|
||
let record = SharedNodeOnChain {
|
||
node_did: node_did,
|
||
jurisdiction: jurisdiction,
|
||
physical_host_id: physical_host_id,
|
||
container_id: container_id,
|
||
network_namespace: network_namespace,
|
||
plugin_hashes: plugin_hashes,
|
||
is_active: true,
|
||
registered_at: block.timestamp,
|
||
jurisdiction_proof_hash: jurisdiction_proof_hash,
|
||
}
|
||
|
||
self.nodes[node_did] = record
|
||
self.jurisdiction_nodes[jurisdiction].push(node_did)
|
||
self.total_nodes += 1
|
||
|
||
emit NodeRegistered(node_did, jurisdiction, block.timestamp)
|
||
return true
|
||
}
|
||
|
||
/// 查询辖区节点数量
|
||
fn get_jurisdiction_node_count(jurisdiction: JurisdictionId) -> Uint64 {
|
||
return self.jurisdiction_nodes[jurisdiction].length() as Uint64
|
||
}
|
||
|
||
event NodeRegistered(node_did: String, jurisdiction: JurisdictionId, timestamp: Uint64)
|
||
}
|