[RFC] 从 CellScript 包注册表到统一 CKB 产物注册表:身份、证据与消费边界

本文是一个关于统一注册表RFC草稿,也是对Terry最新上线的Mermaid功能的测试。
鸣谢Terry的工作。
本文以 nightly-0.23 的 Registry 实现为准。0.23 当前仍不是稳定发布证书;0.24 不在本文讨论范围内,也尚未发布。

从三个月前的 RFC 到现在

五月的第一版 公共注册表 RFC 当时采用了一个极简模型:

1. Git 负责源码分发和版本历史,
2. registry.json 负责版本索引
3. 链上只记录运行时真正需要的部署事实。

这个选择解决的是当时最直接的问题,即如何在不运行一套专用基础设施的情况下发布和解析 CellScript 源码包。

Jan 随后提出了一个问题:如果 namespace/name 本质上是在命名可验证对象,那么它是否也可以描述 CellScript 之外的产物,例如 CKB 本身、bootstrapper、可复现二进制或运行时 verifier?

沿着这个问题继续推演后,我认为答案是肯定的。

CellScript 最新的的commit上,Registry 已经不是单纯的 CellScript 包仓库,而是一个统一的 CKB artifact 注册表, 并且结合到了CellScript本身的cli工具链 cellc 中。

在这个过程中我重新设计了很多细节和边界,目前前后端已经能接受 6 类产物,并且极其严格地把 源码身份、构建身份、部署身份、可用性 拆开处理。

现在的公共 Registry 不再只承担 Git discovery,而增加了以下协调职责:

  • 发布者身份与 namespace 所有权;
  • 限定作用域的 capability;
  • 不可覆盖的 release admission;
  • 不可变对象存储;
  • 隔离验证队列;
  • 构建、复现与部署 evidence;
  • availability 和安全隔离;
  • 主网与短期 Pudge 沙盒的环境分离。

为什么不再只是一个包列表

假设开发者发布了一个 CKB 合约。

最开始,Registry 只能确认:某个开发者以某个名称提交了一组文件。这不代表文件能够编译,也不代表编译结果安全,更不代表合约已经部署到链上。

随后可能发生几件不同的事:

  1. Registry 在隔离环境中重新编译源码;
  2. 开发者发布构建出的二进制;
  3. 其他构建者使用同一份源码独立复现这个二进制;
  4. 二进制被部署到一个真实的 CKB Cell;
  5. 这个版本因为漏洞被标记为不建议使用。

这些事情发生在不同时间,需要不同的验证方法,也不能被一个笼统的“已发布”或“已验证”概括。

这就是当前 Registry 与最初 GitHub 包索引最大的区别:它不仅记录“东西在哪里”,还记录“我们已经检查到了哪一步”。

同一个名字下面可能是什么?

Registry 目前支持六类内容:

  • CellScript 源码库;
  • CellScript profile;
  • CKB 合约;
  • 运行时 verifier;
  • 需要独立复现的二进制;
  • 可以复制修改的项目模板。

它们可以使用同一套名称和版本规则,但不能以相同方式使用。

源码库可以通过 cellc add 加入项目;模板只能复制;二进制必须先检查哈希;CKB 合约只有在确认对应的 Cell 仍然存在后,才能作为可靠的 CellDep 使用。

因此,Registry 中的“类型”不是一个展示标签。它决定文件需要满足什么条件、Registry 如何检查它,以及开发者以后可以怎样使用它。

“发布成功”到底意味着什么?

发布成功只说明三件事:

  • 发布者有权使用这个名称;
  • 提交内容的格式和签名正确;
  • 同一版本没有被覆盖。

接下来,Registry 会分别显示:

  • 内容是否经过检查;
  • 对应程序是否已经部署;
  • 这个版本当前是否仍建议使用。

例如,一个合约可以“内容已经检查,但尚未部署”;也可以“已经部署,但后来因为漏洞被下架”。下架不会删除以前的源码、二进制或链上记录。

这些状态由实际检查结果产生,不能由发布者自己选择。

什么需要上链?

完整源码、构建日志、ABI 和审计文档体积较大,仍保存在链下不可变对象存储中,并通过哈希绑定到具体 release。

真正部署的 CKB Script 代码存在于 CKB Cell 中。Registry 的部署验证会检查:

  • OutPoint 对应的 Cell 是否仍为 live;
  • Cell data 是否与已发布 executable 一致;
  • code_hashhash_type、Type Script identity 是否匹配;
  • codedep_group CellDep 是否按真实语义解析。

0.23 的 Registry commitment 不是整个 Registry 的全局状态根,也不是任意离线文件的通用上链哈希服务。

它只绑定一个已经存在部署证据的具体 release,承诺内容包括:

  • namespace
  • name
  • release
  • source_hash
  • manifest_hash
  • artifact_hash
  • deployed_evidence_hash

链上 Cell data 为 CSREGv1 || commitment_hash

这个 commitment 只证明:达到确认数的 live Commitment Cell,在最近一次协调检查时,与配置的 Scripts、具体 release 身份和已接受部署证据一致。

它不证明:

  • 源码或二进制没有漏洞;
  • Registry 完成了安全审计;
  • 文件来源具有普遍真实性;
  • Registry operators 达成了共识;
  • 任意离线文件都可以通过 Registry 获得链上信任。

当前 commitment 使用配置的 custody Lock,因此它是该 custody key 作出的可归责声明,而不是去中心化共识。

目前支持发布的产物种类

产物类型 内容与用途 发布后的验证 消费方式
source_library 普通 CellScript 源码库 Registry verifier 重新编译,成功后 verified cellc add/install
profile_library CellScript profile、协议模型、schema 库 同样重新编译 cellc add/install
runtime_verifier CKB-VM verifier、外部 TCB 程序 绑定源码、ELF、ABI、verifier ID、IPC ABI fetch / verify / pin,部署后可生成 CellDep
deployable_contract Rust、C、CellScript、JS 等编写的 CKB Lock/Type Script 绑定源码、ELF、ABI、构建与 CKB profile record-deployment / cell-dep
reproducible_binary 需要独立复现的构建工具或 TCB 二进制 初始为 evidence_required,还需独立 builder 报告 fetch / verify / pin
template 可复制、可修改的项目模板 验证 file map 和每个文件哈希 cellc artifact copy,不会成为依赖

语言约束也是封闭的:

  • CellScript library:只接受 CellScript。
  • CKB executable:CellScript、Rust、C、JavaScript、other。
  • Reproducible binary:Rust、C、other。
  • Template:允许所有语言和 unspecified。

最重要的模型改进是:deployable_contractruntime_verifier 发布时不需要假装已经部署。它们首先是 undeployed artifact;之后再用真实链上 Cell 的 OutPoint 补充部署证据。

开发者发布流程

flowchart LR
    C["Coordinate identity<br/>namespace/name@release"]
    S["Source identity<br/>source and manifest hashes"]
    B["Build identity<br/>artifact, ABI and recipe hashes"]
    D["Deployment identity<br/>network, OutPoint and Script hashes"]
    O["Optional release commitment<br/>exact release plus deployed evidence"]

    C -->|"Names"| S
    S -->|"Builds into"| B
    B -->|"May be deployed as"| D
    D -->|"May be committed by configured custody policy"| O

    V["Verification status<br/>pending, hash_bound, verified,<br/>evidence_required or rejected"]
    P["Deployment status<br/>not_applicable, undeployed,<br/>deployed or chain_verified"]
    A["Availability status<br/>active, deprecated,<br/>yanked or quarantined"]

    V -.-> C
    P -.-> C
    A -.-> C

CellScript 源码包

cellc package verify --json
cellc publish --dry-run
cellc publish --authorise

后续已有有效 publishing capability 时:

cellc publish

非 CellScript 产物

先准备:

  • Artifact.toml:坐标、版本、kind、language、bundle 路径。
  • artifact.bundle.json:profile contract 和 base64 编码的不可变对象。

然后:

cellc publish --artifact-manifest Artifact.toml --dry-run
cellc publish --artifact-manifest Artifact.toml --authorise

Bundle 目前最大只能 5 MiB,且不能覆盖同一 release。CLI 会检查对象角色、重复对象、非法字段、安全路径以及所有哈希绑定。

cellc publish --authorise 会在本地生成 delegated P-256 publishing key,将私钥保存在系统 keychain,打开一个 15 分钟、限定到精确 artifact coordinate 的浏览器授权 session。钱包批准后,CLI 会自动继续原来的发布操作。

手工 capability payload、外部钱包签名和现有 key ID 仍作为 CI、恢复及高级流程保留。

CKB 部署证据

发布 CKB executable 后,再记录部署:

cellc artifact record-deployment namespace/[email protected] \
  --network mainnet \
  --code-hash <hash> \
  --hash-type data1 \
  --dep-type code \
  --tx-hash <tx_hash> \
  --index 0 \
  --capability-key-id <key_id>

API 会通过 CKB RPC 验证:

  • OutPoint 仍是 live Cell;
  • Cell data 等于已发布 executable;
  • data/data1/data2/type 身份匹配;
  • Type Script hash 正确;
  • DepGroup 时解析真实成员,而不是把 DepGroup 容器当代码。

验证完成才是 chain_verified

从 DX 角度考虑的已知缺点

发布流程图

sequenceDiagram
    participant C as cellc
    participant B as Registry Browser
    participant W as CKB Wallet
    participant R as Registry API

    C->>C: Generate delegated P-256 key locally
    B->>W: Request scoped capability authorisation
    W-->>B: Sign namespace, scope, key and expiry
    B->>R: Register public capability key
    B->>R: Claim namespace with wallet identity

    Note over C,R: The wallet is not required for every release

    C->>C: Build canonical publish payload
    C->>R: Submit payload signed by delegated key
    R->>R: Verify owner, scope, expiry, nonce and idempotency
    R-->>C: Return accepted release and verification status

当前体验的优点

  • 钱包只负责首次授权,不需要每次发布都弹钱包。

  • capability 被限定到 publish:namespace/name,私钥留在本机 keychain。

  • dry-run、不可覆盖 release、幂等重试和隔离 verifier 都已经具备。

  • “发布了”“验证了”“部署了”“仍可用”不会再混成一个含糊状态。

  • 非 CellScript 产物不会被错误地当成 CellScript dependency。

当前体验摩擦

但是目前我也注意到的很明显的摩擦是:

  • cellc publish --authorise 已经关闭首次发布的 CLI → 浏览器钱包 → CLI 自动继续闭环,但外部钱包、CI 和恢复路径仍然需要显式处理 capability payload。
  • 通用 artifact 虽然可以生成 Artifact.tomlartifact.bundle.json 骨架,但开发者仍需填入真实对象的 base64 字节和完整 profile contract。
  • hash_bound 只代表字节完整性,不代表安全审计、语义正确或适合生产。
  • reproducible build 晋级依赖 Registry policy 中相互独立的 builder 和 operator 接受流程,不能由发布者单方面完成。
  • Registry readiness 只说明服务依赖和配置检查通过,不代表 Registry 中的 artifact 已达到生产安全级别。

注意:

Registry 可能还需要一些UIUX改进和产品化和部署方面的优化,所以目前未进入生产阶段。

  • 主网 Registry commitment 当前为 disabled,所以可以到 chain_verified,但暂时不能声称 on_chain_committed
  • Pudge commitment 已 configured_and_live
  • 主网和 Pudge测试网两边的 reproducer policy 当前都为 disabled,因此 reproducible_binary 可以发布并进入 evidence_required,但还不能完成生产级 reproduced_build → verified 晋级。

详细实现可见我在持续推进的 CellScript 0.23分支

2 Likes

A universal trust generator. It’s universal in the sense that it makes any type of offline file verifiable online. File offline, evidence online, widely distributed?

Can you imagine something like the hash of a file, which you verify after downloading to check the authenticity/integrity of that file?

But where do you get the hash against which you check the hash of your downloaded file? Here: on-chain.

3 Likes

I should probably clarify an boundary a bit,the current 0.23 Registry is not yet a universal trust generator.

hash_bound now means that the bytes recorded by the Registry match the declared hashes. It does not prove that a file is safe, semantically correct, trustworthy in origin, or independently audited.

The current on-chain commitment is not a global hash of the entire Registry either. It binds one specific namespace/name@release, its source, manifest and artifact hashes, and its already RPC-verified deployment evidence.


Also, regarding where the reference hash comes from, the current model has two layers:

  1. The exact object hashes come from an immutable, publisher-signed Registry release record.
  2. For a release with verified deployment evidence, the commitment hash can additionally be checked against a live Commitment Cell using the configured Type Script and custody Lock.

The second layer is still an attributable statement made by the configured custody key. It is not consensus among Registry operators, a security audit, or a general proof that an arbitrary file is trustworthy.


At the service-readiness level, mainnet commitment construction and reconciliation remain disabled. The Pudge Registry Sandbox has its commitment Script configuration enabled, with the required code CellDeps live and sufficiently confirmed. This does not mean that a public artifact commitment currently exists; the Pudge public index is currently empty.

Supporting universal on-chain attestations for arbitrary offline files would require a separate artifact profile, governance model, and consumption boundary. I think it is relevant but that would likely need its own RFC later on.

1 Like