Tutorial 2 — A Provable Shared Registry
Open this outcome in App-Chain Studio
- Level: beginner to intermediate
- Time: about 15 minutes
- Outcome: write owner-controlled data, demonstrate an unauthorized no-op, and retrieve an MPF proof for the current value.
The default cluster also hosts registry-chain, backed by the stock
kv-registry state machine. The first writer becomes the key owner; only that
member can update or delete it.
1. Start the default cluster
Section titled “1. Start the default cluster”Skip this section if Tutorial 1’s cluster is still running.
export YANO_CLUSTER_DIR=/tmp/yano-tutorial-registry./yano.sh appchain cluster start 32. Create a registry entry
Section titled “2. Create a registry entry”Write through node 1 so that node 1 becomes the authenticated owner:
./yano.sh appchain cluster kv registry-chain set supplier-42 active --node 1sleep 3./yano.sh appchain cluster statusThe command body is CBOR, but the launcher builds it for you. Application clients can use the standard-library encoder instead of hand-writing CBOR.
3. Prove the current value
Section titled “3. Prove the current value”The physical state key is the UTF-8 business key. Convert it to hex for the proof endpoint:
KEY_HEX=$(python3 -c 'print("supplier-42".encode().hex())')
curl -s \ "http://127.0.0.1:7070/api/v1/app-chain/chains/registry-chain/state/proof/$KEY_HEX" \ | jq .The proven value contains both owner identity and registry value. A verifier must verify the MPF path against the expected state root; displaying JSON from one node alone is not independent verification.
4. Demonstrate authorization as a deterministic no-op
Section titled “4. Demonstrate authorization as a deterministic no-op”Capture the root, attempt an update through node 2, and compare:
ROOT_BEFORE=$(curl -s http://127.0.0.1:7070/api/v1/app-chain/chains \ | jq -r '.[] | select(.chainId == "registry-chain") | .stateRoot')
./yano.sh appchain cluster kv registry-chain set supplier-42 suspended --node 2sleep 3
ROOT_AFTER=$(curl -s http://127.0.0.1:7070/api/v1/app-chain/chains \ | jq -r '.[] | select(.chainId == "registry-chain") | .stateRoot')
printf 'before=%s\nafter =%s\n' "$ROOT_BEFORE" "$ROOT_AFTER"The unauthorized command can appear in a finalized block, but it must not change the registry entry. This is intentional: the deterministic application result, not “the HTTP call succeeded” or “the block height increased,” is the authorization decision.
Check the value again:
curl -s \ "http://127.0.0.1:7070/api/v1/app-chain/chains/registry-chain/state/proof/$KEY_HEX" \ | jq .Now update through the owner and verify the proof changes:
./yano.sh appchain cluster kv registry-chain set supplier-42 suspended --node 1sleep 3curl -s \ "http://127.0.0.1:7070/api/v1/app-chain/chains/registry-chain/state/proof/$KEY_HEX" \ | jq .5. Clean up
Section titled “5. Clean up”./yano.sh appchain cluster cleanunset YANO_CLUSTER_DIRWhere this pattern fits
Section titled “Where this pattern fits”- consortium allow-lists;
- product, asset, credential, or DID-document registries;
- shared configuration with explicit ownership;
- a current pointer whose exact value must be proven to a third party.
It does not provide organization roles, multi-party policy governance, or arbitrary document indexing. Use the role workflow or a domain plugin when the authorization model is richer than “first writer owns this key.”
Go deeper
Section titled “Go deeper”- Continue with the dedicated
kv-registryreference for configuration, raw REST submission, Java encoding/decoding, and design guidance. - Verify the returned
proofWireHexusing the Java app-chain client rather than trusting the serving node. - Start with
--anchor-mode metadata, fund the printed anchor wallet on a public test network, and connect the proof root to its anchor. - Review
kv-registry.value-format(raw,utf8, orcbor) in the user guide. - Continue with the stock state-machine cookbook.