MpfTrie — Verified Data Structures
Preview — 0.8.0-preview1: APIs may change before stable release.
What is MpfTrie?
MpfTrie is a production-ready implementation of Merkle Patricia Forestry (MPF) with RocksDB persistence. It provides cryptographically verifiable data structures that are compatible with Aiken’s on-chain proof verification , enabling a pattern where data is stored off-chain in a trie and verified on-chain using Plutus scripts.
Key Features
- RocksDB Persistence — high-performance embedded database
- Aiken Compatible — proofs generated by MpfTrie can be verified by Aiken’s on-chain MPF library
- Batch Operations — atomic batch writes with rollback
Dependency
dependencies {
implementation 'com.bloxbean.cardano:merkle-patricia-forestry:0.8.0-preview1'
implementation 'com.bloxbean.cardano:merkle-patricia-forestry-rocksdb:0.8.0-preview1'
// RocksDB is included transitively
}Quick Start
Basic Usage
import com.bloxbean.cardano.vds.mpf.rocksdb.RocksDbNodeStore;
import com.bloxbean.cardano.vds.mpf.MpfTrie;
// Initialize RocksDB-backed node store
RocksDbNodeStore nodeStore = new RocksDbNodeStore("data/mpf");
// Create trie (Blake2b-256 hashing, Cardano/Aiken compatible)
MpfTrie trie = new MpfTrie(nodeStore);
// Store data (keys are automatically hashed)
trie.put("alice".getBytes(), "balance:100".getBytes());
trie.put("bob".getBytes(), "balance:200".getBytes());
// Get root hash for on-chain verification
byte[] rootHash = trie.getRootHash();
// Retrieve data
byte[] value = trie.get("alice".getBytes()); // "balance:100"
// Cleanup
nodeStore.close();Loading an Existing Trie
RocksDbNodeStore nodeStore = new RocksDbNodeStore("data/mpf");
// Load existing trie with known root hash
byte[] existingRoot = ... // previously stored root hash
MpfTrie trie = new MpfTrie(nodeStore, existingRoot);
byte[] value = trie.get("alice".getBytes());
nodeStore.close();Core API Reference
MpfTrie
The primary API for Cardano developers with automatic key hashing and Aiken compatibility.
// Constructors
MpfTrie(NodeStore store) // Blake2b-256, MPF mode
MpfTrie(NodeStore store, byte[] rootHash) // Load existing trie
// Core operations
void put(byte[] key, byte[] value) // Keys automatically hashed
byte[] get(byte[] key)
void delete(byte[] key)
byte[] getRootHash()
// Proof generation (Aiken-compatible)
Optional<ListPlutusData> getProofPlutusData(byte[] key)
Optional<byte[]> getProofWire(byte[] key)RocksDbNodeStore
Low-level node storage implementation.
// Constructors
RocksDbNodeStore(String dbPath)
RocksDbNodeStore(RocksDB db, ColumnFamilyHandle cfNodes)
RocksDbNodeStore(RocksDB db, ColumnFamilyHandle cfNodes, KeyPrefixer keyPrefixer)
// NodeStore interface
byte[] get(byte[] hash)
void put(byte[] hash, byte[] nodeBytes)
void delete(byte[] hash)
// Batch operations
void withBatch(WriteBatch batch, Callable<?> operation)Proof Generation for Aiken
Generate Plutus-compatible proofs that can be verified on-chain by Aiken’s MPF library:
MpfTrie trie = new MpfTrie(nodeStore);
// Store data
trie.put("account123".getBytes(), accountData);
// Generate proof for on-chain verification
Optional<ListPlutusData> proof = trie.getProofPlutusData("account123".getBytes());
// The proof can be included as a redeemer or datum in a Cardano transaction
// and verified by an Aiken validator using the merkle-patricia-forestry libraryThe root hash stored on-chain (e.g., in a datum) combined with the proof allows the Aiken validator to verify that a specific key-value pair exists in the trie without needing the entire data set on-chain.