01Installation
Python 3.10+, a C++17 compiler, CMake ≥ 3.20, OpenSSL, SQLite3, and Boost headers. On Linux and macOS:
git clone https://github.com/digitalhanaarts/MLabChain
cd MLabChain
./build.sh
python -m pip install -e .
python mlabchain.py demo
On Windows, in PowerShell:
git clone https://github.com/digitalhanaarts/MLabChain
cd MLabChain
./build.ps1
python -m pip install -e .
python mlabchain.py demo
02CLI reference
Node lifecycle
| Command | Description |
|---|---|
init | Create a new chain. Options: --network devnet|testnet|mainnet, --governance-keys, --governance-threshold. |
status | Show height, tip, chain work, pending count, supply. |
validate | Replay the full chain and verify every block, transaction, and account state. |
backup --output FILE | SQLite online backup. Wallet is separate. |
wallet-backup --output FILE | Copy the encrypted wallet file to a new location. |
Wallets and accounts
| Command | Description |
|---|---|
create-wallet | Generate a new Ed25519 keypair and save an encrypted wallet. |
balance --address ADDR | Show balance for an address. |
key-rotate --new-public-key HEX | Replace the account's authorized key. |
transfer --to ADDR --amount N [--fee F] [--mine] | Send Mera. |
submit-multisig-transfer ... | Send Mera from a MERA2 multisig account. |
Challenges and ML work
| Command | Description |
|---|---|
challenge-create --id ID --output PATH ... | Write a challenge manifest. Requires --n-samples, --n-features, --seed, --noise, --train-fraction, --max-epochs. |
challenge-register --manifest PATH --budget N | Register a challenge on-chain with a finite budget. |
challenge-status --challenge-id ID | Show the challenge's current state. |
mine --challenge PATH --config PATH | Train, submit, and seal in one step. |
mine-empty --count N | Seal empty blocks to advance maturity. |
submit-ml ... | Low-level: submit an already-built ML certificate. |
Networking
| Command | Description |
|---|---|
node --port N [--listen-host H] [--peers LIST] [--seconds S] | Run a P2P node. Peers are comma-separated host:port pairs. |
sync --peer host:port | One-shot synchronisation with a peer. |
show-tx --tx-hash HEX | Show a transaction by its hash. |
Inspection and devnet
| Command | Description |
|---|---|
faucet --address ADDR --amount N | Devnet-only mint. Disabled on mainnet by genesis flag. |
demo | End-to-end demonstration on a fresh devnet. |
self-test | Run the C++ core's built-in tests. |
03Wire protocol
The P2P protocol is line-delimited over TCP. Each message is a single
UTF-8 line terminated by \n. The first token before
| identifies the message type.
| Message | Direction | Meaning |
|---|---|---|
PING | → | Liveness probe. |
PONG | ← | Liveness response. |
STATUS | → | Request node status. |
STATUS|H|TIP|WORK | ← | Height, tip hash, cumulative work. |
GETCHAIN | → | Request the full chain. |
BLOCK|<wire> | ← | A single block, hex-encoded fields separated by |. |
END | ← | End of a GETCHAIN response. |
TX|<wire> | both | Relay a signed transaction. |
OK | ← | Message accepted. |
ERROR|msg | ← | Message rejected. |
04Challenge manifest schema
The manifest is a JSON document. Its canonical form — sorted keys, no
whitespace, UTF-8 — is hashed to produce manifest_sha256.
Any deviation from canonical form will change the hash.
{
"challenge_id": "MLC-LINEAR-001",
"description": "Deterministic synthetic linear regression",
"dataset_kind": "synthetic_linear",
"dataset_sha256": "…",
"n_samples": 1200,
"n_features": 4,
"generator_seed": 42,
"generator_noise": 0.1,
"split_rule": "first_fraction",
"train_fraction": 0.8,
"metric": "NMSE",
"baseline_kind": "mean_predictor",
"baseline_nmse": 1.0,
"baseline_model_sha256": null,
"max_epochs": 100,
"verifier": "MLabChain-linear-v4",
"schema_version": 4,
"manifest_sha256": "…"
}
05Transaction types
| Type | Signed by | What it does |
|---|---|---|
TRANSFER | Sender | Move Mera between accounts. |
MULTISIG_TRANSFER | m-of-n signer set | Move Mera from a MERA2 account. |
ML_WORK | Contributor | Submit a training run and claim its reward. |
CHALLENGE_REGISTER | Proposer | Register a challenge with a bond and budget. |
KEY_ROTATE | Current key | Replace the account's authorized public key. |
GOV_PARAM | Governance multisig | Schedule a bounded fee-parameter change. |
FAUCET | — | Devnet-only mint. Rejected on mainnet. |
06Error codes
Errors are returned as ERROR|message on the wire, or
printed as ERROR=message by the core CLI. The most
common ones:
| Message | Cause |
|---|---|
invalid sender address | Address fails the checksum or the prefix check. |
invalid Ed25519 signature | Signature does not verify against the public key and message. |
invalid account nonce | Nonce is not exactly account_nonce + pending_count + 1. |
insufficient balance | Sender balance is less than amount + fee, accounting for pending reservations. |
fee below minimum | Fee is below the current min_fee. |
challenge is not registered | The referenced challenge does not exist on-chain. |
challenge is not active | Submission is before activation or after expiry. |
ML result does not improve challenge best | The new quality is not strictly greater than the current best. |
ML reward mismatch | The claimed reward does not match the formula applied to the marginal delta. |
duplicate ML work claim | The (challenge, dataset, model) tuple was already paid. |
maximum supply exceeded | Issuance would push supply past 100,000,000 MERA. |
challenge reward budget exceeded | Issuance would exceed the challenge's remaining budget. |
unsupported database schema | The SQLite file was created by an incompatible protocol version. |
07Migration from v0.2
v0.3 refuses to open a v0.2 database. This is intentional: the consensus rules changed, and silently replaying old history under new rules would be less safe than an explicit boundary.
To migrate:
python tools/migrate_v2.py \
--input ./old/mera_data/mera.sqlite \
--output ./migration/v2_snapshot.json
The output is a JSON snapshot containing every account's balance and nonce, the old genesis hash, the old tip, and a SHA-256 over the whole snapshot. A production migration is expected to define a new genesis that commits to this snapshot before importing balances.
v0.2 and v0.3 use different reward formulas, different address formats, and different state layouts. A mechanical rewrite of a v0.2 database into a v0.3 one would silently reinterpret history. An explicit migration ceremony — with a signed snapshot that both sides agree on — is slower but auditable.
Next: about the project →