7.8 KiB
7.8 KiB
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仅支持基本类型(整数、字节数组、公钥列表)。但汇率系统需要存储更复杂的配置,如:
- 商品权重向量(18个uint16)
- 多协议验证密钥集合(每个协议对应一个bytes)
- 预言机节点元数据(地址、公钥、权重)
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
}
语义:
- 编译器为每个@system_constant结构体生成一个全局只读存储槽,该槽在合约部署时由系统状态树加载一次,并缓存在内存中(类似immutable)
- 若结构体较大,编译器可选择惰性加载(首次访问时加载)
2.3 实现方案
- 编译时生成:对于每个@system_constant函数,编译器生成一个对应的全局变量,并在构造函数中插入从系统状态树读取并反序列化的代码
- 反序列化代码自动生成:根据结构体定义生成对应的from_bytes函数
- 访问开销:首次访问触发一次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汇率变化对资产估值、清算线的影响,而无需部署主网合约或依赖预言机网络。要求:
- 完全模拟链上汇率计算逻辑(相同权重模型、相同价格输入)
- 支持历史回测与假设情景
- 无需实际支付Gas
3.2 设计:条件编译 + 模拟运行时
Charter编译器提供链下执行模式(--mode=offchain),在该模式下:
- 所有@oracle、@system_constant调用被重定向到本地模拟环境
- 区块链状态(账户余额、存储)从快照加载或手动构造
- 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语言特性
- @zk标记:支持多种ZK证明系统(Groth16/Plonk/Halo2)
- @system_constant:支持复杂结构体作为系统常量
- @oracle:预言机函数标记
- #[cfg(mode)]:条件编译支持链下测试
- 内置函数:
__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语言编写