Metadata-Version: 2.4
Name: merkle-py
Version: 1.2.11
Summary: Merkle tree for Python
Home-page: https://github.com/cyrildever/merkle-trees/tree/master/packages/py
Author: Cyril Dever
Project-URL: Bug Tracker, https://github.com/cyrildever/merkle-trees/issues
Keywords: python,merkle-tree,merkle
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.6
Description-Content-Type: text/markdown
Dynamic: author
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: home-page
Dynamic: keywords
Dynamic: project-url
Dynamic: requires-python
Dynamic: summary

# merkle-py
_Python implementation of Merkle tree_

![Github tag (latest by date)](https://img.shields.io/github/v/tag/cyrildever/merkle-trees)
![PyPI - Downloads](https://img.shields.io/pypi/dm/merkle-py)
![Github last commit](https://img.shields.io/github/last-commit/cyrildever/merkle-trees)
![Github issues](https://img.shields.io/github/issues/cyrildever/merkle-trees)
![PyPI - License](https://img.shields.io/pypi/l/merkle-py)

This library defines my special implementation in Python of the notorious Merkle trees. Feel free to use it (with the appropriate credits).

Other implementations include: [Go](../go/README.md), [Scala](../scala/README.md) and [TypeScript](../ts/README.md).

### Usage

```console
$ pip install merkle-py
```

Here are some simple examples of how it works:
```python
from merklepy import MerkleTree, MerkleTreeOptions, build_hash_function, SHA_256

options1 = MerkleTreeOptions(doubleHash= True, engine='sha-256', sort=True)
tree1 = MerkleTree(options1)

# Build a tree from the raw data
proofs1 = tree1.add_leaves(True, '1', '2', '3')
root_hash = tree1.get_root_hash()
assert(tree1.depth() == 1)

json = tree1.to_json()

# Build another identical tree from the JSON of the first one
tree2 = tree_from(json)
assert(tree1.size() == tree2.size())
sha256 = build_hash_function(SHA_256)
assert(tree2.size() == proofs1[0].size)
assert(tree2.validate_proof(proofs1[0], sha256('1'), root_hash) == True)

# Enrich with new hashed data
proofs2 = tree2.add_leaves(False,
    bytes.fromhex('1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'),
    bytes.fromhex('abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789')
)
assert(tree2.size() == 5)
assert(tree2.depth() == 2)

# Because the size of the tree has changed, and so has the root hash
assert(proofs1[0].to_string() != proofs2[0].to_string() and tree2.validate_proof(proofs1[0], sha256('1'), root_hash) == False)
```

#### Important note

As you can see from the examples above, for a continuously growing Merkle tree, proofs may not work at all time. You may need either a new proof from the latest tree, or rebuild the old tree, hence the `size` attribute passed within the `MerkleProof` instance. If you don't use a sorted tree and keep a record of the leaves' hashes in the order they were included in the tree, this allows you to rebuild the corresponding tree and therefore use any proof at any time. \
In other words, this implementation is either not made for a growing tree, or should take this behaviour into account when issuing and verifying proofs.



### Tests

```console
$ git clone https://github.com/cyrildever/merkle-trees.git
$ cd merkle-trees/packages/py/
$ pip install -e .
$ python3 -m unittest discover
```


### License

This library is distributed under a MIT license. \
See the [LICENSE](LICENSE) file.


<hr />
&copy; 2022-2026 Cyril Dever. All rights reserved.
