Code Monkey home page Code Monkey logo

merkly's Introduction

Merkly

The simple and easy implementation of Python Merkle Tree.



Table of Contents

Credits

GitHub Contributors Image

Documentation

HOW TO INSTALL

poetry add merkly
pip install merkly

HOW TO WORKS

WARNING: We use keccak-256 under-the-hood if you dont pass your hash function

This library provides a clean and easy to use implementation of the Merkle Tree with the following features:

  • Create Leaf
  • Create Root
  • Create Proof
  • Verify Proof

HOW TO USE

Creating a Merkle Tree

from merkly.mtree import MerkleTree
from typing import Callable

# choose any hash function that is of type (bytes, bytes) -> bytes
my_hash_function: Callable[[bytes, bytes], bytes] = lambda x, y: x + y

# create a Merkle Tree
mtree = MerkleTree(['a', 'b', 'c', 'd'], my_hash_function)

# show original input
assert mtree.raw_leaves == ['a', 'b', 'c', 'd']

# hashed leaves
assert mtree.leaves == [b'a', b'b', b'c', b'd']

# shorted hashed leaves
assert mtree.short_leaves == [b'a', b'b', b'c', b'd']

Creating a Default Merkle Tree (with Keccak256)

from merkly.mtree import MerkleTree

# create a Merkle Tree with keccak256
mtree = MerkleTree(['a', 'b', 'c', 'd'])

# show original input
assert mtree.raw_leaves == ['a', 'b', 'c', 'd']

# hashed leaves (just bytes)
assert mtree.leaves == [
    b':\xc2%\x16\x8d\xf5B\x12\xa2\\\x1c\x01\xfd5\xbe\xbf\xea@\x8f\xda\xc2\xe3\x1d\xddo\x80\xa4\xbb\xf9\xa5\xf1\xcb', b'\xb5U=\xe3\x15\xe0\xed\xf5\x04\xd9\x15\n\xf8-\xaf\xa5\xc4f\x7f\xa6\x18\xed\no\x19\xc6\x9bA\x16lU\x10', b'\x0bB\xb69<\x1fS\x06\x0f\xe3\xdd\xbf\xcdz\xad\xcc\xa8\x94FZZC\x8fi\xc8}y\x0b"\x99\xb9\xb2', b'\xf1\x91\x8e\x85b#n\xb1z\xdc\x85\x023/L\x9c\x82\xbc\x14\xe1\x9b\xfc\n\xa1\n\xb6t\xffu\xb3\xd2\xf3'
]

# shorted hashed leaves
assert mtree.short_leaves == [b':\xc2', b'\xb5U', b'\x0bB', b'\xf1\x91']


# human leaves
assert mtree.human_leaves == [
    "3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb",
    "b5553de315e0edf504d9150af82dafa5c4667fa618ed0a6f19c69b41166c5510",
    "0b42b6393c1f53060fe3ddbfcd7aadcca894465a5a438f69c87d790b2299b9b2",
    "f1918e8562236eb17adc8502332f4c9c82bc14e19bfc0aa10ab674ff75b3d2f3",
]
# shorted human hashed leaves
assert mtree.human_short_leaves == ["3ac2", "b555", "0b42", "f191"]

Creating a Root

from merkly.mtree import MerkleTree

# create a Merkle Tree
mtree = MerkleTree(['a', 'b', 'c', 'd'])

# get root of tree (This is compatible with MerkleTreeJS)
assert mtree.root.hex() == '68203f90e9d07dc5859259d7536e87a6ba9d345f2552b5b9de2999ddce9ce1bf'

Creating Proof of a leaf

from merkly.mtree import MerkleTree
from merkly.node import Node, Side

# create a Merkle Tree
mtree = MerkleTree(['a', 'b', 'c', 'd'])

# get proof of a `raw` leaf
assert mtree.proof('b') == [
    Node(
        data=b"3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb",
        side=Side.LEFT
    ),
    Node(
        data=b"d253a52d4cb00de2895e85f2529e2976e6aaaa5c18106b68ab66813e14415669",
        side=Side.RIGHT
    )
]

Checking the proof of a sheet

from merkly.mtree import MerkleTree
from merkly.node import Node, Side


# create a Merkle Tree
mtree = MerkleTree(['a', 'b', 'c', 'd'])

# get proof of a raw leaf
p = [
    Node(
        data=b"3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb",
        side=Side.LEFT
    ),
    Node(
        data=b"d253a52d4cb00de2895e85f2529e2976e6aaaa5c18106b68ab66813e14415669",
        side=Side.RIGHT
    )
]

# verify your proof of raw leaf
assert mtree.verify(p, 'b') == True

Roadmap

Feature Status Version
Auto deploy PyPi βœ… Deployed 0.2.0
Create Root βœ… Deployed 0.4.0
Create Proof βœ… Deployed 0.5.0
Verify Proof βœ… Deployed 0.6.0
Use any Hash function βœ… Deployed 0.7.0
Leafs of any size βœ… Deployed 0.8.0
Security deprecation pysha3 βœ… Deployed 0.8.1
Compatible with MerkleTreeJs βœ… Deployed 1.0.0
First Issue solved by community βœ… Deployed 1.0.0
Human readable leaves βœ… Deployed 1.1.0
Accelerator code with Rust πŸ—οΈ Alpha 1.2.0
Tutorial how to use with solidity πŸ–ŠοΈ Design x.x.x
Tutorial how to use with MerkleTreeJS πŸ–ŠοΈ Design x.x.x

Contributing

License

MIT

merkly's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

merkly's Issues

TypeError in MerkleTree Properties in Python 3.8 Environment

Environment

  • Python Version: 3.8
  • Library Version: [VersΓ£o da biblioteca, se aplicΓ‘vel]

Description of the Issue

When running tests using Python 3.8, a TypeError is encountered in the MerkleTree class, specifically in the human_leaves and human_short_leaves properties. This issue does not occur in Python 3.9 or 3.10, indicating it's likely related to type hinting compatibility with Python 3.8.

Error Message

TypeError: 'type' object is not subscriptable

This error occurs when collecting tests that import and use the MerkleTree class.

Steps to Reproduce

  1. Set up a Python 3.8 environment.
  2. Run pytest on the codebase.
  3. Observe the TypeError in the collection phase of the pytest.

Expected Behavior

The MerkleTree class should function correctly without type errors across different Python versions, especially in supported versions like Python 3.8.

Actual Behavior

A TypeError is raised due to the use of Python 3.9+ style list type hints (e.g., list[str]) which are not compatible with Python 3.8.

Possible Solution

Replace the Python 3.9+ list type hints with the Python 3.8 compatible format using the typing module. For instance, change:

@property
def human_leaves(self) -> list[str]:
    ...

to

from typing import List

@property
def human_leaves(self) -> List[str]:
    ...

and similarly for human_short_leaves.

Generate a wrong proof

Describe the bug
The proof is '[961, fc6]', which is not in the tree.

I provided 2 wallet addresses:
wallet = [
'0x5ff...54e',
'0x6fb...942',
]

The code is:
wallet_list = [wallet]
mtree = mtree(wallet_list) # build merkle tree by lib 'merkly'
root = mtree.root # calculate root
leaf = mtree.leafs # calculate leafs
proof = mtree.proof(wallet[0]) # print the first wallet address in the wallet list
print('root', root,
'leaf', leaf,
'proof[0]', proof,
)

the output is :
root :
a3ea60c74884e4d8976733e90e586bc56bf738c18c23208b2c4bab42fcc07d10

leaf:
['96120f2536c0e6873e22a4a4c21d8befd3a60a6a04fc0e840c0afee70b38eb36', 'fc669afbb2103e999115554ddba4fabb9d1ea650308c91c143348ca89cb7c256']

proof: # Why the proof is this? I'm very confused.
[961, fc6]

Exception in root generation for empty tree

Describe the bug
When attempting to retrieve the root for an empty MerkleTree, a RecursionError is encountered.

To Reproduce

>>> from merkly.mtree import MerkleTree
>>> mtree = MerkleTree([])
>>> mtree.root

Expected behavior
I understand that the root for an empty tree isn't really defined, but it would be better to either return None or raise a more deliberate Exception rather than entering into an infinite recursion loop.

Desktop (please complete the following information):

  • OS: MacOS
  • Version 0.8.1

Upgrade Performance

🏎️ More speed

  • The current algorithm is recursive, perhaps an iterative algorithm would be more performant
  • A benchmark test is needed to measure this

Add PYPI classifiers

Is your feature request related to a problem? Please describe.

  • add classifiers to improve pypi searches

Describe the solution you'd like

  • add a field classifiers = [] in pyproject.toml

Describe alternatives you've considered

  • the same as before

Improve docs

  • We need a better issue and PR model
  • We need modern, more expressive labels
  • Update Readme

Improve coverage tests

Describe a new Feature

  • A clear and concise description of the new feature
  • Some context about WHY you want this new feature

Describe what you expect! (Example)

I want Merkly to work like this:

import merkly

data = []
result = merkly.new_feature(data)

assert result == ["new data very cool"]

Implement a Verkle Tree

Describe a new Feature

Study and implement a verkle tree, just for fun

Describe what you expect! (Example)

from merkly.verk import VerkleTree

Docs

Kuszmaul.pdf

Implement compatibility with MerkleTreeJs

Merkly ❀️ MerkleTreeJs

  • Our library does not generate the same merkle root as the library MerkleTreeJs

OBJECTIVE

  • Implement an algorithm that is compatible with Merkletreejs
  • This new algorithm should be optional

Implementation in JS (MerkleTreeJS)

const { MerkleTree } = require('merkletreejs')
const SHA256 = require('crypto-js/sha256')

const leaves = ['a', 'b', 'c', 'd'].map(SHA256)
const tree = new MerkleTree(leaves, SHA256, {})
const root = tree.getRoot().toString('hex')

console.log("SHA256('a'): ", SHA256('a').toString())
console.log("SHA256('a'): ", SHA256('b').toString())
console.log("SHA256('a'): ", SHA256('c').toString())
console.log("SHA256('a'): ", SHA256('d').toString())
console.log("ROOT: ", root)
 
SHA256('a'):  ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb
SHA256('a'):  3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d
SHA256('a'):  2e7d2c03a9507ae265ecf5b5356885a53393a2029d241394997265a1a25aefc6
SHA256('a'):  18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4
ROOT:  14ede5e8e97ad9372327728f5099b95604a39593cac3bd38a343ad76205213e7

Implementation in Merkly

from merkly.mtree import MerkleTree
import hashlib


def sha256(data):
    return hashlib.sha256(data.encode()).hexdigest()

leaves = ["a", "b", "c", "d"]
tree = MerkleTree(leaves, sha256, merkletreejs=True)
root = "tree.root()"

print("SHA256('a'): ", sha256('a'))
print("SHA256('b'): ", sha256('b'))
print("SHA256('c'): ", sha256('c'))
print("SHA256('d'): ", sha256('d'))
print("ROOT: ", root)
SHA256('a'):  ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb
SHA256('a'):  3e23e8160039594a33894f6564e1b1348bbd7a0088d42c4acb73eeaed59c009d
SHA256('a'):  2e7d2c03a9507ae265ecf5b5356885a53393a2029d241394997265a1a25aefc6
SHA256('a'):  18ac3e7343f016890c510e93f935261169d9e3f565436429830faf0934f4f8e4
ROOT:  14ede5e8e97ad9372327728f5099b95604a39593cac3bd38a343ad76205213e7

Compatibility

  • Merkle root
  • Merkle proof
  • Merkle proof verification

Mekle Root FFI

Build Merkle Root using Rust FFI

I want Merkly to work like this:

import merkly

mtree = MerkleTree(['a', 'b', 'c', 'd'], turbo=True)

# build merkle root using Rust by FFI
assert mtree.root.hex() == '68203f90e9d07dc5859259d7536e87a6ba9d345f2552b5b9de2999ddce9ce1bf'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.