Proof of Membership for Mina
Zero-Knowledge Merkle Tree implementation for Mina Protocol, powered by o1js.
Early Stage Project: This package is under active development. APIs may change as we improve the implementation.
Not Released Yet: This npm package is going through changes. If you need access to the codebase now, please contact us.
Installation
bun add @zkthings/proof-membership-mina
# or
npm install @zkthings/proof-membership-mina
Quick Start
import { ZkMerkleTree, MerkleProver, deployZkApp } from '@zkthings/proof-membership-mina';
import { Mina, PrivateKey } from 'o1js';
// 1. Deploy Merkle Prover Contract
const deployment = await deployZkApp(MerkleProver, {
network: 'local',
proofsEnabled: true
});
// 2. Create and populate Merkle Tree
const zkMerkle = new ZkMerkleTree();
const values = ['Banyan', 'Sakura', 'Tembusu'];
// 3. Generate Proof
const { proof, publicSignals } = await zkMerkle.generateMerkleProof(
values,
'Tembusu',
deployment.deployerAccount
);
// 4. Verify (choose method)
// Off-chain (fast, for testing)
const isValidOffChain = await zkMerkle.verifyProofOffChain(proof, publicSignals);
// On-chain (blockchain verification)
const isValidOnChain = await zkMerkle.verifyProofOnChain(
deployment.contract,
proof,
publicSignals
);
Built on Merkle Proofs
The Zk Merkle Tree for Mina leverages Merkle proofs to ensure efficient and secure verification of data membership within a set. Here's a brief overview:
- Array of Items: Begin with your list of items (e.g., account addresses).
- Tree Structure: Organize these items into a hierarchical tree structure.
- Hashing: Each item is hashed, and these hashes are paired and hashed again.
- Root Hash: This process continues until a single hash, the "root hash," is obtained.
The Merkle root acts as a unique fingerprint for your entire list. To prove that an item is part of the list, a user only needs to share a small set of intermediary hashes, known as a "Merkle proof," that link their item to the root. If the proof hashes align with the root, it verifies that the item belongs to the original list without needing to reveal the entire list.
Moving from Test to Production
Production Usage
// Berkeley Testnet Setup
const Berkeley = Mina.Network('https://proxy.berkeley.minaexplorer.com/graphql');
Mina.setActiveInstance(Berkeley);
// Deploy with your credentials
const deployment = await deployZkApp(MerkleProver, {
network: 'berkeley',
deployer: {
key: PrivateKey.fromBase58('YOUR_PRIVATE_KEY'),
account: deployerAccount
}
});
Architecture
@zkthings/proof-membership-mina
├── ZkMerkleTree # Core Merkle Tree implementation
├── MerkleProver # On-chain verification contract
└── Utils
└── deployZkApp # Deployment helper
Best Practices
Local Development
// Fast local testing
const deployment = await deployZkApp(MerkleProver, {
network: 'local',
proofsEnabled: false // Faster for development
});
Production Deployment
// Secure production setup
const deployment = await deployZkApp(MerkleProver, {
network: 'berkeley',
proofsEnabled: true, // Always true in production
deployer: {
key: deployerKey,
account: deployerAccount
}
});
Contributing
PRs welcome! Check our Contributing Guide.
Support
License
MIT © zkThings