Developer guide · Zikaron

Command line

zikaron offers the same ledger operations as the window, one subcommand per action. It is built for scripts: the output is a single JSON value, and the verdict is in the exit code. The full output shapes, exit codes, refusal reasons and flags are in CLI-SCHEMA.md in the source.

Where it is

Installed from the dmg
/Applications/ZIKARON.app/Contents/MacOS/zikaron
Installed from the pkg
/usr/local/bin/zikaron
Built from source
target/release/zikaron

Three conventions

Standard output is one canonical JSON value
Each call prints one value, ending at the value’s last character. The byte format follows law §3.4: compact, members sorted by bytes.
Misuse leaves standard output empty
For wrong arguments or an unreadable path, the exit code is 2, standard output has zero bytes, and the first line of standard error reads <reason> <subject>, as in E_UNREADABLE /nowhere/at/all. Whether standard output holds any bytes tells a caller an answer from a misuse.
Status words pass through unchanged
GREEN, PARTIAL, FAIL, COMPLETE, GAPS and the like are written by the cores and passed on by the command line as they are.

Files are written one way: --out first writes a whole temporary file alongside, syncs it to disk, then renames it into place; when a file of that name already exists, the write stops and the existing file keeps every byte.

Exit codes

CodeMeaningExample
0Answered, affirmativeGREEN, COMPLETE
1Answered, negativeThe entry was refused, or the verdict is FAIL, BROKEN_CHAIN or NO_LABEL
2MisuseWrong arguments or an unreadable path; standard output is empty
3Answered, in betweenPARTIAL, GAPS, UNAVAILABLE
4Answer absentNode unreachable, nodes disagreeing, scan refused

The weight of this table is that 3 and 4 each have a code of their own. Fold “not yet on chain” into 0, and a buyer takes an unanchored grant as cleared; fold it into 1, and a passing “not yet known” reads as “forged”. Fold “node unreachable” into 1, and a network fault reads as “this chain is fake”. A failed scan is an absent answer, and the caller retries or changes nodes.

Twenty-one subcommands

SubcommandWhat it does
keygenGenerate a key and print its address and private key
initWrite the ledger’s creation entry into an empty ledger
historyAppend an anchored record
grantSign a grant and write it to the ledger
revokeSign a revocation and write it to the ledger (ruling file digest optional)
adoptWrite an adoption entry
attestProduce a co-signature with an outside key
succeedWrite a key change or handover entry
annotateWrite a note
retractWrite a deletion entry (the target must be a record in this ledger that is still undeleted)
anchorAnchor a hash on chain, through the registry contract or as a bare self-transfer
scanScan for anchors using the chain settings
auditAudit a ledger against scan results and print a report and verdict
check-grantRun the six checks on a grant
chain-checkCheck a sublicense chain hop by hop (--hop <grant file>[=<audit input file>], repeatable)
depthDepth readings for a record
fpm-signSign a fingerprint manifest
ack-signSign an acknowledgement
badgeEncode or decode a credential (exactly one of --encode and --decode)
kit-exportExport a record kit, written once it passes its self-check
showShow an entry’s author, ID, type, previous entry, sequence and content

Any other first word counts as misuse, with exit code 2.

Flags

All fifty-three flags are long flags, and each takes a value; every subcommand has its own table of flags, and a flag outside it counts as misuse. Members the law requires in an entry’s body may all be left off the command line; the core then refuses the entry under the law, and the command line checks the few items it needs for its own work. That way each rule of judgment exists once, in the core.

Example

Generate a key, create a ledger, record a file, anchor it, audit:

zikaron keygen # {"address":"0x…","ok":true,"privkey":"0x…"} zikaron init --ledger ./ledger --key <private key> --statement "Records of my work" zikaron history --ledger ./ledger --key <private key> \ --content 0x$(shasum -a 256 manuscript.pdf | cut -d' ' -f1) \ --mark bytes-sha256/1 \ --toolchain 0xb7f3c4a226684d6da684b0ac82d36ed5bcba7bb61d09c955bff9437f84a52a4d # {"entryId":"0x…","ledger":"…","ok":true,"seq":1,"written":true} zikaron anchor --key <private key> --endpoint <chain-id>=<node> \ --form registry --registry <contract address> --hash <entryId> zikaron scan --endpoint <chain-id>=<node one> --endpoint <chain-id>=<node two> \ --basis basis.json > fragment.json zikaron audit --ledger ./ledger --fragment fragment.json echo $?

The value of --toolchain is the SHA-256 of the literal bytes-sha256/1, meaning “the content fingerprint is the SHA-256 of a run of bytes”. The command line’s chain layer accepts node addresses of the form http://host:port alone, so point it at a local node or a local proxy; anchor takes exactly one --endpoint. basis.json states the scan range: which chains, which registry contract, which senders, and the start and end blocks; the format is in law §9.4.

Time is injected by the caller

Deadlines and periods are judged by chain time and the moment injected with --now; when --now is left off, chain time alone applies. Every moment comes from the caller, so the same input always reaches the same verdict.

Reading the app’s own ledger

A ledger in ZIKARON Desk’s data folder is encrypted and the passcode lives in the app, so the command line refuses to read one, with exit code 2 and this line on standard error (“locked: this is ZIKARON Desk’s sealed local data; the command line does not read it”):

E_UNREADABLE 已锁定:这是 ZIKARON Desk 封存的本机数据,命令行不读

To hand a ledger to the command line, export a “Ledger mirror” in the app first: each file in the mirror’s entries/ is one entry’s bytes, named with exactly its 64 hexadecimal digits. A single entry can be read by file with show --path; to use them as a --ledger folder, copy the files into an empty folder and add .entry to each file name.