Skip to main content

Command Palette

Search for a command to run...

EnsoVM:客户端验证的极简MoveVM for BTC & Tondi

Updated
•26 min read•View as Markdown
EnsoVM:客户端验证的极简MoveVM for BTC & Tondi
A

人体工学エンジニア、クオンツ金融エンジンアーキテクト、暗号技術の専門家として、 現在は Tondiチェーンの主任研究員を務めております。 RGBプロトコル、DAG構造、クライアント検証型スマートコントラクトなど、 次世代の分散型金融インフラの設計と実装に取り組んでいます。 私は、技術とは単なる道具ではなく、文明秩序を記述するコードだと考えています。

0.导论:圓相

在日本禅宗中,圓相(Enso) 是以单一笔触画出的圆。它的意义在于:

  • 一笔到底的简约(simplicity)
    圓相之圆,拒绝修饰与反复,乃『直指人心』的笔触。它象征修行者的心性能否当下贯通,不假雕饰。简约并非贫乏,而是直面本质的力量。

  • 圆满自足的完整(completeness)
    一个封闭而自成整体的圆,表明真如之境本自圆满,不依赖外缘而自足。它既是『诸法圆融』的象征,也是修行者『无欠无余』的见地。

  • 留白的开放(openness)
    圓相往往不求闭合,留有一线空隙。此『未竟之圆』正是开放之处,意味着圆不排斥不确定性,观者可于其中自由进入,生出自得的体悟。

  • 空无中的无限(emptiness / infinity)
    圓相所围绕的是空,而空并非虚无,而是孕育一切可能的根基。


从工程到禅思的映射

  • 去全局表 = 破除『实体执著』 传统区块链执著于『万物皆须在一处明示』。 圓相 则教人『无所住而生其心』:不执着于固定实体,才能真正自由。 Enso 去掉全局表,改以 DomainRoot 为『私域状态根』。每个参与者自成一域,如『一沙中见世界』。

  • 证明式存储 vmap = 『因缘所生法』在佛理中,一切事物皆因缘和合而成。验证的意义,也不在固定的『账本』,而在可复演的『因缘链条』。 vmap 就是这种『因缘存储』:给你根、路径与证明,你即可独立演绎,确认当下之实。

  • Parcel = 当下的一念 禅强调『一念既生,万法俱备』。Parcel 就是『一次交易的完整一念』:包含证明、事件、签名、资源消耗。 不需要旁证与外史,Parcel 自足以成全。

  • EpochRoot = 公案之断代 禅师以公案截断弟子思虑,使其回到一念。 EpochRoot 就是区块时间的『公案』:它把一段时间的更新统一锚定,形成历史断点。过去无需无限携带,未来只需从这里展开。

  • Fuel ≠ Gas = 『坐禅无价』 禅修不可以金钱计量;坐禅只需姿势端正、气息绵长。 Enso 亦如此:Fuel 并非经济成本,而是修行规矩——超过便停,合度则安。它是『限度』,不是『价格』。


Enso 的跨域互通

『圓相』 并非主动斩断缘起的孤岛。

在工程层面,EnsoVM 基于 Move 语义,天然与 Aptos、Sui 共享“线性资源”的语言结构。 这使得 Enso 能够在保持自身 去全局表、客户端验证 特性的同时,通过 桥接(ESIP-Bridge) 与 Aptos、Sui 建立通信:

当 Enso 需要进入跨链环境时,可以借助 Move 兼容性把 Parcel 翻译为 Aptos/Sui 能理解的全局表事务;

当需要引入外部资产或跨域治理时,可以利用 Aptos/Sui 的账户模型来补充“全局表功能”。

换言之:Enso 是禅宗的圆,极简而自足;但其圆并非封闭,而是能以一笔勾连多界,在验证的间隙中保留通向他链的桥梁。


1. 项目定位与愿景

Enso 的目标:在 MoveVM 深度裁剪 与BTC 或 Tondi的极简锚定下,提供隐私友好、高性能、可跨链的客户端验证协议层,成为 RGB 的工业级继任者与 BTC 生态的 终端验证层(Terminal Validation Layer)。

面向落地,Enso 的价值主张具象为:

  1. 最小门槛:延续 Move 语义(线性/仿射类型),ESIP 与 Aptos Move 在接口层兼容;但去掉账户链/全局表等与客户端验证冲突的设施。

  2. 状态即证明:任何资源/余额/凭证都由 vmap + Proof 表示,交易携带 ProofDelta,第三方无需索引器也能独立验证。

  3. 锚定极简:只把 EpochRoot/Bundle 哈希刻进 Taproot(key tweak 或 leaf 方案)或 Tondi;不把业务状态上链。

  4. 极简运维:节点不再“同步全局状态”,而是缓存近期 EpochRoot 与少量索引;钱包/服务以 Parcel 为一等公民互通。

  5. 可组装原生桥:原生桥接 RGB/Aptos/EVM;ESIP-Bridge 系列形成标准。

  6. 工业级的readiness:白名单原生、AOT/WASM-Min、Fuel 限额、前缀合并与批量验签,保证可靠吞吐与 DoS 抑制。


2. 设计哲学

  1. 隐私优先

    • 无全局账户表;所有事件对外仅是承诺;余额/转账不可被第三方扫描。

    • Parcel 只向参与者暴露必要明文;对外仅可见哈希与锚定数据。

  2. 最小信任

    • 客户端完全独立验证:只需 DomainRoot、Proof 与锚定头信息,即可确认正确性。

    • 任何中继/索引器都是可替代缓存,而非信任根。

  3. 跨链安全

    • 根承诺锚定于 BTC/Tondi Taproot(taptweak 或 TapLeaf),继承 BTC 安全性;

    • RBF 友好锚定策略 + 再锚定窗口,抵御锚定延迟与重组。

  4. Move 兼容

    • ESIP 与 Aptos Move 在模块接口与标准库层维持相似度;

    • 开发者沿用 Move 的类型与“资源不可复制”理念,只是存储/事件语义全改为证明式。

  5. 工程务实

    • 去除随机数/时间/IO 等不确定原生;

    • Fuel = {steps、mem_pages、proof_nodes、commit_events},超限即 abort;

    • 仅 hash、sig-verify、merkle/verkle、bytes 等少数原生保留;

    • 目标是在常规笔记本/手机上实现 50–150ms/笔的可体验延迟。


3. 与 Aptos MoveVM 的核心差异与实现细节

3.1 禁用全局状态

  • 移除 move_to/move_from/borrow_global(_mut) 与基于全局账户的存取。

  • 不再有 sequence number、链上账户余额等概念。

  • 取而代之:通过 vmap 接口对“本地状态域(DomainRoot)”进行证明式读写。

实现要点

  • VM 层:在类型系统保留 resource 约束;但存储指令全部路由至 vmap 原生。

  • 运行时:任何资源落地都要指定 DomainRoot 与 Proof(见 3.2),以便产出 new_root。

  • 编译器:在 Enso-slim feature 下,链接的标准库去掉全局表依赖;在 aptos-compat 下,退化回 Aptos Table/Global(仅供开发调试)。

3.2 vmap:证明式 KV 映射

  • 接口原型(Native):

    • map_read(domain_root: [32]u8, proof: Bytes) -> (value: Bytes, seq: u64)

    • map_write_with_delta(domain_root: [32]u8, proof: Bytes, delta: Bytes, expected_seq: u64) -> (new_root: [32]u8, new_seq: u64, proof_delta: Bytes)

  • 读写均要求证明可验证(Merkle/Verkle 可插件化),并输出差分证明 ProofDelta。

  • ProofDelta 是交易可携带的对象,可直接交付接收方,作为其后续花费的输入。

数据结构(建议 CBOR 编码,版本化)

Scheme {
  id: u16,                    // 注册表ID,避免歧义
  hash_fn: "SHA256" | "BLAKE3" | "KECCAK256",
  tree: "SparseMerkle-2^n" | "Verkle-IPA" | "BinaryMerkle",
  node_encoding: "SSZ-v1" | "CBOR-det-v1",
  params_hash: [32]u8         // 冻结配置摘要
}

VmapProof {
  scheme: Scheme,
  domain_root: [32]u8,
  nodes: [ProofNode],         // 路径节点/承诺片段
  proof_kind: "membership" | "non-membership",  // 证明类型
  max_node_size: u32,         // 最大节点大小限制 (4KB)
  max_branching_factor: u8    // 最大分支因子限制
}

// VmapProof 失败语义
// 任一节点解码失败、路径越界、节点超过 max_node_size 或 max_branching_factor 
// → deterministic abort(计入 Fuel:仅已消耗部分)

VmapDelta {
  old_root: [32]u8,
  new_root: [32]u8,
  prev_seq: u64,              // 前一个序列号
  new_seq: u64,               // 新序列号 (必须 = prev_seq + 1)
  rw_ops: [ RWOp ],           // {key, old_val?, new_val?, expected_seq, witness?, lock_kind, lock_scope, lock_epoch_hint}
  comp_hint: [u8],            // 可选,Prefix-Merge Hints v1,便于前缀合并/批量校验的压缩提示
  spend_auth_tag: [32]u8      // PayJoin防重放标签
}

RWOp {
  key: Bytes,
  old_val: Bytes?,
  new_val: Bytes?,
  expected_seq: u64,
  witness: Bytes?,
  lock_kind: "none" | "optimistic" | "exclusive",
  lock_scope: "key" | "prefix" | "domain",
  lock_epoch_hint: u64?
}

可插拔承诺方案

  • 默认:SHA-256 Merkle,简单可靠、无可信设置。

  • 可选:IPA-Verkle(无可信设置)或 KZG-Verkle(若可接受 SRS,则体积更优)。

  • 通过 scheme 号透明协商,运行时按 scheme 调用对应 verifier。

  • 将这些限制迁移到 Scheme 的 profile(Merkle/Verkle 分别定义上限),不要写死在通用结构。

序列号验证规范:Verifier MUST check new_seq = prev_seq + 1 AND rw_ops[*].expected_seq = prev_seq,否则返回 E_SEQ_REUSE。

冲突检测规范:同 (domain_id, prev_seq) 以外,还应检测同一 key/prefix 的写-写冲突(在 optimistic 模式下)并返回 E_RW_CONFLICT。

3.3 Parcel:一等公民的见证包

Parcel 把 交易 + 证明 + 事件承诺 + 签名 + 运行时度量 合为可独立验证的对象。

结构(CBOR/SSZ/scale 可选,示例以 CBOR 为意向描述)

Parcel {
  header: {
    version: u16,
    network: u8,                   // 0:testnet, 1:mainnet...
    epoch_hint: u64,               // 便于对齐预期锚定的 epoch/index
    inputs: [DomainInput],         // 本次消费所依赖的 DomainRoot 列表(可多域并行)
    schema_refs: [SchemaRef],      // 用到的 schema 版本/哈希
    fuel_limit: FuelLimit,         // steps/mem_pages/proof_nodes/commit_events
    anti_replay_tag: [32]u8,       // 防重放标签
    profile_decl: ProfileDecl,     // Profile声明
    profile_capabilities: ProfileCapabilities  // Profile能力集
  },
  body: {
    vmap_proofs: [VmapProof],      // 读证明集合
    vmap_deltas: [VmapDelta],      // 写差分集合(互斥/可并行合并)
    commitments: [Commitment],     // 承诺事件,外部仅见 hash
    sigs: [SigSlot],               // 多签/门限/脚本签名位
  },
  trailer: {
    metrics: FuelUsage,            // 实际使用;由 verifier 填写并签名确认
    anchor_hint: AnchorHint,       // Taproot 预锚定提示(taptweak 或 leaf path)
    taproot_proof_offchain: TaprootProofOffchain?,  // 离线 taproot 证明(Profile R)
    aux: Bytes                     // 业务自定义区
  }
}

DomainInput {
  domain_id: [32]u8,              // 域标识
  prev_root: [32]u8,              // 前一个状态根
  prev_seq: u64                   // 前一个序列号
}

Commitment { topic: [32]u8, payload_hash: [32]u8 }
FuelLimit   { steps:u32, mem_pages:u32, proof_nodes:u32, commit_events:u16 }
FuelUsage   { steps:u32, mem_pages:u32, proof_nodes:u32, commit_events:u16 }
SigSlot     { algo:u8, pubkey:Bytes, sig:Bytes, role:u8 } // role=HW/LN/MultisigPartner...
SchemaRef   { schema_id:u128, hash:[32]u8, rev:u32 }

TaprootProofOffchain {
  leaf_script: Bytes,
  control_block: Bytes,
  tapleaf_version: u8,
  script_path: "tapscript",
  proof_chain_id: [32]u8,    // 防止复用错误脚本模板
  leaf_template_id: [32]u8,  // 防止复用错误脚本模板
  note: "off-chain proof; not necessarily revealed on-chain"
}

ProfileDecl {
  anchor_profile: "T" | "B",
  chain_id: [32]u8,
  reveal_slo: u64?          // 延迟揭示SLO(例如:24h)
}

ProfileCapabilities {
  allow_offchain_reveal: bool,
  max_rbf_window: u32,
  audit_mode: bool
}

要点:任何第三方仅凭该 Parcel + 对应 DomainRoot 旧值,就能重放验证,并检查 Fuel 限额、事件承诺与签名完整性,无需外部数据库。验证器需支持"纯离线 taproot 证明重建"。

3.4 承诺事件(Commitment Events)

  • 禁止明文 event::emit<T>;仅允许 emit_commitment(topic, H(payload))。

  • topic 可约定为 schema-scoped 前缀(避免冲突)。

  • 明文 payload 由参与方点对点发送或置于离线存储(IPFS/Git/私有对象存储),并以 payload_hash 对齐。

  • 对“观察者”而言:仅知道某主题下发生了某笔承诺,不知道具体内容与参与者余额变化。

3.5 Fuel 模型(代替 Gas)

Fuel ≠ Gas:重要概念澄清

没有 Gas 定价与扣费:Enso 不做经济计量,链下执行本身不收费,不搞链上竞价。

只有 Fuel 限额:Fuel 是"硬上限"而不是"费用单位"。它只承担 DoS 防御与可复现计量的作用——超限就 abort,没有"多付钱就能多跑"的通道。

真正需要付费的只有锚定层:也就是你在 BTC/Tondi 发锚定交易要付的网络手续费;Enso 层本身不收费。

小结:Fuel ≠ Gas。Fuel 是安全闸门,不是价格信号。

Fuel 计数维度

  • 计数维度:

    • steps:解释器指令步数(AOT 后仍计算逻辑步)

    • mem_pages:访问的内存页数(页面大小固定)

    • proof_nodes:校验 Proof 所消耗的节点数

    • commit_events:承诺事件条数

  • 规则:

    • 交易给出 FuelLimit;执行/验证器输出 FuelUsage;

    • 任一维度超限直接 abort(确定性);

    • 节点/钱包可设本地策略(如 steps 上限)过滤 DoS。

  • 好处:无价格波动、无拍卖 mempool;资源消耗可预测,用户体验稳定。

Fuel Schedule v1(确定性常量表)

  • op_step = 1:所有控制/算术/栈指令计 1 步

  • mem_page_touch = 1:首次触达页记 1

  • hash(bytes_len):ceil(bytes_len/64) 计入 crypto_ops

  • sig_verify(algo):Ed25519=8000,Schnorr=6500,SECP256K1=9000(固定常量)

  • merkle_node_verify:每个节点 +1;verkle_* 另表

  • 禁止实现自定义权重;用 Scheme Registry 发布哈希/证明家族的权重参数

  • 常量表来源与基准脚本:补充 Schnorr/Ed25519 的常量表来源与基准脚本,落到 registry/crypto-costs/ 目录,方便多平台再现

Fuel 度量规范

  • FuelUsage 不得依赖外部签字;由验证器可重计算并与签名隔离

  • ParcelDigest 只覆盖 header/body(不含 FuelUsage),防止度量成为信任点

  • 引入 fuel_budget_hint(由发起方声明),验证器据此做启发式拒绝(过大直接拒),并在回执记录实际使用分位值,作为 SDK 未来自适应建议的依据

3.6 白名单原生函数

  • 保留:hash(SHA-256/BLAKE3)、sig-verify(Schnorr/Ed25519/SECP256K1 可插件)、merkle/verkle、bytes 基础。

  • 去除:随机数、时间、外部 IO、系统调用 —— 保证可复现性与可并行性。

  • 扩展:允许 multi-sig 聚合校验(MuSig2 验证)、batch-verify 用于批量验签。

Verifier 与 Natives 概念澄清

Verifier(验证器):

  • Enso:执行/验证器,能重放 Parcel,检查 Proof、Fuel、签名。负责验证 Parcel 的完整性和正确性。

  • Aptos:有 MoveVM runtime verifier(比如模块发布时的字节码 verifier)和 transaction prologue/epilogue verifier,但它是全局链模式,和 Enso 不一样。

Natives(原生函数):

  • Enso:白名单原生函数,固定在 VM 里提供(hash、sig-verify、merkle/verkle、bytes 等)。比 Aptos 的 natives 更少、更"纯函数化"。

  • Aptos:也有 natives,比如 hash, vector, BCS,以及资源/账户相关的原生操作(table、event)。

签名安全要求(Crypto Profile v1)

  • BIP-340 验签:严格规范(确保低 s、pubkey xonly、aux 随机、无 malleability)

  • Ed25519:MUST 启用小序群拒绝(cofactor 清理),禁用非规范编码;采用 RFC8032 严格变体

  • MuSig2(BIP-327):MUST 使用 nonce commitment(pre-commit + reveal),把 parcel_digest 绑定入 challenge;拒绝 nonce 重用

  • 确定性 nonce:使用 RFC6979 风格的确定性 nonce 生成(Schnorr)或 MuSig2 nonce 承诺

  • 禁止 nonce 重用:每个签名会话必须使用唯一的 nonce

  • 域标签:所有签名摘要必须前置域标签:

    • "enso/parcel-sig/v1" - Parcel 签名

    • "enso/epochroot/v1" - EpochRoot 签名

    • "enso/anchorhint/v1" - 锚定提示签名

    • 所有域标签统一:"enso/<topic>/v1",ASCII 仅小写,固定长度,不得本地化

3.7 Schema & Codex

  • Schema 不存放链上,仅登记 (schema_id, hash) 于 Tondi(或 Aptos 兼容链);可附带一个可选的 location(IPFS/Git URL)。

  • 版本演进通过 rev 与 hash 绑定,去歧义。

  • Codex:面向合约/应用的离线资源包(接口说明、测试向量、审计报告、客户端模板)。

  • Schema Registry 增加"实现哈希 + 代码来源的 SPDX SBOM 指纹",方便审计。

Schema 完整性要求

  • AOT 二进制哈希:SchemaRef 必须包含精确匹配的 AOT WASM-Min 二进制哈希

  • 无网络获取:验证期间禁止网络获取,确保确定性

  • 版本化注册表:维护版本化的 Scheme 注册表(哈希固定)

  • 参数冻结:每个 Scheme 的配置参数通过 params_hash 冻结

Deterministic CBOR 实现指纹

  • MUST 使用 RFC8949 Canonical CBOR:

    • map key 按字节序排序

    • 禁止同值多编码

    • 整数最短编码

    • 字节串与文本串区分,不得混用

  • MUST 固定所有多字节字段的小端或大端(建议小端与 WASM 对齐),并在 Schema Registry 附上 跨平台向量

  • aux、comp_hint 的格式必须版本化:{ver:u8, body: bytes}

  • 官方编码器哈希:在 Scheme Registry 中附上官方编码器实现哈希(或版本号+测试向量)

  • 边角行为一致性:避免"同是 RFC 8949 但边角行为不同"的问题

  • 跨平台测试向量:提供 x86/ARM/wasmtime 的编码一致性验证

3.8 双配置编译

  • --features Enso-slim:生产模式,启用 vmap、Fuel、承诺事件、白名单原生,禁用全局表。

  • --features aptos-compat:兼容/调试模式,允许 Table/Global 与标准事件,便于迁移/调试/对比测试。


4. 从 RGB 原生流程到 Enso:逐步对照与落地

你给出的 RGB 流程图(含 Invoice → Coinselect → Operation Request → compose_psbt → RBF → 多签/HW/LN 签名 → finalize/extract/broadcast → update UTXO → consignment 等步骤)可以一一映射到 Enso 的Parcel 组装与 Taproot 锚定:

4.1 角色与对象映射

  • Invoice(对方付款请求) → Enso Invoice(包含接收方 DomainRoot、期望 schema、金额/资源类型、锚定偏好与 Fuel 建议)。

  • Coinsel(UTXO 选择) → Proof 输入选择(选择将要花费的 DomainRoot 和对应 VmapProof 条目)。

  • Operation Request(组合多操作) → Parcel.body 的多个 VmapDelta 与 Commitment 条目。

  • compose_psbt / pre-commit PSBT → pre-parcel(尚未签名/尚未锚定的 Parcel 草案)。

  • RBF / committed PSBT → AnchorHint + 再锚定策略(见 5.3)。

  • 多签/HW/LN signer → SigSlot.role(MultisigPartner / HW / LN),使用 MuSig2/SECP256K1/Schnorr。

  • finalize/extract/broadcast TX → taproot_commit + 广播锚定交易(BTC/Tondi)。

  • update UTXO set → 更新 EpochRoot/AnchorIndex + 客户端本地 DomainRoot 缓存。

  • consignment(RGB 交付包) → Parcel(Enso 的一等公民见证包)。

4.2 Enso 支付交易生命周期(与 RGB 对照)

  1. 付款人收到 Enso-Invoice:

    • 包含:收款人 domain_root_recv、schema_ref、amount/asset_id、fuel_suggest、可选 payjoin/LN 路由偏好。
  2. Proof/输入选择(Coinsel 同义):

    • 钱包从本地缓存/离线库挑选要花费的 DomainRoot 对应 VmapProof;如需,可与对方 PayJoin(见 8.2)协商,使双方都写入各自 VmapDelta,减少可链接性。

Coinsel 概念说明

  1. 构造 pre-parcel(compose_parcel):

    • 计算所需 VmapDelta(扣减付款人余额、增加收款人承诺、生成新的 DomainRootOut 提示);

    • 打入 Commitment:例如 topic=ESIP-20::transfer,payload_hash=H(sender,receiver,amount,nonce);

    • 设定 FuelLimit;

    • 设定 AnchorHint(锚定在哪个 UTXO/哪些输入键位做 taptweak)。

  2. 多方签名(SigSlot):

    • 按 SigSlot.role 分配签名位:MultisigPartner、HW、LN;

    • 验签/批量验签;

    • 可选择“预制 Bundle”(例如适配企业审批流)。

  3. 锚定与广播:

    • 根据 AnchorHint 生成 Taproot 承诺(Key-path tweak 或 Script-path);

    • 构造 BTC/Tondi 交易并广播;

    • 若手续费不足/拥堵,执行 RBF 再锚定。

  4. 更新与交付:

    • 广播成功后记录 EpochRoot 与锚定位置;

    • 向收款方交付正式 Parcel(含签名与实际 FuelUsage);

    • 收款方据此更新其 DomainRoot 缓存,无需第三方索引器即可继续花费。

  5. 冲突处理(NDM 模式):

    • 若出现冲突 Parcel(与已有锚定冲突),客户端按规范化规则自动拒绝非规范化历史,等待规范化锚定达到最终性。

关键点:整个生命周期中,对外世界最多看到“某 Taproot 锚定了一个哈希”,无法从链上直接读取余额/账户明文;只有参与方凭 Parcel 全量验证。


5. 锚定与共识:BTC/Taproot 与 Tondi

5.1 锚定载体

Profiles(两套运行档)

Profile T — Tondi-first(默认):

  • 锚定策略:单源锚定在 Tondi,每个 epoch_id 只允许一个锚定源

  • 承诺方式:Taproot 包含脚本叶(tapret/tapscript)或等价结构,Tondi 侧采用等价的 Taproot-only 结构

  • 验证模型:离线 consignment/Parcel 携带完整证明材料,支持纯离线验证

  • 第三方公证:不保证"即时公证",需要离线材料交给对手方/审计方

  • Key-path MAY be used for spending aggregation, BUT MUST NOT be used to commit ensoc directly. ensoc is committed via a TapLeaf.

Profile B — BTC-only(可选):

  • 锚定策略:单源锚定在 BTC,每个 epoch_id 只允许一个锚定源

  • 承诺方式:Taproot 含承诺叶;提供链上可揭示路径(推荐双输出锚定)

  • SLO:建议 ≤2 conf 内完成一次 reveal,或在最终性阈值前完成

  • Fork choice:已揭示(public-verifiable)候选 优先

  • Key-path MAY be used for spending aggregation, BUT MUST NOT be used to commit ensoc directly. ensoc is committed via a TapLeaf.

  • BTC Taproot:

    • Key-path taptweak:将承诺哈希参与到公钥 tweak 中,零脚本开销,但需妥善处理多签(MuSig2)聚合。

    • Script-path TapLeaf:将承诺放入一个叶子;优点是灵活可组合(可与 CSV/CLTV 约束参数同叶),代价是交易体积略增。

    • 两者可并存,由 AnchorHint 指示优先级。

Taproot 承诺规范(统一)

  • EpochRoot 承诺:ensoc = H("enso/epochroot/v1" || epoch_id || prev_epoch_root || merkle_root || scheme.params_hash || anchor_profile || chain_id)

  • ensoc MUST 被编码进「脚本树某个 TapLeaf」的脚本字节,而不是直接拼入 key-path tweak

  • key-path 仅用于花费聚合;不得单独用于承诺 ensoc

Anchor Leaf (Tapscript, v1)

# push-only、可揭示、花费必然成功(仅用于 reveal 交易)
OP_FALSE OP_IF
  <OP_PUSH32: ENSO_EPOCHROOT_COMMITMENT>  # ensoc = H_enso(epoch_root_struct)
OP_ENDIF
OP_TRUE

MerkleRoot = H_TapLeaf(AnchorLeaf) (当树中只有此叶时)

注:OP_TRUE 使脚本路径花费可成功,用于 reveal 交易;锚定 UTXO 的实际资金花费仍走 key-path(正常签名),不受此叶影响。

  • Tondi(Taproot-Compatible DAG 支付层):

    • 作为便宜且快速的锚定层;

    • 单源锚定:每个 epoch_id 只允许一个锚定源,要么 Tondi 要么 BTC。

5.2 EpochRoot:时间片锚定机制

概念说明

EpochRoot 是 Enso 协议中引入的 全局时间片锚定机制,用于为客户端验证提供"历史截断点"。

  • Epoch 是绝对的、全局统一的:整个系统按固定时间窗口(如 10 分钟)划分,所有 Domain 都使用同一节奏,而非每个资产/合约独立推进;

  • EpochRoot = 全局快照:聚合者在每个时间窗口内收集所有 DomainRoot 更新,构造 Merkle 树并锚定到 BTC/Tondi,形成统一的"历史截断点";

  • 跨域一致性:任何 Parcel 只需证明其 DomainRoot 被包含在某个 EpochRoot 内,即可确认合法性与时间顺序,避免 RGB 式的历史膨胀问题。

5.2.4 Anchor Reveal 机制

默认策略(Profile T 和 Profile B):

  • 默认:off-chain proof 即可(和 RGB 一样),不要求 on-chain reveal

  • 不保证"即时公证",需要离线材料交给对手方/审计方

ESIP-R1: On-chain Reveal(可选扩展):

  • MAY:在需要第三方可公开验证时,按模板把 ensoc 放进可花费的 tapleaf(或等价)并广播一次 reveal 交易

  • 开启条件、频率、SLO 均由应用/钱包策略决定,协议不强制

  • SDK/UI:把 reveal 暴露成开关(审计/对账/桥接时勾选),默认 OFF

数据结构定义

<epoch_root> ::= {
    epoch_id: uint64,                  // Epoch 序号,全局绝对时间
    prev_epoch_root: H256,             // 前一个 EpochRoot 哈希
    merkle_root: H256,                 // 本 Epoch 内 DomainUpdate 的聚合根
    updates: [<domain_update>],        // 本 Epoch 内所有 DomainRoot 更新的集合
    anchor: AnchorRef,                 // 在 BTC/Tondi 上的锚定位置
    scheme: Scheme                     // 使用的承诺方案
}

<domain_update> ::= {
    domain_id: H256,       // 域标识(schema / contract / asset)
    prev_root: H256,       // 前一个状态根
    prev_seq: uint64,      // 前一个序列号
    new_root: H256,        // 新的状态根
    new_seq: uint64        // 新序列号 (必须 = prev_seq + 1)
}

<anchor_ref> ::= {
    chain: "Tondi" | "BTC",
    txid: H256,
    vout: uint32,
    block_height: uint64?,  // BTC: 区块高度
    dag_depth: uint32?,     // Tondi: DAG深度
    blue_score: uint64?,    // Tondi: 蓝分(若Tondi有此指标)
    strategy: "script_path",
    reveal_txid: H256?,     // 可空,reveal 交易的 txid
    reveal_outpoint: H256?, // 可空,reveal 交易的输出点
    reveal_status: "none" | "offchain-only" | "onchain",  // 揭示状态
    anchor_profile: "T" | "B",  // 锚定配置
    policy_ver: uint32     // 策略版本
    // no dual-anchoring/backstop; single source per epoch
}

验证规则

  1. 链式完整性 prev_epoch_root 必须正确链接到上一个已确认的 EpochRoot。

  2. 锚定有效性 merkle_root 必须存在于 BTC/Tondi 的 Taproot commitment 中。

  3. 序列号单调性 对于任何固定的 (domain_id, prev_seq),在整个历史中最多只能有一个 DomainUpdate 被接受。

  4. 归属证明 任一 Parcel 的输入 DomainInput 必须能通过 proof 被包含在某个锚定的 epoch_root 中。

  5. 差分验证 应用 Parcel 携带的 VmapDelta,从 prev_root 推导出 new_root,并与 EpochRoot 内记录的 new_root 一致。

  6. 分叉选择规则 对于同一 epoch_id 的多个候选 EpochRoot:

    • Profile T(Tondi-first):按 dag_depth/blue-score → tie-break by (txid,vout)

    • Profile B(BTC-only):按区块高度低者优先 → tie-break by (txid,vout)

    • 单源锚定:每个 epoch_id 只允许一个锚定源,要么 chain="Tondi",要么 chain="BTC"

    • 不再有"BTC backstop"或"双路一致性"条款

  7. 时间宽容窗口

    • 客户端"容忍窗口"从 {n-1,n,n+1} 改为:允许 ±Δ(由链时间校正给出);并以锚定块时间最终归档

    • 最终归档以锚定时刻所在块的时间为准,由聚合器/验证器执行

工作流程

  1. 用户提交 Parcel

    • 用户生成交易 Parcel,包含 ProofDelta (旧根 → 新根)。

    • 提交给网络上的聚合者。

  2. 聚合者构建 EpochRoot

    • 聚合者在 Epoch 时间窗口内收集所有 DomainRoot 更新。

    • 构建 Merkle/Verkle 树,得到 merkle_root。

  3. 锚定

    • 聚合者将 merkle_root 写入 BTC/Tondi 的 Taproot commitment(或治理链事件)。

    • 生成 epoch_root 结构体。

聚合者(Aggregator)角色说明

聚合者是任意提交 EpochRoot 的打包者,可以是钱包服务商、独立运营者或社区节点,任何人都能运行 aggregator 程序(permissionless)。它的职责是在时间窗口内收集用户提交的 DomainRoot 更新,聚合进 Merkle/Verkle 树并提交到 BTC/Tondi 进行锚定。聚合者不需要被信任,因为它不能篡改用户交易:如果收录了你的 DomainRoot,你能拿到 Merkle inclusion proof 独立验证;如果漏掉交易,最坏情况是等待下一轮提交。安全性来源于 BTC/Tondi 的不可篡改锚定和客户端验证,而不是 aggregator 本身的诚实性。多个 aggregator 可以并存,最终谁锚定成功谁就成为历史的一部分。

聚合器签名认证(Aggregator Attestation)

防"多口径"对策(非信任但可追责):

  • 聚合器对 ensoc 出具 签名声明:agg_sig = Sig(H_enso("attest/v1" || ensoc || anchor_txid || epoch_id))

  • 可选将 ensoc → anchor_txid 的映射,以 git/nostr 等不可改写日志形式对外发布(软约束、便于事后审计)

  • 非信任根,仅做追责与对比快照

聚合者经济与反审查:

  • 聚合者费用承诺:agg_fee_commit = H("enso/aggfee/v1" || epoch_id || parcel_head_hash || quote_id || fee_quote_hash),并提供链下支付通道建议(LN/钱包积分),以便"有偿加速收录"而不破坏最小信任

  • SelfBundle 行为升级为协议义务:聚合者必须在下一 Epoch 的"目录节"记录收到的 SelfBundle 索引;客户端在"无 reveal 候选"时优先选"已 reveal 的 SelfBundle"

  • 聚合者声明最小格式:签名的 ensoc ↔ anchor_txid 公告,并建议通过 git/nostr 双写,作为追责与对比快照来源(非信任根)

  1. 客户端验证

    • 客户端验证:

      • 我的 DomainRoot 是否出现在某个锚定的 EpochRoot 里?

      • ProofDelta 重放是否能得出同样的新根?

    • 如果成立,则确认交易不可篡改。

白话解释

  • DomainRoot = 某个"资产小账本"的最新封面(每个资产/合约都有自己的状态树根哈希)

  • Parcel = "交易凭证包"(包含 ProofDelta,说明"旧 DomainRoot → 新 DomainRoot"的差分证明)

  • EpochRoot = "全局时间快照"(每 10 分钟收集所有 DomainRoot 更新,聚合后锚定到 BTC/Tondi,形成统一的历史截断点)

关键区别:Epoch 是全局绝对时间,不是每个资产独立推进;这样所有资产都有统一的时间锚点,避免 RGB 式的历史膨胀。

EpochRoot 工作流程

sequenceDiagram
    participant U as User (Client)
    participant A as Aggregator
    participant L1 as BTC/Tondi (Layer1)
    participant V as Verifier (Other Client)

    U->>A: Submit Parcel (ProofDelta, DomainRoot update)
    A->>A: Collect multiple DomainRoot updates during Epoch
    A->>A: Build Merkle Tree -> Merkle Root
    A->>L1: Commit EpochRoot (Merkle Root) via Taproot/Tondi
    L1-->>All: Publish anchor_tx (contains EpochRoot)

    V->>L1: Fetch EpochRoot anchor
    V->>A: Request Merkle proof for DomainRoot
    A->>V: Return Merkle proof
    V->>V: Verify inclusion + replay ProofDelta
    V->>V: Confirm DomainRoot_out is valid

关系图示

flowchart TB
    subgraph UserSide["User / Client Side"]
        P[Parcel] -->|contains| PD[ProofDelta]
        PD -->|updates| DR_in[DomainRoot Old]
        PD -->|produces| DR_out[DomainRoot New]
    end

    subgraph Aggregator["Aggregator / Epoch Builder"]
        DR_out --> DC1[DomainCommitment 1]
        DR_other1[DomainRoot UserB] --> DC2[DomainCommitment 2]
        DR_other2[DomainRoot UserC] --> DC3[DomainCommitment N]
        DC1 & DC2 & DC3 --> MR[Merkle Root]
        MR --> ER[EpochRoot]
    end

    subgraph Layer1["BTC / Tondi"]
        ER --> Anchor[On-chain Anchor]
    end

    P -.-> N1[Parcel = local proof package]
    DR_out -.-> N2[DomainRoot = per-domain state]
    MR -.-> N3[Merkle Root = commitment of many DomainRoots]
    ER -.-> N4[EpochRoot = snapshot anchored to L1]

一句话区别总结

  • Parcel = 交易凭证包(说明一次状态更新)

  • DomainRoot = 某个域的当前状态根(像小账本封面)

  • EpochRoot = 全局时间片内所有 DomainRoot 更新的聚合锚定(统一历史截断点)

技术总结

  • EpochRoot = "全局时间片快照 + 统一锚定":所有 Domain 使用同一时间节奏,形成跨域一致的历史截断点

  • 验证独立性:客户端只需证明 DomainRoot 被包含在某个 EpochRoot 内,不依赖聚合者诚实性

  • 历史截断:通过全局 Epoch 机制避免 RGB 式的 consignment 线性膨胀问题

5.3 Bundle 聚合

  • Enso 推荐每 N 分钟/区块形成一个 Bundle(若干 Parcel 的承诺聚合),再锚定至 Taproot:

    • EpochRoot = MerkleRoot(Bundle);

    • Bundle 仅含 Parcel 哈希及必要索引;

    • 客户端只需缓存最近 K 个 EpochRoot 与一份 AnchorIndex(< 10MB 级别)。

  • 优点:

    • 成本与体积可控;

    • RBF 更简单:替换的只是 Bundle 承诺位。

    • 隐私更好:多笔 Parcel 混合承诺。

5.4 RBF 与再锚定策略

RBF 替换规则

  • 候选标识:承诺候选由 {epoch_id, candidate_outpoint} 唯一标识

  • 替换条件:允许替换仅当:

    • 相同的 epoch_id

    • 花费相同的输入(标准 RBF)

    • 具有更高的 fee_per_wu(更高的费率)

  • 确认阈值:

    • Tondi:dag_depth < D_final 可替换;默认 D_final=30(可调 20–60)

    • BTC:conf < C_final 可替换;默认 C_final=2(可调 2–6)

  • 单源锚定:每个 epoch_id 只允许一个锚定源,要么 Tondi 要么 BTC

  • 密封后:任何冲突的候选将被忽略

锚定转录

  • 锚定承诺:anchor_commit = H("enso/anchor/v1" || parcel_hash || candidate_outpoint || strategy)

  • Parcel 哈希:包含所有签名字段,但不包括 trailer.metrics(由验证器后填写)

  • 防重放标签:anti_replay_tag = H_enso("parcel/anti-replay/v1" || network_id || chain_id || anchor_chain || schema_id || domain_id || prev_root || prev_seq || parcel_digest_min)

  • EpochRoot 承诺:ensoc = H("enso/epochroot/v1" || epoch_id || prev_epoch_root || merkle_root || scheme.params_hash || anchor_profile || chain_id),其中 anchor_profile ∈ {"T","B"},用于防跨配置重放

  • 达阈值即终局:协议层无冲正或裁决流程

5.5 Parcel 传递延迟与锚定异步性

关键理解:Parcel 的合法性与最终性是分离的。即使 Parcel 在用户间传递很久才被收录进 EpochRoot,也不会影响其安全性:

  • 合法性验证:接收方只需确认 Parcel 的输入 DomainRoot 已锚定在某个较早的 EpochRoot 中,即可通过 ProofDelta 重放验证更新正确性;

  • 最终性确认:新 DomainRoot 的最终性取决于何时被 aggregator 收录进新的 EpochRoot,类似比特币的"0 确认交易"概念;

  • 风险控制:在锚定前,新 DomainRoot 处于"合法但未确认"状态,机构用户可要求等待锚定确认,但不会导致证明失效或安全性问题。

5.6 重组(reorg)应对

  • BTC:极小概率深度重组;Enso 客户端在缓存多代 EpochRoot,如锚定被回滚,按 Parcel 的 FuelUsage 与签名重放验证并自动再锚定(若可行)。

  • Tondi:DAG 结构需设定锚定确认深度与时间窗,确保稳定性。

  • 单源锚定:每个 epoch_id 只允许一个锚定源,要么 Tondi 要么 BTC

  • 客户端按规范化规则回滚:当出现更优锚定时,客户端自动回滚到更优的规范化 EpochRoot 链,无需争议流程。


6. 可并行性与批量优化

6.1 ProofDelta 的无冲突合并

  • 两个 Parcel 若涉及的 VmapDelta.rw_ops 在键空间无交集或可交换(依据 version/锁),则可并行验证与提交。

  • 客户端/打包器可做前缀合并:将多个 RW 操作压缩为较短路径证明,减少 proof_nodes 与字节数。

6.2 批量验签

  • 对同算法同消息结构的签名批量验证(Ed25519/SECP256K1/Schnorr),节约 30–60% 执行时间。

  • MuSig2 聚合签名:多签方先离线聚合,Parcel 上链只带一枚可验证的 Schnorr 签名。

  • 安全前提:禁止跨不同消息批验(只有同消息或同算法同域时允许),避免批验证被利用。

6.3 AOT/WASM-Min

AOT 是什么?

AOT = Ahead-Of-Time compilation(预编译)。

在 Enso 里它的含义是:把 Move 字节码在发布/构建阶段就编译成我们约束过的目标(见"WASM-Min"),运行时直接加载定稿产物,而不是像 JIT 那样边跑边翻译。

这样做的好处:

  • 确定性:没有 JIT 的随机优化差异;同一字节流在任何设备上都跑出同样的步数/内存访问。

  • 可审计:发布的是"代码 hash = H(产物)",Parcel/钱包都对这个 hash 认账,审计方只需复核一次。

  • 冷启动快:加载即跑,移动端/浏览器也能稳。

  • 资源可静态估算:配合我们的 Fuel 计数器(steps、mem_pages…),可以在上链前做"能否在限额内跑完"的静态/半静态检查。

  • 跨平台:统一到一个极简的执行目标(WASM-Min),避免各平台 VM 差异。

小结:AOT 是工程上的"把不确定性前置消化",使运行时只做"可验证的解释/执行"。

WASM-Min 是什么?

WASM-Min = 为客户端验证场景裁剪过的 WebAssembly 子集,目标是"可复现 + 可计量 + 可沙箱"。我们对标准 WASM 进行最小化:

  • 指令子集:只保留 i32/i64 整数运算与必需控制流;MUST 禁用浮点、SIMD、线程、原子等非必要/不确定特性。

  • 内存模型:单一线性内存,页数上限固定(例如 64 页);禁止动态增长超限。

  • 导入函数白名单:仅允许 hash、sig_verify、merkle/verkle、bytes 这类确定性原生;没有时间/随机/IO。

  • 宿主交互:不提供系统调用;状态访问统一走 vmap 原生接口。

  • 计量钩子:在 AOT 时插桩,运行时对每条指令/每次内存页触达/每个证明节点校验累计 Fuel,用于"超限即中止"。

  • 格式稳定:同一 WASM-Min 产物在任何环境重放得到完全一致的 FuelUsage。

  • WASM 版本号/特性位:给出WASM 版本号/特性位白名单。

确定性行为规范

  • 整数运算:二进制补码,加法/乘法/移位溢出时定义包装行为

  • 内存管理:页面大小固定(64 KiB),mem_pages 在每页首次触达时计数

  • 字节序:统一使用小端序

  • 内存增长:禁止 memory.grow 超过声明的最大值;失败时在触达内存前确定性中止

  • 加密操作:每次 hash/SigVerify 调用递增 proof_nodes 或专用 crypto_ops 计数器

  • 跨平台一致性:所有行为必须在不同平台上产生相同结果

Genesis / 初始状态规范

  • genesis_root:每个域的初始状态根,genesis_root = H("enso/genesis/v1" || schema_id || domain_id)

  • genesis_seq:初始序列号固定为 0

  • 首次写入约束:任何域的首次状态更新必须从 (prev_seq=0, prev_root=genesis_root) 开始

  • 空树根常量:使用固定的空树根常量作为基础,确保跨域一致性

小结:WASM-Min 是"可验证执行目标"。不是为了通用计算,而是专职给客户端验证与可并行的资产逻辑服务。

实现要点

  • Move 字节码在构建期做 AOT 编译,生成简化 WASM(无宿主系统调用、固定内存页上限),验证器内嵌一个极小型解释器。

  • 好处:平台广泛、可沙箱、便于移动端与浏览器端运行(WebAssembly)。


7. 隐私模型

  • 可链接性控制

    • PayJoin(收/付双方都写各自 VmapDelta,第三方难以判定谁向谁转移)。

    • Commitment.topic 需避免直接泄露资产/应用标识(可哈希化 schema 域)。

    • payload_hash 内建议加入会话随机盐与时序混淆字段。

隐私增强措施

  • 域盐化主题:topic = H("enso/topic/v1" || schema_id || domain_id || topic_label || session_salt)

  • 批量填充:允许每个 Bundle 包含虚拟承诺条目以打破大小泄露(可选,受 commit_events Fuel 限制)

  • 会话盐:在 payload_hash 中包含会话随机盐和时序混淆字段

  • 流量指纹防护:避免使用稳定的主题标签,防止流量分析

  • 审计披露开关:提供"审计披露开关",仅对披露对象公开 topic_label 的映射字典

  • 可选择披露

    • 参与者可在合规场景向监管/审计方披露明文 payload 与校验路径;

    • 非参与者仅见锚定与承诺哈希。

  • 离线明文存储

    • 推荐 IPFS + 私有对象存储双写;

    • Parcel 中仅带 CID/hash;丢失时可由对端/见证方补齐。


8. 生态与集成

8.1 钱包 SDK

  • 功能:

    • 解析/构造 Parcel(含 CBOR/SSZ 编解码);

    • vmap_proof 生成与校验;

    • Fuel 预算估算;

    • AnchorHint 生成(Taproot taptweak/leaf);

    • MuSig2/HW/LN 签名适配(Ledger/Trezor、LND/LDK)。

  • 接口草案(Rust/TS 双栈):

fn create_invoice(domain_root_recv: [u8;32], asset: AssetRef, amount: u128, opts: InvoiceOpts) -> Invoice;

fn compose_parcel(inputs: &[AccInput], outputs: &[Commitment], fuel_suggest: FuelLimit, schemas: &[SchemaRef]) -> PreParcel;

fn sign_parcel(pre: &PreParcel, signer: &dyn Signer) -> Parcel;

fn verify_parcel(parcel: &Parcel, domain_roots: &[Bytes32], epoch_roots: &[Bytes32]) -> Result<FuelUsage, Error>;

fn anchor_to_btc(parcel_batch: &[Parcel], feerate: Feerate) -> BtcTxid;

8.2 LN 集成与 PayJoin

  • LN Signer:将 LN 路由与 Enso Parcel 支付捆绑(在 SigSlot.role=LN),可实现发票自动清结。

  • PayJoin:

    • 协商阶段双方互换各自的 VmapProof 片段与 delta 草案;

    • 由一方组装联合 Parcel 并回传给对方签名;

    • 锚定后各自本地更新 DomainRoot;

    • 进一步降低链上可链接性与统计学分析风险。

PayJoin 安全机制

  • 会话 nonce:协商期间双方各自生成 SessionNonce

  • 花费授权标签:spend_auth_tag = H("enso/payjoin/v1" || parcel_digest_min || session_nonce_me || session_nonce_you || chain_id || my_domain_id || your_domain_id || prev_root || prev_seq)

  • 防重放:每个 VmapDelta 必须携带并签名对方的预期 spend_auth_tag

  • 会话隔离:不同会话产生不同标签,防止旧 delta 被重用

  • 双向签名覆盖:要求双向签名覆盖,明确失败回滚:任一方未签,现有片段不得在后续会话复用(通过标签不匹配实现)

8.3 轻量索引器(可选设施)

  • 目的:仅追踪 EpochRoot 与 Parcel CID/哈希,提供"最近 N 个 Epoch 的目录"。

  • 不含:余额/账户明文。

  • 增益:提升钱包"找回/同步速度",但不引入信任。

轻客户端取证路径

  • 最小可替代接口:get_epoch_root(epoch_id) -> (anchor_ref, epoch_root_bytes, proof_of_inclusion_for_domain)

  • 独立验证:客户端必须能在不信任提供方的前提下,通过 BTC/Tondi 的锚定独立验证 epoch_root_bytes 与自己 DomainUpdate 的包含性

  • 无信任依赖:任何索引器都是可替代缓存,而非信任根

8.4 桥与多链互操作

  • RGB ↔ Enso:

    1. 读兼容:导入 RGB consignment,校验其 Taproot 锚定与 AluVM 规则,生成等效 Parcel(映射 schema 字段)。

    2. 双向桥:锁定 RGB → Enso 铸造;Enso 销毁 → RGB 解锁。

  • Enso ↔ Aptos/EVM:

    • 由 ESIP-Bridge 定义最小跨链凭证格式(承诺 + 见证),在目标链上做轻量 Verifier 合约。

    • 跨链桥最小凭证结构:{epoch_root, domain_update, anchor_ref, reveal_proof, parcel_head_hash}


9. 无争议模式(NDM)

目标:协议只定义"有效或无效"的可验证规则;不引入治理裁决、冻结或冲正。一切以客户端可验证与锚定最终性为准。

9.1 原则(取代"争议/欺诈窗口")

  • 无仲裁:协议层 不提供 争议提交、冻结、审理、冲正等流程。

  • 可验证即有效:客户端/验证器只依据 Parcel + VmapProof + EpochRoot 的确定性验证规则来判定有效/无效。

  • 冲突即无效:任意出现同一 (domain_id, prev_seq) 的多重更新,除被选定的规范化 EpochRoot 内的那一条,其余全部自动无效(被验证器拒绝)。

  • 最终性即终局:锚定达到最终性阈值(BTC 2 conf / Tondi 指定 DAG 深度)后,不可撤销。无需也不允许"冲正"。

9.2 冲突处理(纯规则化,非裁决)

  • 域单调性约束(已在你文档中) new_seq = prev_seq + 1;对相同 (domain_id, prev_seq) 在同一历史中最多接受一条 DomainUpdate。

  • Epoch 规范化(已在你文档 5.2/5.4 中) 针对同一 epoch_id 的多个候选 EpochRoot:

    1. BTC 优先;

    2. 多个 BTC 候选取区块高度更低者;平局按 (txid, vout) 字典序;

    3. 仅有 Tondi 时按 DAG 分数更高;平局按 txid 字典序。

  • 验证器行为

    • 构建/同步"唯一的规范化 EpochRoot 链"。

    • 对于任何不在规范链中的 DomainUpdate 或违反 (domain_id, prev_seq) 唯一性的更新,一律本地拒绝,无需上链处理。

  • 无冻结、无裁决

    • 没有"冻结 DomainRoot"的概念;钱包只是拒绝引用非规范化历史;

    • 没有"窗口内举证"或"黑名单/罚没"机制。

9.3 省略与删除

  • 删除原 9.1 的"反例 Parcel/冻结/裁决/冲正/治理链登记"等全部内容。

  • 文档其他章节若提及"争议/窗口/治理裁决",统一改为:

    • "客户端拒绝非规范化历史";

    • "等待规范化锚定达到最终性"。

9.4 安全与用户体验说明

  • 安全性:

    • 双花在 域序列单调 + Epoch 规范化 + 最终性阈值 下,被协议规则直接排除,无需裁决。

    • 若两个聚合者并行包含了同一 (domain_id, prev_seq) 的不同更新,只有规范化 EpochRoot 内的那条被客户端接受。

  • 可用性:

    • 发送方/接收方可以在"未最终性"阶段使用 Parcel 做乐观流转;风控上,只要尚未达最终性,对手方可选择延迟二次花费或仅作条件性记账。
  • 失败语义:

    • 一旦规范化 Epoch 确认,与之冲突的更新将永久无效;钱包应以明确错误码返回(见下)。

9.5 错误码(NDM 版本)

  • E_SEQ_REUSE:同一 (domain_id, prev_seq) 已被消费(或在规范化历史中出现过)。

  • E_NON_CANONICAL_EPOCH:引用的 EpochRoot 不在规范化链上。

  • E_BAD_UPDATE_CONFLICT:Parcel 的 new_root/new_seq 与规范化 Epoch 的记录不一致。

  • E_NOT_FINAL:对方要求最终性,但当前引用的锚定尚未达阈值。

  • E_BAD_PROOF / E_BAD_ENCODING / E_FUEL_EXCEEDED:保留已有的验证错误。

  • E_BAD_REVEAL:control_block/leaf 不匹配(仅在启用 ESIP-R1 时可能出现)

  • E_PROFILE_LINT_FAIL:Profile 配置错误(如 profile=T 但 anchor_ref 指向 BTC)

  • E_CRYPTO_PROFILE_MISMATCH:密码学配置不匹配

  • E_CBOR_CANON_FAIL:CBOR 规范化失败

  • E_SCHEME_UNSUPPORTED:不支持的 Scheme

  • E_BAD_SPENDTAG:PayJoin 花费标签不匹配

9.6 白帽与审计

  • 审计优先级:verifier、natives、Parcel 编解码、锚定器、MuSig2 聚合。

  • 设立持续赏金:对影响完整性/隐私/DoS的问题给出梯度奖励。

9.7 密钥与签名安全

  • 默认 Schnorr(SECP256K1),可配置 Ed25519。

  • 多签:推荐 MuSig2 聚合;门限方案可采用 FROST。

  • 硬件钱包集成:给出标准化 ParcelDigest(域隔离),避免签名歧义。


10. 性能与状态规模(实现级估算)

  • 单笔验证:50–150ms(常见笔记本/手机 SoC;Merkle 方案;100–300 个 proof nodes)。

  • Parcel 大小:1–3KB(Merkle);Verkle 方案可进一步缩小。

  • 批量优化:批量验签 + 前缀合并,吞吐提升 30–60%。

  • 存储:

    • 客户端持久化 DomainRoot 与其最近若干 VmapProof 片段;

    • 节点仅需保存近 N 个 EpochRoot 与 AnchorIndex(几十 MB 级);

    • 不存在全网线性膨胀。

  • 并行性:ProofDelta 无冲突的 Parcel 几近线性扩展(CPU 核心增加即吞吐提升)。


11. 开发者体验(DX)

11.1 标准库与 ESIP

  • ESIP-20:

    • resource struct Coin { id: AssetId, amount: u128 }

    • transfer(sender_root, receiver_root, amount) → 产生两个 VmapDelta,与 Commitment(topic=H("enso/topic/v1" || schema_id || domain_id || "ESIP20/transfer" || session_salt), payload_hash)。

  • ESIP-721:

    • NFT 的 mint/burn/transfer,每次转移只改动所属者的子域键。
  • ESIP-AMM:

    • 以 vmap 存放池子曲线参数与流动性凭证;Swap 仅是两类资产资源的等式变换与承诺事件。

硬件钱包显示规范

  • 硬件签名 UI MUST 显示:schema_id、domain_id、prev_seq -> new_seq、chain_id/anchor_chain、anchor_profile、tondi_depth/btc_conf、fuel_limit 摘要、payjoin 会话标记

  • 硬件钱包显示补充:profile=T/B、D_final/C_final、reveal_slo 关键摘要,降低误签概率

  • UI 显示:仅显示 profile、chain_id、最终性阈值;不展示任何"回落/双写"字样

  • ParcelDigest 规范冻结,并提供 3 组跨实现测试向量(单签、MuSig2、批验)

策略预设与自动回退矩阵

SDK 提供预设:

  • retail:Profile T,D_final=20

  • merchant:Profile T,D_final=30

  • institutional:Profile B 或 Profile T + ESIP-R1,C_final=3–6

Profile 选择策略:

  • MUST:支持按域/应用/钱包粒度选择 Profile:同一网络里,A 应用用 Tondi,B 应用用 BTC 都可以;每个 epoch_root 明确写明来源链

  • MAY:在某个 epoch 边界进行"单向迁移"(例如从 T→B),通过在该 epoch 的 ensoc 里标记 profile_switch=true(纯信息标记,仅提醒客户端更新后续数据源),但不做双边镜像

SDK 体验与安全护栏

显式协商 Profile:

  • 在 Invoice / compose_parcel 中显式协商 Profile与 D_final/C_final、reveal_slo,并在硬件钱包 UI 显示摘要

  • 默认启用风险档位(retail/merchant/institutional 三档),把"等待最终性"的默认值做成风险档位(商户/机构默认等待)

配置体检:

  • 增加 **"配置体检"**命令(lint):检测 profile 混搭、锚定延迟异常、Tondi 指标停滞预警

  • 提供配置 Lint(构建/签名前校验):检测 epoch_id 越界、D_final/C_final 非法组合,失败即阻止签名(E_PROFILE_LINT_FAIL)

11.2 SDK 选项与配置

type EnsoOptions = {
  profile: "T" | "B";          // default: "T"
  finality: { T?: number; B?: number }; // e.g., {T:30, B:2}
  reveal: { 
    enabled: boolean;          // default: false
    policy?: "never"|"per_epoch"|"per_week"|"on_demand"  // default: "never"
  };
};

默认配置:

  • profile=T、reveal.enabled=false、D_final=30(Tondi 示例),C_final=2(BTC 示例)

构建期 Lint 规则:

  • 阻止 profile=T 但 anchor_ref 指向 BTC → E_PROFILE_LINT_FAIL

  • 阻止开启 reveal.enabled=true 却缺少 AnchorLeaf 模板/证明 → E_PROFILE_LINT_FAIL

  • 同一 epoch_id 下若检测到不同链来源,构建即失败 → E_PROFILE_LINT_FAIL

11.3 合约模板与样例(伪代码)

module ESIP20::coin {
  struct Coin has key, store { id: AssetId, amount: u128 }

  public fun transfer(domain_sender: DomainRoot, proof_s: Proof, 
                      domain_recv: DomainRoot, proof_r: Proof, 
                      amount: u128) acquires Coin {
    // 1) read & check sender balance
    let (val_s, ver_s) = vmap::map_read(domain_sender, proof_s);
    assert!(deserialize<Coin>(val_s).amount >= amount, E_INSUFFICIENT);

    // 2) write sender-
    let delta_s = build_delta_sub(domain_sender, amount, ver_s);
    let (new_s, pd_s) = vmap::map_write_with_delta(domain_sender, proof_s, delta_s);

    // 3) write receiver+
    let (val_r, ver_r) = vmap::map_read(domain_recv, proof_r); // may be empty => ver=0
    let delta_r = build_delta_add(domain_recv, amount, ver_r);
    let (new_r, pd_r) = vmap::map_write_with_delta(domain_recv, proof_r, delta_r);

    // 4) commitment
    let payload_hash = H(serialize(sender=domain_sender, recv=domain_recv, amount));
    event::emit_commitment(H("ESIP20/transfer"), payload_hash);

    // 5) record deltas to Parcel (由运行时自动收集并输出)
    runtime::attach_delta(pd_s);
    runtime::attach_delta(pd_r);
  }
}

说明:vmap::* 为原生;runtime::* 把 ProofDelta 收集入当前 Parcel。开发者只写“业务逻辑”,不必手撸证明细节。

11.4 工具链

  • Enso-c(编译器):Move → AOT-WASM-Min;

  • Enso-vm(执行器):WASM 解释 + vmap 原生;

  • Enso-wallet(CLI/SDK):构造/签名/验证/锚定;

  • Enso-anchor(服务):打包 Bundle、管理 RBF、广播到 BTC/Tondi;

  • Enso-index(可选):近端缓存最近 Epoch 的目录。


12. 线下资源与 Schema 登记

  • 在 Tondi 链上登记 (schema_id, hash, rev);

  • 业务团队将 Schema 与 Codex 发布到 Git/IPFS(多副本),并在变更时更新登记;

  • 客户端在构造 Parcel 时,携带 schema_refs,便于验证器加载相应的编译产物与接口约束(可预缓存)。


13. 历史状态膨胀问题:RGB vs Enso 技术对比

13.1 状态存储的两种模式

(a) RGB Consignment 模式

  • 每次转账都要带上 从创世到现状的完整证明链。

  • 新用户验证时必须 重放整个 DAG,才能确认资产合法性。

  • consignment 越传越大,线性膨胀不可避免。

(b) Enso 根 + 差分 模式

  • 状态抽象为 DomainRoot(域根承诺)。

  • 每次交易只提交 ProofDelta(旧根 → 新根)。

  • 定期通过 EpochRoot 把状态链"压缩"并锚定到 BTC/Tondi。

  • 验证者只需确认 DomainRoot 属于某个已锚定的 EpochRoot,即可信任其从创世的合法性。

13.2 状态演化对比

RGB 状态演化

flowchart LR
    G[Genesis] --> C1[Tx1 Consignment]
    C1 --> C2[Tx2 Consignment]
    C2 --> Cn[Txn Consignment]

    subgraph Notes
      direction TB
      N1[Each new tx carries full history proof]
      N2[Consignment grows linearly]
      N3[Size: KB -> MB -> GB]
    end

    G -.-> N1
    C1 -.-> N2
    Cn -.-> N3

Enso 状态演化

flowchart LR
    ER1[EpochRoot n-1] --> PD[ProofDelta]
    PD --> DR[DomainRoot n-1]
    DR --> ER2[EpochRoot n]

    subgraph Notes["Notes"]
      direction TB
      N1[Each EpochRoot is a compression point]
      N2[ProofDelta only describes recent change]
      N3[History does not grow linearly]
    end

    ER1 -.-> N1
    PD -.-> N2
    ER2 -.-> N3

13.3 验证流程差异

步骤 RGB Enso
输入验证 需重放完整 consignment,从创世追溯 只需确认 DomainRoot 属于某 EpochRoot
交易验证 重放 AluVM + 全历史状态 重放 AOT-WASM-Min + ProofDelta
新用户同步 必须获取全历史 只需最近 EpochRoot + Parcel
存储增长 线性增长 受限于 Epoch 窗口

13.4 工程参数(建议配置)

  • Epoch 长度:建议 10 分钟(与 BTC 出块时间对齐)。

  • 客户端保存窗口:最近 ~2 周的 EpochRoot(≈2016 块),仅需几十 MB。

  • ProofDelta 大小:每笔交易约 1–3 KB,不随历史累积膨胀。

  • 归档服务:社区可自愿提供完整历史,但验证过程不依赖。

13.5 技术总结

  • RGB:历史证明与状态绑定 → consignment 越滚越大 → 验证和存储成本线性增加。

  • Enso:根承诺 + 差分更新 + Epoch 截断 → 验证成本恒定,存储仅随 Epoch 窗口线性增长。

图解结论: Enso 把状态验证从"重放历史"改造为"验证差分 + 锚定背书",从而解决了 RGB 无法避免的历史状态膨胀。


14. RGB 兼容策略(落地细节)

  1. 读兼容

    • 编写 rgb-import 工具,将 RGB consignment 解析为:

      • Taproot 锚定(验证其在 BTC 的位置);

      • AluVM 字节码与状态过渡;

      • 转换为等价的 VmapProof/VmapDelta 与 Commitment,输出 Enso Parcel。

  2. 双向桥

    • 锁定 → 铸造:在 RGB 侧构造 burn/lock,以 consignment 证明作为 Enso 的 Commitment 明文,Enso 侧合约铸造等额资产;

    • 销毁 → 解锁:反向提供 Enso 的 Parcel 与锚定,RGB 侧合约/工具释放原资产。

  3. 执行兼容(可选)

    • 内嵌 AluVM 解释器(作为一个受 Fuel 限额的模块);

    • 成本较高,仅为存量合约过渡期所用。

  4. Schema 映射

    • 在治理链上登记 rgb_schema_id ↔ Enso_schema_id 映射;

    • 钱包 SDK 在导入/导出时自动套用映射。


15. 安全审计清单(可执行)

Threat Model

攻击面:双花、重放、聚合者拒收、RBF 竞速、reorg、CBOR 非规范、批量验签滥用、MuSig2 session、Ed25519 小序群、topic 流量分析等。

  1. 加密层:哈希域隔离、签名域分离、MuSig2 聚合实现、批量验签正确性。

  2. vmap:Merkle/Verkle 验证正确性;路径歧义/键冲突测试;版本号与并发写冲突检测。

  3. Fuel:步数与内存计量的确定性;跨平台一致性(x86/ARM/wasmtime/wasmer)。

  4. Parcel 编解码:版本向前/向后兼容;畸形输入拒绝策略。

  5. 锚定器:RBF 策略正确性;重组恢复;双写 BTC/Tondi 的一致性。

  6. 事件承诺:重放攻击防御(加入 nonce/timestamp + 会话盐);payload 混淆策略。

  7. 桥与互操作:跨链验证器的假阳性/假阴性率;多重签名/见证依赖的审计。

v1 加固审计重点

  1. 双花防护:序列号单调性验证;同一 (domain_id, prev_seq) 的重复检测

  2. 重放防护:anti_replay_tag 计算正确性;跨 epoch/链的重放检测

  3. 分叉选择:EpochRoot 规范化算法;重组处理逻辑

  4. 编码确定性:Deterministic CBOR 实现;跨平台编码一致性

  5. 签名安全:确定性 nonce 生成;MuSig2 转录绑定;域标签使用

  6. PayJoin 安全:会话 nonce 管理;spend_auth_tag 验证

  7. 隐私保护:域盐化主题;批量填充有效性;流量指纹防护

NDM 审计重点

  1. 冲突剔除:多候选 EpochRoot 下 (domain_id, prev_seq) 唯一性维持

  2. 最终性回归:到达 BTC 2 conf/Tondi 指定深度后,拒绝任何替换候选

统一错误码与拒绝策略

验证器错误枚举(NDM 版本):

  • E_BAD_PROOF:证明验证失败

  • E_SEQ_REUSE:同一 (domain_id, prev_seq) 已被消费(或在规范化历史中出现过)

  • E_NON_CANONICAL_EPOCH:引用的 EpochRoot 不在规范化链上

  • E_BAD_UPDATE_CONFLICT:Parcel 的 new_root/new_seq 与规范化 Epoch 的记录不一致

  • E_NOT_FINAL:对方要求最终性,但当前引用的锚定尚未达阈值

  • E_FUEL_EXCEEDED:Fuel 限额超限

  • E_BAD_ENCODING:编码格式错误

  • E_BAD_SPENDTAG:PayJoin 花费标签不匹配

  • E_ANCHOR_MALFORMED:锚定格式错误

拒绝策略(NDM 版本):

  • SDK 将错误码对应成可本地化提示

  • 冲突 = 本地拒绝(E_SEQ_REUSE / E_NON_CANONICAL_EPOCH)

  • 钱包策略:可配置"是否等待最终性"开关(商户/机构默认开启)


16. 上线路线图(灰度到主网)

  1. DevNet(4–6 周)

    • Enso-vm 零件化:vmap=Merkle、Fuel、承诺事件;

    • Enso-c 基本可用;

    • ESIP-20/ESIP-721 样例合约与 50+ 单元/集成测试;

    • 基础钱包 CLI:构造/签名/本地验证。

  2. Testnet-A(6–10 周)

    • Enso-anchor 对接 Tondi 测试网;

    • Bundle/RBF 测试;

    • 轻量索引器 Enso-index;

    • RGB 导入 PoC。

v1 加固实施清单

  • [ ] 添加序列号/锁定语义并更新所有示例代码(ESIP-20/721)以读取和递增 prev_seq/new_seq

  • [ ] 发布 Scheme Registry v1(Merkle-SHA256-SMT;Verkle-IPA)与参数摘要

  • [ ] 交付 Deterministic CBOR 编码器/解码器 + 测试向量

  • [ ] 在钱包 SDK 中实现 epoch 分叉选择 和重组逻辑

  • [ ] 在 SDK 协商中添加 PayJoin spend_auth_tag

  • [ ] 扩展硬件钱包流程以显示 domain_id、prev_seq → new_seq 和 epoch_hint

  • [ ] 模糊测试 VmapDelta 合并并强制"每个 epoch 每个 (domain_id, prev_seq) 一个更新"

落地里程碑(DevNet→Testnet-A 可执行路线)

第 0–2 周:协议骨架落地

  • [ ] Scheme Registry v1:Merkle-SMT(SHA256, binary, CBOR-det-v1),发布 params_hash 与 10 组测试向量(空树、单叶、两叶、深路径)

  • [ ] Deterministic CBOR:固化编码顺序与数值规范,产出 cross-platform 向量(x86/ARM/wasmtime)

  • [ ] ParcelDigest v1:冻结"签什么/不签什么"结构,给出 3 个签名样例(单签、MuSig2、批验)

  • [ ] Taproot 承诺库:key-path/script-path 两套 helper + 单元测试(对比 Bitcoin Core 参考行为)

第 3–4 周:最小可行验证器/钱包

  • [ ] enso-vm(min):仅保留必需 natives(hash/sig/merkle/bytes),实现 Fuel 四维计数

  • [ ] vmap-verifier:支持 SMT(节点与路径验证、限额、错误语义)

  • [ ] wallet-cli:compose → sign → verify → anchor(sim) 全闭环,本地"自锚定"模式可运行

  • [ ] 序列号/锁:实现 (domain_id, prev_seq)->new_seq=prev_seq+1 约束与重复检测

  • [ ] PayJoin v1:SessionNonce + spend_auth_tag 协商与校验

第 5–6 周:DevNet 验证场景

  • [ ] 并行性回归:1000 笔无冲突写入并行验证,目标 QPS→核数线性扩展±20%

  • [ ] DoS 抗性:构造极端大深度/大分支证明,验证 Fuel 与限额行为正确

  • [ ] 重放与双花:脚本化三类攻击(同 prev_seq 双提交、跨 epoch 重放、PayJoin 部分重用),期望全部被拒

  • [ ] 锚定与 RBF:模拟两候选同 epoch,测试"候选集合+2 确认密封"的再组织逻辑

Testnet-A 启动前交付物

  • [ ] 协议常量与域标签表

  • [ ] 参考实现(Rust/TS)+ 测试向量仓库

  • [ ] 开发者文档:Parcel 字段级规范、错误码、Taproot 绑定手册

NDM 落地检查单

  • [ ] 文档删除/替换所有"争议/冻结/裁决/冲正/治理登记"的描述

  • [ ] 错误码与 SDK 返回值改为:冲突 = 本地拒绝(E_SEQ_REUSE / E_NON_CANONICAL_EPOCH)

  • [ ] 钱包策略:可配置"是否等待最终性"开关(商户/机构默认开启)

  • [ ] 测试向量:

    • 同 (domain_id, prev_seq) 的 A/B 双花 → 仅规范 Epoch 接受 A 或 B 之一

    • 两候选 EpochRoot(BTC 不同高度)→ 客户端选择较低高度

    • 达到最终性后提交替换 → 被拒绝

  1. Testnet-B(8–12 周)

    • LN/PayJoin 集成;

    • MuSig2/FROST;

    • Verkle 验证器插件;

    • 审计第一轮 + 赏金计划启动。

  2. Mainnet-Phase-1

    • Tondi 主网锚定 + 可选 BTC 周锚定;

    • ESIP-20/721 稳定版;

    • SDK v1(Rust/TS/Swift/Kotlin)。

  3. Mainnet-Phase-2

    • BTC 高频锚定与再锚定策略优化;

    • 桥接(RGB/Aptos/EVM)上线;

    • 争议裁决在治理链全量启用。


17. 运维与监控

  • Anchor 监控:跟踪每个 Bundle 的 RBF 状态、确认高度、双路锚定一致性。

  • Fuel 指标:统计每类合约的平均/分位 FuelUsage,用于 SDK 侧给用户自动推荐 FuelLimit。

  • 隐私审计:定期做外部链上分析演练,评估可链接性并优化 PayJoin/混淆策略。

  • 备份策略:Parcel 与离线明文(若需)冗余;DomainRoot/Proof 快照定期导出。


18. 关键参数建议(初始缺省)

  • FuelLimit 初值:steps=1e6、mem_pages=64、proof_nodes=1024、commit_events=16。

steps=1e6 参数说明

steps=1e6 的含义:

  • 这是 Fuel 模型里的一个初始参数。

  • steps = 解释器可执行的最大指令步数。

  • 1e6 = 一百万步,作为默认硬上限。

  • 相当于"交易脚本最多跑一百万条虚拟机指令",超过就 abort。

  • 类似 Aptos/EVM 的 gas limit,但 Enso 没有费用,只是安全阈值。

  • 用于防止 DoS 攻击和确保执行时间的可预测性。

  • Epoch:以 10–20 分钟为一轮聚合;拥堵期动态缩至 5 分钟。

  • RBF 窗口:至 1 个确认(Tondi)/2 个确认(BTC)可替换;超过阈值记为最终。

RBF 窗口合理性评估

当前配置:

  • Tondi:1 个确认可替换;超过阈值 = 最终。

  • BTC:2 个确认可替换;超过阈值 = 最终。

评估结果:

  • BTC:2 确认 ~20 分钟,比较合理,和 LN 生态的常见参数一致。

  • Tondi (GhostDAG, 10 bps):如果 1 bps=1 秒,10 bps = 每秒 10 个区块,1 个确认太短。建议用确认深度窗口,比如 10~20 block depth ≈ 1~2秒,比较稳。

建议的 RBF 窗口:

  • Tondi:确认深度 >= 30 → 终局;之前允许替换。

  • BTC:2 确认 → 终局。

  • 缓存深度:客户端保留最近 2016 个 EpochRoot(约两周 BTC 难度周期对齐)。

  • 签名算法:默认 Schnorr(SECP256K1);企业级可启用 Ed25519 门限。

  • 哈希:BLAKE3(运行时)+ SHA-256(与 BTC 生态一致用作锚定前映射)。

规范性限制

  • 最大 proof_nodes:每个 Parcel 4096 个(超限返回 E_FUEL_EXCEEDED)

  • 最大节点大小:每个 VmapProof.nodes[*] 4 KiB(超限返回 E_BAD_PROOF)

  • 最大 commit_events:每个 Parcel 16 个(超限返回 E_FUEL_EXCEEDED)

  • 最大 Parcel 大小:64 KiB(超限返回 E_BAD_ENCODING)

  • 确定性 CBOR:使用 RFC 8949 规范编码

  • EpochID 计算:epoch_id = floor(median_time_past / EPOCH_SECONDS)(BTC)或 Tondi 的协议时间,不要依赖本地 unix_time

自锚定回退

  • SelfBundle:用户可直接发布 {epoch_id, DomainUpdate} 到 BTC/Tondi

  • SelfBundle MUST 使用与 aggregator 相同的 Anchor Leaf 脚本

  • 聚合器接受:聚合器必须接受 SelfBundle 并包含在下一个 epoch 汇总中

  • 聚合器必须**在下一 Epoch 把 SelfBundle 纳入"目录",以便客户端能统一发现

  • **客户端在"无 reveal 候选"时,优先选自锚定且已 reveal 的条目

  • 独立有效性:SelfBundle 即使未被汇总也保持有效承诺

  • 单源锚定:SelfBundle 也必须遵循单源锚定原则,每个 epoch_id 只允许一个锚定源


19. 风险与对策

  • Proof 膨胀:

    • 对策:前缀合并、Verkle、Bundle 聚合、分层 DomainRoot(分域分根)。
  • 重放/重锚:

    • 对策:payload_hash 加入会话盐与 epoch_hint;最终性阈值之后禁止再锚。
  • 实现复杂度:

    • 对策:先落地 Merkle & Schnorr 基线,后插 Verkle/MuSig2;A/B 层层启用。
  • 开发者错配(把 Enso 当全局链使用):

    • 对策:文档/SDK 从一开始只暴露"证明式存储"范式,杜绝全局状态心智。

风险与边界(Profile 相关)

  • Tondi 共识稳定性:以 D_final 降低尾部风险;单源锚定确保每个 epoch_id 只有一个锚定源

  • 单源锚定:每个 epoch_id 只允许一个锚定源,要么 Tondi 要么 BTC,避免双写不一致问题

  • 桥接/审计需求:对"他链/审计"场景,建议使用 Profile B 或开启 ESIP-R1;SDK 提供一键"审计模式"开关(总在 BTC 留痕)

  • 运营成本:BTC 周锚的费用需可配置阈值与批量阈值;提供成本预估与费用分摊(按 Parcel 大小/权重)

  • 不可公证窗口(Profile T):第三方在未获得 parcel 前无法旁观验证;这与 RGB 一致,是设计选择。

  • 反多口径:离线 taproot 证明 + 聚合器签名 + 公共日志,可显著降低作恶空间,但不是"纯链上无需信任";如需纯链上自证,请使用 Profile B 或延迟揭示。

  • 桥接:要求"信道内可验证"(对端必须接收并校验 off-chain taproot 证明),否则走 Profile B 或开启 ESIP-R1。


20. 面向产品的三种典型落地

  1. 机构级结算金库

    • 多签(MuSig2)+ 合规披露(选择性提交明文);

    • Profile B(BTC 单源锚定)或 Profile T + ESIP-R1 保证审计可追溯;

    • Fuel 限额与签批流程映射到企业风控。

  2. 高频支付(电商/游戏)

    • Profile T(Tondi 单源锚定)+ 可选 ESIP-R1 按需 reveal;

    • SDK 自动批量合并 Parcel,商户/用户体验接近 Web2。

  3. 跨链资产网关

    • RGB/Enso/Aptos/EVM 多向桥;

    • 只在目标链持有“可验证收据”,避免重复记账风险。


21. 与原生 RGB 的工程对齐总结

  • Invoice/Coinsel/Operation → Enso 的 Invoice/Proof 选择/compose_parcel。

  • PSBT 预提交/填充/承诺 → Pre-Parcel → SigSlot 填充 → AnchorHint。

  • RBF、多个签名源(多签伙伴/LN/HW) → RBF 再锚定、SigSlot.role=MultisigPartner/LN/HW。

  • Finalize/Extract/Broadcast → taproot_commit → 广播 → 记录 EpochRoot。

  • Update UTXO/Consignment → 更新 AnchorIndex/DomainRoot 缓存,Parcel 即 consignment。

  • Valid contract state → 客户端基于 Parcel + Proof 独立验证的新 DomainRoot。

换言之:RGB 的“PSBT + consignment”在 Enso 中被统一为 “Parcel + Anchor” ,并且通过 Move 的线性资源语义,把“不可复制资产/凭证”的约束内化进类型系统,兼得隐私、并行与可审计。


22. 验证与对抗性测试(直接可跑的测试蓝本)

测试必须项(回归集最小版)

单源约束:

  • 同一 epoch_id 同时出现 T 和 B → 构建失败(E_PROFILE_LINT_FAIL)

分叉选择:

  • Profile=T 只按 DAG 指标选;Profile=B 只按高度选

无 reveal 验证:

  • 在 reveal.enabled=false 时,纯 off-chain 证明可完成全流程

可选 reveal:

  • 启用 ESIP-R1 后,control_block/tapleaf 不匹配 → E_BAD_REVEAL

序列号与冲突:

  • new_seq != prev_seq+1 或同 (domain_id, prev_seq) 多提交 → 拒绝

RBF:

  • 仅在同一链、未达最终性时允许替换;达阈值后拒绝

风险边界(已收敛)

不可公证窗口:

  • Profile T 在未披露前,第三方无法旁观验证——这是刻意的隐私选择;要公证时再打开 ESIP-R1 或改用 Profile B

实现复杂度:

  • 比双写方案显著降低:锚定器、SDK、验证器都只关注单一链

运营:

  • 费用与吞吐按各自链独立评估;无跨链一致性负担

双花(同输入)测试

构造:相同 (domain_id, prev_root, prev_seq),制作 Parcel A/B 两个不同 new_root/new_seq

预期:

  • 验证器在单 Parcel 内拒绝重复触达

  • 在 EpochRoot 构建时拒绝同 (domain_id, prev_seq) 的重复

  • 在不同聚合器各自锚定 → 客户端按 fork choice 只接受"更早 BTC 高度"的那一个

Anchor Reveal 测试

构造:锚定后 1 个 Epoch 内未 reveal → 客户端应降权该候选;reveal 后切换到 reveal 候选

预期:

  • 未 reveal 的候选在客户端选择时被降权

  • reveal 后客户端自动切换到已 reveal 的候选

  • 验证 control_block 与 leaf 脚本的一致性

序列号统一测试

构造:rw_ops.expected_seq != prev_seq → E_SEQ_REUSE;同域并发 A/B,只有规范链中的那个通过

预期:

  • 序列号不匹配时返回 E_SEQ_REUSE

  • 同域并发交易中只有规范链上的交易被接受

CBOR 规范化测试

构造:同值不同编码(leading zeros / map 顺序)→ E_CBOR_CANON_FAIL

预期:

  • 非规范 CBOR 编码被拒绝

  • 返回 E_CBOR_CANON_FAIL 错误码

MuSig2 会话复用攻击测试

构造:nonce 重用/commit 缺失 → 拒绝

预期:

  • nonce 重用被检测并拒绝

  • 缺少 nonce commitment 的签名被拒绝

Ed25519 小序群测试

构造:恶意点输入 → 拒绝

预期:

  • 小序群点被检测并拒绝

  • 非规范编码被拒绝

Fuel 边界测试

构造:hash/verify 超权重 → E_FUEL_EXCEEDED

预期:

  • 超过 Fuel 限制的操作被中止

  • 返回 E_FUEL_EXCEEDED 错误码

跨 epoch 重放测试

构造:在 epoch n 生成 Parcel P(prev_seq=10→11),随后在 epoch n+2 再投递同一 P

预期:

  • 因 prev_seq 已被消费,验证器报 E_SEQ_REUSE

  • anti_replay_tag 也不匹配当前上下文

PayJoin 部分重用测试

构造:捕获对方 delta,换一个会话复用

预期:spend_auth_tag 不匹配 → E_BAD_SPENDTAG

证明节点洪泛测试

构造:大量大节点/胖叶

预期:

  • 触发 max_node_size 或 proof_nodes 超限 → E_FUEL_EXCEEDED

  • 资源占用不致 OOM

CBOR 非规范编码测试

构造:同值不同编码(leading zeros、map key 非排序)

预期:

  • 哈希不一致而被签名校验拒绝

  • 或在"严格模式"直接 E_BAD_ENCODING

锚定分叉 & RBF 测试

构造:同 epoch_id 两个候选;一个 BTC 高度更低、另一个费率更高但后确认

预期:

  • 客户端按规则选择"更早高度"的 BTC 候选

  • 超过 2 conf sealed 后拒绝替换

NDM 冲突剔除测试

构造:同 (domain_id, prev_seq) 的 A/B 双花,分别被不同聚合器锚定

预期:

  • 仅规范 Epoch 接受 A 或 B 之一

  • 客户端自动拒绝非规范化历史

  • 达到最终性后,冲突更新永久无效

最终性回归测试

构造:达到 BTC 2 conf 后提交替换候选

预期:

  • 被拒绝,返回 E_NOT_FINAL 或相应错误

  • 协议层无冲正或裁决流程

Anchor Reveal 不匹配测试

构造:control_block 与 leaf 脚本不导出同一 Merkle 根 → E_BAD_REVEAL

预期:

  • reveal 证明与锚定承诺不匹配

  • 返回 E_BAD_REVEAL 错误码


23. 结语(一句话)

Enso = 客户端验证(Proof/Parcel 一等公民) + Move 线性资源(不可复制) + Taproot 锚定(BTC/Tondi 最小信任) + 工业级工程(Fuel、AOT、白名单原生)。
它不是"再造一条链",而是把状态与验证放回终端边缘,以极简的锚定承诺连接全网安全。通过单源锚定和Profile T(Tondi-first,默认) 和 Profile B(BTC-only,可选) 两套运行档,实现"每个 epoch_id 只允许一个锚定源"的策略,既保留与 RGB 的对齐,又为需要审计/桥接的一方留升级路径。按本方案推进,可在2025 Q4~2026 Q1 内完成从 DevNet → Testnet → 主网灰度 的落地闭环。