Skip to content

Commit

Permalink
feat(merkle-tree): Contract with tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hudem1 authored and julio4 committed Sep 27, 2024
1 parent 0d03409 commit 263f933
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 29 deletions.
53 changes: 26 additions & 27 deletions listings/applications/merkle_tree/src/contract.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,17 @@ mod Errors {
pub mod MerkleTree {
use core::poseidon::PoseidonTrait;
use core::hash::{HashStateTrait, HashStateExTrait};
use starknet::storage::{
Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerWriteAccess,
StoragePointerReadAccess
};
use super::ByteArrayHashTrait;

#[storage]
struct Storage {
// cannot store Array, therefore use a LegacyMap to simulate an array
hashes: LegacyMap::<usize, felt252>,
hashes_length: usize
pub hashes: Map::<usize, felt252>,
pub hashes_length: usize
}

#[derive(Drop, Serde, Copy)]
Expand All @@ -58,31 +62,27 @@ pub mod MerkleTree {

// first, hash every leaf
let mut i = 0;
while let Option::Some(value) = data
.pop_front() {
_hashes.append(value.hash());
while let Option::Some(value) = data.pop_front() {
_hashes.append(value.hash());

i += 1;
};
i += 1;
};

// then, hash all levels above leaves
let mut current_nodes_lvl_len = data_len;
let mut hashes_offset = 0;

while current_nodes_lvl_len > 0 {
let mut i = 0;
while i < current_nodes_lvl_len
- 1 {
let left_elem = *_hashes.at(hashes_offset + i);
let right_elem = *_hashes.at(hashes_offset + i + 1);
while i < current_nodes_lvl_len - 1 {
let left_elem = *_hashes.at(hashes_offset + i);
let right_elem = *_hashes.at(hashes_offset + i + 1);

let hash = PoseidonTrait::new()
.update_with((left_elem, right_elem))
.finalize();
_hashes.append(hash);
let hash = PoseidonTrait::new().update_with((left_elem, right_elem)).finalize();
_hashes.append(hash);

i += 2;
};
i += 2;
};

hashes_offset += current_nodes_lvl_len;
current_nodes_lvl_len /= 2;
Expand Down Expand Up @@ -116,17 +116,16 @@ pub mod MerkleTree {
) -> bool {
let mut current_hash = leaf;

while let Option::Some(value) = proof
.pop_front() {
current_hash =
if index % 2 == 0 {
PoseidonTrait::new().update_with((current_hash, value)).finalize()
} else {
PoseidonTrait::new().update_with((value, current_hash)).finalize()
};
while let Option::Some(value) = proof.pop_front() {
current_hash =
if index % 2 == 0 {
PoseidonTrait::new().update_with((current_hash, value)).finalize()
} else {
PoseidonTrait::new().update_with((value, current_hash)).finalize()
};

index /= 2;
};
index /= 2;
};

current_hash == root
}
Expand Down
4 changes: 2 additions & 2 deletions src/applications/merkle_tree.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ Here's a quick summary of how it operates and what functionalities it supports:
- Off-chain data: a user's credentials.
- On-chain data: the Merkle root representing the credentials.

### Visual Example
### Visual example

![Diagram of a Merkle Tree](../assets/merkle_root.png)
![Diagram of the Merkle Tree](../assets/merkle_root.png)

The above diagram represents a merkle tree.\
Each leaf node is the hash of some data.\
Expand Down

0 comments on commit 263f933

Please sign in to comment.