Technical Canon
The network runs as a closed, invite-only testnet. Testnet coins are worth nothing. The rules are the same on testnet
and on mainnet, except for the parameters where this page says otherwise.
This page collects the rules Morana runs by: numbers, formats and trust boundaries. The rest of the documentation explains the same things in plain words and links here for the exact values.
1 XMOR = 100,000,000 atoms. Every amount in the network rules is a whole number of atoms.
Contents
- 1. What Morana is
- 2. The chain: networks, proof of work, blocks
- 3. Issuance and shares
- 4. Relays on chain and their economics
- 5. MORID names
- 6. The private layer
- 7. Addresses, keys and the payment link
- 8. Wallet
- 9. Gateway
- 10. Messenger and the relay swarm
- 11. Mining and the pool
- 12. Releases and signature checks
- 13. The path to mainnet
1. What Morana is
One network with one coin, XMOR, tying together four things: payments (public and private), names (MORID — an on-chain name that addresses are bound to), message delivery (a swarm of independent relays that the network pays out of each block) and GPU mining (KawPow).
| Component | What it does |
|---|---|
Node moranad |
A fork of Bitcoin Core 31.1: consensus, P2P, RPC, KawPow, the Sapling private layer (Zcash's scheme for hidden transfers), the name and relay registries |
| Lightd gateway | An untrusted indexer over the node: REST and gRPC for the wallet and the messenger |
| Wallet | Linux, Windows, macOS, Android and iPhone; keys only on your device; transparent and private transfers; 16 languages |
| Messenger and relays | End-to-end encryption (Olm); a relay network whose members are listed on the blockchain; Linux, Windows, macOS, Android and iPhone; 16 languages |
| Pool | Stratum for KawPow, PPLNS payouts (the reward is split by the most recent shares of work sent in) |
| Explorer | A view over the gateway: blocks, public transfers, names, relays |
Trust boundaries in one line: only the node determines whether the network’s rules are followed; the gateway can withhold but cannot forge what the client re-checks itself (headers, Merkle branches, block roots, filters); relays see only encrypted envelopes and the recipient's mailbox; the apps do not send the recovery phrase, private wallet keys or conversation decryption keys to servers.
2. The chain
2.1 Networks
The core is Bitcoin Core 31.1 with Morana's changes. The chain has no checkpoints, and neither mainnet nor testnet has DNS seeds.
| Parameter | Mainnet | Testnet tmor |
Regtest |
|---|---|---|---|
| P2P port | 49331 | 39233 | 49233 |
| RPC port (localhost only) | 49332 | 39232 | 49232 |
| Magic | MORA |
MORT |
MORR |
| Public address | mor1… |
tmor1… |
morrt1… |
| Private address | morp1… |
tmorp1… |
morrtp1… |
| Unified address | mu1… |
tmu1… |
murt1… |
| Target block time | 60 s | 60 s | 60 s, no retargeting |
| Halving | every 2,100,000 blocks | every 2,100,000 blocks | every 150 blocks |
| Target limit (powLimit) | 2^228 | 2^228 | 7fff… |
| BIP34, BIP66, CLTV, CSV, SegWit | from height 1 | from height 1 | SegWit from height 0 |
| Deep-reorg protection | 100 blocks, after sync | none | none |
The first 60 blocks after genesis use a launch target: on testnet it is 0x1d00ffff (the target limit divided by 16); on mainnet it is set from the hashrate expected on the day the launch is announced. That way the first blocks do not go to whoever shows up first with a lot of hashpower while difficulty is still near zero.
The supply limit is 10,500,000,000 XMOR. Genesis coins cannot be spent and are not part of that limit.
2.2 Proof of work: KawPow and LWMA
The block header carries three extra fields: the height nHeight, a 64-bit nonce nNonce64 and mix_hash. The header hash is KawPow: sha256d over Bitcoin's six classic fields, then KawPow with nNonce64 and the height. The DAG epoch is the height divided by 7,500; the program period is the height divided by 3. The height in the header must equal the block's real height, or the block is rejected.
Difficulty is LWMA: a 60-block window, T the target block time, k = N(N+1)T/2. Each block's solve time in the window is clamped to ±6T and enters the sum weighted by its position; the sum never falls below k/10. The next target is the window's average target multiplied by the weighted sum over k, never above the target limit. Below height 60 the target limit applies (adjusted by the launch target from §2.1).
2.3 Blocks and transactions
| Parameter | Value |
|---|---|
| Block weight | up to 4,000,000 |
| Sigops per block | up to 80,000 |
| Block reward maturity | 100 blocks |
| Transaction version | 2 |
| OP_RETURN data | up to 145 bytes in total per transaction |
| Minimum relay fee | 100 atoms per 1,000 vbytes |
| Node dust threshold | 3,000 atoms |
| Surcharge per private action | 1,000,000 atoms per action (default value) |
The private part of a transaction travels in the extended format with flag 4 (the Sapling bundle); the network always rejects transactions with flag 2. After nLockTime come the private value balance and the binding signature bindingSig.
More detail, as a table: Network Parameters.
3. Issuance and shares
3.1 Block reward
The block reward is 2,500 XMOR and halves every 2,100,000 blocks. The first block is an ordinary block: there is no reserve and no premine.
| Measure | Value |
|---|---|
| Era length | 2,100,000 blocks from one halving to the next, about 4 years at 60 s |
| Blocks per year | 525,600 |
| Issuance per day in the first era | 3,600,000 XMOR |
| Total issuance | 10,500,000,000 XMOR |
3.2 Shares
| Period | Reward | Miner | Developers | Relays |
|---|---|---|---|---|
| First era, blocks 1 … 525,600 | 2,500 | 80% | 17% = 425 XMOR | 3% = 75 XMOR |
| First era, remainder to block 2,100,000 | 2,500 | 82% | 15% = 375 XMOR | 3% = 75 XMOR |
| Second era | 1,250 | 86% | 8% = 100 XMOR | 6% = 75 XMOR |
| Third era | 625 | 90% | 4% = 25 XMOR | 6% = 37.5 XMOR |
| After that | 312.5 → 0 | 94% | 0% | 6% = 18.75 XMOR → 0 |
Over all time: developers 1,076,280,000 XMOR (10.25%), relays up to 472,500,000 XMOR (4.5%), miners at least 8,951,220,000 XMOR. The relay share is an upper bound: whatever relays do not claim because of the cap (§4.3) goes to the miner in the same block.
3.3 Required coinbase outputs
A node accepts a block only if its coinbase (the block's first transaction, which issues the reward) has:
- while the developer share is nonzero, exactly one output paying its exact amount to the recipient’s script;
- exactly one relay-share output to the P2WPKH of the relay at the head of the queue — if the queue is not empty;
- at a swarm-membership epoch boundary (every 10,080 blocks), exactly one MRST output committing to the relay set, and once names are active, the MNST name-state commitment as well;
- a total no greater than fees plus the block reward.
4. Relays on chain and their economics
4.1 Records
Every relay record is an OP_RETURN output with its own identifying prefix.
- MREL — registration. Version 1 is 78 bytes:
relay_id(32 bytes, Ed25519), the payout key hash (20), the owner key hash (20). Version 2 is 98 bytes, adding the service key hash (20). Actions: register, deregister, rotate the service key, top up the stake. Registration needs an input that reveals the owner key and a stake output to that key's hash of at least the required stake. A top-up must raise the stake. - Deregistration — the relay enters the exiting state; the stake can be spent no earlier than 43,200 blocks (30 days) later.
- MRHB — the heartbeat, 69 bytes:
relay_idand the hash of an anchor block. The anchor is at most 120 blocks old and strictly increases from one heartbeat to the next; it is signed with the owner key (version 1) or the service key (version 2). The liveness window is 1,440 blocks (about a day). - MRST — the swarm-membership commitment, 49 bytes: epoch number, snapshot height, member count and Merkle root. Written into the coinbase at every 10,080-block epoch boundary; an empty swarm gives a zero root.
4.2 The payout queue
The queue admits relays that are active, hold at least the required stake, have a heartbeat inside the window and have earned less than the cap this epoch. Each block pays the relay with the smallest key (last payout height, registration height, relay_id). It is a round-robin queue, not a lottery: with N eligible relays, each gets the relay share every Nth block. An empty queue leaves the share with the miner.
4.3 Economics
The payout epoch E is the height divided by 10,080 (about a week).
- Epoch pool = the relay share per block × 10,080, plus 80% of name registration and renewal fees (§5.3). In the first and second eras the relay share is 75 XMOR per block, which is 756,000 XMOR a week before name fees.
- N̄ — the lower median of the number of active relays over the last four epochs. N_ref = max(30, ⌈0.75 · N̄⌉).
- Income cap C(E) = pool / max(N̄, N_ref).
- Stake S(E) = T(E) × pool / max(N̄, N_ref), where T is "weeks of income", counted in half-weeks. S moves by at most ±25% per epoch, with a floor of 15,000 XMOR; S(0) = 15,000 XMOR.
- T(E): 8 half-weeks (4 weeks) for the first 26 epochs, then rising step by step to 30 half-weeks (15 weeks).
- Eligibility. Registration requires a stake of S(E). Payout eligibility uses S(E − 2), giving an existing relay two epochs to top up after the requirement rises.
With a pool of 756,000 XMOR a week and identical honest relays:
| Relays in the network | Income per relay per week | Calculated stake at T = 4 weeks | Calculated stake at T = 15 weeks |
|---|---|---|---|
| 30 | 25,200 XMOR | 100,800 XMOR | 378,000 XMOR |
| 100 | 7,560 XMOR | 30,240 XMOR | 113,400 XMOR |
| 300 | 2,520 XMOR | 15,000 XMOR (minimum stake) | 37,800 XMOR |
The formula sets the stake at 4 weeks of rewards during the initial period and 15 weeks after the transition period. The minimum stake and reward cap can change this ratio. See Relay economics.
4.4 Relay RPC
listrelays (with an economics summary: epoch, pool, N̄, N_ref, cap, stake), getrelayinfo, getrelaypayouts, getmrstcommitment, getnetworkparams.
5. MORID names
5.1 Name rules
Lowercase Latin letters a-z, digits 0-9, hyphen and underscore; 1 to 32 characters, with one-character names reserved. A name is stored as written, with no case folding. Each name has one record on chain: the owner key hash, the registration transaction and height, its state, an operation counter and the declared unified address. Reserved and forbidden names are on the MORID Names page.
5.2 Registration: commit-reveal
First an MNCM commitment (37 bytes) goes on chain, where commitment = SHA256d(name ‖ owner key hash ‖ nonce). No sooner than 6 blocks later comes the MORID v2 reveal with the name, the owner key hash and the nonce, and the transaction's inputs prove ownership of the key (P2WPKH or P2PKH). A commitment never expires. At most 32 reveals fit in one block.
5.3 Price, term and renewal
| Rule | Value |
|---|---|
| Price ladder | B × 32 / 16 / 8 / 4 / 2 / 1 for 2, 3, 4, 5, 6 and 7+ characters |
| Base price B | the era's block reward divided by 25: 100 XMOR in the first era |
| Demand multiplier | ×1 … ×64, stepping ±50% per 1,440-block epoch (one day) |
| Daily demand targets | 1 / 2 / 5 / 15 / 45 / 150 for tiers 2 … 7+ |
| Who is paid | 20% to the miner as a fee, 80% to the relay pool |
| Name term | 525,600 blocks (about a year) |
| Renewal | 25% of the tier price without the demand multiplier, once a year, at least 1 XMOR |
| Grace period after expiry | 43,200 blocks (30 days) |
| After the grace period | the name is free; re-registration is a Dutch auction from 16× down to 1× over 20,160 blocks |
| Short names, 2–4 characters | locked for 262,800 blocks after names activate, then each goes through a Dutch auction from 16× |
Price = ladder × the tier's demand multiplier, in integers. The price state lives on chain and is rolled back as a whole on a reorg.
5.4 Transfer and sale
The MORID v3 record: to consensus, "transfer" and "sale" are the same action. The seller and the new owner must each spend a P2WPKH output of their own key with SIGHASH_ALL. Consensus does not check the payment to the seller, but both sides sign the whole transaction, so the payment and the transfer can sit in one transaction: either all of it goes through or none of it does. A transfer to oneself is rejected.
5.5 A name's unified address
The MORID v4 record: the name's owner writes a receiver container — TLV with codes in ascending order: Sapling (code 2, 43 bytes, required) and P2WPKH (code 16, 20 bytes); 22 to 96 bytes in total.
5.6 The name-state commitment
MNST (49 bytes): epoch number, snapshot height, record count and root. The leaves are every field of a record, including the expiry height and the renewal count, sorted and bracketed by boundary leaves. So "the name exists", "the name does not exist" and "the name has expired" are all provable: a client that receives a branch must reject a record whose term has run out. On testnet the commitment is written from the first 10,080-block boundary; the RPC getmnstproof returns the proof.
6. The private layer
6.1 What it is
Sapling from Zcash: hidden amounts and recipients, Groth16 proofs on the BLS12-381 curve. A transaction can carry public inputs and outputs together with a private part. The wallet's three operations — public to private (T→Z), private to private (Z→Z) and private to public (Z→T) — are built on the device, without the node's RPC.
6.2 Format and signature
The private part: spends (cv, anchor, nullifier, rk, a 192-byte proof, a 64-byte signature), outputs, the private value balance and the binding signature. Consensus allows up to 256 spends and 256 outputs per transaction; relay policy allows up to 10 and 10. The public inputs of a hybrid transaction sign the ZIP-243 digest, SIGHASH_ALL only.
6.3 Order of checks
First the context-free checks: version, balance range, no coinbase with a private part, limits, duplicate nullifiers. Then the contextual ones: the binding signature, the nullifier is unspent both in the database and in the block, the anchor is known, the pool neither goes negative nor overflows. The Groth16 check comes last (zcash_proofs and bellman), and its result is cached. In the mempool the expensive check runs after inputs and fees have been checked.
6.4 The pool balance check and the emergency switch
The pool balance check (the "turnstile", modeled on ZIP-209) applies to every transaction and every whole block: the sum of private value balances cannot take the tracked private pool below zero, so nothing can leave the pool beyond what went into it. It runs before Groth16 — the last line of defense against a bug in the proof system itself. On testnet this check is on from height 1.
The emergency switch: from a given height on, private transactions are not accepted. Only a new node release can change that height (modeled on ZIP-257). On testnet and on mainnet the switch is built into the consensus rules but currently off: no shutdown height is set.
6.5 Numbered pools
The private part carries a pool-number byte. Each pool has its own tree root, nullifier set and balance counter. Sealing prevents the pool balance from increasing while preserving withdrawals. An emergency shutdown of private operations also suspends withdrawals. A node release sets these activation heights. The testnet uses one private pool, numbered 1.
6.6 State
The depth-32 commitment tree, the nullifier set, historical roots with reference counts and the pool counter live in a separate database with a full undo for every block. A fast-sync snapshot carries its own private-state hash; a snapshot without it will not load.
6.7 Sapling parameters
The files from Zcash's 2018 Sapling MPC ceremony, about 90 participants. The node and the wallet ship them in the build; without them the node will not start while the layer is active.
| File | Size, bytes | SHA-256 |
|---|---|---|
sapling-spend.params |
47,958,396 | 8e48ffd23abb3a5fd9c5589204f32d9c31285a04b78096ba40a79b75677efc13 |
sapling-output.params |
3,592,860 | 2f0ebbcbb9bb0bcffe95a397e7eba89c29eb4dde6191c339db88570e3f3fb0e4 |
6.8 Activation heights
| Rule | Mainnet | Testnet tmor |
Regtest |
|---|---|---|---|
| Private layer | height chosen at launch | 1 | 400 |
| ZIP-243 signature | enabled by the node release for launch | 1 | 0 |
| Pool balance check | enabled by the node release for launch | 1 | 1 |
| Emergency switch | built in, off | built in, off | built in, off |
7. Addresses, keys and the payment link
- Recovery phrase — BIP39, 24 words. It derives the main wallet, messenger and relay-owner keys. The backup key is derived separately from the password and a random salt.
- Public addresses (T) — BIP84
m/84'/coin'/0'/{0|1}/i, P2WPKH bech32; coin type 1' on testnet. Receive and change branches, gap limit 20. - Private addresses (Z) — ZIP-32
m/32'/coin_type'/account', coin type 29233' on testnet. A Sapling address is an 11-byte diversifier ‖ 32-byte pk_d, bech32m with the prefixmorp,tmorpormorrtp. An incoming viewing key permits viewing incoming payments, but not spending. - Mainnet: derivation stays locked until the stress-testing stage is complete and the coin type is registered.
- Unified addresses (UA) —
mu1…andtmu1…: TLV with a required Sapling receiver, F4Jumble, bech32m without the 90-character limit. - The payment link
morana:follows ZIP-321: 1 XMOR = 100,000,000 atoms, memo in base64url up to 512 bytes; an unknownreq-parameter is refused; the address is checked against the wallet's network. - Messenger identity — from the same phrase: HKDF-SHA256 with the salt
MORANA/root/v1and a separate domain per purpose, Ed25519 keys. Profiles: Morana and Shadow. Shadow has its own phrase or is linked to the first profile through a separate domain; it always runs in maximum-privacy mode and never connects directly.
Shadow is designed to connect only through bridges or Tor. This protection is not yet fully implemented on the closed testnet: a relay operator may see the device’s IP address. See known limitations.
8. Wallet
Storage: SQLCipher. The key is derived from the password using Argon2id; a newly created vault uses 19 MiB, t = 2, p = 1. Each vault stores its own KDF parameters. The phrase and seed have an additional layer of XChaCha20-Poly1305 encryption. File permissions are 0600; replacement is atomic. Storage is bound to its network.
The .morbak backup: MORBAK04 encrypts a database snapshot with XChaCha20-Poly1305. Its key is derived from the wallet password using Argon2id (256 MiB, t = 4, p = 1). The file contains no recovery phrase or private keys. It can be imported only into the same identity, restored with its 24 words, on the same network.
Syncing the public side through the gateway: history in pages of 500 rows with a cursor, up to 200 pages — beyond that the sync stops with a resume point rather than truncating; a response is at most 4 MiB, a UTXO snapshot at most 64 MiB. The more private route is BIP157/158 filters, which reveal no addresses.
Syncing the private side: compact blocks in pages of 100 (REST or gRPC); headers are checked from the built-in genesis; reorgs up to 100 blocks back; Sapling witnesses are computed on the device.
Sending: a one-time "prepare → review → execute" plan with an expiry; if the state or the network changes, it is refused. A broadcast receipt is not a receipt of inclusion in a block.
Builds for Linux, Windows, macOS, Android and iPhone. All versions share a Rust core; each platform has its own build. The interface is available in 16 languages: en, ru, es, de, fr, pt-BR, zh-CN, ja, tr, ar, pt, hi, id, ko, pl, vi.
9. Gateway
What it serves: server and height information; compact blocks and raw headers (up to 1,000 per request), a header chain from the client's anchor; BIP157/158 filters; public block bodies (up to 10); full Sapling outputs; transaction and CPFP package submission; UTXOs by scriptPubKey (up to 100 per request) and history (up to 500 rows, with a cursor); status and inclusion proofs; MORID name resolution with a Merkle branch; network parameters, the relay registry, payouts, the MRST swarm membership.
Trust model: the gateway does not receive users’ private keys, sign their transfers or decrypt their private data. The client checks header work (KawPow over 124 bytes), chain continuity from its own anchor, Merkle branches, block roots, filters and the built-in genesis. A node failure is reported as a failure. Compare with an independent source or your own node to check whether the gateway is showing the chain with the most cumulative work.
Protection: 10 requests per second with a burst of 20 per client, 2 with a burst of 5 for sync; request bodies up to 1 MiB, transactions up to 500,000 bytes; amounts in responses are whole atoms only.
10. Messenger and the relay swarm
The following section describes the intended messenger design. Some metadata protection requirements are not yet met on the closed testnet. All relays on the closed testnet are operated by the project. Some metadata is still visible to their operators. Further protection of this data is planned for the open testnet. See known limitations.
10.1 Encryption and the envelope
Sessions use vodozemac (Olm): Curve25519 and Ed25519, 3DH and Double Ratchet, forward secrecy. The safety number is built from both identity keys. Prekey bundles are stored on relays: a signed prekey and one-time prekeys. Each one-time prekey is handed out at most once.
The envelope: the recipient's mailbox, an envelope ID, a nonce, a size "bucket" (1, 4, 16, 64, 256 KiB, then multiples of 256 KiB) and a time to live. The header carries no time and no sender. First contact uses a mailbox derived from the identity key: HKDF(identity key, MORANA/root/v1/relay/mailbox-id), 64 hex characters. Ongoing conversations use separate pair or group mailboxes that change with each epoch.
Contacts connect through an invite morana:contact#… or a short card morana:c#…: the card is encrypted with XChaCha20-Poly1305, the key is in the link itself, and the relay stores only ciphertext. .morm attachments are under XChaCha20-Poly1305, up to 8 MiB, kept for 7 days. Receipts are end-to-end: a relay knows only "accepted", "stored", "confirmed by the recipient" and "expired"; a relay signs its storage receipt after writing to disk. Groups use sender keys; there are no channels.
10.2 The swarm
A relay is an HTTPS server whose transport key is separate from its identity. The app selects up to five relays for a mailbox using a BLAKE3 rendezvous hash over the network, the mailbox and the relay. With 5 relays selected, a message is accepted after 4 confirm storage. Relays copy envelopes to their neighbors in the selected group in a single hop, replication factor 3.
The app takes the swarm's membership from the chain (MRST, §4.1). While the network still has few relays, apps also check against a relay list signed by the project; that list does not replace the on-chain record. On top of HTTPS there is an onion layer (X25519); the client's Tor is the built-in Arti; the connection order is direct, then bridges, then VPN. Onion routing is a single hop to the relay. Against spam: blind tokens (RFC 9474) on first contact, quotas and retention limits; there is no proof of work per message.
| Storage limit | Value |
|---|---|
| Envelope | up to 64 KiB |
| Mailbox | up to 100 MiB and up to 5,000 envelopes |
| Message retention | 14 days |
| Registration bundle retention | 90 days |
| Relay database | up to 50 GiB, up to 200,000 queued envelopes, up to 50,000 mailboxes |
When full, a relay answers 507, and what it already holds stays readable. A relay sees only the recipient's mailbox, the envelope ID, the nonce, the size bucket and the time to live.
10.3 Apps and the chain
The app runs on Linux, Windows, macOS, Android and iPhone. From the messenger you can register a relay, register a name (commit-reveal) and transfer a name; the app takes the name price from the gateway and will not build the transaction without a current price. There is no separate payment by the user for a mailbox.
11. Mining and the pool
Stratum: the project pool on port 3032 (TCP). Difficulty adjusts itself: start 0.001, minimum 0.00025, maximum 0.05, target — one share per worker approximately every 10 s, retargeting every 60 s, 30% variance.
Coinbase: the pool builds the coinbase from the template's required outputs — the developer share, the relay share, MRST — and the rest goes to the pool's address. The pool recomputes the reward itself and refuses on any mismatch with the node.
Payouts: PPLNS (factor 0.5), a 1% pool fee, a minimum payout of 1 XMOR, payouts every 600 s. A miner sets their own payout threshold in the stratum password: pl=N. The threshold is stored per address, applied after valid shares, within the pool's bounds and no more than once a day — the first value of the day wins. Without pl= the pool's threshold applies.
12. Releases and signature checks
Versions follow SemVer, one per component; the tag morana/vX.Y.Z goes on the commit of the artifact that was released. File name: <component>-<vX.Y.Z>-<target>+<12 hex>.<extension>. Each release comes with a manifest, a CycloneDX SBOM and SHA256SUMS with the signature SHA256SUMS.sig (minisign). Verifying a release signature requires the project’s public key. If no key is published on the verification page, its instructions cannot be used to verify the signature. How to check a downloaded file: Verify Your Download.
13. The path to mainnet
Mainnet rule activation heights are set in a node release before launch. Emergency shutdown and pool sealing are built into the software; their activation heights are set separately.
- Closed testnet. Participation is by invitation. This stage includes four weeks of testing relay and name economics, followed by a report with measurements.
- Stress testing. Malformed transactions, extended fuzzing runs, reference-vector checks and tests of the emergency switch. Before the open testnet, a week of attack and service-failure exercises checks the network’s resilience. Reported bugs are investigated and fixes are checked again.
- Open testnet. Open participation and publication of the source code, with testing by users outside the project.
- Mainnet. Launch once the readiness conditions are met. The working target is Q1–Q2 2027, not a promised date.
On testnet, private transfers and names activate at height 1, the relay registry and payouts at height 2, and MRST and MNST commitments at height 10,080. The emergency shutdown and pool sealing are inactive.
Mainnet is targeted for Q1–Q2 2027: a working target, not a promised date.
More: Network Roadmap.