{"id":16701453,"url":"https://github.com/ferd/merklet","last_synced_at":"2025-05-07T00:05:02.969Z","repository":{"id":12917186,"uuid":"15594640","full_name":"ferd/merklet","owner":"ferd","description":"Merkle Trees for data replication in Erlang","archived":false,"fork":false,"pushed_at":"2021-02-05T00:10:12.000Z","size":58,"stargazers_count":78,"open_issues_count":0,"forks_count":15,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-04-15T00:04:52.945Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ferd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-01-02T21:47:58.000Z","updated_at":"2024-07-17T13:04:05.000Z","dependencies_parsed_at":"2022-09-10T18:51:21.466Z","dependency_job_id":null,"html_url":"https://github.com/ferd/merklet","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ferd%2Fmerklet","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ferd%2Fmerklet/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ferd%2Fmerklet/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ferd%2Fmerklet/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ferd","download_url":"https://codeload.github.com/ferd/merklet/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252788514,"owners_count":21804284,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-12T18:44:07.371Z","updated_at":"2025-05-07T00:05:02.921Z","avatar_url":"https://github.com/ferd.png","language":"Erlang","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Merklet #\n\nReimplementation of Riak's old merkle tree module, but in a more readable\nmanner (according to me). Other difference include:\n\n- Renaming some functions just because\n- Insertion wants only binaries for keys and values, but makes no assumption\n  with regards to hashing.\n- Deleting nodes doesn't leave empty inner nodes as part of the tree, and\n  inner nodes with a single child node see the child promoted to the current\n  level.\n- Slightly more efficient diffing. This is due to not having as many leftover\n  inner nodes, and using difference lists on offsets of two inner nodes instead\n  of iterating across all offsets. I.e. the cost is linear with the number of\n  children of an inner node, rather than a flat minimal 255 rounds for each.\n- The diff algorithm explicitly points out differences in keys *and* values,\n  not just keys.\n- It is possible to do incremental tree diffing over the network, and uses\n  an internal binary serialization format that could eventually be opened\n  and usable by more languages.\n\nFurther documentation (and changes) to come.\n\nTodo list:\n\n- I'd like to finalize the serialization format and make it public rather\n  than private to the module to be more language-agnostic\n- Specify an actual protocol for types of distributed calls, although that\n  may be left to a higher-level library.\n\n## Compiling ##\n\n    $ rebar3 compile\n\n## Running Tests\n\n    $ rebar3 as test do proper, eunit, ct\n\n## Usage\n\n```erlang\n1\u003e T4 = merklet:insert({term_to_binary(\"wf\"), \u003c\u003c\"hehe\"\u003e\u003e}, T3 = merklet:insert({term_to_binary(\"c\"), \u003c\u003c\"third\"\u003e\u003e}, T2 = merklet:insert({\u003c\u003c\"b\"\u003e\u003e, \u003c\u003c\"other\"\u003e\u003e}, T1 = merklet:insert({\u003c\u003c\"a\"\u003e\u003e, \u003c\u003c\"val\"\u003e\u003e}, T0 = undefined)))).\n#inner{hashchildren = \u003c\u003c106,248,148,67,122,133,161,251,\n                        225,195,114,6,143,172,176,84,172,\n                        184,27,93\u003e\u003e,\n       children = [{134,\n                    #leaf{userkey = \u003c\u003c\"a\"\u003e\u003e,\n                          hashkey = \u003c\u003c134,247,228,55,250,165,167,252,225,93,29,220,\n                                      185,234,234,234,55,118,103,184\u003e\u003e,\n                          hash = \u003c\u003c65,36,144,16,123,227,33,235,119,175,10,124,246,\n                                   206,104,227,161,8,...\u003e\u003e}},\n                   {211,\n                    #inner{hashchildren = \u003c\u003c170,222,15,48,84,153,7,5,86,207,\n                                            227,247,171,218,50,2,120,249,218,\n                                            245\u003e\u003e,\n                           children = [{29,\n                                        #leaf{userkey = \u003c\u003c131,107,0,1,99\u003e\u003e,\n                                              hashkey = \u003c\u003c211,29,241,167,251,188,205,162,69,235,0,101,\n                                                          90,...\u003e\u003e,\n                                              hash = \u003c\u003c234,174,116,145,240,25,48,115,149,166,49,...\u003e\u003e}},\n                                       {191,\n                                        #leaf{userkey = \u003c\u003c131,107,0,2,119,102\u003e\u003e,\n                                              hashkey = \u003c\u003c211,191,171,22,1,47,67,156,204,229,77,113,...\u003e\u003e,\n                                              hash = \u003c\u003c139,130,66,190,81,141,104,185,159,140,...\u003e\u003e}}],\n                           offset = 1}},\n                   {233,\n                    #leaf{userkey = \u003c\u003c\"b\"\u003e\u003e,\n                          hashkey = \u003c\u003c233,215,31,94,231,201,45,109,201,233,47,253,\n                                      173,23,184,189,73,65,...\u003e\u003e,\n                          hash = \u003c\u003c30,97,58,207,252,237,241,68,194,28,170,220,89,\n                                   211,245,221,...\u003e\u003e}}],\n       offset = 0}\n2\u003e merklet:delete(term_to_binary(\"wf\"), T4).\n#inner{hashchildren = \u003c\u003c6,190,175,250,248,245,80,92,143,\n                        119,250,104,201,226,231,127,189,\n                        10,11,21\u003e\u003e,\n       children = [{134,\n                    #leaf{userkey = \u003c\u003c\"a\"\u003e\u003e,\n                          hashkey = \u003c\u003c134,247,228,55,250,165,167,252,225,93,29,220,\n                                      185,234,234,234,55,118,103,184\u003e\u003e,\n                          hash = \u003c\u003c65,36,144,16,123,227,33,235,119,175,10,124,246,\n                                   206,104,227,161,8,...\u003e\u003e}},\n                   {211,\n                    #leaf{userkey = \u003c\u003c131,107,0,1,99\u003e\u003e,\n                          hashkey = \u003c\u003c211,29,241,167,251,188,205,162,69,235,0,101,\n                                      90,83,57,132,52,158,32,...\u003e\u003e,\n                          hash = \u003c\u003c234,174,116,145,240,25,48,115,149,166,49,44,\n                                   177,64,179,22,57,...\u003e\u003e}},\n                   {233,\n                    #leaf{userkey = \u003c\u003c\"b\"\u003e\u003e,\n                          hashkey = \u003c\u003c233,215,31,94,231,201,45,109,201,233,47,253,\n                                      173,23,184,189,73,65,...\u003e\u003e,\n                          hash = \u003c\u003c30,97,58,207,252,237,241,68,194,28,170,220,89,\n                                   211,245,221,...\u003e\u003e}}],\n       offset = 0}\n3\u003e merklet:keys(T3).\n[\u003c\u003c\"a\"\u003e\u003e,\u003c\u003c\"b\"\u003e\u003e,\u003c\u003c131,107,0,1,99\u003e\u003e]\n4\u003e merklet:keys(T4).\n[\u003c\u003c\"a\"\u003e\u003e,\u003c\u003c\"b\"\u003e\u003e,\u003c\u003c131,107,0,1,99\u003e\u003e,\u003c\u003c131,107,0,2,119,102\u003e\u003e]\n5\u003e merklet:diff(T3,T4).\n[\u003c\u003c131,107,0,2,119,102\u003e\u003e]\n6\u003e merklet:diff(T3,undefined).\n[\u003c\u003c\"a\"\u003e\u003e,\u003c\u003c\"b\"\u003e\u003e,\u003c\u003c131,107,0,1,99\u003e\u003e\n```\n\n## Changelog ##\n\n- 2.0.0: use `bxor` as the hashing function for children node and remove some less necessary hashing for a major speed boost (thanks to [@systream](https://github.com/ferd/merklet/pull/7))\n- 1.0.2: use the `rand` module to be more current in code (thanks @michaelklishin)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fferd%2Fmerklet","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fferd%2Fmerklet","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fferd%2Fmerklet/lists"}