About midnight-storage
A skill outlining Midnight’s storage stack for readers studying how blockchain state is organized, committed, and queried. It explains ParityDB, the Patricia-Merkle trie, storage-key hashing, and available query paths.
Key features
- 01ParityDB state persistence
- 02Patricia-Merkle trie state commitments
- 03twoxhash storage keys
- 04Per-block state commit flow
- 05RPC and GraphQL query paths
Use cases
- 01Understand Midnight state persistence
- 02Review how state roots are computed
- 03Find paths for contract-state queries
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ kali-decoder/ midnight-skills --skill midnight-storageAfter installing, type/midnight-storagein Claude Code to confirm it loaded.
Details
From the project READMEStorage
Midnight is built on the Polkadot SDK (Substrate) and uses ParityDB as its default database backend.
Storage stack
flowchart TB
subgraph Runtime["Runtime execution"]
STF["State transition function (WASM)"]
PM["pallet-midnight + other pallets"]
end
subgraph Trie["State layer"]
MPT["Patricia-Merkle trie"]
T2H["twoxhash — storage key generation"]
MPT --- T2H
end
subgraph Persist["Persistence"]
PDB["ParityDB — key-value store"]
end
STF --> PM
PM --> MPT
MPT --> PDB
MPT --> Commit["State root commitment per block"]
ParityDB
ParityDB is a fast key-value store designed for blockchain workloads.
- Stores all on-chain state.
- Default backend for Substrate/Polkadot SDK chains including Midnight.
- Optimized for high write throughput during block import and state commits.
Patricia-Merkle trie
The trie is the underlying data structure for state commitments.
| Property | Benefit |
|---|---|
| Merkle structure | Tamper-evident state root per block |
| Inclusion proofs | Efficient verification of contract state, balances, etc. |
| Incremental updates | Only changed paths recomputed per block |
Canonical ledger state from runtime pallets (including pallet-midnight) is organized in this trie and persisted via ParityDB.
flowchart LR
BlockN["Block N state root"] --> Root["Trie root hash"]
Root --> Leaf1["Storage item A"]
Root --> Leaf2["Storage item B"]
Root --> Leaf3["Contract state …"]
Query["RPC / light client"] --> Proof["Merkle inclusion proof"]
Proof --> Leaf2
twoxhash (storage keys)
twoxhash generates storage keys within the trie.
| Aspect | Detail |
|---|---|
| Type | Non-cryptographic hash |
| Purpose | Fast internal key-value lookups |
| Properties | Speed, low collision rate |
| Not for | Security-sensitive hashing (use Blake2-256) |
twoxhash significantly improves trie performance for map lookups without the cost of cryptographic hashing on every key derivation.
See midnight-cryptography/ for the full hash/signature split.
State commit flow
Every block:
- Runtime executes transactions and updates pallet storage.
- Changed trie nodes are computed; state root is derived.
- Midnight Ledger commitment is persisted alongside standard Substrate state (
pallet-midnight). - ParityDB persists the updated trie backing store.
sequenceDiagram
participant RT as Runtime
participant Trie as Patricia-Merkle trie
participant PM as pallet-midnight
participant DB as ParityDB
RT->>Trie: Apply storage writes (twoxhash keys)
RT->>PM: Commit ledger state
Trie->>Trie: Compute new state root
PM->>DB: Persist ledger commitment
Trie->>DB: Persist trie nodes
Querying storage
| Access path | Use case |
|---|---|
state_getStorage (RPC) | Raw storage key reads |
midnight_contractState (RPC) | Contract-specific state |
| Indexer GraphQL | Application-friendly contract/event queries |
Related skills
midnight-onchain-logic/— what gets written to storagemidnight-cryptography/— Blake2-256 vs twoxhashmidnight-rpc/— reading state via JSON-RPCmidnight-transactions/— how txs trigger storage updates