This document describes the genesis verification process for Midnight networks. Verification ensures that the generated chain specification is correct and matches the expected Cardano smart contract state.
Genesis verification validates the chain specification before network launch. The process involves five verification steps:
- Cardano Tip Finalization - Verifies the Cardano block has enough confirmations
- Config File Regeneration - Regenerates config files and compares with existing
- LedgerState Verification - Validates genesis state contents from chain-spec-raw.json
- Dparameter Verification - Checks system parameters consistency
- Auth Script Verification - Verifies upgradable contracts share the same authorization script
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Genesis Verification Flow β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Step 0: Cardano Tip Finalization (Mandatory)
ββββββββββββββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββ ββββββββββββββββββββββββ βββββββββββββββββββββββ
β cardano-tip.json βββββββββΆβ midnight-node ββββββΆβ PASS: Block has β
β (block hash) β β verify-cardano-tip- β β enough confirmationsβ
βββββββββββββββββββββββ β finalized β βββββββββββββββββββββββ
ββββββββββββββββββββββββ
βββββββββββββββββββββββ β
β pc-chain-config.jsonββββββββββββββββββ
β (security_parameter)β
βββββββββββββββββββββββ
Step 1: Config File Regeneration
ββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββ ββββββββββββββββββββββββ βββββββββββββββββββββββ
β *-addresses.json βββββββββΆβ midnight-node ββββββΆβ Regenerated β
β (all address files) β β generate-*-genesis β β *-config.json β
βββββββββββββββββββββββ ββββββββββββββββββββββββ βββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββ βββββββββββββββββββββββ
β Existing ββββββββββββββββββββββββββββββββββββββΆβ Compare JSON β
β *-config.json β β (diff check) β
βββββββββββββββββββββββ βββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββ
β PASS: Files match β
β FAIL: Files differ β
βββββββββββββββββββββββ
Step 2: LedgerState Verification
ββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββ ββββββββββββββββββββββββ βββββββββββββββββββββββ
β chain-spec-raw.json βββββββββΆβ midnight-node ββββββΆβ 2a. DustState β
β (genesis_state) β β verify-ledger-state- β β matches config β
βββββββββββββββββββββββ β genesis β βββββββββββββββββββββββ€
ββββββββββββββββββββββββ β 2b. Empty state β
βββββββββββββββββββββββ β β (mainnet only) β
β cnight-config.json ββββββββββββββββββ€ βββββββββββββββββββββββ€
βββββββββββββββββββββββ€ β β 2c. NIGHT supply β
β ledger-parameters- ββββββββββββββββββ β = 24B invariant β
β config.json β βββββββββββββββββββββββ€
βββββββββββββββββββββββ β 2d. LedgerParametersβ
β match config β
βββββββββββββββββββββββ
Step 3: Dparameter Verification
βββββββββββββββββββββββββββββββ
βββββββββββββββββββββββ ββββββββββββββββββββββββ βββββββββββββββββββββββ
β system-parameters- βββββββββΆβ JSON comparison ββββββΆβ 3a. num_registered β
β config.json β β β β _candidates = 0 β
βββββββββββββββββββββββ ββββββββββββββββββββββββ βββββββββββββββββββββββ€
β² β 3b. num_permissionedβ
βββββββββββββββββββββββ β β matches count β
β permissioned- βββββββββββββββββββ βββββββββββββββββββββββ
β candidates- β
β config.json β
βββββββββββββββββββββββ
Step 4: Auth Script Verification
ββββββββββββββββββββββββββββββββ
βββββββββββββββββββββββ ββββββββββββββββββββββββ βββββββββββββββββββββββ
β federated-authority-βββββββββΆβ midnight-node ββββββΆβ 4a. compiled_code β
β addresses.json β β verify-auth-script β β hash = policy_idβ
βββββββββββββββββββββββ€ β β βββββββββββββββββββββββ€
β ics-addresses.json βββββββββΆβ (runs all 3 verify β β 4b. two_stage_policyβ
βββββββββββββββββββββββ€ β commands internally) β β embedded in codeβ
β permissioned- βββββββββΆβ β βββββββββββββββββββββββ€
β candidates- β ββββββββββββββββββββββββ β 4c. observed auth β
β addresses.json β β β matches expectedβ
βββββββββββββββββββββββ β βββββββββββββββββββββββ€
βΌ β 4d. all contracts β
βββββββββββββββββββββββ ββββββββββββββββββββββββ β share same auth β
β Cardano db-sync βββββββββΆβ Query observed β βββββββββββββββββββββββ
β (PostgreSQL) β β auth scripts β
βββββββββββββββββββββββ ββββββββββββββββββββββββ
The midnight-node binary provides several verification commands:
Verifies that a Cardano block hash has enough confirmations based on security_parameter:
midnight-node verify-cardano-tip-finalized --cardano-tip <block_hash>The command checks:
- Block exists in db-sync
- Block has at least
security_parameterconfirmations - Returns the block number and confirmation count
Validates the genesis state from chain-spec-raw.json:
midnight-node verify-ledger-state-genesis \
--chain-spec <path/to/chain-spec-raw.json> \
--cnight-config <path/to/cnight-config.json> \
--ledger-parameters-config <path/to/ledger-parameters-config.json> \
--network <network_name>Outputs status markers:
DUST_STATE_OK- DustState matches cnight-config.jsonEMPTY_STATE_OK- State is empty (mainnet only)SUPPLY_INVARIANT_OK- Total NIGHT supply equals 24BLEDGER_PARAMETERS_OK- LedgerParameters match config
Verifies all upgradable contracts use the expected authorization script:
# Verify all contracts at once
midnight-node verify-auth-script --cardano-tip <block_hash>
# Verify individual contracts
midnight-node verify-federated-authority-auth-script --cardano-tip <block_hash>
midnight-node verify-ics-auth-script --cardano-tip <block_hash>
midnight-node verify-permissioned-candidates-auth-script --cardano-tip <block_hash>For each contract, verification checks:
- The
compiled_codehash matches thepolicy_id(Plutus V3:blake2b_224(0x03 || script_bytes)) - The
two_stage_policy_idis embedded in thecompiled_code - The authorization script observed on Cardano matches the expected value from config
| Variable | Description |
|---|---|
CFG_PRESET |
Network preset (e.g., qanet, preview, devnet) |
DB_SYNC_POSTGRES_CONNECTION_STRING |
PostgreSQL connection to Cardano db-sync |
ALLOW_NON_SSL |
Allow non-SSL database connections (dev only) |
| File | Used By | Description |
|---|---|---|
cardano-tip.json |
All steps | Cardano block hash reference point |
pc-chain-config.json |
Step 0 | Contains security_parameter for finalization check |
chain-spec-raw.json |
Step 2 | Raw chain specification with genesis state |
cnight-config.json |
Steps 1, 2 | cNIGHT genesis configuration |
ics-config.json |
Step 1 | ICS genesis configuration |
federated-authority-config.json |
Step 1 | Federated authority configuration |
permissioned-candidates-config.json |
Steps 1, 3 | Permissioned candidates configuration |
system-parameters-config.json |
Step 3 | System parameters including Dparameter |
ledger-parameters-config.json |
Step 2 | Ledger parameters |
| File | Used By | Description |
|---|---|---|
cnight-addresses.json |
Step 1 | cNIGHT contract addresses |
ics-addresses.json |
Steps 1, 4 | ICS contract addresses with compiled code |
federated-authority-addresses.json |
Steps 1, 4 | Federated authority addresses with compiled code |
permissioned-candidates-addresses.json |
Steps 1, 4 | Permissioned candidates addresses with compiled code |
For a guided verification experience, use the interactive shell script:
./scripts/genesis/genesis-verification.sh-
Build the midnight-node binary (release mode):
cargo build --release -p midnight-node
-
Access to Cardano db-sync database:
- Local:
postgres://cardano@localhost:54322/cexplorer - Or a remote db-sync instance
- Local:
-
Generated chain specification and config files for the network
./scripts/genesis/genesis-verification.shChoose from available networks:
mainnetqanetdevnetgovnetnode-dev-01previewpreprod
Enter when prompted:
-
DB Sync PostgreSQL connection string
- Default:
postgres://cardano@localhost:54322/cexplorer
- Default:
-
Cardano block hash (tip)
- If
cardano-tip.jsonexists, the value is prefilled - Must be a finalized block for reliable verification
- If
The tool runs each step sequentially:
Step 0: Cardano Tip Finalization (Mandatory)
- Verifies the block has enough confirmations
- If not finalized, prompts to continue or abort
Step 1: Config File Regeneration
- Regenerates all config files from addresses
- Compares with existing files
- Reports any differences
Step 2: LedgerState Verification
- Extracts genesis state from chain-spec-raw.json
- Validates DustState, supply invariant, and parameters
Step 3: Dparameter Verification
- Checks system-parameters-config.json consistency
- Verifies num_registered_candidates = 0
- Verifies num_permissioned_candidates matches actual count
Step 4: Auth Script Verification
- Verifies all upgradable contracts
- Checks compiled code hashes
- Confirms authorization scripts match
=================================================================
Midnight Genesis Verification Tool
=================================================================
This tool verifies the chain specification for a network.
It performs the following checks:
0. Cardano Tip Finalization - Verifies the Cardano tip has enough confirmations
1. Config File Regeneration - Regenerates config files and compares with existing
2. LedgerState Verification - Verifies genesis_state contents from chain-spec-raw.json
a. DustState matches cnight-config.json system_tx
b. Empty state for mainnet (no faucet funding)
c. Total NIGHT supply invariance (24B)
d. LedgerParameters match config
3. Dparameter Verification - Verifies system-parameters-config.json consistency
4. Auth Script Verification - Verifies upgradable contracts share the same auth script
>>> Select Network
Available networks:
1) mainnet
2) qanet
...
Select network (1-7): 2
[PASS] Selected network: qanet
>>> Configuration
[INFO] Found cardano tip in res/qanet/cardano-tip.json
Cardano block hash (tip) [0x6b0eda47...]:
Configuration Summary:
Network: qanet
Security Parameter: 432
Cardano Tip: 0x6b0eda47...
>>> Step 0: Verify Cardano Tip is Finalized
Block 12345678 has 500 confirmations (required: 432)
[PASS] Step 0: Cardano tip is finalized!
>>> Step 1: Regenerate and Compare Genesis Config Files
> Regenerating cnight-config.json...
[PASS] cnight-config.json matches
> Regenerating ics-config.json...
[PASS] ics-config.json matches
...
=================================================================
Verification Summary
=================================================================
Results for qanet:
[PASS] Step 0: Cardano Tip Finalization
[PASS] Step 1: Config File Regeneration
[PASS] Step 2: LedgerState Verification
[PASS] Step 3: Dparameter Verification
[PASS] Step 4: Auth Script Verification
[PASS] All verification checks passed!
If Step 0 fails:
- Wait for more Cardano blocks to be produced
- Use a block hash with more confirmations
- Check that db-sync is fully synced
If Step 1 shows differences:
- Review the diff output carefully
- Check if smart contract state changed since generation
- Regenerate config files if needed
If Step 4 fails:
- Verify the address files contain correct
compiled_code - Check that
two_stage_policy_idmatches across contracts - Ensure db-sync has the transaction data for the contracts
export ALLOW_NON_SSL=true # Only for local development!Midnight uses upgradable Cardano smart contracts with a two-stage policy pattern:
- Two-Stage Policy - The governance policy that controls upgrades
- Authorization Script - A Plutus V3 script that references the two-stage policy
For each upgradable contract:
policy_id=blake2b_224(0x03 || compiled_code)compiled_codecontains the embeddedtwo_stage_policy_id- All contracts must share the same authorization script
The verification ensures:
- Hashes are computed correctly
- Policy IDs are embedded correctly
- Observed values on Cardano match expected values