Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/y-pakorn/cw-merkle-tree

Sparse merkle tree with variants implementation for CosmWasm smart contract.
https://github.com/y-pakorn/cw-merkle-tree

Last synced: about 1 month ago
JSON representation

Sparse merkle tree with variants implementation for CosmWasm smart contract.

Awesome Lists containing this project

README

        

CW Merkle Tree




Crates.io


docs.rs

Crates.io

Sparse merkle tree with variants implementation for CosmWasm smart contract

## Variants

### Sparse Merkle Tree

Normal sparse merkle tree with customizable tree level and default leaf.

### Sparse Merkle Tree With History

Like sparse merkle tree but able to check valid root hash with all previous root hashes.

### Sparse Merkle Tree With History Bounded

Like sparse merkle tree but able to check valid root hash with previous root hashes upto specified history level.

## Example Usage

### Hasher

Implement the hasher trait for desired hasher struct.

```rust
#[derive(Clone, Copy, Debug)]
pub struct Blake2;

impl Hasher for Blake2 {
fn hash_two(&self, left: &Uint256, right: &Uint256) -> Result {
let mut hasher = Blake2b512::new();
hasher.update(left.to_be_bytes());
hasher.update(right.to_be_bytes());
Ok(Uint256::from_be_bytes(
hasher.finalize()[0..32]
.try_into()
.map_err(|e: TryFromSliceError| HasherError::Custom(e.to_string()))?,
))
}
}
```

### Merkle Tree

First, instantiate the merkle tree by using `new` constructor function and specify leaf and hasher type.

```rust
const TREE: SparseMerkleTree =
SparseMerkleTree::new("hashes", "leafs", "level", "zeros");
```

Then initialize the tree by invoking the `init` function, preferably in `instantiate` entry point.

```rust
pub fn instantiate(
deps: DepsMut,
_env: Env,
_info: MessageInfo,
_msg: InstantiateMsg,
) -> Result {
let hashed_zero = Blake2.hash_two(&Uint256::zero(), &Uint256::zero())?;
TREE.init(deps.storage, 20, hashed_zero, &Blake2)?;

// ...
}
```

Next, insert a leaf into next available index of the tree by invoking `insert` function, `insert` will return inserted index and the new root.

```rust
let leaf = Blake2.hash_two(&Uint256::one(), &Uint256::one())?;

let (index, new_root) = TREE.insert(&mut storage, leaf, &Blake2)?;

assert_eq!(index, 0);
assert_eq!(
new_root,
Uint256::from_str(
"65270348628983318905821145914244198139930176154042934882987463098115489862117"
)?
);
assert_eq!(new_root, TREE.get_latest_root(&storage)?);
assert!(TREE.is_valid_root(&storage, &new_root)?);
```