<p align="center">
<a href="https://pypi.org/project/merkly/">
<img alt="Merkly" src="https://raw.githubusercontent.com/olivmath/merkly/main/assets/merkly-banner.png" width="1000">
</a>
</p>
<p align="center">The simple and easy implementation of Python Merkle Tree.</p>
---
<p align="center">
<a href="https://pypi.org/project/merkly/">
<img src="https://img.shields.io/pypi/v/merkly">
</a>
<a href="https://github.com/olivmath/merkly/actions/workflows/ci.yml">
<img src="https://github.com/olivmath/merkly/actions/workflows/ci.yml/badge.svg?branch=main">
</a>
<a href="https://pypi.org/project/merkly/">
<img src="https://img.shields.io/pypi/pyversions/merkly">
</a>
<a href="https://pypi.org/project/merkly/">
<img src="https://img.shields.io/pypi/dm/merkly">
</a>
<a href="https://github.com/olivmath/merkly/graphs/code-frequency">
<img src="https://img.shields.io/github/commit-activity/m/olivmath/merkly">
</a>
<a href="https://github.com/olivmath/merkly/blob/main/LICENSE">
<img src="https://img.shields.io/pypi/l/merkly">
</a>
</p>
---
## Table of Contents
- [Credits](#credits)
- [Documentation](#Documentation)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [License](#license)
## Credits
[![GitHub Contributors Image](https://contrib.rocks/image?repo=olivmath/merkly)](https://github.com/olivmath/merkly/graphs/contributors)
## 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**
```python
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)**
```python
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']
######## comming soon!
# 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**
```python
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**
```python
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**
```python
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 |
| Accelerator code with Rust | 🏗️ Alpha | 1.1.0 |
| Tutorial how to use with solidity | 🖊️ Design | x.x.x |
| Tutorial how to use with MerkleTreeJS | 🖊️ Design | x.x.x |
## Contributing
- Before read a code of conduct: **[CODE_OF_CONDUCT](CODE_OF_CONDUCT.md)**
- Follow the guide of development: **[CONTRIBUTING](CONTRIBUTING.md)**
## License
[MIT](LICENSE)
Raw data
{
"_id": null,
"home_page": "https://github.com/olivmath/merkly.git",
"name": "merkly",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8,<4.0",
"maintainer_email": "",
"keywords": "merkle-tree,merkle-proof,merkle-root,keccak256,blockchain",
"author": "Lucas Oliveira",
"author_email": "olivmath@protonmail.com",
"download_url": "https://files.pythonhosted.org/packages/b8/84/79fcc88c46eda5b922da7d685eb1e26d2c1c8a6f7977c790899d55f12155/merkly-1.0.2.tar.gz",
"platform": null,
"description": "<p align=\"center\">\n <a href=\"https://pypi.org/project/merkly/\">\n <img alt=\"Merkly\" src=\"https://raw.githubusercontent.com/olivmath/merkly/main/assets/merkly-banner.png\" width=\"1000\">\n </a>\n</p>\n\n<p align=\"center\">The simple and easy implementation of Python Merkle Tree.</p>\n\n---\n\n<p align=\"center\">\n <a href=\"https://pypi.org/project/merkly/\">\n <img src=\"https://img.shields.io/pypi/v/merkly\">\n </a>\n <a href=\"https://github.com/olivmath/merkly/actions/workflows/ci.yml\">\n <img src=\"https://github.com/olivmath/merkly/actions/workflows/ci.yml/badge.svg?branch=main\">\n </a>\n <a href=\"https://pypi.org/project/merkly/\">\n <img src=\"https://img.shields.io/pypi/pyversions/merkly\">\n </a>\n <a href=\"https://pypi.org/project/merkly/\">\n <img src=\"https://img.shields.io/pypi/dm/merkly\">\n </a>\n <a href=\"https://github.com/olivmath/merkly/graphs/code-frequency\">\n <img src=\"https://img.shields.io/github/commit-activity/m/olivmath/merkly\">\n </a>\n <a href=\"https://github.com/olivmath/merkly/blob/main/LICENSE\">\n <img src=\"https://img.shields.io/pypi/l/merkly\">\n </a>\n</p>\n\n---\n\n## Table of Contents\n\n- [Credits](#credits)\n- [Documentation](#Documentation)\n- [Roadmap](#roadmap)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Credits\n\n[![GitHub Contributors Image](https://contrib.rocks/image?repo=olivmath/merkly)](https://github.com/olivmath/merkly/graphs/contributors)\n\n## Documentation\n\n**HOW TO INSTALL**\n\n```\npoetry add merkly\n```\n\n```\npip install merkly\n```\n\n**HOW TO WORKS**\n\n> **WARNING:** We use keccak-256 under-the-hood if you dont pass your hash function\n\nThis library provides a clean and easy to use implementation of the Merkle Tree with the following features:\n\n- Create Leaf\n- Create Root\n- Create Proof\n- Verify Proof\n\n**HOW TO USE**\n\n**Creating a Merkle Tree**\n\n```python\nfrom merkly.mtree import MerkleTree\nfrom typing import Callable\n\n# choose any hash function that is of type (bytes, bytes) -> bytes\nmy_hash_function: Callable[[bytes, bytes], bytes] = lambda x, y: x + y\n\n# create a Merkle Tree\nmtree = MerkleTree(['a', 'b', 'c', 'd'], my_hash_function)\n\n# show original input\nassert mtree.raw_leaves == ['a', 'b', 'c', 'd']\n\n# hashed leaves\nassert mtree.leaves == [b'a', b'b', b'c', b'd']\n\n# shorted hashed leaves\nassert mtree.short_leaves == [b'a', b'b', b'c', b'd']\n```\n\n**Creating a Default Merkle Tree (with Keccak256)**\n\n```python\nfrom merkly.mtree import MerkleTree\n\n# create a Merkle Tree with keccak256\nmtree = MerkleTree(['a', 'b', 'c', 'd'])\n\n# show original input\nassert mtree.raw_leaves == ['a', 'b', 'c', 'd']\n\n# hashed leaves (just bytes)\nassert mtree.leaves == [\n 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'\n]\n\n# shorted hashed leaves\nassert mtree.short_leaves == [b':\\xc2', b'\\xb5U', b'\\x0bB', b'\\xf1\\x91']\n\n\n######## comming soon!\n\n# human leaves\nassert mtree.human_leaves == [\n \"3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb\",\n \"b5553de315e0edf504d9150af82dafa5c4667fa618ed0a6f19c69b41166c5510\",\n \"0b42b6393c1f53060fe3ddbfcd7aadcca894465a5a438f69c87d790b2299b9b2\",\n \"f1918e8562236eb17adc8502332f4c9c82bc14e19bfc0aa10ab674ff75b3d2f3\",\n]\n# shorted human hashed leaves\nassert mtree.human_short_leaves = [\"3ac2\", \"b555\", \"0b42\", \"f191\"]\n```\n\n**Creating a Root**\n\n```python\nfrom merkly.mtree import MerkleTree\n\n# create a Merkle Tree\nmtree = MerkleTree(['a', 'b', 'c', 'd'])\n\n# get root of tree (This is compatible with MerkleTreeJS)\nassert mtree.root.hex() == '68203f90e9d07dc5859259d7536e87a6ba9d345f2552b5b9de2999ddce9ce1bf'\n```\n\n**Creating Proof of a leaf**\n\n```python\nfrom merkly.mtree import MerkleTree\nfrom merkly.node import Node, Side\n\n# create a Merkle Tree\nmtree = MerkleTree(['a', 'b', 'c', 'd'])\n\n# get proof of a `raw` leaf\nassert mtree.proof('b') == [\n Node(data=b\"3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb\", side=Side.LEFT),\n Node(data=b\"d253a52d4cb00de2895e85f2529e2976e6aaaa5c18106b68ab66813e14415669\", side=Side.RIGHT)\n]\n```\n\n**Checking the proof of a sheet**\n\n```python\nfrom merkly.mtree import MerkleTree\nfrom merkly.node import Node, Side\n\n\n# create a Merkle Tree\nmtree = MerkleTree(['a', 'b', 'c', 'd'])\n\n# get proof of a raw leaf\np = [\n Node(\n data=b\"3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb\",\n side=Side.LEFT\n ),\n Node(\n data=b\"d253a52d4cb00de2895e85f2529e2976e6aaaa5c18106b68ab66813e14415669\",\n side=Side.RIGHT\n )\n]\n\n# verify your proof of raw leaf\nassert mtree.verify(p, 'b') == True\n```\n\n## Roadmap\n\n| Feature | Status | Version |\n| ------------------------------------- | ----------- | ------- |\n| Auto deploy PyPi | \u2705 Deployed | 0.2.0 |\n| Create Root | \u2705 Deployed | 0.4.0 |\n| Create Proof | \u2705 Deployed | 0.5.0 |\n| Verify Proof | \u2705 Deployed | 0.6.0 |\n| Use any Hash function | \u2705 Deployed | 0.7.0 |\n| Leafs of any size | \u2705 Deployed | 0.8.0 |\n| Security deprecation pysha3 | \u2705 Deployed | 0.8.1 |\n| Compatible with MerkleTreeJs | \u2705 Deployed | 1.0.0 |\n| First Issue solved by community | \u2705 Deployed | 1.0.0 |\n| Accelerator code with Rust | \ud83c\udfd7\ufe0f Alpha | 1.1.0 |\n| Tutorial how to use with solidity | \ud83d\udd8a\ufe0f Design | x.x.x |\n| Tutorial how to use with MerkleTreeJS | \ud83d\udd8a\ufe0f Design | x.x.x |\n\n## Contributing\n\n- Before read a code of conduct: **[CODE_OF_CONDUCT](CODE_OF_CONDUCT.md)**\n- Follow the guide of development: **[CONTRIBUTING](CONTRIBUTING.md)**\n\n## License\n\n[MIT](LICENSE)\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "\ud83c\udf33 The simple and easy implementation of Merkle Tree",
"version": "1.0.2",
"project_urls": {
"Documentation": "https://pypi.org/project/merkly/",
"Homepage": "https://github.com/olivmath/merkly.git",
"Repository": "https://github.com/olivmath/merkly.git"
},
"split_keywords": [
"merkle-tree",
"merkle-proof",
"merkle-root",
"keccak256",
"blockchain"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "241dcb185f22e25473fe69630e500616fe92185a95823b5229bfad961e8210a1",
"md5": "081f0f9c305a8269392f3640849ef2bc",
"sha256": "b6acae8a8d31f9ad1647c8b9cdaf73621151106d1dc3e0856423f23cbe386023"
},
"downloads": -1,
"filename": "merkly-1.0.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "081f0f9c305a8269392f3640849ef2bc",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8,<4.0",
"size": 7979,
"upload_time": "2023-12-31T03:28:39",
"upload_time_iso_8601": "2023-12-31T03:28:39.290294Z",
"url": "https://files.pythonhosted.org/packages/24/1d/cb185f22e25473fe69630e500616fe92185a95823b5229bfad961e8210a1/merkly-1.0.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "b88479fcc88c46eda5b922da7d685eb1e26d2c1c8a6f7977c790899d55f12155",
"md5": "e9ca7bf441f9847ed00a6e0490e07734",
"sha256": "d5711023141aa45ba6689430984686567a68ed04acd9e1cc7c602d0f37381817"
},
"downloads": -1,
"filename": "merkly-1.0.2.tar.gz",
"has_sig": false,
"md5_digest": "e9ca7bf441f9847ed00a6e0490e07734",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8,<4.0",
"size": 6838,
"upload_time": "2023-12-31T03:28:41",
"upload_time_iso_8601": "2023-12-31T03:28:41.054119Z",
"url": "https://files.pythonhosted.org/packages/b8/84/79fcc88c46eda5b922da7d685eb1e26d2c1c8a6f7977c790899d55f12155/merkly-1.0.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-12-31 03:28:41",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "olivmath",
"github_project": "merkly",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "merkly"
}