Go to file
Miguel Mota a69a927e8e Update docs 2020-06-06 12:12:30 -07:00
.github Create FUNDING.yml 2019-06-01 16:00:17 -07:00
diagrams Update docs 2020-06-06 12:12:30 -07:00
dist Update docs 2020-06-06 12:12:30 -07:00
test Update docs 2020-06-06 12:12:30 -07:00
.editorconfig init 2017-07-22 00:31:30 -07:00
.eslintrc Add multiproof support 2020-06-01 22:12:14 -07:00
.gitattributes init 2017-07-22 00:31:30 -07:00
.gitignore Add .npmrc 2020-02-13 13:01:03 -08:00
.npmignore Ignore typescript files for published package. Closes #22 2020-02-13 13:03:59 -08:00
.npmrc Add .npmrc 2020-02-13 13:01:03 -08:00
.travis.yml fix travis 2019-01-19 15:49:36 -08:00
LICENSE update readme 2018-10-22 23:40:56 -07:00
README.md Update docs 2020-06-06 12:12:30 -07:00
index.ts Update docs 2020-06-06 12:12:30 -07:00
package.json Update docs 2020-06-06 12:12:30 -07:00
tsconfig.json Update README 2020-06-01 23:29:33 -07:00

README.md


merkletree.js logo


MerkleTree.js

Construct Merkle Trees and verify proofs in JavaScript.

License Build Status dependencies Status NPM version PRs Welcome

Contents

Install

npm install merkletreejs

Getting started

Construct tree, generate proof, and verify proof:

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

const leaves = ['a', 'b', 'c'].map(x => SHA256(x))
const tree = new MerkleTree(leaves, SHA256)
const root = tree.getRoot().toString('hex')
const leaf = SHA256('a')
const proof = tree.getProof(leaf)
console.log(tree.verify(proof, leaf, root)) // true


const badLeaves = ['a', 'x', 'c'].map(x => SHA256(x))
const badTree = new MerkleTree(badLeaves, SHA256)
const badLeaf = SHA256('x')
const badProof = tree.getProof(badLeaf)
console.log(tree.verify(badProof, leaf, root)) // false

Print tree to console:

MerkleTree.print(tree)

Output

└─ 311d2e46f49b15fff8b746b74ad57f2cc9e0d9939fda94387141a2d3fdf187ae
   ├─ 176f0f307632fdd5831875eb709e2f68d770b102262998b214ddeb3f04164ae1
   │  ├─ 3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb
   │  └─ b5553de315e0edf504d9150af82dafa5c4667fa618ed0a6f19c69b41166c5510
   └─ 0b42b6393c1f53060fe3ddbfcd7aadcca894465a5a438f69c87d790b2299b9b2
      └─ 0b42b6393c1f53060fe3ddbfcd7aadcca894465a5a438f69c87d790b2299b9b2

Diagrams

Visualization of Merkle Tree

Merkle Tree

Visualization of Merkle Tree Proof

Merkle Tree Proof

Visualization of Invalid Merkle Tree Proofs

Merkle Tree Proof

Visualization of Bitcoin Merkle Tree

Merkle Tree Proof

Documentation

Class

Hierarchy

MerkleTree

Constructors

Properties

Methods


Constructors

constructor

new MerkleTree(leaves: any, hashAlgorithm?: any, options?: Options): MerkleTree

Parameters:

Name Type Default value Description
leaves any - Array of hashed leaves. Each leaf must be a Buffer.
Default value hashAlgorithm any SHA256 Algorithm used for hashing leaves and nodes
Default value options Options {} Additional options

Returns: MerkleTree


Properties

duplicateOdd

● duplicateOdd: boolean


hashAlgo

● hashAlgo: function

Type declaration

▸(value: TValue): THashAlgo

Parameters:

Name Type
value TValue

Returns: THashAlgo


hashLeaves

● hashLeaves: boolean


isBitcoinTree

● isBitcoinTree: boolean


layers

● layers: TLayer[]


leaves

● leaves: TLeaf[]


sort

● sort: boolean


sortLeaves

● sortLeaves: boolean


sortPairs

● sortPairs: boolean


Methods

<Private> _bufferIndexOf

_bufferIndexOf(arr: any, el: any): number

Parameters:

Name Type
arr any
el any

Returns: number

  • Index number

<Private> _bufferToHex

_bufferToHex(value: Buffer): string

Parameters:

Name Type Description
value Buffer -

Returns: string


<Private> _bufferify

_bufferify(x: any): any

Parameters:

Name Type
x any

Returns: any


<Private> _bufferifyFn

_bufferifyFn(f: any): (Anonymous function)

Parameters:

Name Type
f any

Returns: (Anonymous function)


<Private> _createHashes

_createHashes(nodes: any): void

Parameters:

Name Type
nodes any

Returns: void


<Private> _getPairNode

_getPairNode(layer: any, idx: any): any

Parameters:

Name Type Description
layer any Tree layer
idx any

Returns: any

  • Node

<Private> _isHexString

_isHexString(v: any): boolean

Parameters:

Name Type
v any

Returns: boolean


<Private> _log2

_log2(x: any): any

Parameters:

Name Type
x any

Returns: any


<Private> _toTreeString

_toTreeString(): any

Returns: any


<Private> _zip

_zip(a: any, b: any): any

Parameters:

Name Type Description
a any first array
b any second array

Returns: any


getDepth

getDepth(): number

Returns: number


getHexLayers

getHexLayers(): any

Returns: any


getHexLayersFlat

getHexLayersFlat(): any

Returns: any


getHexLeaves

getHexLeaves(): string[]

Returns: string[]


getHexMultiProof

getHexMultiProof(tree: any, indices: any): string[]

Parameters:

Name Type Description
tree any
indices any Tree indices.

Returns: string[]

  • Multiproofs as hex strings.

getHexProof

getHexProof(leaf: any, index: any): string[]

Parameters:

Name Type Description
leaf any Target leaf
Optional index any

Returns: string[]

  • Proof array as hex strings.

getHexRoot

getHexRoot(): string

Returns: string


getLayers

getLayers(): any[]

Returns: any[]


getLayersAsObject

getLayersAsObject(): any

Returns: any


getLayersFlat

getLayersFlat(): any

Returns: any


getLeaves

getLeaves(data: any[]): any[]

Parameters:

Name Type
Optional data any[]

Returns: any[]


getMultiProof

getMultiProof(tree: any, indices: any): any[]

Parameters:

Name Type Description
tree any
indices any Tree indices.

Returns: any[]

  • Multiproofs

getProof

getProof(leaf: any, index: any): any[]

Parameters:

Name Type Description
leaf any Target leaf
Optional index any

Returns: any[]

  • Array of objects containing a position property of type string with values of 'left' or 'right' and a data property of type Buffer.

getProofFlags

getProofFlags(els: any, proofs: any): any[]

Parameters:

Name Type
els any
proofs any

Returns: any[]

  • Boolean flags

getProofIndices

getProofIndices(treeIndices: any, depth: any): any[]

Parameters:

Name Type Description
treeIndices any Tree indices
depth any Tree depth; number of layers.

Returns: any[]

  • Proof indices

getRoot

getRoot(): any

Returns: any


print

print(): void

Returns: void


toString

toString(): any

Returns: any


verify

verify(proof: any, targetNode: any, root: any): boolean

Parameters:

Name Type Description
proof any Array of proof objects that should connect target node to Merkle root.
targetNode any Target node Buffer
root any Merkle root Buffer

Returns: boolean


verifyMultiProof

verifyMultiProof(root: any, indices: any, leaves: any, depth: any, proof: any): any

Parameters:

Name Type Description
root any Merkle tree root
indices any Leave indices
leaves any Leaf values at indices.
depth any Tree depth
proof any Multiproofs given indices

Returns: any


<Static> bufferify

bufferify(x: any): any

Parameters:

Name Type
x any

Returns: any


<Static> getMultiProof

getMultiProof(tree: any, indices: any): any[]

Parameters:

Name Type Description
tree any Tree as a flat array.
indices any Tree indices.

Returns: any[]

  • Multiproofs

<Static> isHexString

isHexString(v: any): boolean

Parameters:

Name Type
v any

Returns: boolean


<Static> print

print(tree: any): void

Parameters:

Name Type Description
tree any Merkle tree instance.

Returns: void

Test

npm test

FAQ

  • Q: How do you verify merkle proofs in Solidity?

    • A: Check out the example repo merkletreejs-solidity on how to generate merkle proofs with this library and verify them in Solidity.
  • Q: How do you verify merkle multiproofs in Solidity?

Notes

As is, this implemenation is vulnerable to a second pre-image attack. Use a difference hashing algorithm function for leaves and nodes, so that H(x) != H'(x).

Also, as is, this implementation is vulnerable to a forgery attack for an unbalanced tree, where the last leaf node can be duplicated to create an artificial balanced tree, resulting in the same Merkle root hash. Do not accept unbalanced tree to prevent this.

More info here.

Resources

Contributing

Pull requests are welcome!

For contributions please create a new branch and submit a pull request for review.

License

MIT