merkletreejs
Advanced tools
Comparing version 0.0.25 to 0.1.0
@@ -0,1 +1,11 @@ | ||
interface Options { | ||
/** If set to `true`, an odd node will be duplicated and combined to make a pair to generate the layer hash. */ | ||
duplicateOdd: boolean; | ||
/** If set to `true`, the leaves will hashed using the set hashing algorithms. */ | ||
hashLeaves: boolean; | ||
/** If set to `true`, constructs the Merkle Tree using the [Bitcoin Merkle Tree implementation](http://www.righto.com/2014/02/bitcoin-mining-hard-way-algorithms.html). Enable it when you need to replicate Bitcoin constructed Merkle Trees. In Bitcoin Merkle Trees, single nodes are combined with themselves, and each output hash is hashed again. */ | ||
isBitcoinTree: boolean; | ||
/** If set to `true`, the leaves and hashing pairs will be sorted. */ | ||
sort: boolean; | ||
} | ||
/** | ||
@@ -6,6 +16,9 @@ * Class reprensenting a Merkle Tree | ||
export declare class MerkleTree { | ||
hashAlgo: any; | ||
leaves: any; | ||
layers: any; | ||
duplicateOdd: boolean; | ||
hashAlgo: (value: any) => any; | ||
hashLeaves: boolean; | ||
isBitcoinTree: boolean; | ||
leaves: any[]; | ||
layers: any[]; | ||
sort: boolean; | ||
/** | ||
@@ -18,19 +31,18 @@ * @desc Constructs a Merkle Tree. | ||
* @param {Object} options - Additional options | ||
* @param {Boolean} options.isBitcoinTree - If set to `true`, constructs the Merkle | ||
* Tree using the [Bitcoin Merkle Tree implementation](http://www.righto.com/2014/02/bitcoin-mining-hard-way-algorithms.html). Enable it when you need | ||
* to replicate Bitcoin constructed Merkle Trees. In Bitcoin Merkle Trees, single nodes are combined with themselves, and each output hash is hashed again. | ||
* @example | ||
* const MerkleTree = require('merkletreejs') | ||
* const crypto = require('crypto') | ||
*```js | ||
*const MerkleTree = require('merkletreejs') | ||
*const crypto = require('crypto') | ||
* | ||
* function sha256(data) { | ||
* // returns Buffer | ||
* return crypto.createHash('sha256').update(data).digest() | ||
* } | ||
*function sha256(data) { | ||
* // returns Buffer | ||
* return crypto.createHash('sha256').update(data).digest() | ||
*} | ||
* | ||
* const leaves = ['a', 'b', 'c'].map(x => sha3(x)) | ||
*const leaves = ['a', 'b', 'c'].map(x => sha3(x)) | ||
* | ||
* const tree = new MerkleTree(leaves, sha256) | ||
*const tree = new MerkleTree(leaves, sha256) | ||
*``` | ||
*/ | ||
constructor(leaves: any, hashAlgorithm: any, options?: any); | ||
constructor(leaves: any, hashAlgorithm: any, options?: Options); | ||
createHashes(nodes: any): void; | ||
@@ -42,5 +54,7 @@ /** | ||
* @example | ||
* const leaves = tree.getLeaves() | ||
*```js | ||
*const leaves = tree.getLeaves() | ||
*``` | ||
*/ | ||
getLeaves(): any; | ||
getLeaves(): any[]; | ||
/** | ||
@@ -51,5 +65,7 @@ * getLayers | ||
* @example | ||
* const layers = tree.getLayers() | ||
*```js | ||
*const layers = tree.getLayers() | ||
*``` | ||
*/ | ||
getLayers(): any; | ||
getLayers(): any[]; | ||
/** | ||
@@ -60,3 +76,5 @@ * getRoot | ||
* @example | ||
* const root = tree.getRoot() | ||
*```js | ||
*const root = tree.getRoot() | ||
*``` | ||
*/ | ||
@@ -72,9 +90,13 @@ getRoot(): any; | ||
* with values of 'left' or 'right' and a data property of type Buffer. | ||
* @example | ||
* const proof = tree.getProof(leaves[2]) | ||
*@example | ||
* ```js | ||
*const proof = tree.getProof(leaves[2]) | ||
*``` | ||
* | ||
* @example | ||
* const leaves = ['a', 'b', 'a'].map(x => sha3(x)) | ||
* const tree = new MerkleTree(leaves, sha3) | ||
* const proof = tree.getProof(leaves[2], 2) | ||
*```js | ||
*const leaves = ['a', 'b', 'a'].map(x => sha3(x)) | ||
*const tree = new MerkleTree(leaves, sha3) | ||
*const proof = tree.getProof(leaves[2], 2) | ||
*``` | ||
*/ | ||
@@ -92,6 +114,7 @@ getProof(leaf: any, index?: any): any[]; | ||
* @example | ||
* const root = tree.getRoot() | ||
* const proof = tree.getProof(leaves[2]) | ||
* const verified = tree.verify(proof, leaves[2], root) | ||
* | ||
*```js | ||
*const root = tree.getRoot() | ||
*const proof = tree.getProof(leaves[2]) | ||
*const verified = tree.verify(proof, leaves[2], root) | ||
*``` | ||
*/ | ||
@@ -98,0 +121,0 @@ verify(proof: any, targetNode: any, root: any): boolean; |
@@ -18,24 +18,29 @@ "use strict"; | ||
* @param {Object} options - Additional options | ||
* @param {Boolean} options.isBitcoinTree - If set to `true`, constructs the Merkle | ||
* Tree using the [Bitcoin Merkle Tree implementation](http://www.righto.com/2014/02/bitcoin-mining-hard-way-algorithms.html). Enable it when you need | ||
* to replicate Bitcoin constructed Merkle Trees. In Bitcoin Merkle Trees, single nodes are combined with themselves, and each output hash is hashed again. | ||
* @example | ||
* const MerkleTree = require('merkletreejs') | ||
* const crypto = require('crypto') | ||
*```js | ||
*const MerkleTree = require('merkletreejs') | ||
*const crypto = require('crypto') | ||
* | ||
* function sha256(data) { | ||
* // returns Buffer | ||
* return crypto.createHash('sha256').update(data).digest() | ||
* } | ||
*function sha256(data) { | ||
* // returns Buffer | ||
* return crypto.createHash('sha256').update(data).digest() | ||
*} | ||
* | ||
* const leaves = ['a', 'b', 'c'].map(x => sha3(x)) | ||
*const leaves = ['a', 'b', 'c'].map(x => sha3(x)) | ||
* | ||
* const tree = new MerkleTree(leaves, sha256) | ||
*const tree = new MerkleTree(leaves, sha256) | ||
*``` | ||
*/ | ||
function MerkleTree(leaves, hashAlgorithm, options) { | ||
if (options === void 0) { options = {}; } | ||
this.isBitcoinTree = !!options.isBitcoinTree; | ||
this.hashLeaves = !!options.hashLeaves; | ||
this.sort = !!options.sort; | ||
this.duplicateOdd = !!options.duplicateOdd; | ||
this.hashAlgo = bufferifyFn(hashAlgorithm); | ||
if (this.hashLeaves) { | ||
leaves = leaves.map(this.hashAlgo); | ||
} | ||
this.leaves = leaves.map(bufferify); | ||
this.layers = [this.leaves]; | ||
this.isBitcoinTree = !!options.isBitcoinTree; | ||
this.createHashes(this.leaves); | ||
@@ -48,11 +53,40 @@ } | ||
this.layers.push([]); | ||
for (var i = 0; i < nodes.length - 1; i += 2) { | ||
for (var i = 0; i < nodes.length; i += 2) { | ||
if (i + 1 === nodes.length) { | ||
if (nodes.length % 2 === 1) { | ||
var data_1 = nodes[nodes.length - 1]; | ||
var hash_1 = data_1; | ||
// is bitcoin tree | ||
if (this.isBitcoinTree) { | ||
// Bitcoin method of duplicating the odd ending nodes | ||
data_1 = Buffer.concat([reverse(data_1), reverse(data_1)]); | ||
hash_1 = this.hashAlgo(data_1); | ||
hash_1 = reverse(this.hashAlgo(hash_1)); | ||
this.layers[layerIndex].push(hash_1); | ||
continue; | ||
} | ||
else { | ||
if (!this.duplicateOdd) { | ||
this.layers[layerIndex].push(nodes[i]); | ||
continue; | ||
} | ||
} | ||
} | ||
} | ||
var left = nodes[i]; | ||
var right = nodes[i + 1]; | ||
var right = i + 1 == nodes.length ? left : nodes[i + 1]; | ||
var data = null; | ||
if (this.isBitcoinTree) { | ||
data = Buffer.concat([reverse(left), reverse(right)]); | ||
var combined = [reverse(left), reverse(right)]; | ||
if (this.sort) { | ||
combined.sort(Buffer.compare); | ||
} | ||
data = Buffer.concat(combined); | ||
} | ||
else { | ||
data = Buffer.concat([left, right]); | ||
var combined = [left, right]; | ||
if (this.sort) { | ||
combined.sort(Buffer.compare); | ||
} | ||
data = Buffer.concat(combined); | ||
} | ||
@@ -66,15 +100,2 @@ var hash = this.hashAlgo(data); | ||
} | ||
// is odd number of nodes | ||
if (nodes.length % 2 === 1) { | ||
var data = nodes[nodes.length - 1]; | ||
var hash = data; | ||
// is bitcoin tree | ||
if (this.isBitcoinTree) { | ||
// Bitcoin method of duplicating the odd ending nodes | ||
data = Buffer.concat([reverse(data), reverse(data)]); | ||
hash = this.hashAlgo(data); | ||
hash = reverse(this.hashAlgo(hash)); | ||
} | ||
this.layers[layerIndex].push(hash); | ||
} | ||
nodes = this.layers[layerIndex]; | ||
@@ -88,3 +109,5 @@ } | ||
* @example | ||
* const leaves = tree.getLeaves() | ||
*```js | ||
*const leaves = tree.getLeaves() | ||
*``` | ||
*/ | ||
@@ -99,3 +122,5 @@ MerkleTree.prototype.getLeaves = function () { | ||
* @example | ||
* const layers = tree.getLayers() | ||
*```js | ||
*const layers = tree.getLayers() | ||
*``` | ||
*/ | ||
@@ -110,3 +135,5 @@ MerkleTree.prototype.getLayers = function () { | ||
* @example | ||
* const root = tree.getRoot() | ||
*```js | ||
*const root = tree.getRoot() | ||
*``` | ||
*/ | ||
@@ -124,9 +151,13 @@ MerkleTree.prototype.getRoot = function () { | ||
* with values of 'left' or 'right' and a data property of type Buffer. | ||
* @example | ||
* const proof = tree.getProof(leaves[2]) | ||
*@example | ||
* ```js | ||
*const proof = tree.getProof(leaves[2]) | ||
*``` | ||
* | ||
* @example | ||
* const leaves = ['a', 'b', 'a'].map(x => sha3(x)) | ||
* const tree = new MerkleTree(leaves, sha3) | ||
* const proof = tree.getProof(leaves[2], 2) | ||
*```js | ||
*const leaves = ['a', 'b', 'a'].map(x => sha3(x)) | ||
*const tree = new MerkleTree(leaves, sha3) | ||
*const proof = tree.getProof(leaves[2], 2) | ||
*``` | ||
*/ | ||
@@ -192,6 +223,7 @@ MerkleTree.prototype.getProof = function (leaf, index) { | ||
* @example | ||
* const root = tree.getRoot() | ||
* const proof = tree.getProof(leaves[2]) | ||
* const verified = tree.verify(proof, leaves[2], root) | ||
* | ||
*```js | ||
*const root = tree.getRoot() | ||
*const proof = tree.getProof(leaves[2]) | ||
*const verified = tree.verify(proof, leaves[2], root) | ||
*``` | ||
*/ | ||
@@ -198,0 +230,0 @@ MerkleTree.prototype.verify = function (proof, targetNode, root) { |
195
index.ts
@@ -5,2 +5,14 @@ import * as reverse from 'buffer-reverse' | ||
interface Options { | ||
/** If set to `true`, an odd node will be duplicated and combined to make a pair to generate the layer hash. */ | ||
duplicateOdd: boolean | ||
/** If set to `true`, the leaves will hashed using the set hashing algorithms. */ | ||
hashLeaves: boolean | ||
/** If set to `true`, constructs the Merkle Tree using the [Bitcoin Merkle Tree implementation](http://www.righto.com/2014/02/bitcoin-mining-hard-way-algorithms.html). Enable it when you need to replicate Bitcoin constructed Merkle Trees. In Bitcoin Merkle Trees, single nodes are combined with themselves, and each output hash is hashed again. */ | ||
isBitcoinTree: boolean | ||
/** If set to `true`, the leaves and hashing pairs will be sorted. */ | ||
sort: boolean | ||
} | ||
/** | ||
@@ -11,6 +23,9 @@ * Class reprensenting a Merkle Tree | ||
export class MerkleTree { | ||
hashAlgo: any | ||
leaves: any | ||
layers: any | ||
duplicateOdd: boolean | ||
hashAlgo: (value:any) => any | ||
hashLeaves: boolean | ||
isBitcoinTree: boolean | ||
leaves: any[] | ||
layers: any[] | ||
sort: boolean | ||
@@ -24,24 +39,29 @@ /** | ||
* @param {Object} options - Additional options | ||
* @param {Boolean} options.isBitcoinTree - If set to `true`, constructs the Merkle | ||
* Tree using the [Bitcoin Merkle Tree implementation](http://www.righto.com/2014/02/bitcoin-mining-hard-way-algorithms.html). Enable it when you need | ||
* to replicate Bitcoin constructed Merkle Trees. In Bitcoin Merkle Trees, single nodes are combined with themselves, and each output hash is hashed again. | ||
* @example | ||
* const MerkleTree = require('merkletreejs') | ||
* const crypto = require('crypto') | ||
*```js | ||
*const MerkleTree = require('merkletreejs') | ||
*const crypto = require('crypto') | ||
* | ||
* function sha256(data) { | ||
* // returns Buffer | ||
* return crypto.createHash('sha256').update(data).digest() | ||
* } | ||
*function sha256(data) { | ||
* // returns Buffer | ||
* return crypto.createHash('sha256').update(data).digest() | ||
*} | ||
* | ||
* const leaves = ['a', 'b', 'c'].map(x => sha3(x)) | ||
*const leaves = ['a', 'b', 'c'].map(x => sha3(x)) | ||
* | ||
* const tree = new MerkleTree(leaves, sha256) | ||
*const tree = new MerkleTree(leaves, sha256) | ||
*``` | ||
*/ | ||
constructor(leaves, hashAlgorithm, options={} as any) { | ||
constructor(leaves, hashAlgorithm, options:Options={} as any) { | ||
this.isBitcoinTree = !!options.isBitcoinTree | ||
this.hashLeaves = !!options.hashLeaves | ||
this.sort = !!options.sort | ||
this.duplicateOdd = !!options.duplicateOdd | ||
this.hashAlgo = bufferifyFn(hashAlgorithm) | ||
if (this.hashLeaves) { | ||
leaves = leaves.map(this.hashAlgo) | ||
} | ||
this.leaves = leaves.map(bufferify) | ||
this.layers = [this.leaves] | ||
this.isBitcoinTree = !!options.isBitcoinTree | ||
this.createHashes(this.leaves) | ||
@@ -58,11 +78,46 @@ } | ||
for (let i = 0; i < nodes.length - 1; i += 2) { | ||
for (let i = 0; i < nodes.length; i += 2) { | ||
if (i+1 === nodes.length) { | ||
if (nodes.length % 2 === 1) { | ||
let data = nodes[nodes.length-1] | ||
let hash = data | ||
// is bitcoin tree | ||
if (this.isBitcoinTree) { | ||
// Bitcoin method of duplicating the odd ending nodes | ||
data = Buffer.concat([reverse(data), reverse(data)]) | ||
hash = this.hashAlgo(data) | ||
hash = reverse(this.hashAlgo(hash)) | ||
this.layers[layerIndex].push(hash) | ||
continue | ||
} else { | ||
if (!this.duplicateOdd) { | ||
this.layers[layerIndex].push(nodes[i]) | ||
continue | ||
} | ||
} | ||
} | ||
} | ||
const left = nodes[i] | ||
const right = nodes[i+1] | ||
const right = i + 1 == nodes.length ? left : nodes[i + 1]; | ||
let data = null | ||
if (this.isBitcoinTree) { | ||
data = Buffer.concat([reverse(left), reverse(right)]) | ||
let combined = [reverse(left), reverse(right)] | ||
if (this.sort) { | ||
combined.sort(Buffer.compare) | ||
} | ||
data = Buffer.concat(combined) | ||
} else { | ||
data = Buffer.concat([left, right]) | ||
let combined = [left, right] | ||
if (this.sort) { | ||
combined.sort(Buffer.compare) | ||
} | ||
data = Buffer.concat(combined) | ||
} | ||
@@ -80,21 +135,4 @@ | ||
// is odd number of nodes | ||
if (nodes.length % 2 === 1) { | ||
let data = nodes[nodes.length-1] | ||
let hash = data | ||
// is bitcoin tree | ||
if (this.isBitcoinTree) { | ||
// Bitcoin method of duplicating the odd ending nodes | ||
data = Buffer.concat([reverse(data), reverse(data)]) | ||
hash = this.hashAlgo(data) | ||
hash = reverse(this.hashAlgo(hash)) | ||
} | ||
this.layers[layerIndex].push(hash) | ||
} | ||
nodes = this.layers[layerIndex] | ||
} | ||
} | ||
@@ -107,3 +145,5 @@ | ||
* @example | ||
* const leaves = tree.getLeaves() | ||
*```js | ||
*const leaves = tree.getLeaves() | ||
*``` | ||
*/ | ||
@@ -119,3 +159,5 @@ getLeaves() { | ||
* @example | ||
* const layers = tree.getLayers() | ||
*```js | ||
*const layers = tree.getLayers() | ||
*``` | ||
*/ | ||
@@ -131,3 +173,5 @@ getLayers() { | ||
* @example | ||
* const root = tree.getRoot() | ||
*```js | ||
*const root = tree.getRoot() | ||
*``` | ||
*/ | ||
@@ -146,9 +190,13 @@ getRoot() { | ||
* with values of 'left' or 'right' and a data property of type Buffer. | ||
* @example | ||
* const proof = tree.getProof(leaves[2]) | ||
*@example | ||
* ```js | ||
*const proof = tree.getProof(leaves[2]) | ||
*``` | ||
* | ||
* @example | ||
* const leaves = ['a', 'b', 'a'].map(x => sha3(x)) | ||
* const tree = new MerkleTree(leaves, sha3) | ||
* const proof = tree.getProof(leaves[2], 2) | ||
*```js | ||
*const leaves = ['a', 'b', 'a'].map(x => sha3(x)) | ||
*const tree = new MerkleTree(leaves, sha3) | ||
*const proof = tree.getProof(leaves[2], 2) | ||
*``` | ||
*/ | ||
@@ -192,31 +240,31 @@ getProof(leaf, index?) { | ||
} | ||
} | ||
return proof | ||
return proof | ||
} else { | ||
} else { | ||
// Proof Generation for Non-Bitcoin Trees | ||
// Proof Generation for Non-Bitcoin Trees | ||
for (let i = 0; i < this.layers.length; i++) { | ||
const layer = this.layers[i] | ||
const isRightNode = index % 2 | ||
const pairIndex = (isRightNode ? index - 1 : index + 1) | ||
for (let i = 0; i < this.layers.length; i++) { | ||
const layer = this.layers[i] | ||
const isRightNode = index % 2 | ||
const pairIndex = (isRightNode ? index - 1 : index + 1) | ||
if (pairIndex < layer.length) { | ||
proof.push({ | ||
position: isRightNode ? 'left': 'right', | ||
data: layer[pairIndex] | ||
}) | ||
} | ||
if (pairIndex < layer.length) { | ||
proof.push({ | ||
position: isRightNode ? 'left': 'right', | ||
data: layer[pairIndex] | ||
}) | ||
} | ||
// set index to parent index | ||
index = (index / 2)|0 | ||
// set index to parent index | ||
index = (index / 2)|0 | ||
} | ||
} | ||
return proof | ||
return proof | ||
} | ||
} | ||
} | ||
} | ||
@@ -233,6 +281,7 @@ /** | ||
* @example | ||
* const root = tree.getRoot() | ||
* const proof = tree.getProof(leaves[2]) | ||
* const verified = tree.verify(proof, leaves[2], root) | ||
* | ||
*```js | ||
*const root = tree.getRoot() | ||
*const proof = tree.getProof(leaves[2]) | ||
*const verified = tree.verify(proof, leaves[2], root) | ||
*``` | ||
*/ | ||
@@ -244,5 +293,5 @@ verify(proof, targetNode, root) { | ||
if (!Array.isArray(proof) || | ||
!proof.length || | ||
!targetNode || | ||
!root) { | ||
!proof.length || | ||
!targetNode || | ||
!root) { | ||
return false | ||
@@ -249,0 +298,0 @@ } |
{ | ||
"name": "merkletreejs", | ||
"version": "0.0.25", | ||
"version": "0.1.0", | ||
"description": "Construct Merkle Trees and verify proofs", | ||
@@ -10,3 +10,3 @@ "main": "dist/index.js", | ||
"build": "rm -rf dist/ && tsc", | ||
"docs:md": "node jsdoc.js" | ||
"docs:md": "rm -rf docs/ && typedoc --theme markdown index.ts --out docs --mdEngine github --mdDocusaurus --mdHideSources" | ||
}, | ||
@@ -44,4 +44,5 @@ "repository": { | ||
"ethereumjs-util": "^5.1.2", | ||
"jsdoc-to-markdown": "^3.0.0", | ||
"tape": "^4.9.2", | ||
"typedoc": "^0.14.2", | ||
"typedoc-plugin-markdown": "^1.2.1", | ||
"typescript": "^3.4.1" | ||
@@ -56,4 +57,5 @@ }, | ||
"is-buffer": "^2.0.3", | ||
"merkle-lib": "^2.0.10", | ||
"treeify": "^1.1.0" | ||
} | ||
} |
476
README.md
@@ -94,59 +94,65 @@ <h3 align="center"> | ||
## Classes | ||
<!-- :%s// --> | ||
<!-- :%s/\[Options\]()/\[Options\](#options) --> | ||
<dl> | ||
<dt><a href="#MerkleTree">MerkleTree</a></dt> | ||
<dd></dd> | ||
</dl> | ||
## Class | ||
## Objects | ||
Class reprensenting a Merkle Tree | ||
<dl> | ||
<dt><a href="#MerkleTree">MerkleTree</a> : <code>object</code></dt> | ||
<dd><p>Class reprensenting a Merkle Tree</p> | ||
</dd> | ||
</dl> | ||
*__namespace__*: MerkleTree | ||
<a name="MerkleTree"></a> | ||
## Hierarchy | ||
## MerkleTree | ||
**Kind**: global class | ||
**MerkleTree** | ||
* [MerkleTree](#MerkleTree) | ||
* [new MerkleTree(leaves, hashAlgorithm, options)](#new_MerkleTree_new) | ||
* [.getLeaves()](#MerkleTree+getLeaves) ⇒ <code>Array.<Buffer></code> | ||
* [.getLayers()](#MerkleTree+getLayers) ⇒ <code>Array.<Buffer></code> | ||
* [.getRoot()](#MerkleTree+getRoot) ⇒ <code>Buffer</code> | ||
* [.getProof(leaf, [index])](#MerkleTree+getProof) ⇒ <code>Array.<Object></code> | ||
* [.verify(proof, targetNode, root)](#MerkleTree+verify) ⇒ <code>Boolean</code> | ||
### Constructors | ||
* [constructor](#constructor) | ||
* * * | ||
### Properties | ||
<a name="new_MerkleTree_new"></a> | ||
* [duplicateOdd](#duplicateodd) | ||
* [hashAlgo](#hashalgo) | ||
* [hashLeaves](#hashleaves) | ||
* [isBitcoinTree](#isbitcointree) | ||
* [layers](#layers) | ||
* [leaves](#leaves) | ||
* [sort](#sort) | ||
### new MerkleTree(leaves, hashAlgorithm, options) | ||
Constructs a Merkle Tree. | ||
All nodes and leaves are stored as Buffers. | ||
Lonely leaf nodes are promoted to the next level up without being hashed again. | ||
### Methods | ||
* [createHashes](#createhashes) | ||
* [getLayers](#getlayers) | ||
* [getLayersAsObject](#getlayersasobject) | ||
* [getLeaves](#getleaves) | ||
* [getProof](#getproof) | ||
* [getRoot](#getroot) | ||
* [print](#print) | ||
* [toString](#tostring) | ||
* [toTreeString](#totreestring) | ||
* [verify](#verify) | ||
* [bufferify](#bufferify) | ||
* [print](#print-1) | ||
| Param | Type | Description | | ||
| --- | --- | --- | | ||
| leaves | <code>Array.<Buffer></code> | Array of hashed leaves. Each leaf must be a Buffer. | | ||
| hashAlgorithm | <code>function</code> | Algorithm used for hashing leaves and nodes | | ||
| options | <code>Object</code> | Additional options | | ||
| options.isBitcoinTree | <code>Boolean</code> | If set to `true`, constructs the Merkle Tree using the [Bitcoin Merkle Tree implementation](http://www.righto.com/2014/02/bitcoin-mining-hard-way-algorithms.html). Enable it when you need to replicate Bitcoin constructed Merkle Trees. In Bitcoin Merkle Trees, single nodes are combined with themselves, and each output hash is hashed again. | | ||
## Constructors | ||
**Example** | ||
```js | ||
const { MerkleTree } = require('merkletreejs') | ||
<a id="constructor"></a> | ||
### constructor | ||
⊕ **new MerkleTree**(leaves: *`any`*, hashAlgorithm: *`any`*, options?: *[Options](#options) | ||
*__desc__*: Constructs a Merkle Tree. All nodes and leaves are stored as Buffers. Lonely leaf nodes are promoted to the next level up without being hashed again. | ||
*__example__*: | ||
```js | ||
const MerkleTree = require('merkletreejs') | ||
const crypto = require('crypto') | ||
function sha256(data) { | ||
// returns Buffer | ||
return crypto.createHash('sha256').update(data).digest() | ||
// returns Buffer | ||
return crypto.createHash('sha256').update(data).digest() | ||
} | ||
const leaves = ['a', 'b', 'c'].map(x => sha256(x)) | ||
const leaves = ['a', 'b', 'c'].map(x => sha3(x)) | ||
@@ -156,224 +162,228 @@ const tree = new MerkleTree(leaves, sha256) | ||
* * * | ||
**Parameters:** | ||
<a name="MerkleTree+getLeaves"></a> | ||
| Name | Type | Default value | Description | | ||
| ------ | ------ | ------ | ------ | | ||
| leaves | `any` | - | Array of hashed leaves. Each leaf must be a Buffer. | | ||
| hashAlgorithm | `any` | - | Algorithm used for hashing leaves and nodes | | ||
| `Default value` options | [Options](#options) | {} as any | Additional options | | ||
### merkleTree.getLeaves() ⇒ <code>Array.<Buffer></code> | ||
Returns array of leaves of Merkle Tree. | ||
**Returns:** [MerkleTree]() | ||
**Kind**: instance method of [<code>MerkleTree</code>](#MerkleTree) | ||
**Example** | ||
```js | ||
const leaves = tree.getLeaves() | ||
``` | ||
## Properties | ||
* * * | ||
<a id="duplicateodd"></a> | ||
<a name="MerkleTree+getLayers"></a> | ||
### duplicateOdd | ||
### merkleTree.getLayers() ⇒ <code>Array.<Buffer></code> | ||
Returns array of all layers of Merkle Tree, including leaves and root. | ||
**● duplicateOdd**: *`boolean`* | ||
**Kind**: instance method of [<code>MerkleTree</code>](#MerkleTree) | ||
**Example** | ||
```js | ||
const layers = tree.getLayers() | ||
``` | ||
___ | ||
<a id="hashalgo"></a> | ||
* * * | ||
### hashAlgo | ||
<a name="MerkleTree+getRoot"></a> | ||
**● hashAlgo**: *`function`* | ||
### merkleTree.getRoot() ⇒ <code>Buffer</code> | ||
Returns the Merkle root hash as a Buffer. | ||
#### Type declaration | ||
▸(value: *`any`*): `any` | ||
**Kind**: instance method of [<code>MerkleTree</code>](#MerkleTree) | ||
**Example** | ||
```js | ||
const root = tree.getRoot() | ||
``` | ||
**Parameters:** | ||
* * * | ||
| Name | Type | | ||
| ------ | ------ | | ||
| value | `any` | | ||
<a name="MerkleTree+getProof"></a> | ||
**Returns:** `any` | ||
### merkleTree.getProof(leaf, [index]) ⇒ <code>Array.<Object></code> | ||
Returns the proof for a target leaf. | ||
___ | ||
<a id="hashleaves"></a> | ||
**Kind**: instance method of [<code>MerkleTree</code>](#MerkleTree) | ||
**Returns**: <code>Array.<Object></code> - - Array of objects containing a position property of type string with values of 'left' or 'right' and a data property of type Buffer. | ||
### hashLeaves | ||
| Param | Type | Description | | ||
| --- | --- | --- | | ||
| leaf | <code>Buffer</code> | Target leaf | | ||
| [index] | <code>Number</code> | Target leaf index in leaves array. Use if there are leaves containing duplicate data in order to distinguish it. | | ||
**● hashLeaves**: *`boolean`* | ||
**Example** | ||
```js | ||
const proof = tree.getProof(leaves[2]) | ||
``` | ||
**Example** | ||
```js | ||
const leaves = ['a', 'b', 'a'].map(x => sha256(x)) | ||
const tree = new MerkleTree(leaves, sha256) | ||
const proof = tree.getProof(leaves[2], 2) | ||
``` | ||
___ | ||
<a id="isbitcointree"></a> | ||
* * * | ||
### isBitcoinTree | ||
<a name="MerkleTree+verify"></a> | ||
**● isBitcoinTree**: *`boolean`* | ||
### merkleTree.verify(proof, targetNode, root) ⇒ <code>Boolean</code> | ||
Returns true if the proof path (array of hashes) can connect the target node | ||
to the Merkle root. | ||
___ | ||
<a id="layers"></a> | ||
**Kind**: instance method of [<code>MerkleTree</code>](#MerkleTree) | ||
### layers | ||
| Param | Type | Description | | ||
| --- | --- | --- | | ||
| proof | <code>Array.<Object></code> | Array of proof objects that should connect target node to Merkle root. | | ||
| targetNode | <code>Buffer</code> | Target node Buffer | | ||
| root | <code>Buffer</code> | Merkle root Buffer | | ||
**● layers**: *`any`[]* | ||
**Example** | ||
```js | ||
const root = tree.getRoot() | ||
const proof = tree.getProof(leaves[2]) | ||
const verified = tree.verify(proof, leaves[2], root) | ||
``` | ||
___ | ||
<a id="leaves"></a> | ||
* * * | ||
### leaves | ||
<a name="MerkleTree"></a> | ||
**● leaves**: *`any`[]* | ||
## MerkleTree : <code>object</code> | ||
Class reprensenting a Merkle Tree | ||
___ | ||
<a id="sort"></a> | ||
**Kind**: global namespace | ||
### sort | ||
* [MerkleTree](#MerkleTree) : <code>object</code> | ||
* [new MerkleTree(leaves, hashAlgorithm, options)](#new_MerkleTree_new) | ||
* [.getLeaves()](#MerkleTree+getLeaves) ⇒ <code>Array.<Buffer></code> | ||
* [.getLayers()](#MerkleTree+getLayers) ⇒ <code>Array.<Buffer></code> | ||
* [.getRoot()](#MerkleTree+getRoot) ⇒ <code>Buffer</code> | ||
* [.getProof(leaf, [index])](#MerkleTree+getProof) ⇒ <code>Array.<Object></code> | ||
* [.verify(proof, targetNode, root)](#MerkleTree+verify) ⇒ <code>Boolean</code> | ||
**● sort**: *`boolean`* | ||
___ | ||
* * * | ||
## Methods | ||
<a name="new_MerkleTree_new"></a> | ||
<a id="createhashes"></a> | ||
### new MerkleTree(leaves, hashAlgorithm, options) | ||
Constructs a Merkle Tree. | ||
All nodes and leaves are stored as Buffers. | ||
Lonely leaf nodes are promoted to the next level up without being hashed again. | ||
### createHashes | ||
▸ **createHashes**(nodes: *`any`*): `void` | ||
| Param | Type | Description | | ||
| --- | --- | --- | | ||
| leaves | <code>Array.<Buffer></code> | Array of hashed leaves. Each leaf must be a Buffer. | | ||
| hashAlgorithm | <code>function</code> | Algorithm used for hashing leaves and nodes | | ||
| options | <code>Object</code> | Additional options | | ||
| options.isBitcoinTree | <code>Boolean</code> | If set to `true`, constructs the Merkle Tree using the [Bitcoin Merkle Tree implementation](http://www.righto.com/2014/02/bitcoin-mining-hard-way-algorithms.html). Enable it when you need to replicate Bitcoin constructed Merkle Trees. In Bitcoin Merkle Trees, single nodes are combined with themselves, and each output hash is hashed again. | | ||
**Parameters:** | ||
**Example** | ||
```js | ||
const { MerkleTree } = require('merkletreejs') | ||
const crypto = require('crypto') | ||
| Name | Type | | ||
| ------ | ------ | | ||
| nodes | `any` | | ||
function sha256(data) { | ||
// returns Buffer | ||
return crypto.createHash('sha256').update(data).digest() | ||
} | ||
**Returns:** `void` | ||
const leaves = ['a', 'b', 'c'].map(x => sha256(x)) | ||
___ | ||
<a id="getlayers"></a> | ||
const tree = new MerkleTree(leaves, sha256) | ||
``` | ||
### getLayers | ||
* * * | ||
▸ **getLayers**(): `any`[] | ||
<a name="MerkleTree+getLeaves"></a> | ||
getLayers | ||
### merkleTree.getLeaves() ⇒ <code>Array.<Buffer></code> | ||
Returns array of leaves of Merkle Tree. | ||
*__desc__*: Returns array of all layers of Merkle Tree, including leaves and root. | ||
**Kind**: instance method of [<code>MerkleTree</code>](#MerkleTree) | ||
**Example** | ||
```js | ||
const leaves = tree.getLeaves() | ||
*__example__*: | ||
```js | ||
const layers = tree.getLayers() | ||
``` | ||
* * * | ||
**Returns:** `any`[] | ||
<a name="MerkleTree+getLayers"></a> | ||
___ | ||
<a id="getlayersasobject"></a> | ||
### merkleTree.getLayers() ⇒ <code>Array.<Buffer></code> | ||
Returns array of all layers of Merkle Tree, including leaves and root. | ||
### getLayersAsObject | ||
**Kind**: instance method of [<code>MerkleTree</code>](#MerkleTree) | ||
**Example** | ||
```js | ||
const layers = tree.getLayers() | ||
``` | ||
▸ **getLayersAsObject**(): `any` | ||
* * * | ||
**Returns:** `any` | ||
<a name="MerkleTree+getRoot"></a> | ||
___ | ||
<a id="getleaves"></a> | ||
### merkleTree.getRoot() ⇒ <code>Buffer</code> | ||
Returns the Merkle root hash as a Buffer. | ||
### getLeaves | ||
**Kind**: instance method of [<code>MerkleTree</code>](#MerkleTree) | ||
**Example** | ||
```js | ||
const root = tree.getRoot() | ||
▸ **getLeaves**(): `any`[] | ||
getLeaves | ||
*__desc__*: Returns array of leaves of Merkle Tree. | ||
*__example__*: | ||
```js | ||
const leaves = tree.getLeaves() | ||
``` | ||
* * * | ||
**Returns:** `any`[] | ||
<a name="MerkleTree+getProof"></a> | ||
___ | ||
<a id="getproof"></a> | ||
### merkleTree.getProof(leaf, [index]) ⇒ <code>Array.<Object></code> | ||
Returns the proof for a target leaf. | ||
### getProof | ||
**Kind**: instance method of [<code>MerkleTree</code>](#MerkleTree) | ||
**Returns**: <code>Array.<Buffer></code> - - Array of objects containing a position property of type string with values of 'left' or 'right' and a data property of type Buffer. | ||
▸ **getProof**(leaf: *`any`*, index?: *`any`*): `any`[] | ||
| Param | Type | Description | | ||
| --- | --- | --- | | ||
| leaf | <code>Buffer</code> | Target leaf | | ||
| [index] | <code>Number</code> | Target leaf index in leaves array. Use if there are leaves containing duplicate data in order to distinguish it. | | ||
getProof | ||
**Example** | ||
```js | ||
*__desc__*: Returns the proof for a target leaf. | ||
*__example__*: | ||
```js | ||
const proof = tree.getProof(leaves[2]) | ||
``` | ||
**Example** | ||
```js | ||
const leaves = ['a', 'b', 'a'].map(x => sha256(x)) | ||
const tree = new MerkleTree(leaves, sha256) | ||
*__example__*: | ||
```js | ||
const leaves = ['a', 'b', 'a'].map(x => sha3(x)) | ||
const tree = new MerkleTree(leaves, sha3) | ||
const proof = tree.getProof(leaves[2], 2) | ||
``` | ||
* * * | ||
**Parameters:** | ||
<a name="MerkleTree+verify"></a> | ||
| Name | Type | Description | | ||
| ------ | ------ | ------ | | ||
| leaf | `any` | Target leaf | | ||
| `Optional` index | `any` | | ||
### merkleTree.verify(proof, targetNode, root) ⇒ <code>Boolean</code> | ||
Returns true if the proof path (array of hashes) can connect the target node | ||
to the Merkle root. | ||
**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. | ||
**Kind**: instance method of [<code>MerkleTree</code>](#MerkleTree) | ||
___ | ||
<a id="getroot"></a> | ||
| Param | Type | Description | | ||
| --- | --- | --- | | ||
| proof | <code>Array.<Buffer></code> | Array of proof Buffer hashes that should connect target node to Merkle root. | | ||
| targetNode | <code>Buffer</code> | Target node Buffer | | ||
| root | <code>Buffer</code> | Merkle root Buffer | | ||
### getRoot | ||
**Example** | ||
```js | ||
▸ **getRoot**(): `any` | ||
getRoot | ||
*__desc__*: Returns the Merkle root hash as a Buffer. | ||
*__example__*: | ||
```js | ||
const root = tree.getRoot() | ||
``` | ||
**Returns:** `any` | ||
___ | ||
<a id="print"></a> | ||
▸ **print**(): `void` | ||
**Returns:** `void` | ||
___ | ||
<a id="tostring"></a> | ||
### toString | ||
▸ **toString**(): `any` | ||
**Returns:** `any` | ||
___ | ||
<a id="totreestring"></a> | ||
### toTreeString | ||
▸ **toTreeString**(): `any` | ||
**Returns:** `any` | ||
___ | ||
<a id="verify"></a> | ||
### verify | ||
▸ **verify**(proof: *`any`*, targetNode: *`any`*, root: *`any`*): `boolean` | ||
verify | ||
*__desc__*: Returns true if the proof path (array of hashes) can connect the target node to the Merkle root. | ||
*__example__*: | ||
```js | ||
const root = tree.getRoot() | ||
const proof = tree.getProof(leaves[2]) | ||
@@ -383,4 +393,84 @@ const verified = tree.verify(proof, leaves[2], root) | ||
* * * | ||
**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` | ||
___ | ||
<a id="bufferify"></a> | ||
### `<Static>` bufferify | ||
▸ **bufferify**(x: *`any`*): `any` | ||
**Parameters:** | ||
| Name | Type | | ||
| ------ | ------ | | ||
| x | `any` | | ||
**Returns:** `any` | ||
___ | ||
<a id="print-1"></a> | ||
### `<Static>` print | ||
▸ **print**(tree: *`any`*): `void` | ||
**Parameters:** | ||
| Name | Type | | ||
| ------ | ------ | | ||
| tree | `any` | | ||
**Returns:** `void` | ||
## Interface | ||
## Options | ||
## Properties | ||
<a id="duplicateodd"></a> | ||
### duplicateOdd | ||
**● duplicateOdd**: *`boolean`* | ||
If set to `true`, an odd node will be duplicated and combined to make a pair to generate the layer hash. | ||
___ | ||
<a id="hashleaves"></a> | ||
### hashLeaves | ||
**● hashLeaves**: *`boolean`* | ||
If set to `true`, the leaves will hashed using the set hashing algorithms. | ||
___ | ||
<a id="isbitcointree"></a> | ||
### isBitcoinTree | ||
**● isBitcoinTree**: *`boolean`* | ||
If set to `true`, constructs the Merkle Tree using the [Bitcoin Merkle Tree implementation](http://www.righto.com/2014/02/bitcoin-mining-hard-way-algorithms.html). Enable it when you need to replicate Bitcoin constructed Merkle Trees. In Bitcoin Merkle Trees, single nodes are combined with themselves, and each output hash is hashed again. | ||
___ | ||
<a id="sort"></a> | ||
### sort | ||
**● sort**: *`boolean`* | ||
If set to `true`, the leaves and hashing pairs will be sorted. | ||
## Test | ||
@@ -387,0 +477,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
60509
16
827
513
5
7
+ Addedmerkle-lib@^2.0.10
+ Addedmerkle-lib@2.0.10(transitive)