From 263f9330bcb33ea8b792db149a0fd71ade40be81 Mon Sep 17 00:00:00 2001 From: Hugo Demeyere Date: Wed, 26 Jun 2024 12:47:36 +0900 Subject: [PATCH] feat(merkle-tree): Contract with tests --- .../merkle_tree/src/contract.cairo | 53 +++++++++---------- src/applications/merkle_tree.md | 4 +- 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/listings/applications/merkle_tree/src/contract.cairo b/listings/applications/merkle_tree/src/contract.cairo index 9d17bc4f..02599cbe 100644 --- a/listings/applications/merkle_tree/src/contract.cairo +++ b/listings/applications/merkle_tree/src/contract.cairo @@ -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::, - hashes_length: usize + pub hashes: Map::, + pub hashes_length: usize } #[derive(Drop, Serde, Copy)] @@ -58,12 +62,11 @@ 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; @@ -71,18 +74,15 @@ pub mod MerkleTree { 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; @@ -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 } diff --git a/src/applications/merkle_tree.md b/src/applications/merkle_tree.md index 196b7b28..13d7b021 100644 --- a/src/applications/merkle_tree.md +++ b/src/applications/merkle_tree.md @@ -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.\