zkDeal engineering · Technology Brief
More than a transaction, less than a chain
Trace an accepted zkDeal room checkpoint from the running system record to its Blockscout receipt and human-readable L1 transaction page.
CORE MODEL
zkdeal: more than a transaction, less than a chain
A guide to zkdeal's room model, capital path and relationship to the proving stacks used by ZK-based Ethereum L2s
Thesis: Most L2s prove a continuing shared chain. zkdeal proves one bounded room. An application chooses an allowed room profile; zkdeal binds that profile at room opening and proves each accepted checkpoint against it. The difference is lifecycle and settlement design, not a new cryptographic primitive.
Explore the architecture
Room anatomy: the app chooses; zkDeal pins and proves
Drag the canvas to pan, use the wheel or pinch gesture to zoom, and use the controls to zoom or fit the whole model. Expand for a page-sized view; press Escape to close it.
View the static reference image

Read the figure transcript
Room anatomy. The application chooses an allowed authorization mode, data route, lifecycle, proof template, participants, assets, clocks and application policy. zkdeal binds those choices when the room opens and verifies each accepted checkpoint against them. On the L1-funded validity path, consumed deposits credit their named beneficiaries before application execution and every room binds an exit route. The timing hierarchy is signed intent, room block, batch, accepted L1 checkpoint and Ethereum finality.
The five-stage time ladder and core vocabulary
Room: A room is an isolated EVM workflow with its own policy, assets, membership state and proof program. It has a deliberate close instead of running as one shared, always-on chain.
Settlement sequence: A signed intent enters a room block, and room blocks form a batch. The proof and journal turn that batch into an accepted L1 checkpoint. Ethereum finality makes the checkpoint canonical; until then, the room result remains provisional.
| Term | Plain meaning | Term | Plain meaning |
|---|---|---|---|
| Intent | A participant-authorized room transaction or application commitment. | Room block | A local EVM block; it is not an Ethereum block. |
| Batch | A proved sequence of room blocks; current hosted progress uses 2–4 room blocks. | Checkpoint | A proof-backed journal accepted by the L1 RoomManager. |
| Journal | A compact commitment to roots, data, cursors, liabilities, withdrawal leaves and close—not a readable event log. | Proof program | The RISC Zero guest/STF that re-executes the batch under the pinned policy. |
| Forced inbox | An L1 request that must be included, revert, receive a proved rejection, or halt room progress after its deadline. | RoomVault | L1 escrow with balances and liabilities segregated per room and asset. |
| Exit binding | A required validity-only policy component that pins how proved state becomes withdrawal leaves. | Terminal batch | A recovery-only final proof on deployment rails that support recovery close; the Stage-oriented validity rail exits through ordinary proof-bearing batches. |
Authorization, membership and checkpoint rhythm
Joint-consent rail: An application may choose unanimous approvers for a small jointly controlled room. Every active approver signs the same checkpoint journal, and participants keep the replay data. This is a deliberate consent-room option rather than the standard rollup Stage path.
Stage-oriented validity rail: An application may choose validity-only settlement with Ethereum calldata. Customers sign room transactions; the bound proof checks input and execution, while exact genesis data, deposits and forced inputs remain reconstructable from L1. The rollup-oriented deployment enforces this combination for every room it admits.
One-shot, rolling and sparse: A one-shot room closes at its first checkpoint; a rolling room checkpoints repeatedly; a sparse room waits longer. Sparse timing can amortize per-checkpoint submission overhead, but it also extends the rollback and operator-dependency window.
What the proof establishes—and what it does not
| Enforced after the validity rail is selected | Chosen by the application or deployment |
|---|---|
| Validity-proof authorization, exact-genesis binding, deterministic execution, state continuity, Ethereum-data binding and liability conservation. L1-funded validity rooms also enforce beneficiary credit and a room-bound route from proved state to L1 claims. | The application selects admission clocks, ordering and clearing, visibility, participant capacity, assets, confirmations and exit allocation from the deployment's allowed templates. Governance and the outer settlement profile belong to the deployment. |
Where the architecture is useful
Best fit: Choose a room when a high-value workflow has a clear beginning and end—for example, a deal, auction, game, fund episode or controlled settlement—and needs its own provable market rule and room-scoped L1 accounting.
Complementary fit: A persistent L2 remains the natural home for always-on composability, shared liquidity and broad wallet, RPC and indexer support. zkdeal can handle a bounded episode that begins in, returns to or coordinates with that wider market.
Use a continuing chain when: the application needs unrestricted contracts, permissionless entry, live cross-application composability or sustained chain-wide throughput during the episode. The eight-room recursive limit applies to one aggregate receipt; it is not a concurrency limit.
Motivational example
A proof claim should end at a transaction you can inspect
“The checkpoint was proved” is a useful internal log line. It is not yet a useful answer for a user. The answer becomes concrete when you can name the Ethereum transaction, open it in an explorer, inspect its receipt, and connect it back to the room that produced it.
That path also explains the room model better than a new vocabulary diagram. The application runs several policy-bound actions. The room produces a checkpoint. Ethereum accepts the canonical result. The room can then continue or close according to its profile. Every claim in that sentence has a different piece of evidence.
- Read the accepted checkpoint transaction hash from the running system.
- Open the same hash through the local Blockscout API and transaction page.
- Match receipt status, block number, and room evidence before calling the checkpoint settled.
Demo / use it today
See an accepted checkpoint in the block explorer
Continue from the successful local enclave and its preserved startup-acceptance artifact. Validate that artifact first, then bind its finalized L1 transaction and canonical block hash to Blockscout’s indexed transaction and block records.
Before you start
- A Bash-compatible shell: Linux, macOS, or WSL on Windows. The copyable commands use POSIX shell syntax.
- The complete local Kurtosis enclave from this series, with at least one accepted checkpoint.
- curl and jq.
- The local coordinator and explorer ports printed by Kurtosis; no public-network credentials are required.
Gate the evidence before reading the hash
Download the enclave’s acceptance artifact into a private temporary directory and run the official validator without printing the artifact. Require a full transaction hash, manager address, finalized status, block number, and canonical block hash.
Ask the explorer for the same transaction
Use Blockscout’s transaction API to require the same hash, successful status, RoomManager destination, and block number. Then use its block API to require the same canonical block hash.
Open the human-readable evidence
Print the transaction page URL last. The public transcript uses placeholders and shows only verification booleans; the raw evidence and API responses remain private because they include run-specific identity and calldata.
Name the preserved enclave
ENCLAVE=zkdeal-publicDownload the evidence into a private temporary directory
umask 077 && EVIDENCE_DIR="$(mktemp -d)" && \
kurtosis files download "$ENCLAVE" zkdeal-v5-kurtosis-evidence "$EVIDENCE_DIR" >/dev/null && \
EVIDENCE="$(find "$EVIDENCE_DIR" -name v5-kurtosis-evidence.json -print -quit)" && test -n "$EVIDENCE"Run the official evidence validator from the pinned image
CONTROL_IMAGE=docker.io/zkdeal/coordinator:20260827-shopfinal-faa4149@sha256:fd6a3f687b2b09e3df1336f0318804b339d12fa9d53e0a5ed9d6796bd047ec05 && \
docker run --rm --mount "type=bind,src=$EVIDENCE,dst=/evidence.json,readonly" \
--entrypoint /bin/sh "$CONTROL_IMAGE" -c \
'cd /app/kurtosis-testing && pnpm --filter @zkdeal/bench validate /evidence.json >/dev/null'Read only a sanitized proof and settlement summary
docker run --rm --mount "type=bind,src=$EVIDENCE,dst=/evidence.json,readonly" \
--entrypoint node "$CONTROL_IMAGE" -e \
'const e=JSON.parse(require("fs").readFileSync(process.argv[1]));const full64=(v)=>typeof v==="string"&&/^0x[0-9a-fA-F]{64}$/.test(v);const full40=(v)=>typeof v==="string"&&/^0x[0-9a-fA-F]{40}$/.test(v);const c=e.transactions.submitCanonicity;const out={decision:e.decision,imageIdPresent:typeof e.imageId==="string"&&e.imageId.length>0,journalHashComplete:full64(e.journalHash),transactionComplete:full64(e.transactions.submit),managerComplete:full40(e.contracts.manager),finality:c.status,blockHashComplete:full64(c.blockHash)};if(out.decision!=="VERIFIED"||!out.imageIdPresent||!out.journalHashComplete||!out.transactionComplete||!out.managerComplete||out.finality!=="FINALIZED"||!out.blockHashComplete)process.exit(1);console.log(JSON.stringify(out))' \
/evidence.jsonExpected output shape
{"decision":"VERIFIED","imageIdPresent":true,"journalHashComplete":true,"transactionComplete":true,"managerComplete":true,"finality":"FINALIZED","blockHashComplete":true}Read the exact transaction, canonical block, and explorer endpoint
export TX="$(jq -r .transactions.submit "$EVIDENCE")" \
BLOCK="$(jq -r .transactions.submitBlock "$EVIDENCE")" \
BLOCK_HASH="$(jq -r .transactions.submitCanonicity.blockHash "$EVIDENCE")" \
MANAGER="$(jq -r .contracts.manager "$EVIDENCE")" && \
EXPLORER="$(kurtosis port print "$ENCLAVE" explorer http --format ip,number)" && \
export BLOCK_HASH MANAGER EXPLORERMatch the exact checkpoint transaction in Blockscout
curl -fsS "http://$EXPLORER/api/v2/transactions/$TX" | jq -e -c \
'{indexed:(.hash==env.TX),success:((.status|ascii_downcase)=="ok"),managerMatches:(((.to.hash // .to)|ascii_downcase)==(env.MANAGER|ascii_downcase)),blockMatches:((.block_number|tostring)==env.BLOCK)} | \
select(.indexed and .success and .managerMatches and .blockMatches)'Expected output shape
{"indexed":true,"success":true,"managerMatches":true,"blockMatches":true}Match the checkpoint's canonical block hash
curl -fsS "http://$EXPLORER/api/v2/blocks/$BLOCK" | jq -e -c \
'{indexed:((.height|tostring)==env.BLOCK),hashMatches:((.hash|ascii_downcase)==(env.BLOCK_HASH|ascii_downcase))} | \
select(.indexed and .hashMatches)'Expected output shape
{"indexed":true,"hashMatches":true}Print the human-readable transaction page
node -e "console.log('http://' + process.env.EXPLORER + '/tx/' + process.env.TX)"Expected output shape
http://127.0.0.1:3200/tx/<accepted-checkpoint-transaction>Remove the temporary evidence copy
rm -r -- "$EVIDENCE_DIR" && \
unset EVIDENCE_DIR EVIDENCE TX BLOCK BLOCK_HASH MANAGER EXPLORER CONTROL_IMAGEWhat this gives you: In the validated B200 run, the official evidence validator passed and the zkDeal system record, Blockscout transaction response, canonical block response, and transaction page all agreed on the same finalized L1 checkpoint.
Interactive validated I/O
Trace an accepted checkpoint into Blockscout
Select text directly in the player, pause at any point, or copy the complete transcript below.
Copy or read the complete transcript
$ ENCLAVE=zkdeal-public
$ umask 077 && EVIDENCE_DIR="$(mktemp -d)" && \
> kurtosis files download "$ENCLAVE" zkdeal-v5-kurtosis-evidence "$EVIDENCE_DIR" >/dev/null && \
> EVIDENCE="$(find "$EVIDENCE_DIR" -name v5-kurtosis-evidence.json -print -quit)" && test -n "$EVIDENCE"
$ CONTROL_IMAGE=docker.io/zkdeal/coordinator:20260827-shopfinal-faa4149@sha256:fd6a3f687b2b09e3df1336f0318804b339d12fa9d53e0a5ed9d6796bd047ec05 && \
> docker run --rm --mount "type=bind,src=$EVIDENCE,dst=/evidence.json,readonly" \
> --entrypoint /bin/sh "$CONTROL_IMAGE" -c \
> 'cd /app/kurtosis-testing && pnpm --filter @zkdeal/bench validate /evidence.json >/dev/null'
$ docker run --rm --mount "type=bind,src=$EVIDENCE,dst=/evidence.json,readonly" \
> --entrypoint node "$CONTROL_IMAGE" -e \
> 'const e=JSON.parse(require("fs").readFileSync(process.argv[1]));const full64=(v)=>typeof v==="string"&&/^0x[0-9a-fA-F]{64}$/.test(v);const full40=(v)=>typeof v==="string"&&/^0x[0-9a-fA-F]{40}$/.test(v);const c=e.transactions.submitCanonicity;const out={decision:e.decision,imageIdPresent:typeof e.imageId==="string"&&e.imageId.length>0,journalHashComplete:full64(e.journalHash),transactionComplete:full64(e.transactions.submit),managerComplete:full40(e.contracts.manager),finality:c.status,blockHashComplete:full64(c.blockHash)};if(out.decision!=="VERIFIED"||!out.imageIdPresent||!out.journalHashComplete||!out.transactionComplete||!out.managerComplete||out.finality!=="FINALIZED"||!out.blockHashComplete)process.exit(1);console.log(JSON.stringify(out))' \
> /evidence.json
{"decision":"VERIFIED","imageIdPresent":true,"journalHashComplete":true,"transactionComplete":true,"managerComplete":true,"finality":"FINALIZED","blockHashComplete":true}
$ export TX="$(jq -r .transactions.submit "$EVIDENCE")" \
> BLOCK="$(jq -r .transactions.submitBlock "$EVIDENCE")" \
> BLOCK_HASH="$(jq -r .transactions.submitCanonicity.blockHash "$EVIDENCE")" \
> MANAGER="$(jq -r .contracts.manager "$EVIDENCE")" && \
> EXPLORER="$(kurtosis port print "$ENCLAVE" explorer http --format ip,number)" && \
> export BLOCK_HASH MANAGER EXPLORER
$ curl -fsS "http://$EXPLORER/api/v2/transactions/$TX" | jq -e -c \
> '{indexed:(.hash==env.TX),success:((.status|ascii_downcase)=="ok"),managerMatches:(((.to.hash // .to)|ascii_downcase)==(env.MANAGER|ascii_downcase)),blockMatches:((.block_number|tostring)==env.BLOCK)} | \
> select(.indexed and .success and .managerMatches and .blockMatches)'
{"indexed":true,"success":true,"managerMatches":true,"blockMatches":true}
$ curl -fsS "http://$EXPLORER/api/v2/blocks/$BLOCK" | jq -e -c \
> '{indexed:((.height|tostring)==env.BLOCK),hashMatches:((.hash|ascii_downcase)==(env.BLOCK_HASH|ascii_downcase))} | \
> select(.indexed and .hashMatches)'
{"indexed":true,"hashMatches":true}
$ node -e "console.log('http://' + process.env.EXPLORER + '/tx/' + process.env.TX)"
http://127.0.0.1:3200/tx/<accepted-checkpoint-transaction>
$ rm -r -- "$EVIDENCE_DIR" && \
> unset EVIDENCE_DIR EVIDENCE TX BLOCK BLOCK_HASH MANAGER EXPLORER CONTROL_IMAGEVideo fallback generated with VHS 0.11.0
Pinned public inputs
Repositories and images used here
Current first-party zkdeal repositories and packages are MIT licensed. These pinned historical inputs retain the license recorded at each referenced commit or image digest.