Skip to main content

Merkle Tree

After obtaining a Document instance, you can utilize these methods to examine and verify the current state of the merkle tree.

Get the merkle proof status for a document

After performing a document-related operation (create, update, or drop), the document must be queued for the next merkle tree update. You can verify the document's status in the merkle tree by calling the merkleProofStatus method on a Document object.

Definition

await zkdb.db(databaseName: string)
.collection(collectionName: string)
.findOne(filter: Record<string, any>)
.merkleProofStatus(): Promise<EQueueTaskStatus>;

Parameters

  • None

Returns

  • Promise<EQueueTaskStatus>: Returns the current status of the document's inclusion in the Merkle tree generation process. This indicates whether the document is queued for processing, currently being processed, successfully included, or has encountered errors.
enum EQueueTaskStatus {
Queued = "Queued",
Processing = "Processing",
Success = "Success",
Failed = "Failed",
Unknown = "Unknown",
}
  • Queued: The document has been queued for the next merkle tree update.
  • Processing: The document is currently being processed for the next merkle tree update.
  • Success: The document has been successfully processed and incorporated into the merkle tree.
  • Failed: The document processing has failed and is not included in the merkle tree. This status also indicates that subsequent operations on the document will be blocked until corrective action is taken. Refer to Detect and retry failed operations for more information on how to handle failure.
  • Unknown: The document's status cannot be determined. This should only occur if there is an underlying issue with the zkDatabase.

Example

import { CircuitString, UInt64 } from 'o1js';
import { Schema, ZkDatabase, Permission } from 'zkdb';
import { EQueueTaskStatus } from '@zkdb/common'

const zkdb = await ZkDatabase.connect({
userName: "chiro-user",
privateKey: "EKFTciRxyxshZjimay9sktsn7v5PvmC5zPq7q4JnitHUytxUVnFP",
environment: "node",
// This URL is for test environment
url: "https://api.zkdatabase.org/graphql",
});

await zkdb.auth.signIn();

class Shirt extends Schema.create({
name: CircuitString,
price: UInt64,
}) {}

type TShirt = typeof Shirt;

const collection = await zkdb
.db('zkdb_test')
.collection<TShirt>('test_collection');

await collection.insert({
name: 'Test Shirt',
price: 10n,
});

await collection.insert(
{
name: 'Orochi',
price: 10n ** 9n,
},
Permission.policyStrict()
);

const status = await document.merkleProofStatus();
console.assert([
EQueueTaskStatus.Queued,
EQueueTaskStatus.Processing,
EQueueTaskStatus.Success,
EQueueTaskStatus.Failed,
EQueueTaskStatus.Unknown,
].includes(status))

await zkdb.auth.signOut();

Result:

Once you've confirmed that the document's merkle tree proof status is Success, you can retrieve its merkle proof using the merkleProof method on the Document object. If the status is not Success, the merkle proof may correspond to an empty node.

Get Merkle Proof

Retrieve the merkle proof for a document once its status is Success.

Definition

await zkdb.db(databaseName: string)
.collection(collectionName: string)
.findOne(filter: Record<string, any>)
.merkleProof(): Promise<TMerkleProof[]>;

Parameters

  • None

Returns

  • Promise<TMerkleProof[]>: Returns an array of cryptographic Merkle proofs that demonstrate the document's inclusion in the database's Merkle tree. These proofs can be used to verify document authenticity and integrity without revealing the entire database structure, essential for zero-knowledge verification.
type TMerkleProof = {
sibling: string;
isLeft: boolean;
};

Example

import { CircuitString, UInt64 } from 'o1js';
import { Schema, ZkDatabase, Permission } from 'zkdb';
import { EQueueTaskStatus } from '@zkdb/common'

const zkdb = await ZkDatabase.connect({
userName: "chiro-user",
privateKey: "EKFTciRxyxshZjimay9sktsn7v5PvmC5zPq7q4JnitHUytxUVnFP",
environment: "node",
// This URL is for test environment
url: "https://api.zkdatabase.org/graphql",
});

await zkdb.auth.signIn();

class Shirt extends Schema.create({
name: CircuitString,
price: UInt64,
}) {}

type TShirt = typeof Shirt;

const collection = await zkdb
.db('zkdb_test')
.collection<TShirt>('test_collection');

await collection.insert({
name: 'Test Shirt',
price: 10n,
});

await collection.insert(
{
name: 'Orochi',
price: 10n ** 9n,
},
Permission.policyStrict()
);

let status;
while ((status = await document.merkleProofStatus()) !== EQueueTaskStatus.Success) {
if (status === EQueueTaskStatus.Failed) {
throw new Error('Document processing failed');
}
await new Promise(resolve => setTimeout(resolve, 1000));
}

const proof = await document.merkleProof();
console.assert(proof)

await zkdb.auth.signOut();

Result:

[
{
"sibling": "0x1234...",
"isLeft": true
},
{
"sibling": "0x5678...",
"isLeft": false
}
]

Verify Merkle Proof

Verify a merkle proof against a schema to ensure document integrity.

Definition

zkdb.db(databaseName: string)
.collection(collectionName: string)
.findOne(filter: Record<string, any>)
.merkleProofVerify(schema: Schema, proof: TMerkleProof[]): boolean;

Parameters

  • schema (Schema): The schema class used to validate the document.
  • proof (TMerkleProof[]): The merkle proof to verify.

Returns

  • boolean: Returns true if the Merkle proof successfully validates the document's inclusion in the database at the specified root hash, false if the proof is invalid or the document has been tampered with. This provides cryptographic verification of document authenticity.

Example

import { CircuitString, UInt64 } from 'o1js';
import { Schema, Permission, ZkDatabase } from 'zkdb';

const zkdb = await ZkDatabase.connect({
userName: "chiro-user",
privateKey: "EKFTciRxyxshZjimay9sktsn7v5PvmC5zPq7q4JnitHUytxUVnFP",
environment: "node",
// This URL is for test environment
url: "https://api.zkdatabase.org/graphql",
});

await zkdb.auth.signIn();

class Shirt extends Schema.create({
name: CircuitString,
price: UInt64,
}) {}

type TShirt = typeof Shirt;

const ShirtSchema = new Schema<TShirt>();

const dbTest = zkdb.db('zkdb_test');
const collection = dbTest.collection('Shirt');
const doc = await collection.findOne({ name: 'Shirt 1' });
const proof = await doc.merkleProof();
const isValid = doc.merkleProofVerify(ShirtSchema, proof);

console.log('Proof is valid:', isValid);

await zkdb.auth.signOut();

Result:

Proof is valid: true