-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
41 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,47 @@ | ||
Copy code | ||
# merkle-zeppelin | ||
Yet another MerkleTree library with implementation aligned to openzeppelin implementation | ||
A Merkle Tree library aligned with OpenZeppelin's implementation standards. | ||
|
||
### How Tree is constructed | ||
Animations shows how algorithm builds tree for later checking or counting proofs. | ||
Letters on the bottom represents list of numbers in program memory. | ||
### What's the purpose of Merkle Tree | ||
|
||
![Constructing tree](images/tree_construction.gif) | ||
By storing just one value, the server can confirm whether a specific value belongs to a previously constructed tree.<br> | ||
The server needs to store only the root hash of the tree.<br> | ||
Requests must include the value to be verified along with a list of hashes specific to that value—known as proofs.<br> | ||
This algorithm is particularly valuable when saving storage space is more important than computational power. | ||
|
||
Notice that each node number in final tree when divided by 2 (without rest) gives its parent number. That's why `None` is needed there, otherwise there is no such a rule. | ||
### How the Tree is Constructed | ||
The animation demonstrates the algorithm constructing a tree for proof verification or calculation. The letters at the bottom represent a list of items stored in the program's memory. | ||
|
||
Each element represented by single or few letters is hashed value. | ||
let's assume `a, ..., e` are given values, then `A = hash(a), ..., E = hash(e)` and `AB = hash(A + B) = hash(hash(a) + hash(b))` and so on... | ||
![Constructing the tree](images/tree_construction.gif) | ||
|
||
Using this library you can choose which hash function is used, default `keccak256` is used (as in [original implementation](https://github.com/OpenZeppelin/merkle-tree])) | ||
Note that dividing the number of each node in the final tree by 2 (without remainder) identifies its parent node. The `None` placeholder ensures the first element is indexed at 1, not 0, maintaining this parent-child relationship. | ||
|
||
Each element, represented by one or more letters, is a hashed value. For instance, given `a, ..., e`, we have `A = hash(a), ..., E = hash(e)`, where `AB = hash(A + B) = hash(hash(a) + hash(b))`, and so on. | ||
|
||
This library allows selection of the hash function, with `keccak256` set as the default to match the [OpenZeppelin implementation](https://github.com/OpenZeppelin/merkle-tree). | ||
|
||
### Collecting Proofs | ||
Consider the example below: | ||
|
||
![Collecting proofs](images/collect_proofs.gif) | ||
|
||
To collect proofs for a specific value, locate the leaf containing the hash of that value. Collect the sibling's value, move up to the parent node, and repeat until you reach the root. | ||
|
||
The proofs are the sibling values collected on this path. | ||
|
||
**Note** | ||
- To find a sibling's node number, use `current_node_number ^ 1`. | ||
- To find a parent's node number, use `current_node_number // 2`. | ||
|
||
### Verifying Proofs | ||
|
||
To verify proofs, you only need the root value. For example: | ||
``` | ||
value = b | ||
proofs = [A, E, CD] | ||
``` | ||
1. Hash the value `b` to get `B`. | ||
2. Combine `B` with the first proof and hash result: `hash(A + B) = AB`. | ||
3. Combine `AB` with the second proof and hash result: `hash(AB + E) = ABE`. | ||
4. Combine `ABE` with the third proof and hash result: `hash(ABE + CD) = ABCDE`, which is the *calculated root*. | ||
5. If the *calculated root* matches the stored root value, it confirms that the value `b` is part of the tree. |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.