type Node = string | bigint; type Key = Node; type Value = Node; type EntryMark = Node; type Entry = [Key, Value, EntryMark]; type ChildNodes = Node[]; type Siblings = Node[]; type HashFunction = (childNodes: ChildNodes) => Node; interface EntryResponse { entry: Entry | Node[]; matchingEntry?: Entry | Node[]; siblings: Siblings; } interface MerkleProof extends EntryResponse { root: Node; membership: boolean; } /** * SparseMerkleTree class provides all the functions to create a sparse Merkle tree * and to take advantage of its features: {@linkcode SMT.add}, {@linkcode SMT.get}, * {@linkcode SMT.update}, {@linkcode SMT.delete}, {@linkcode SMT.createProof}, * {@linkcode SMT.verifyProof}. * To better understand the code below it may be useful to describe the terminology used: * * **nodes**: every node in the tree is the hash of the two child nodes (`H(x, y)`); * * **root node**: the root node is the top hash and since it represents the whole data * structure it can be used to certify its integrity; * * **leaf nodes**: every leaf node is the hash of a key/value pair and an additional * value to mark the node as leaf node (`H(x, y, 1)`); * * **entry**: a tree entry is a key/value pair used to create the leaf nodes; * * **zero nodes**: a zero node is an hash of zeros and in this implementation `H(0,0) = 0`; * * **siblings**: the children of a parent node are siblings; * * **path**: every entry key is a number < 2^256 that can be converted in a binary number, * and this binary number is the path used to place the entry in the tree (1 or 0 define the * child node to choose); * * **matching node**: when an entry is not found and the path leads to another existing entry, * this entry is a matching entry and it has some of the first bits in common with the entry not found; * * **depth**: the depth of a node is the length of the path to its root. */ declare class SMT { private hash; private zeroNode; private entryMark; private bigNumbers; private nodes; root: Node; /** * Initializes the SparseMerkleTree attributes. * @param hash Hash function used to hash the child nodes. * @param bigNumbers BigInt type enabling. */ constructor(hash: HashFunction, bigNumbers?: boolean); /** * Gets a key and if the key exists in the tree the function returns the * value, otherwise it returns 'undefined'. * @param key A key of a tree entry. * @returns A value of a tree entry or 'undefined'. */ get(key: Key): Value | undefined; /** * Adds a new entry in the tree. It retrieves a matching entry * or a zero node with a top-down approach and then it updates all the * hashes of the nodes in the path of the new entry with a bottom-up approach. * @param key The key of the new entry. * @param value The value of the new entry. */ add(key: Key, value: Value): void; /** * Updates a value of an entry in the tree. Also in this case * all the hashes of the nodes in the path of the entry are updated * with a bottom-up approach. * @param key The key of the entry. * @param value The value of the entry. */ update(key: Key, value: Value): void; /** * Deletes an entry in the tree. Also in this case all the hashes of * the nodes in the path of the entry are updated with a bottom-up approach. * @param key The key of the entry. */ delete(key: Key): void; /** * Creates a proof to prove the membership or the non-membership * of a tree entry. * @param key A key of an existing or a non-existing entry. * @returns The membership or the non-membership proof. */ createProof(key: Key): MerkleProof; /** * Verifies a membership or a non-membership proof. * @param merkleProof The proof to verify. * @returns True if the proof is valid, false otherwise. */ verifyProof(merkleProof: MerkleProof): boolean; /** * Searches for an entry in the tree. If the key passed as parameter exists in * the tree, the function returns the entry, otherwise it returns the entry * with only the key, and when there is another existing entry * in the same path it returns also this entry as 'matching entry'. * In any case the function returns the siblings of the path. * @param key The key of the entry to search for. * @returns The entry response. */ private retrieveEntry; /** * Calculates nodes with a bottom-up approach until it reaches the root node. * @param node The node to start from. * @param path The path of the key. * @param siblings The siblings of the path. * @returns The root node. */ private calculateRoot; /** * Adds new nodes in the tree with a bottom-up approach until it reaches the root node. * @param node The node to start from. * @param path The path of the key. * @param siblings The siblings of the path. * @param i The index to start from. * @returns The root node. */ private addNewNodes; /** * Deletes nodes in the tree with a bottom-up approach until it reaches the root node. * @param node The node to start from. * @param path The path of the key. * @param siblings The siblings of the path. */ private deleteOldNodes; /** * Checks if a node is a leaf node. * @param node A node of the tree. * @returns True if the node is a leaf, false otherwise. */ private isLeaf; /** * Checks the parameter type. * @param parameter The parameter to check. */ private checkParameterType; } /** * Converts a hexadecimal number to a binary number. * @param n A hexadecimal number. * @returns The relative binary number. */ declare function hexToBin(n: string): string; /** * Returns the binary representation of a key. For each key it is possible * to obtain an array of 256 padded bits. * @param key The key of a tree entry. * @returns The relative array of bits. */ declare function keyToPath(key: string | bigint): number[]; /** * Returns the index of the last non-zero element of an array. * If there are only zero elements the function returns -1. * @param array An array of hexadecimal or big numbers. * @returns The index of the last non-zero element. */ declare function getIndexOfLastNonZeroElement(array: any[]): number; /** * Returns the first common elements of two arrays. * @param array1 The first array. * @param array2 The second array. * @returns The array of the first common elements. */ declare function getFirstCommonElements(array1: any[], array2: any[]): any[]; /** * Checks if a number is a hexadecimal number. * @param n A hexadecimal number. * @returns True if the number is a hexadecimal, false otherwise. */ declare function checkHex(n: string): boolean; export { type ChildNodes, type Entry, type EntryMark, type EntryResponse, type HashFunction, type Key, type MerkleProof, type Node, SMT, type Siblings, type Value, checkHex, getFirstCommonElements, getIndexOfLastNonZeroElement, hexToBin, keyToPath };