@kevincharm/sparse-merkle-tree
Version:
Sparse Merkle Tree implementation in Solidity with accompanying JS library
96 lines (95 loc) • 3.18 kB
TypeScript
export interface Proof {
/** Whether or not the entry exists in the db */
exists: boolean;
/** Leaf hash */
leaf: string;
/** If exists, then will have a value */
value: string | null;
/** Index, derived from key */
index: bigint;
/** 256-bit number; each bit represents whether a sibling subtree is nonzero */
enables: bigint;
/** List of nonzero sibling subtrees */
siblings: string[];
}
export interface UpdateProof extends Proof {
/** H(key, value, 1) */
newLeaf: string;
}
/**
* Hash function that takes 1-3 256-bit numbers and returns a hash digest that
* is also 256 bits.
*/
export type HashFunction = (...inputs: bigint[]) => bigint;
export type DeserialiserFunction = (input: string) => bigint;
export type SerialiserFunction = (input: bigint) => string;
export interface SparseMerkleTreeKVOptions {
zeroElement?: bigint;
hashFn?: HashFunction;
deserialiserFn?: DeserialiserFunction;
serialiserFn?: SerialiserFunction;
}
/**
* SparseMerkleTree
* Raw sparse Merkle tree implementation
*/
export declare class SparseMerkleTree {
db: Map<bigint, [bigint, bigint, bigint?]>;
private _root;
private _depth;
private _zeroElement;
private _hashFn;
private _deserialiserFn;
private _serialiserFn;
constructor(depth: number, options?: SparseMerkleTreeKVOptions);
hash(...inputs: bigint[]): bigint;
get root(): string;
/**
* Get a proof of membership (or non-membership) of a leaf
*
* @param index Index of leaf
* @returns {Proof} Proof of membership (or non-membership)
*/
get(index: bigint): Proof;
/**
* Verify membership of a leaf using a Merkle proof.
*
* @param leaf Leaf = H(key, value, 1)
* @param index Index = H(key), i.e. path of leaf in the Merkle tree
* @param enables 256-bitstring signifying which siblings are non-zero in the path
* @param siblings Non-zero sibling subtree hashes
* @returns {boolean} true if the proof is valid for this tree
*/
verifyProof(leaf: string, index: bigint, enables: bigint, siblings: string[]): boolean;
/**
* Walk down the tree to determine whether a key exists in the database.
*
* @param index Index of leaf
* @returns true if key exists
*/
exists(index: bigint): boolean;
/**
* Insert a (key,value) into the database. Throws if key already exists.
*
* @param index Index of leaf
* @param leaf Value of leaf
* @returns {Proof} Membership of previous (key,value) leaf
*/
insert(index: bigint, leaf: string): UpdateProof;
/**
* Update a value belonging to an existing key. Throws if key does not exist.
*
* @param index Index of leaf
* @param newLeaf New value of leaf
* @returns {Proof} Membership of previous (key,value) leaf
*/
update(index: bigint, newLeaf: string): UpdateProof;
/**
* Update the value of a leaf at a specified index
*
* @param index Index of leaf
* @param newLeaf_ New value of leaf
* @returns {Proof} Membership of previous (key,value) leaf
*/
private upsert;
}