Skip to main content
Version: 2.15.0

Merkle Trees

Merkle trees are a fundamental data structure for collections in o1js, as they allow for efficient proofs of data inclusion. There are several classes of Merkle tree exported by o1js, with various properties.

IndexedMerkleMap​

The IndexedMerkleMap is a wrapper around a basic Merkle tree that offers a convenient interface, with a key-value like API for getting and setting values.

Both the key and the value in of the map can be typed as Field or BigInt.

note

IndexedMerkleMap has a maximum height of 52, which means it can store up to 2^52 (roughly four quadrillion) elements. Therefore, it is not suitable for use cases requiring collision resistance over a larger domain, but it is suitable for most applications. For instance, an app with billions of users could have a leaf for each user stored in an IndexedMerkleMap.

const height = 4; // 2 ^ 4 = 16 leaves
class MyIndexedMerkleMap extends IndexedMerkleMap(height) {}

const map = new MyIndexedMerkleMap();
map.insert(1n, 20n);
map.insert(2n, 30n);

map.get(1n); // 20n
map.getOption(2n).orElse(0n); // 30n, Use .getOption to safely access values that may not exist
map.getOption(3n).orElse(0n); // 0n, values default to 0n

MerkleTree​

The MerkleTree class is a general sparse Merkle tree implementation in JavaScript (not provable). It is used to build and store data in a tree structure, and exposes methods for generating witnesses and roots to use within provable code.

MerkleWitness​

The MerkleWitness class is a proof of inclusion for a specific leaf in a MerkleTree. The MerkleWitness class is provable, so it can be used as an input into a provable function. The witness consists of the leaf index and the hashes of sibling nodes, needed to generate the root hash of the tree.

const tree = new MerkleTree(height);
tree.setLeaf(0n, Field(10));
tree.setLeaf(1n, Field(20));

tree.getLeaf(0n); // Field(10)
tree.getLeaf(1n); // Field(20)
tree.getLeaf(2n); // Field(0), values default to Field(0)

class MyMerkleWitness extends MerkleWitness(height) {}
const w = new MyMerkleWitness(tree.getWitness(1n));

MerkleList​

The MerkleList is a class which represents a dynamic list of elements that can be committed to a single hash. This is a useful data structure when editing a list is required within a proof. To pass a list into a proof as an argument, a provable array may be simpler.

// Create a MerkleList with any provable type, e.g. Field
class MyList extends MerkleList.create(Field) {}

let list = MyList.empty();
list.push(Field(5));
let element = list.pop(); // Field(5)

Read more at the language reference: IndexedMerkleMap, MerkleTree, MerkleWitness, MerkleList.