Repository navigation
[Language/ABI] Bind runtime Script values to verified package interfaces #11
Description
Summary
Connect CellScript's runtime Script/ScriptRef values with its canonical package-interface and deployment identities.
The desired abstraction is a typed handle such as ScriptHandle<I> or VerifierHandle<I>: a runtime-selected Lock or Type Script whose implementation is proven to satisfy a declared interface contract, while remaining an ordinary non-Cell value that grants no lifecycle authority by itself.
This issue supplies the identity foundation required by the open foreign roles in #10.
Current gap
CellScript already has two strong but disconnected layers:
Runtime Script identity
The language can construct and inspect CKB Scripts:
ScriptandScriptRef;code_hash,hash_type, and args;- exact Lock/Type Script matching;
- code/data CellDep identities;
- deployment records.
Compile-time package identity
The compiler emits:
cellscript-package-interface-v2;- canonical
interface_hash; - six-dimensional compatibility reports;
- typed-semantics and lowering identities;
- generated-builder and deployment contracts;
- Registry admission checks.
A raw runtime Script does not currently carry or prove a package interface. Conversely, an interface_hash in Registry metadata does not prove which Script bytes are executing in a transaction.
flowchart LR
RS["Runtime Script<br/>code_hash + hash_type + args"] -. "missing verified link" .- PI["Package interface<br/>interface_hash + schema + effects"]
ART["Checked artifact"] --> PI
DEP["Deployment identity"] --> RS
Required security property
A consumer accepting ScriptHandle<I> must be able to answer all three questions independently:
- What Script is present in the transaction?
- What exact checked artifact or allowed upgrade line does that Script resolve to?
- Why does that artifact satisfy interface contract
I?
The answer must not depend on a mutable Registry lookup during consensus execution.
Handle classes
The design should distinguish at least:
Exact artifact handle
Binds one exact checked artifact:
Script identity
+ deployable ELF/data hash
+ typed artifact identity
+ exact interface_hash
+ target/profile/ABI identity
This is the simplest and safest first version.
Deployment-line handle
Binds an upgradeable deployment identity, such as a Type ID code Cell, plus an explicit compatibility/upgrade policy.
The verifier or builder must resolve the actual code bytes used by the transaction and prove that the selected deployment belongs to the allowed line. A Type-hash Script reference alone must not be treated as proof that every future code Cell remains interface-compatible.
Compatible open handle
Accepts one of several implementations satisfying a minimum interface or schema/effect contract.
This requires a versioned compatibility policy and a consensus-verifiable binding from the selected Script to a checked interface receipt. It must not be implemented as “look up the code hash in the Registry and trust the response.”
Candidate receipt model
The exact encoding requires an RFC. A receipt could bind:
receipt_version
interface_hash
typed_semantics_hash
deployable_artifact_hash
target_profile_hash
runtime_abi_hash
deployment_identity
upgrade_policy
flowchart TB
SRC["Package source"] --> COMP["CellScript compiler"]
COMP --> IFACE["Canonical interface hash"]
COMP --> ART["ELF + typed/lowering records"]
ART --> CHECK["Independent checker"]
CHECK --> RECEIPT["Verified interface receipt"]
RECEIPT --> DEPLOY["Deployment record / code Cell"]
DEPLOY --> HANDLE["Runtime ScriptHandle<I>"]
HANDLE --> ROLE["Open or closed transaction role"]
For data-hash code deployment, exact Script code identity can anchor the artifact strongly. For Type-hash/upgradeable deployment, the RFC must define how the concrete code Cell and its upgrade policy are bound and revalidated.
Type-system requirements
A handle type must:
- be an ordinary fixed-width value, not a Cell-backed resource;
- carry no implicit
create,consume,replace, or authorization capability; - encode Lock versus Type Script role explicitly;
- distinguish exact from compatible/upgradeable policies;
- preserve target, VM, source-encoding, witness ABI, and Script hash-type identities;
- prevent implicit conversion from raw
ScriptorHash; - require explicit checked construction;
- be serializable only through a versioned canonical representation;
- expose safe equality and exact-preservation operations;
- remain separate from a peer Cell's decoded state.
The open-role system may state that an output uses the same implementation as an input, but that relation must compare the complete accepted handle identity, not only a code hash or interface name.
Trust boundaries
| Evidence | What it proves | What it does not prove |
|---|---|---|
raw Script fields |
transaction carries this Script structure | the code satisfies interface I |
| Registry interface record | a published package claims this interface | the transaction executes that artifact |
| independent checker | artifact records and ELF agree structurally | deployment/live-chain identity |
| deployment record | expected artifact was recorded at an outpoint | the current transaction resolved the same bytes unless checked |
| code/data hash check | exact code bytes are selected | source-level intent unless bound to checked artifact |
| Type ID | unique/upgradable code-cell identity | upgrade compatibility |
| CKB-VM dry-run | selected Scripts accept this exact transaction | general source equivalence or future upgrades |
Implementation phases
Phase 0 — threat model and exact handle
- enumerate substitution, downgrade, stale-deployment, Registry-spoofing, and type-hash upgrade attacks;
- define an exact artifact receipt and canonical hash;
- define how the builder and on-chain Script check the selected implementation;
- keep compatible/open handles out of scope until exact handles are proven.
Phase 1 — exact closed handles
- add the fixed-width handle/receipt representation;
- integrate it with public interfaces, deployment manifests, ProtocolBundle, metadata, and
tx validate; - generate exact Script/data/code identity checks;
- preserve the handle across declared input/output roles;
- add independent checker and mutation coverage.
Phase 2 — upgradeable deployment lines
- define upgrade authorization separately from compatibility;
- require every selected code version to have a checked receipt;
- reject stale, yanked, incompatible, or unbound versions according to policy;
- preserve historical receipt identity in audit evidence.
Phase 3 — compatible open handles
- define minimum interface and schema/effect requirements;
- admit only implementations with a consensus-verifiable receipt binding;
- integrate with [Language design] Model typed cross-Script transaction roles without runtime linkage #10 open roles;
- test implementation substitution, same-interface/different-behavior boundaries, and downgrade policy.
Acceptance matrix
| Case | Expected |
|---|---|
| exact checked artifact and exact Script identity | pass |
| same interface name, different interface hash | reject |
| same schema, incompatible effects/ABI | reject |
| valid Registry record but wrong transaction Script | reject |
| exact code hash but receipt for another target/profile | reject |
| Type ID points to unreceipted upgraded code | reject |
| allowed additive upgrade under explicit policy | pass only after full receipt verification |
| compatible interface but state schema mismatch | reject |
| output claims same implementation but changes args/policy | reject |
| removed receipt/Script binding machine block | standalone checker rejects |
Completion criteria
- An accepted RFC defines exact, upgradeable, and compatible handle classes.
- Exact artifact handles ship before compatible open handles.
- The handle representation is canonical, versioned, fixed-width, and non-linear.
- Raw Script identity, artifact identity, interface identity, and deployment identity remain separate fields.
- No Registry lookup is treated as consensus proof.
- Data-hash and Type-hash deployment paths have explicit, different security contracts.
- ProtocolBundle and
tx validateresolve and verify handles. - Typed semantics, ProofPlan, lowering records, standalone checker, and CKB-VM fixtures cover the binding.
- Negative tests cover substitution, downgrade, stale deployments, wrong profile/ABI, changed args, and unreceipted upgrades.
- Open cross-Script roles in [Language design] Model typed cross-Script transaction roles without runtime linkage #10 cannot stabilize without this contract.
Non-goals
- treating interface compatibility as behavioral equivalence;
- dynamically downloading or executing package metadata on chain;
- granting Cell lifecycle authority through a handle value;
- making Registry availability a consensus dependency;
- hiding upgrade authorization inside compatibility checks;
- accepting a Type ID as automatic proof of compatible code;
- generic dynamic dispatch unrelated to CKB Scripts.
Dependencies
- [Architecture][Builder] Add an artifact-only multi-Script ProtocolBundle #9 — ProtocolBundle artifact composition.
- [Language design] Model typed cross-Script transaction roles without runtime linkage #10 — typed cross-Script roles consume this handle in their open-role phase.
Activity
a19q3 commentedon Aug 27, 2026
Research update: Argent's own follow-up document validates the receipt concern
Comment audit
There were no prior comments on this issue at the time of review.
The most important upstream evidence is not the open-ICC feature itself, but Argent's explicit list of unresolved app-linking problems:
https://github.com/argent-lang/argent/blob/6a627da4abdd53e71fdb71da0f711ccc96424eb6/docs/app-linking-followups.md
Argent records that its current imported interface fingerprint includes only the actor name, state name, and top-level Sil state fields. It does not include nested layouts, Argent source types, state expansions, or the actor handle, and artifact verification does not recompute exported fingerprints. The proposed follow-up is a complete receipt binding app, actor, source-state interface, all used layouts, and the exact actor handle, recomputed during verification.
That is strong confirmation that CellScript should not stabilize an interface-bound Script handle around a shallow or producer-supplied fingerprint.
What CellScript already has
CellScript starts from a stronger per-package base:
The gap is narrower but still security-critical: there is no verified link from a runtime CKB Script to the exact checked artifact and interface record.
A complete receipt must be recomputed from the exported artifact boundary, not copied from Registry metadata or trusted from the importing package.
Exact handle verification flow
For the first exact handle, the RFC should specify this complete chain:
The runtime value itself should remain non-authoritative: it does not grant consume/create/replace capabilities and does not prove peer behavior.
Data-hash and Type-hash are different security contracts
The official CKB transaction specification explains that code_hash/hash_type locates code through CellDeps:
https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0022-transaction-structure/0022-transaction-structure.md
For a data-hash deployment, exact code bytes can be bound directly.
For a Type-hash deployment, the Script identifies a code Cell by its Type Script hash. That supports code-cell replacement/upgrades, but it does not prove that the currently selected code bytes remain interface-compatible. An exact handle must therefore bind the concrete code bytes used in the current transaction, while an upgrade-line handle additionally needs:
TYPE_ID or Type hash alone is not an interface receipt.
Where can the receipt commitment live?
The RFC should compare explicit trust models rather than assuming one:
The issue should not promise compatible open handles until one model has an end-to-end CKB threat analysis.
Receipt content
At minimum, preserve distinct fields for:
Do not replace this with one opaque “compatible” bit. Interface compatibility is not behavioral equivalence.
Independent verification requirement
Argent's follow-up specifically calls for recomputing exported receipts and comparing imports with verified exports. CellScript should require the same:
Acceptance additions
Relationship to the new toolchain issues
Conclusion
The issue is well-founded and should start with exact artifact handles only. Argent's own app-linking follow-up is a useful negative design result: a receipt that omits nested layouts, source type identity, exact runtime handle, or independent recomputation is not a safe interface binding.
a19q3 commentedon Sep 11, 2026
Completed for the exact fixed-width 0.30 handle scope. Exact artifact receipts and CSHDLv1 values landed in
a9311bdb; source/runtime CKB checks in130f7078; pre-signing validation in019d1c05; and exact-version Type-hash deployment-line admission/liveness/runtime evidence ine5dbf3ecthrough6d768372. Generic compatible-open Script/verifier handles are explicitly split into post-v1 issue #28, with open roles in #29. Ledger/docs recordremaining_work=[]atcdc5b53c. No TAC or release workflow was invoked.