Zarchain user guide

Everything you need to use the Zarchain iOS app and web tools during the test programme. Zarchain is an educational proof-of-work network: the coins (ZAR) have no monetary value and the chain may be reset between test rounds.

TL;DR — Install the app → create a wallet → back up the recovery key → tap Faucet → send some ZAR to a friend by scanning their QR → tap Mine to earn 50 ZAR → watch it all in the explorer.

1. Getting started

  1. Install the app. Accept the TestFlight invitation on your iPhone (iOS 17 or newer), install TestFlight from the App Store if prompted, then install Zarchain.
  2. Create a wallet. On first launch choose Create new wallet. A P-256 key pair is generated on your phone and stored in the iOS Keychain (device-only, protected by your passcode / Face ID).
  3. Back up your recovery key. Settings → Wallet → Show recovery key. Keep it private; anyone holding it controls the wallet. You can restore it on another phone with Import wallet.
  4. Check the node. The app is pre-configured with the test node URL. Settings → Network shows connection status; tap Test connection if anything looks wrong.

2. Your wallet & keys

Your address looks like zar4269889431e3131966fcaf6a457141943ed2c35b: the prefix zar followed by 40 hex characters derived from your public key (SHA-256 of the uncompressed key, first 20 bytes). Share your address freely — it is how people pay you.

TermMeaning
BalanceConfirmed ZAR on-chain.
AvailableBalance minus what you have already sent that is still pending. This is what you can spend right now.
PendingA transaction accepted by the node but not yet included in a block. It is confirmed at the next block (auto-mined roughly every 15s when there is something to mine, or immediately when anyone taps Mine).
ConfirmedIncluded in a block. The explorer shows the block number.

3. Claiming test coins (Faucet)

  1. Wallet tab → Faucet.
  2. Choose an amount up to the current maximum (1000 ZAR) and tap Claim.
  3. The grant is queued as a network transaction and credited when the next block is mined. Your balance updates automatically.

Each address can claim once per 60 seconds. The admin can change limits or disable the faucet; the app shows the current rules.

4. Sending & receiving

Receive

Wallet tab → Receive shows your QR code and address with Copy and Share buttons. The QR encodes zarchain:<address> and can optionally include an amount.

Send

  1. Wallet tab → Send. Enter a recipient by pasting an address or tapping the camera icon to scan their QR code.
  2. Enter the amount (whole ZAR) and an optional memo (visible on-chain, max 280 characters).
  3. Review the summary. Tap Confirm and authenticate with Face ID / Touch ID / passcode.
  4. The app signs the transaction locally and submits it. It appears as pending in Activity and confirms at the next block.
Transfers are final once confirmed. Double-check the recipient address — the first and last characters are shown prominently in the review screen for this reason.

The app will refuse to send more than your available balance, to send to yourself, or to send to a malformed address; the node enforces the same rules independently.

5. Mining

Mine tab → Mine a block. The node performs proof-of-work on your behalf (finding a hash with 4 leading zeros) and credits the 50 ZAR block reward to your address, together with any pending transactions in that block. Mining also confirms everyone's pending transactions, which makes it a useful thing to do during a test session.

The node additionally auto-mines whenever the mempool is non-empty so nobody's payment waits forever; those rewards go to the node treasury.

6. Explorer

The in-app Explorer tab and the web explorer show the same live data: network stats, the newest blocks, the mempool and an activity feed. Tap a block for its transactions, tap a transaction for its signature and public key, or search any block height, block hash, transaction id or address.

7. Security model

  • Keys never leave the device. Generation, storage (Keychain, WhenUnlockedThisDeviceOnly) and signing happen on the phone. The node only ever sees public keys and signatures.
  • Every transfer is signed with ECDSA P-256 over SHA-256 of sender|recipient|amount|payload|memo|timestamp|nonce. The node verifies the signature, checks the public key hashes to the sender address, and rejects anything tampered with.
  • Replay protection. A transaction id is the hash of its signed content. The node rejects any id already pending or confirmed, and any signed transaction older than 15 minutes.
  • No double spend. The mempool tracks pending outflows per address, so you cannot spend the same ZAR twice even before confirmation. Blocks are re-validated against balances when received from peers.
  • Transport. Production nodes serve HTTPS (Let's Encrypt via --acme-domain). Local test nodes may use plain HTTP on the LAN; the app allows this only for private addresses.
  • Biometric confirmation. Sending and revealing the recovery key require Face ID / Touch ID or the device passcode.
  • Rate limiting. Faucet, mining and transaction endpoints are rate-limited per client and the admin can pause the network.

What Zarchain is not: a Sybil-resistant public blockchain. Peers are trusted operators, and network mints (faucet/admin) are issued by the node itself. It is a safe, realistic sandbox — not real money.

8. Test scenarios for the beta

If you are helping test, try to complete these and note anything surprising:

  1. Onboarding: create a wallet, back up the key, delete the app, reinstall and import the key. Balance should be identical.
  2. Faucet: claim, wait for confirmation, claim again immediately (expect a cooldown message with a countdown).
  3. Send to a friend: scan their QR, send 25 ZAR with a memo. Both phones should show the pending → confirmed transition without pulling to refresh.
  4. Overspend: try to send more than available. The Send button should stay disabled with a clear reason.
  5. Two quick sends: send 60 then 60 from a 100 ZAR wallet before the first confirms. The second must be refused as insufficient.
  6. Mining: mine a block and check the reward lands and your pending transactions confirm.
  7. Offline: enable Airplane mode, open the app (cached data with an offline banner), then reconnect.
  8. Explorer: find your transaction in the web explorer by pasting its id or your address.
  9. Accessibility: use larger Dynamic Type and VoiceOver on the wallet screen.

9. Troubleshooting

SymptomWhat to do
"Cannot reach node"Check Settings → Network URL. On a LAN node your phone must be on the same Wi‑Fi. Tap Test connection.
Faucet says cooldownWait for the countdown, or ask the admin to mint to your address.
Transaction stuck pendingTap Mine, or wait for auto-mine. If the network is paused the app shows a banner.
"insufficient balance" but I have coinsYour available balance excludes pending sends. Wait for confirmation.
"transaction timestamp too old"Your phone clock is wrong. Enable Set Automatically in iOS Date & Time.
Balance went to zeroThe admin reset the chain for a new test round. Claim from the faucet again.

10. Admin guide

Open /admin and sign in with the admin token (printed at node start, or ZARCHAIN_ADMIN_TOKEN). From the console you can:

  • Pause / resume the network with a broadcast message.
  • Tune mining: difficulty (1–7), public mining on/off, auto-mine and its interval.
  • Tune the faucet: enable, per-request maximum, per-address cooldown.
  • Mint ZAR to any address (with optional immediate mining) and mine blocks manually.
  • Inspect & drop pending transactions, manage peers and force a sync.
  • Export a full chain snapshot, and reset to genesis for a fresh round.

Running a node

go build -o zarchain ./cmd/node
./zarchain --port 8080 --data-dir /var/lib/zarchain --self-url https://zarchain.example.com
# public HTTPS with automatic certificates:
./zarchain --acme-domain zarchain.example.com --acme-email you@example.com --data-dir /var/lib/zarchain
# docker:
docker compose up -d --build

Chain, settings, the node wallet and the admin token live in the data directory. Back it up to preserve state across upgrades.

11. API reference

EndpointDescription
GET /statusHeight, difficulty, supply, faucet/mining rules, pause state, message.
GET /blocks?limit=&before=Block summaries, newest first.
GET /block/{index|hash|latest}Full block with transactions.
GET /tx/{id}Transaction with confirmation status.
GET /address/{addr}Balance, available, pending in/out, history.
GET /pendingMempool.
GET /search?q=Resolve a height, hash, tx id or address.
GET /eventsServer-sent events: status, block, tx, settings.
POST /transactionsSubmit a signed transfer: {sender, recipient, amount, payload, memo, timestamp, nonce, signature, publicKey}.
POST /faucet{address, amount} — queue a test grant.
POST /mine{minerAddress} — mine one block, reward to miner.
GET /peers, POST /peersPeer list / announce.
/admin/api/*Admin endpoints (Bearer token): overview, settings, mine, mint, mempool, peers, balances, activity, export, reset.

Signing (for other clients)

message   = sender + "|" + recipient + "|" + amount + "|" + payload + "|" + memo + "|" + timestamp + "|" + nonce
digest    = SHA-256(message)
signature = base64( DER( ECDSA-P256-sign(digest) ) )
publicKey = base64( 0x04 || X || Y )          // X9.63 uncompressed
address   = "zar" + hex( SHA-256(publicKey bytes)[0:20] )
id        = hex( SHA-256(message) )

Test vector: private scalar AQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyA= → address zar4269889431e3131966fcaf6a457141943ed2c35b.

12. FAQ

Is ZAR real money? No. It is a test token with no value; balances can be reset.

Can I have more than one wallet? One wallet per app install. Use Import to switch, after backing up the current key.

What if I lose my recovery key? The coins are unrecoverable — exactly like a real blockchain. Ask the admin to mint new test coins to a new wallet.

Why did my send fail with "invalid signature"? The app signed with a different key than the address (e.g. after importing another wallet mid-send). Retry from the Send screen.

Where is the source? Ask the project owner; the node is Go, the app is SwiftUI.