Spark Program | zk-Lock for CKB

1. Project overview and positioning / 项目概述与定位

zk-Lock is a reusable CKB lock script that conditions cell spending on a valid Groth16 proof. Any developer can write a Circom circuit, commit to its verifying key, and lock CKB cells behind it; to spend the cell, the spender submits a proof that satisfies the circuit.

The primitive is the integration layer that turns the existing on-chain Groth16 verifier into something developers can build with. The Spark-funded scope is the minimal primitive (lock script, CLI, deployed testnet artifact, and tutorial) sufficient for a developer to lock a cell behind their own circuit and unlock it end-to-end. Consumer-facing applications (web app, treasure hunt launch event) are out of scope for this grant.

2. Team profile / 团队简介

3. Project background and problem statement / 项目背景与问题陈述

CKB has a working on-chain Groth16 verifier (load-bearing prior work, already shipped). What is missing is the integration layer that lets developers actually use it: there is no standard way to lock a cell behind a circuit, no convention for binding cells to specific public inputs, no tooling for a developer to go from “I have a Circom circuit” to “I have CKB locked behind it.”

The result is that zk on CKB is currently reachable only by developers who can wire together the verifier crate, lock-script scaffolding, witness encoding, and tx construction themselves. Each new use case repeats this work. The primitive does not exist as ecosystem infrastructure.

4. Solution approach / 解决方案

A single-purpose CKB lock script with one spend path: the cell unlocks iff a valid Groth16 proof matches the committed verifying key and public inputs.

Four design choices, settled during pre-proposal research:

  • vkey storage: 32-byte vk_hash in lock.args; the full verifying key lives in a shared cell_dep referenced by data_hash. Mirrors the secp256k1 system-script pattern (small commitment in args, shared data cell), so many cells can reuse one vkey cell instead of each carrying full vkey bytes.
  • Public-input binding: lock.args also carries a 32-byte public_inputs_commitment. The cell is bound to specific public inputs, not just to the circuit, which is what makes zk-Lock a primitive rather than a generic verifier wrapper.
  • Minimal lock, compose for the rest: no refund branch, no creator pubkey, no deadline. Applications that need refund or settlement (treasure hunt, auctions, escrow) layer them on via a wrapping lock or a type script. Keeps the audit surface tight and the primitive usable for sealed-bid auctions, private claims, conditional escrow, and anonymous airdrops without favouring any one of them.
  • Claimer-binding convention: circuit authors include the claimer’s lock-script hash as a public input, so a proof copied from a pending transaction cannot be redirected to another address. Enforced implicitly via public_inputs_commitment; templated in the docs and CLI.

5. Technical architecture / 技术架构

Locked cell
  lock.code_hash:  <zk-Lock script hash>
  lock.args:       vk_hash (32B) || public_inputs_commitment (32B)   = 64 bytes

Cell deps (referenced by the unlock tx)
  zk-Lock script cell                  (the code)
  vkey cell                            (data = serialized vkey; referenced by data_hash)

Witness (unlock tx)
  witness.lock:    proof || public_inputs

Script logic (built on top of the existing verifier-core crate):

  1. Read (vk_hash, public_inputs_commitment) from lock.args.
  2. Scan cell_deps; find the dep whose blake2b(data) == vk_hash. Fail if none, fail if duplicate.
  3. Read (proof, public_inputs) from witness.lock.
  4. Check hash(public_inputs) == public_inputs_commitment.
  5. Call into groth16-ckb verifier with (vk, proof, public_inputs).
  6. Return success only if all checks pass.

Off-chain pipeline:

Circom circuit  →  snarkjs proof  →  CCC SDK  →  CKB

All off-chain tooling is mature (Circom, snarkjs, CCC). All on-chain logic reuses infrastructure already shipped (groth16-ckb verifier, CKB-VM).

6. Weekly execution plan / 执行计划

Week Focus Concrete output
1 Lock script architecture; integrate groth16-ckb verifier as a lock Workspace skeleton compiles; stub lock script reads args
2 Cell-dep vkey loading; witness parsing; end-to-end test against a known-good fixture All-paths unit + integration tests pass locally
3 Deploy to CKB Pudge testnet; minimal CLI for lock/unlock; tutorial draft Testnet tx hash demonstrating a successful unlock
4 Reference Circom circuit (Poseidon hash preimage); worked end-to-end demo via CLI; documentation polish Repository, tutorial, and demo reproducible by a third party from a clean checkout

Four weeks solo. Conservative by design: explicitly avoids scope I cannot defend within Spark’s timeline (web app, wallet integration, public launch event).

7. Funding requirements / 所需资金与资金分配明细

Total request: $1,704.

Item Hours / cost Subtotal
Lock script (week 1–2): args parsing, cell-dep vkey lookup, witness decode, integration with verifier-core, unit + integration tests 70h × $12/hr $840
Testnet deployment + CLI (week 3): deploy to Pudge, lock/unlock subcommands, first successful on-chain unlock tx 42h × $12/hr $504
Reference circuit + demo + docs (week 4): Poseidon-preimage Circom circuit, snarkjs proof pipeline, tutorial markdown + short architecture reference 30h × $12/hr $360
Total 142h $1,704

Payment cadence per Spark norms: 20% upfront at project start, 80% drawn at weekly sync meetings based on demonstrated progress.

8. Deliverables and verification methods / 交付物与验证方式

Deliverable How to verify
zk-Lock script source code Public GitHub repo; cargo build --release produces riscv64imac binary; cargo test passes
Deployed lock script on Pudge testnet Cell OutPoint published in README; explorer link
Working end-to-end unlock Testnet transaction hash showing a cell unlocked by a valid Groth16 proof
Reference Circom circuit (Poseidon preimage) .circom source + snarkjs build script; reproducible vkey hash
CLI tool cargo install-able; --help documents lock and unlock subcommands
Tutorial Markdown in repo: “How to lock a cell behind your own Circom circuit”; a third party can follow it from clean checkout to a successful testnet unlock

Documentation scope: repository markdown only (README.md, tutorial, short architecture reference, CLI --help). No hosted docs site within this grant; a public-facing docs site is out of scope for this milestone.

9. Current state vs funded scope / 当前状态 vs. 资助范围

Already shipped (not funded by this grant):

  • Groth16/BN254 verifier on CKB-VM (groth16-ckb), confirmed on Pudge testnet 2026-05-15. Experimental and not yet audited.

Funded by this grant:

  • The lock-script layer that wraps the verifier as a reusable primitive.
  • CLI tooling to make the primitive usable from a terminal.
  • Reference circuit + tutorial demonstrating end-to-end use.
  • Testnet deployment of the lock script itself.

Explicitly out of scope for this grant:

  • Web app with wallet integration.
  • Public treasure hunt launch event.
  • Mainnet deployment (audit-gated; pending Phase 4 hardening of the verifier).

10. CKB ecosystem alignment / CKB 生态契合度

  • Complements existing team’s work. The SP1 verifier (XuJiandong’s team) is for complex computation; zk-Lock is for simple circuits. Both are valid, complementary use cases of zk on CKB.
  • Builds on what is already shipped. The Groth16 verifier becomes the load-bearing piece of an ecosystem primitive rather than an orphan demo.
  • Unlocks new application categories. Sealed-bid auctions, private claims, conditional escrow, and anonymous airdrops all reduce to “lock a cell behind a circuit” once the primitive exists.
  • Demonstrates the cell model and Web5 composability. Single-purpose lock + composition via wrappers and type scripts is idiomatic CKB design and aligned with the Web5 emphasis on small composable primitives layered organically rather than monolithic vertical stacks. The worked demo is intended as a reference for how to compose zk primitives in the cell model.

Risks and mitigations / 风险与缓解措施

Risk Mitigation
Verifier cycle cost is ~102M per verification (~2.9% of a block budget), limiting how many unlocks fit per block Cost is empirically measured and acceptable for the treasure-hunt-style workloads this Spark milestone targets. Optimization (precomputed pairing tables, batched verification) is deferred to a separate effort.
Mainnet deployment of the verifier is audit-gated; this grant cannot deliver mainnet artifacts Scope is explicitly testnet only (Pudge). Mainnet readiness is a separate future effort after audit and out of scope here.
groth16-ckb lives in a nested Cargo workspace; the git dependency may need a fallback to a local clone if Cargo resolution edge-cases bite Tested in week 1. Fallback (local-path dep) is documented in the README.
Tutorial reproducibility depends on Circom and snarkjs versions, which evolve Tutorial pins exact versions; CI verifies the recipe still produces the same vkey hash at each commit.

Out of scope (explicit) / 明确不在范围内

To keep evaluation crisp, this grant does not cover: web app, wallet integration, browser-side proof generation UI, mainnet deployment, public launch event with real CKB, or audit. Those are deliberately deferred to keep the Spark milestone focused on the testnet primitive.

12 Likes

Hi @Mulandi_Cecilia 您的申请之前不知道是因为什么原因,没有被我们的格式筛选识别,进而没有进入每周的评审会,后来又因为论坛改版的AI移到了Archive区域

目前已经引动到Spark的子区,会尽快进入评审,感谢您的理解

3 Likes

Hi @Mulandi_Cecilia,

Thank you for your interest in the Spark Program and for submitting the zk-Lock for CKB proposal.

After review by the Spark Program committee, your proposal has been assigned a status of Pending. This is not a rejection, but an invitation to revise.

The committee recognizes the value of your project idea. The zk-Lock primitive is a meaningful piece of infrastructure for the CKB ecosystem, and we appreciate the rigorous technical background you bring from the CKB Builders Program.

Main Revision Recommendations:

  • Budget Adjustment:
    The committee has no objections to the project’s objectives and methodology, but the proposed $1704 budget does not align with the usual funding conventions for pure technical projects under the Spark Program, and no reasonable justification was provided for the excess. After careful consideration, the committee has agreed to provide funding of $900 for the project.

If your team is willing to accept the grant, please revise and resubmit according to the feedback above.
We will arrange a new round of review as soon as possible.

Best,
xingtian
On behalf of the Spark Program Committee

Revised proposal (v2), accepting committee’s $900 revision

Hi @xingtianchunyan,

Thank you for the committee’s review. I accept the revised funding of $900 and have updated Section 7 (Funding requirements) accordingly. The project scope, deliverables, and weekly execution plan remain unchanged from the original proposal, per the committee’s confirmation that they had no objections to the objectives and methodology.

Resubmitting for the next review round.

1. Project overview and positioning / 项目概述与定位

zk-Lock is a reusable CKB lock script that conditions cell spending on a valid Groth16 proof. Any developer can write a Circom circuit, commit to its verifying key, and lock CKB cells behind it; to spend the cell, the spender submits a proof that satisfies the circuit.

The primitive is the integration layer that turns the existing on-chain Groth16 verifier into something developers can build with. The Spark-funded scope is the minimal primitive (lock script, CLI, deployed testnet artifact, and tutorial) sufficient for a developer to lock a cell behind their own circuit and unlock it end-to-end. Consumer-facing applications (web app, treasure hunt launch event) are out of scope for this grant.

2. Team profile / 团队简介

Name: Cecilia Mulandi

GitHub: CECILIA-MULANDI

Role: Solo developer; current participant in the CKB Builders Program (completed 12 weeks)

Contact: [email protected], Telegram @ceciliamulandi

Relevant prior work:

3. Project background and problem statement / 项目背景与问题陈述

CKB has a working on-chain Groth16 verifier (load-bearing prior work, already shipped). What is missing is the integration layer that lets developers actually use it: there is no standard way to lock a cell behind a circuit, no convention for binding cells to specific public inputs, no tooling for a developer to go from “I have a Circom circuit” to “I have CKB locked behind it.”

The result is that zk on CKB is currently reachable only by developers who can wire together the verifier crate, lock-script scaffolding, witness encoding, and tx construction themselves. Each new use case repeats this work. The primitive does not exist as ecosystem infrastructure.

4. Solution approach / 解决方案

A single-purpose CKB lock script with one spend path: the cell unlocks iff a valid Groth16 proof matches the committed verifying key and public inputs.

Four design choices, settled during pre-proposal research:

  • vkey storage: 32-byte vk_hash in lock.args; the full verifying key lives in a shared cell_dep referenced by data_hash. Mirrors the secp256k1 system-script pattern (small commitment in args, shared data cell), so many cells can reuse one vkey cell instead of each carrying full vkey bytes.
  • Public-input binding: lock.args also carries a 32-byte public_inputs_commitment. The cell is bound to specific public inputs, not just to the circuit, which is what makes zk-Lock a primitive rather than a generic verifier wrapper.
  • Minimal lock, compose for the rest: no refund branch, no creator pubkey, no deadline. Applications that need refund or settlement (treasure hunt, auctions, escrow) layer them on via a wrapping lock or a type script. Keeps the audit surface tight and the primitive usable for sealed-bid auctions, private claims, conditional escrow, and anonymous airdrops without favouring any one of them.
  • Claimer-binding convention: circuit authors include the claimer’s lock-script hash as a public input, so a proof copied from a pending transaction cannot be redirected to another address. Enforced implicitly via public_inputs_commitment; templated in the docs and CLI.

5. Technical architecture / 技术架构

Locked cell
  lock.code_hash:  <zk-Lock script hash>
  lock.args:       vk_hash (32B) || public_inputs_commitment (32B)   = 64 bytes

Cell deps (referenced by the unlock tx)
  zk-Lock script cell                  (the code)
  vkey cell                            (data = serialized vkey; referenced by data_hash)

Witness (unlock tx)
  witness.lock:    proof || public_inputs

Script logic (built on top of the existing verifier-core crate):

  1. Read (vk_hash, public_inputs_commitment) from lock.args.
  2. Scan cell_deps; find the dep whose blake2b(data) == vk_hash. Fail if none, fail if duplicate.
  3. Read (proof, public_inputs) from witness.lock.
  4. Check hash(public_inputs) == public_inputs_commitment.
  5. Call into groth16-ckb verifier with (vk, proof, public_inputs).
  6. Return success only if all checks pass.

Off-chain pipeline:

Circom circuit  →  snarkjs proof  →  CCC SDK  →  CKB

All off-chain tooling is mature (Circom, snarkjs, CCC). All on-chain logic reuses infrastructure already shipped (groth16-ckb verifier, CKB-VM).

6. Weekly execution plan / 执行计划

Week Focus Concrete output
1 Lock script architecture; integrate groth16-ckb verifier as a lock Workspace skeleton compiles; stub lock script reads args
2 Cell-dep vkey loading; witness parsing; end-to-end test against a known-good fixture All-paths unit + integration tests pass locally
3 Deploy to CKB Pudge testnet; minimal CLI for lock/unlock; tutorial draft Testnet tx hash demonstrating a successful unlock
4 Reference Circom circuit (Poseidon hash preimage); worked end-to-end demo via CLI; documentation polish Repository, tutorial, and demo reproducible by a third party from a clean checkout

Four weeks solo. Conservative by design: explicitly avoids scope I cannot defend within Spark’s timeline (web app, wallet integration, public launch event).

7. Funding requirements / 所需资金与资金分配明细

Total request: $900 (accepting the committee’s revised figure).

Milestone-based, tied to the deliverables in Section 8:

Milestone Deliverable gate Payment
M1: Lock script core (end of week 2) Args parsing, cell-dep vkey lookup, witness decode, integration with groth16-ckb verifier; unit + integration tests pass locally $360
M2: Testnet deployment + CLI (end of week 3) Lock script deployed to Pudge; lock / unlock CLI subcommands; first successful on-chain unlock tx (hash published) $300
M3: Reference circuit + tutorial (end of week 4) Poseidon-preimage Circom circuit reproducible from clean checkout; end-to-end tutorial verified by a third party from circom → snarkjs → CKB unlock $240
Total $900

Payment cadence per Spark norms: 20% upfront ($180) at project start, remainder drawn at weekly sync meetings against the milestone gates above.

8. Deliverables and verification methods / 交付物与验证方式

Deliverable How to verify
zk-Lock script source code Public GitHub repo; cargo build --release produces riscv64imac binary; cargo test passes
Deployed lock script on Pudge testnet Cell OutPoint published in README; explorer link
Working end-to-end unlock Testnet transaction hash showing a cell unlocked by a valid Groth16 proof
Reference Circom circuit (Poseidon preimage) .circom source + snarkjs build script; reproducible vkey hash
CLI tool cargo install-able; --help documents lock and unlock subcommands
Tutorial Markdown in repo: “How to lock a cell behind your own Circom circuit”; a third party can follow it from clean checkout to a successful testnet unlock

Documentation scope: repository markdown only (README.md, tutorial, short architecture reference, CLI --help). No hosted docs site within this grant; a public-facing docs site is out of scope for this milestone.

9. Current state vs funded scope / 当前状态 vs. 资助范围

Already shipped (not funded by this grant):

  • Groth16/BN254 verifier on CKB-VM (groth16-ckb), confirmed on Pudge testnet 2026-05-15. Experimental and not yet audited.

Funded by this grant:

  • The lock-script layer that wraps the verifier as a reusable primitive.
  • CLI tooling to make the primitive usable from a terminal.
  • Reference circuit + tutorial demonstrating end-to-end use.
  • Testnet deployment of the lock script itself.

Explicitly out of scope for this grant:

  • Web app with wallet integration.
  • Public treasure hunt launch event.
  • Mainnet deployment (audit-gated; pending Phase 4 hardening of the verifier).

10. CKB ecosystem alignment / CKB 生态契合度

  • Complements existing team’s work. The SP1 verifier (XuJiandong’s team) is for complex computation; zk-Lock is for simple circuits. Both are valid, complementary use cases of zk on CKB.
  • Builds on what is already shipped. The Groth16 verifier becomes the load-bearing piece of an ecosystem primitive rather than an orphan demo.
  • Unlocks new application categories. Sealed-bid auctions, private claims, conditional escrow, and anonymous airdrops all reduce to “lock a cell behind a circuit” once the primitive exists.
  • Demonstrates the cell model and Web5 composability. Single-purpose lock + composition via wrappers and type scripts is idiomatic CKB design and aligned with the Web5 emphasis on small composable primitives layered organically rather than monolithic vertical stacks. The worked demo is intended as a reference for how to compose zk primitives in the cell model.

Risks and mitigations / 风险与缓解措施

Risk Mitigation
Verifier cycle cost is ~102M per verification (~2.9% of a block budget), limiting how many unlocks fit per block Cost is empirically measured and acceptable for the treasure-hunt-style workloads this Spark milestone targets. Optimization (precomputed pairing tables, batched verification) is deferred to a separate effort.
Mainnet deployment of the verifier is audit-gated; this grant cannot deliver mainnet artifacts Scope is explicitly testnet only (Pudge). Mainnet readiness is a separate future effort after audit and out of scope here.
groth16-ckb lives in a nested Cargo workspace; the git dependency may need a fallback to a local clone if Cargo resolution edge-cases bite Tested in week 1. Fallback (local-path dep) is documented in the README.
Tutorial reproducibility depends on Circom and snarkjs versions, which evolve Tutorial pins exact versions; CI verifies the recipe still produces the same vkey hash at each commit.

Out of scope (explicit) / 明确不在范围内

To keep evaluation crisp, this grant does not cover: web app, wallet integration, browser-side proof generation UI, mainnet deployment, public launch event with real CKB, or audit. Those are deliberately deferred to keep the Spark milestone focused on the testnet primitive.

7 Likes

Hi @Mulandi_Cecilia The committee has reviewed your revised proposal and decided to approve zk-Lock for CKB. We recognize the project’s potential to deliver a reusable Groth16 lock script and developer toolchain, creating a standardized integration layer for zero-knowledge applications on CKB.

Based on the agreed $900 budget and the current CKB price of $0.00083, the grant amount is 1,084,338 CKB. Please reply to this thread with your CKB payout address, email address, and Discord handle to facilitate grant distribution and team communications. We also invite you to participate in our upcoming Ecosystem Monthly Call to share progress.

Best,
Hongzhou
On behalf of Spark committee
cc @Hanssen @yixiu.ckbfans.bit @xingtianchunyan

2 Likes

Hello @zz_tovarishch ,

Thank you for the approval.

CKB payout address: ckb1qyqvg82lj877guytl3g9dqccrzzuhtmp2a4qg8yq7z
Email address: [email protected]
Discord handle: cec3026

Kind regards,
Cecilia Mulandi

1 Like

初始支付 20% 216,868CKB

https://explorer.nervos.org/en/transaction/0x60a5b52445e856d3f74a3cda21378e8880bcbd919296ea8c1b2dec618b336c1f

1 Like

Hello @zz_tovarishch,

Confirmed receipt. Thank you.

4 Likes

Hi @Mulandi_Cecilia ,

We noticed that the first update for the zk-lock project has still not been released, so we are reaching out to check on the latest developments.

First, I hope you and your team are doing well. Please take good care of your health and maintain a balance between work and rest.

From the project’s perspective, we are eager to understand the current progress—whether it is advancing smoothly, encountering any obstacles, or what the overall status is. Even a brief update can help the committee and the community stay informed and provide support when needed.

Please share the latest status at your earliest convenience. If there are any difficulties affecting progress, please do not hesitate to let us know—the committee is willing to provide every assistance.

We look forward to your reply.

Best,
xingtian

2 Likes

Hello @xingtianchunyan,

Thank you for checking in and my apologies for the delay. Today marks the end of week 2 and I have closed M1 smoothly.

M1 deliverable gate: args parsing, cell-dep vkey lookup, witness decode, integration with the Groth16 verifier from my prior groth16-ckb work which I pulled into this repo as verifier-core crate have fully been implemented and tested locally.

The lock script is located at contracts/zk-lock and it:

  • Validates the 64-byte lock args (vk_hash(32B) || pi_commitment(32B)).
  • Looks up the verifying key by scanning cell deps for a cell whose data hash matches vk_hash, mirroring the shared-vkey pattern from the proposal.
  • Parses the witness lock as proof (128) || pi_count (u32 LE) || public_inputs (pi_count × 32) and rejects malformed framing with specific error codes.
  • Recomputes blake2b_256(public_inputs) and checks it against the pi_commitment bound into the args.
  • Delegates final Groth16 verification to verifier-core.

Here is the github repo for reference: zk-Lock.

I am now moving on to M2 and should have an update posted here next week.

Thanks again.

Kind regards,
Cecilia Mulandi

3 Likes

Hello @xingtianchunyan,

I have closed M2 successfully. M2 delivery gate:

  • Lock script deployed to Pudge testnet
  • CLI lock and unlock subcommands implemented
  • First successful on-chain unlock transaction

Here are the tx hashes:

I am moving on to M3 and should have an update posted here next week too.

Kind regards,
Cecilia Mulandi

3 Likes

Hi @Mulandi_Cecilia ,

You have delivered the weekly reports on time for two consecutive weeks—your consistency is excellent. Keep it up!

Best,
xingtian

1 Like

Hi @Mulandi_Cecilia ,

We hope everything goes smoothly with the work for the third milestone of the ZK-Lock project!

If your progress has slowed down, you can share some of your work results to help the community and committee understand your progress.

Of course, you can also share the challenges you encountered along the way, as well as your experiences facing setbacks and learning to overcome them. Failure is the mother of success, and these experiences of setbacks are equally important to the community.

Best,
xingtian

1 Like

Hello @xingtianchunyan,

Thank you for checking in. I did close the majority but not all of M3 yesterday.
Two things remain:

  • The third-party tester run, I finished a bit late into the night, but I will do a cold reach out to one community member today
  • CI deliverable has not been met, I am having some payment issues that I will be sorting before the end of today but in case it does not go to plan I will ping you here

M3 delivery gate (new since M2)

  • TypeScript SDK at sdk/ts/, covering the off-chain surface: encodeVerifyingKey, encodeProof, encodePublicInputs, hashVk, hashPi, deployVk, lock, unlock. Built on CCC.
  • Rust CLI extended with the snarkjs encoding pipeline and an offline sanity check: encode-vk, encode-proof, encode-pi, verify. The CLI now goes from snarkjs artifacts to an unlocked cell without any external tool.
  • Reproducible Circom circuit at circuits/poseidon-preimage/. build.sh pins the ptau file by blake2b-512 hash and the toolchain via package-lock.json, so any user reproduces the same vk.
  • End-to-end tutorial at docs/tutorial.md, walking from the circuit through snarkjs setup, encoding, deployment, locking, and unlocking on Pudge. The TypeScript SDK path and the Rust CLI path are documented in parallel so the reader picks their preferred stack.
  • CI workflow that pins the circuit’s vk_hash on every push and PR, as per the risks table in the proposal.

Fresh Pudge testnet run

Tutorial run against the Poseidon-preimage circuit using the current SDK:

Step Transaction
vk deploy 0x6c72cc8ad1746aa1a8bc86483cda5a579a9490241011ddaac38b400ff670a2e6
lock 0xfa4d3f1d5a67ea93aaadbd360a28e76794fcd207d05354e07c60c934f0265ef0
unlock 0x7cc857323e8d41668378ea95c6f0abdbc9f84697ce11b63ae8e18f1529264d65

A few setbacks and learnings I have had so far

Scope extension. In the proposal I originally scoped the tutorial around the TypeScript CCC path. Partway through, I realised a Rust developer coming to the repo via the CLI would still have to reach for a separate tool to encode snarkjs artifacts, which I thought would be a terrible developer experience for my fellow rust devs. So, I extended the scope a bit to build the same encoder natively in Rust and round-trip verified that both produce byte-identical output. It cost extra time, but the CLI path is now self-contained.

CI run pending. The vk_hash workflow is committed and pushed, but its first run has not completed because my GitHub account is in a stuck billing verification state (zero owed, but an authorization hold has not cleared). I have a support ticket open and will post the green run confirmation here once resolved. The workflow itself is reviewable in the repo now.

Here is the repo for reference: zk-Lock

Kind regards,
Cecilia Mulandi

1 Like

Hi @Mulandi_Cecilia ,

Glad to see your update, an applaud your persistence and hard work!

But I still have to suggest that you try to avoid staying up late as much as possible—taking good care of your health is the most important thing~~

Best,
xingtian

1 Like

Hello @xingtianchunyan,

Look who is taking the “no late nights” advice seriously today :).

An update on fully closing M3

I have resolved and wrapped up what was remaining when I last gave an update.

CI: the GitHub billing hold cleared. circuit-vk-hash now runs on every push and PR against both circuits, pinning:

  • poseidon-preimage (tutorial): 0x1f0424a56478f21e3890d5101ead7c3c4eaee7394dae31ed56c15e965fe82fa7
  • poseidon-preimage-bound: 0xaed87acbbd9f9e4b87bf10e910b98508b58013823a5ae86637b4d32e1e0295bf

I reached out to a few people to test and we got some feedback, credits to @truthixify who walked through the tutorial end-to-end and gave very valuable feedback.

Beyond proposal scope

The approved proposal covered the generic zk-lock only. While reviewing that script, @truthixify pointed out that it is exposed to mempool witness-copy and recipient-redirect attacks whenever a proof’s public inputs don’t bind to state that the transaction actually reads. I thought the suggestion was worth acting on, so I built a transaction-binding sibling script, zk-lock-bound. It reserves the first public input for a scalar derived from the input outpoint and the first output, then constrains that scalar on chain during verification.

Since this sits outside the original proposal, I’d love the committee to look at the PR and decide whether it belongs in the main repo: feat: adding zk-lock-bound transaction-binding script by CECILIA-MULANDI · Pull Request #4 · CECILIA-MULANDI/zk-Lock · GitHub

Both variants are deployed on Pudge with reference lock/unlock transactions listed in the README:

  • Generic contract cell: 0x7d80c7a2781328cc766497f9d67b036a4d1295bda9f1de0d329bf08afd0e06fb:0
  • Bound contract cell: 0x9cf1e0a6ecc8eeb2705a894a828c07898e77a68a0b9d42b4ff8953bd7c569f5f:0

The repo: GitHub - CECILIA-MULANDI/zk-Lock: Reusable CKB lock script that conditions cell spending on a valid Groth16 proof. · GitHub

Kind regards,
Cecilia Mulandi

3 Likes

Hi @Mulandi_Cecilia ,

Thank you for your patience (not staying up late is the right choice, haha). The committee is still reviewing the final project closure deliverables for zk-lock.

Regarding the current situation, the committee would like to express its clear position:

  1. Regarding the out-of-scope aspects, we encourage the team to continue exploring and expanding the boundaries of zero-knowledge primitives within the CKB ecosystem.
  2. Regarding your request that the committee review the PR and decide whether to merge it into the main repository, the committee will remain completely neutral and will not express any opinion. The committee fully respects the applicant’s absolute autonomy in managing the repository and will not comment on any potential merging or integration of zk-Lock or other projects into the repository.
  3. Our core vision is to ensure that zk-Lock leaves a long-term and accessible path for broader participation in the CKB community. We hope the team can preserve the valuable experience and accumulated insights from this process for community developers to learn from and build upon, rather than confirming the deliverables solely through AI-generated workflow assessments or committee-level validation.

We appreciate the effort you have put into expanding the CKB cryptographic toolkit.

Best,
Xingtian
On behalf of the Spark Program Committee

1 Like

你好,@Mulandi_Cecilia:

我在上一周的沟通中可能表达不够明确。委员会很认可你打下的坚实工程基础,但以项目目前的形式来看,尚未完全达到 Spark Program 的结项标准。具体而言,我们认为,在将项目视为完成之前,应该为社区开放更多的参与机会。

我们理解,作为一名独立开发者,您的时间有限,也由衷感谢您迄今为止付出的努力。提出这些建议是为了帮助项目在生态中留下深远影响,而非增加不必要的负担。如果有任何影响进度的困难,请随时告知我们——委员会愿意提供一切协助。

请您方便时尽早分享最新进展。期待您的回复。

此致
xingtian
On behalf of the Spark Program Committee

cc: @zz_tovarishch , @yixiu.ckbfans.bit , @Hanssen

gm gm @xingtianchunyan and the committee,

Thank you for being direct. I think I had read the previous post and interpreted it narrowly. First, I have merged PR #4, so zk-lock-bound is now part of the main codebase. I believe it gives the project a rounder feel and also extends the use cases for teams that want to use zk-Lock. Second, I have added licenses and a contribution guideline so that others can open issues and contribute to the project independently. Third, CI now runs the build and the full test suite on every push and pull request, not just the circuit vk_hash pin I mentioned earlier, so a contributor finds out whether their change is sound without waiting on me.

The project was posted in the CKBuilders TG group and I also did DM a few builders that had interacted with the groth16 verifier to get their feedback on this project, and we received feedback. One piece came from @truthixify, which was addressed in PR #4. Another came from @ArthurZhang, who assessed M1 and tagged the project. He also went through the project after we delivered M3 and gave feedback on the flow and clarity of the tutorial, which was addressed. @OWK50GA also went through the tutorial, and we had a discussion on some design choices, specifically why witness.lock is a flat positional layout rather than Molecule.

That discussion and the reasoning behind the design choices are now documented in docs/encoding-rationale.md, including a few open questions I would rather not settle on my own. Anyone is welcome to open an issue on those, or on anything else in the repo, whether it is a bug or just a discussion.

My immediate next moves are outward rather than inward: supporting the people building on this work, and on the verifier it sits on

Kind regards,
Cecilia Mulandi

2 Likes