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

人体工学エンジニア、クオンツ金融エンジンアーキテクト、暗号技術の専門家として、 現在は 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 的价值主张具象为:
最小门槛:延续 Move 语义(线性/仿射类型),ESIP 与 Aptos Move 在接口层兼容;但去掉账户链/全局表等与客户端验证冲突的设施。
状态即证明:任何资源/余额/凭证都由 vmap + Proof 表示,交易携带 ProofDelta,第三方无需索引器也能独立验证。
锚定极简:只把 EpochRoot/Bundle 哈希刻进 Taproot(key tweak 或 leaf 方案)或 Tondi;不把业务状态上链。
极简运维:节点不再“同步全局状态”,而是缓存近期 EpochRoot 与少量索引;钱包/服务以 Parcel 为一等公民互通。
可组装原生桥:原生桥接 RGB/Aptos/EVM;ESIP-Bridge 系列形成标准。
工业级的readiness:白名单原生、AOT/WASM-Min、Fuel 限额、前缀合并与批量验签,保证可靠吞吐与 DoS 抑制。
2. 设计哲学
隐私优先
无全局账户表;所有事件对外仅是承诺;余额/转账不可被第三方扫描。
Parcel 只向参与者暴露必要明文;对外仅可见哈希与锚定数据。
最小信任
客户端完全独立验证:只需 DomainRoot、Proof 与锚定头信息,即可确认正确性。
任何中继/索引器都是可替代缓存,而非信任根。
跨链安全
根承诺锚定于 BTC/Tondi Taproot(taptweak 或 TapLeaf),继承 BTC 安全性;
RBF 友好锚定策略 + 再锚定窗口,抵御锚定延迟与重组。
Move 兼容
ESIP 与 Aptos Move 在模块接口与标准库层维持相似度;
开发者沿用 Move 的类型与“资源不可复制”理念,只是存储/事件语义全改为证明式。
工程务实
去除随机数/时间/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-slimfeature 下,链接的标准库去掉全局表依赖;在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:首次触达页记 1hash(bytes_len):ceil(bytes_len/64)计入crypto_opssig_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 对照)
付款人收到 Enso-Invoice:
- 包含:收款人
domain_root_recv、schema_ref、amount/asset_id、fuel_suggest、可选payjoin/LN路由偏好。
- 包含:收款人
Proof/输入选择(Coinsel 同义):
- 钱包从本地缓存/离线库挑选要花费的
DomainRoot对应VmapProof;如需,可与对方 PayJoin(见 8.2)协商,使双方都写入各自VmapDelta,减少可链接性。
- 钱包从本地缓存/离线库挑选要花费的
Coinsel 概念说明
构造 pre-parcel(compose_parcel):
计算所需
VmapDelta(扣减付款人余额、增加收款人承诺、生成新的DomainRootOut提示);打入
Commitment:例如topic=ESIP-20::transfer,payload_hash=H(sender,receiver,amount,nonce);设定
FuelLimit;设定
AnchorHint(锚定在哪个 UTXO/哪些输入键位做 taptweak)。
多方签名(SigSlot):
按
SigSlot.role分配签名位:MultisigPartner、HW、LN;验签/批量验签;
可选择“预制 Bundle”(例如适配企业审批流)。
锚定与广播:
根据
AnchorHint生成 Taproot 承诺(Key-path tweak 或 Script-path);构造 BTC/Tondi 交易并广播;
若手续费不足/拥堵,执行 RBF 再锚定。
更新与交付:
广播成功后记录
EpochRoot与锚定位置;向收款方交付正式 Parcel(含签名与实际
FuelUsage);收款方据此更新其
DomainRoot缓存,无需第三方索引器即可继续花费。
冲突处理(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
}
验证规则
链式完整性
prev_epoch_root必须正确链接到上一个已确认的 EpochRoot。锚定有效性
merkle_root必须存在于 BTC/Tondi 的 Taproot commitment 中。序列号单调性 对于任何固定的
(domain_id, prev_seq),在整个历史中最多只能有一个DomainUpdate被接受。归属证明 任一 Parcel 的输入
DomainInput必须能通过proof被包含在某个锚定的epoch_root中。差分验证 应用 Parcel 携带的
VmapDelta,从prev_root推导出new_root,并与 EpochRoot 内记录的new_root一致。分叉选择规则 对于同一
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"或"双路一致性"条款
时间宽容窗口
客户端"容忍窗口"从
{n-1,n,n+1}改为:允许±Δ(由链时间校正给出);并以锚定块时间最终归档最终归档以锚定时刻所在块的时间为准,由聚合器/验证器执行
工作流程
用户提交 Parcel
用户生成交易 Parcel,包含 ProofDelta (旧根 → 新根)。
提交给网络上的聚合者。
聚合者构建 EpochRoot
聚合者在 Epoch 时间窗口内收集所有 DomainRoot 更新。
构建 Merkle/Verkle 树,得到
merkle_root。
锚定
聚合者将
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 双写,作为追责与对比快照来源(非信任根)
客户端验证
客户端验证:
我的
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_eventsFuel 限制)会话盐:在
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:
读兼容:导入 RGB consignment,校验其 Taproot 锚定与 AluVM 规则,生成等效
Parcel(映射 schema 字段)。双向桥:锁定 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:BTC 优先;
多个 BTC 候选取区块高度更低者;平局按
(txid, vout)字典序;仅有 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:不支持的 SchemeE_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,每次转移只改动所属者的子域键。
- NFT 的
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=20merchant:Profile T,
D_final=30institutional: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 兼容策略(落地细节)
读兼容
编写
rgb-import工具,将 RGB consignment 解析为:Taproot 锚定(验证其在 BTC 的位置);
AluVM 字节码与状态过渡;
转换为等价的
VmapProof/VmapDelta与Commitment,输出 Enso Parcel。
双向桥
锁定 → 铸造:在 RGB 侧构造
burn/lock,以 consignment 证明作为 Enso 的Commitment明文,Enso 侧合约铸造等额资产;销毁 → 解锁:反向提供 Enso 的 Parcel 与锚定,RGB 侧合约/工具释放原资产。
执行兼容(可选)
内嵌 AluVM 解释器(作为一个受 Fuel 限额的模块);
成本较高,仅为存量合约过渡期所用。
Schema 映射
在治理链上登记
rgb_schema_id ↔ Enso_schema_id映射;钱包 SDK 在导入/导出时自动套用映射。
15. 安全审计清单(可执行)
Threat Model
攻击面:双花、重放、聚合者拒收、RBF 竞速、reorg、CBOR 非规范、批量验签滥用、MuSig2 session、Ed25519 小序群、topic 流量分析等。
加密层:哈希域隔离、签名域分离、MuSig2 聚合实现、批量验签正确性。
vmap:Merkle/Verkle 验证正确性;路径歧义/键冲突测试;版本号与并发写冲突检测。
Fuel:步数与内存计量的确定性;跨平台一致性(x86/ARM/wasmtime/wasmer)。
Parcel 编解码:版本向前/向后兼容;畸形输入拒绝策略。
锚定器:RBF 策略正确性;重组恢复;双写 BTC/Tondi 的一致性。
事件承诺:重放攻击防御(加入 nonce/timestamp + 会话盐);payload 混淆策略。
桥与互操作:跨链验证器的假阳性/假阴性率;多重签名/见证依赖的审计。
v1 加固审计重点
双花防护:序列号单调性验证;同一
(domain_id, prev_seq)的重复检测重放防护:
anti_replay_tag计算正确性;跨 epoch/链的重放检测分叉选择:EpochRoot 规范化算法;重组处理逻辑
编码确定性:Deterministic CBOR 实现;跨平台编码一致性
签名安全:确定性 nonce 生成;MuSig2 转录绑定;域标签使用
PayJoin 安全:会话 nonce 管理;
spend_auth_tag验证隐私保护:域盐化主题;批量填充有效性;流量指纹防护
NDM 审计重点
冲突剔除:多候选 EpochRoot 下
(domain_id, prev_seq)唯一性维持最终性回归:到达 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. 上线路线图(灰度到主网)
DevNet(4–6 周)
Enso-vm零件化:vmap=Merkle、Fuel、承诺事件;Enso-c基本可用;ESIP-20/ESIP-721 样例合约与 50+ 单元/集成测试;
基础钱包 CLI:构造/签名/本地验证。
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 不同高度)→ 客户端选择较低高度
达到最终性后提交替换 → 被拒绝
Testnet-B(8–12 周)
LN/PayJoin 集成;
MuSig2/FROST;
Verkle 验证器插件;
审计第一轮 + 赏金计划启动。
Mainnet-Phase-1
Tondi 主网锚定 + 可选 BTC 周锚定;
ESIP-20/721 稳定版;
SDK v1(Rust/TS/Swift/Kotlin)。
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/TondiSelfBundle 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. 面向产品的三种典型落地
机构级结算金库
多签(MuSig2)+ 合规披露(选择性提交明文);
Profile B(BTC 单源锚定)或 Profile T + ESIP-R1 保证审计可追溯;
Fuel 限额与签批流程映射到企业风控。
高频支付(电商/游戏)
Profile T(Tondi 单源锚定)+ 可选 ESIP-R1 按需 reveal;
SDK 自动批量合并 Parcel,商户/用户体验接近 Web2。
跨链资产网关
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_REUSEanti_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 → 主网灰度 的落地闭环。



