NAC_Blockchain/CHARTER_LANGUAGE_SPEC.md

7.8 KiB
Raw Blame History

Charter语言规范要点

来源: Charter语言规范扩展增补.docx


1. 多ZK证明系统的内置支持

1.1 设计动机

  • XTZH汇率收据的零知识证明目前仅支持Groth16 (BN254曲线)
  • 需扩展支持Plonk(任意门限)、Halo2无需可信设置等主流zkSNARK系统
  • 必须保持上层API统一允许证明类型在运行时或编译期选择

1.2 语法扩展:@zk标记与多后端抽象

/// 零知识证明方案枚举
public enum ZKProtocol {
    Groth16Bn254,
    PlonkBn254,
    PlonkBls12_381,
    Halo2Kzg,
    Halo2IPA
}

/// 统一的ZK证明验证接口编译器内联多路分发
@zk(protocol: ZKProtocol)
public func verify_zk_proof(
    proof: bytes,
    public_inputs: []uint64,
    vk: bytes  /// 验证密钥,格式取决于协议
) -> bool;

1.3 NVM指令扩展

操作码 指令名称 功能 Gas成本
0xF8 ZK_VERIFY_PLONK 验证Plonk证明(BN254/Bls12-381) 25,000
0xF9 ZK_VERIFY_HALO2 验证Halo2证明(KZG/IPA) 35,000
0xFA ZK_AGGREGATE 聚合多个ZK证明(用于批量汇率收据) 15,000 + 每证明5,000

1.4 标准库封装 (xtzh/zk.charter)

/// 通用ZK验证函数协议在编译期常量时零开销
public func verify_proof(
    proof: bytes,
    inputs: []uint64,
    vk: bytes
) -> bool {
    // 编译器优化:若协议为编译期常量,直接内联对应指令
    return __builtin_zk_verify(proof, inputs, vk);
}

/// 批量验证多个证明(用于同一批汇率收据)
public func verify_batch(
    proofs: []bytes,
    inputs_list: [][]uint64,
    vks: []bytes,
    protocol: ZKProtocol
) -> bool {
    return __builtin_zk_aggregate(proofs, inputs_list, vks, protocol);
}

1.5 使用示例(预言机代码)

import "xtzh/zk.charter";

@oracle
func submit_zk_rate_with_plonk(
    receipt: ConstitutionalReceipt,
    proof: bytes,
    inputs: []uint64,
    vk: bytes
) {
    // 选择Plonk协议编译期常量
    const ZKProtocol PROTOCOL = ZKProtocol.PlonkBn254;
    require(xtzh::zk::verify_proof(proof, inputs, vk), "ZK proof invalid");
    
    xtzh::submit_rate(receipt);
}

2. @system_constant 支持复杂结构体常量

2.1 问题

现有@system_constant仅支持基本类型整数、字节数组、公钥列表。但汇率系统需要存储更复杂的配置

  1. 商品权重向量18个uint16
  2. 多协议验证密钥集合每个协议对应一个bytes
  3. 预言机节点元数据(地址、公钥、权重)

2.2 语法扩展

/// 商品权重配置
public struct CommodityConfig {
    beta: [18]uint16;      // 静态权重(基点,和=5000
    names: [18]bytes32;    // 商品名称(固定长度字节)
    enabled: [18]bool;     // 是否激活
}

/// 预言机节点信息
public struct OracleNode {
    pubkey: bytes48;       // BLS公钥
    weight: uint16;        // 投票权重1-100
    endpoint: bytes;       // API地址仅链下使用
}

/// 系统常量声明
@system_constant(key = "XTZH_COMMODITY_CONFIG")
public func commodity_config() -> CommodityConfig;

@system_constant(key = "XTZH_ORACLE_NODES")
public func oracle_nodes() -> []OracleNode;

@system_constant(key = "XTZH_ZK_VKS")
public struct ZKVerificationKeys {
    groth16: bytes,
    plonk_bn254: bytes,
    halo2_kzg: bytes
}

语义

  1. 编译器为每个@system_constant结构体生成一个全局只读存储槽该槽在合约部署时由系统状态树加载一次并缓存在内存中类似immutable
  2. 若结构体较大,编译器可选择惰性加载(首次访问时加载)

2.3 实现方案

  1. 编译时生成:对于每个@system_constant函数编译器生成一个对应的全局变量并在构造函数中插入从系统状态树读取并反序列化的代码
  2. 反序列化代码自动生成根据结构体定义生成对应的from_bytes函数
  3. 访问开销首次访问触发一次SYSTEM_STATE_READ指令后续访问为内存加载零成本

2.4 使用示例

import "xtzh/governance.charter";

func get_gold_weight() -> uint16 {
    let config = xtzh::governance::commodity_config();
    return config.beta[0];  // 假设黄金是第一个商品
}

func verify_with_latest_vk(proof: bytes, inputs: []uint64) -> bool {
    let vks = xtzh::governance::zk_vks();
    return xtzh::zk::verify_proof(proof, inputs, vks.groth16);
}

3. xtzh::simulate_rate 沙箱函数(链下测试)

3.1 需求

开发者尤其是RWA资产发行方需要在链下环境测试XTZH汇率变化对资产估值、清算线的影响而无需部署主网合约或依赖预言机网络。要求

  1. 完全模拟链上汇率计算逻辑(相同权重模型、相同价格输入)
  2. 支持历史回测与假设情景
  3. 无需实际支付Gas

3.2 设计:条件编译 + 模拟运行时

Charter编译器提供链下执行模式--mode=offchain在该模式下

  1. 所有@oracle、@system_constant调用被重定向到本地模拟环境
  2. 区块链状态(账户余额、存储)从快照加载或手动构造
  3. Gas计量被禁用或仅记录不扣费

3.3 标准库扩展

/// 仅在offchain模式可用主网编译时报错
#[cfg(mode = "offchain")]
public func simulate_rate(
    commodity_prices: [18]uint64,  // 输入18种商品的美元价格6位小数
    gold_price: uint64              // 黄金价格(美元/盎司6位小数
) -> uint64 {
    // 1. 加载权重配置offchain模式下从本地JSON读取
    let config = __offchain_load_config("xtzh_commodity_config.json");
    
    // 2. 计算加权平均价格
    let mut weighted_sum: uint128 = 0;
    for i in 0..18 {
        if config.enabled[i] {
            weighted_sum += (commodity_prices[i] as uint128) * (config.beta[i] as uint128);
        }
    }
    let basket_price = weighted_sum / 5000;  // 归一化(权重和=5000基点
    
    // 3. 计算XTZH汇率1 XTZH = basket_price / gold_price
    return (basket_price * 1_000_000) / gold_price;
}

/// 批量回测历史数据
#[cfg(mode = "offchain")]
public func backtest_rates(
    historical_data: []HistoricalSnapshot
) -> []uint64 {
    let mut rates = [];
    for snapshot in historical_data {
        rates.push(simulate_rate(snapshot.prices, snapshot.gold_price));
    }
    return rates;
}

关键要点总结

Charter语言特性

  1. @zk标记支持多种ZK证明系统Groth16/Plonk/Halo2
  2. @system_constant:支持复杂结构体作为系统常量
  3. @oracle:预言机函数标记
  4. #[cfg(mode)]:条件编译支持链下测试
  5. 内置函数
    • __builtin_zk_verify(): ZK证明验证
    • __builtin_zk_aggregate(): 批量ZK证明聚合
    • __offchain_load_config(): 链下配置加载

数据类型

  • bytes: 动态字节数组
  • bytes32, bytes48: 固定长度字节数组
  • [N]T: 固定长度数组
  • []T: 动态数组
  • map<K, V>: 映射
  • uint16, uint64, uint128, uint256: 无符号整数
  • bool: 布尔值
  • DID: 去中心化身份标识符
  • Address: NAC地址32字节

合约结构

contract ContractName {
    storage {
        // 存储变量
    }
    
    constructor(params) {
        // 构造函数
    }
    
    pub fn function_name(params) -> ReturnType {
        // 公共函数
    }
}

Asset定义

asset AssetName {
    gnacs: 0xXXXXXXXXXXXX;  // GNACS编码
    sovereignty: C2;          // 主权级别
    
    owner: DID;
    // 其他字段
}

重要提醒

  • NAC公链使用Charter语言不是Solidity
  • 不要继承ERC-20、ERC-721等以太坊标准
  • 使用ACC-20协议作为NAC的资产标准
  • 所有合约必须使用Charter语言编写