add getting started example

This commit is contained in:
Miguel Mota 2018-12-09 19:10:43 -08:00
parent 02f9f9b80f
commit 069cc98640
5 changed files with 318 additions and 218 deletions

View File

@ -12,6 +12,7 @@
- [Diagrams](#diagrams)
- [Install](#install)
- [Getting started](#Getting-started)
- [Documentation](#documentation)
- [Test](#test)
- [FAQ](#faq)
@ -43,6 +44,48 @@ Diagram of Bitcoin Merkle Tree
npm install merkletreejs
```
## Getting started
Construct tree, generate proof, and verify proof:
```bash
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:
```js
const leaves = ['a', 'b', 'c'].map(x => sha3(x))
const tree = new MerkleTree(leaves, sha256)
MerkleTree.print(tree)
```
Output
```bash
└─ 311d2e46f49b15fff8b746b74ad57f2cc9e0d9939fda94387141a2d3fdf187ae
├─ 176f0f307632fdd5831875eb709e2f68d770b102262998b214ddeb3f04164ae1
│ ├─ 3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb
│ └─ b5553de315e0edf504d9150af82dafa5c4667fa618ed0a6f19c69b41166c5510
└─ 0b42b6393c1f53060fe3ddbfcd7aadcca894465a5a438f69c87d790b2299b9b2
└─ 0b42b6393c1f53060fe3ddbfcd7aadcca894465a5a438f69c87d790b2299b9b2
```
## Documentation
## Classes

View File

@ -1,5 +1,6 @@
const reverse = require('buffer-reverse')
const CryptoJS = require('crypto-js')
const treeify = require('treeify')
/**
* Class reprensenting a Merkle Tree
@ -220,6 +221,7 @@ class MerkleTree {
*/
verify(proof, targetNode, root) {
let hash = bufferify(targetNode)
root = bufferify(root)
if (!Array.isArray(proof) ||
!proof.length ||
@ -256,6 +258,38 @@ class MerkleTree {
static bufferify(x) {
return bufferify(x)
}
static print(tree, opts) {
opts = opts || {}
const log = opts instanceof Object && opts.log !== false
const layers = tree.getLayers().map(x => x.map(x => x.toString('hex')))
const objs = []
for (let i = 0; i < layers.length; i++) {
const arr = []
for (let j = 0; j < layers[i].length; j++) {
const obj = { [layers[i][j]]: {} }
if (objs.length) {
const a = objs.shift()
const akey = Object.keys(a)[0]
obj[layers[i][j]][akey] = a[akey]
if (objs.length) {
const b = objs.shift()
const bkey = Object.keys(b)[0]
obj[layers[i][j]][bkey] = b[bkey]
}
}
arr.push(obj)
}
objs.push(...arr)
}
const str = treeify.asTree(objs[0], true)
if (log) console.log(str)
return str
}
}
function bufferify(x) {

439
package-lock.json generated
View File

@ -16,7 +16,7 @@
"integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
"dev": true,
"requires": {
"acorn": "3.3.0"
"acorn": "^3.0.4"
}
},
"align-text": {
@ -25,9 +25,9 @@
"integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
"dev": true,
"requires": {
"kind-of": "3.2.2",
"longest": "1.0.1",
"repeat-string": "1.6.1"
"kind-of": "^3.0.2",
"longest": "^1.0.1",
"repeat-string": "^1.5.2"
}
},
"amdefine": {
@ -42,7 +42,7 @@
"integrity": "sha1-HBg5S2r5t2/5pjUJ+kl2af0s5T4=",
"dev": true,
"requires": {
"array-back": "1.0.4"
"array-back": "^1.0.3"
},
"dependencies": {
"array-back": {
@ -51,7 +51,7 @@
"integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
"dev": true,
"requires": {
"typical": "2.6.1"
"typical": "^2.6.0"
}
}
}
@ -62,7 +62,7 @@
"integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
"dev": true,
"requires": {
"typical": "2.6.1"
"typical": "^2.6.1"
}
},
"async": {
@ -89,7 +89,7 @@
"integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=",
"dev": true,
"requires": {
"safe-buffer": "5.1.2"
"safe-buffer": "^5.0.1"
}
},
"bluebird": {
@ -110,7 +110,7 @@
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "1.0.0",
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
@ -126,12 +126,12 @@
"integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
"dev": true,
"requires": {
"buffer-xor": "1.0.3",
"cipher-base": "1.0.4",
"create-hash": "1.2.0",
"evp_bytestokey": "1.0.3",
"inherits": "2.0.3",
"safe-buffer": "5.1.2"
"buffer-xor": "^1.0.3",
"cipher-base": "^1.0.0",
"create-hash": "^1.1.0",
"evp_bytestokey": "^1.0.3",
"inherits": "^2.0.1",
"safe-buffer": "^5.0.1"
}
},
"buffer-reverse": {
@ -151,9 +151,9 @@
"integrity": "sha512-4TgWfe9SF+bUy5cCql8gWHqKNrviufNwSYxLjf2utB0pY4+bdcuFwMmY1hDB+67Gz/L1vmhFNhePAjJTFBtV+Q==",
"dev": true,
"requires": {
"array-back": "2.0.0",
"fs-then-native": "2.0.0",
"mkdirp2": "1.0.4"
"array-back": "^2.0.0",
"fs-then-native": "^2.0.0",
"mkdirp2": "^1.0.3"
}
},
"camelcase": {
@ -169,7 +169,7 @@
"integrity": "sha1-mMyJDKZS3S7w5ws3klMQ/56Q/Is=",
"dev": true,
"requires": {
"underscore-contrib": "0.3.0"
"underscore-contrib": "~0.3.0"
}
},
"center-align": {
@ -179,8 +179,8 @@
"dev": true,
"optional": true,
"requires": {
"align-text": "0.1.4",
"lazy-cache": "1.0.4"
"align-text": "^0.1.3",
"lazy-cache": "^1.0.3"
}
},
"cipher-base": {
@ -189,8 +189,8 @@
"integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
"dev": true,
"requires": {
"inherits": "2.0.3",
"safe-buffer": "5.1.2"
"inherits": "^2.0.1",
"safe-buffer": "^5.0.1"
}
},
"cliui": {
@ -200,8 +200,8 @@
"dev": true,
"optional": true,
"requires": {
"center-align": "0.1.3",
"right-align": "0.1.3",
"center-align": "^0.1.1",
"right-align": "^0.1.1",
"wordwrap": "0.0.2"
},
"dependencies": {
@ -220,8 +220,8 @@
"integrity": "sha512-0y0rBgoX8IzIjBAUnO73SEtSb4Mhk3IoceWJq5zZSxb9mWORhWH8xLYo4EDSOE1jRBk1LhmfjqWFFt10h/+MEA==",
"dev": true,
"requires": {
"stream-connect": "1.0.2",
"stream-via": "1.0.4"
"stream-connect": "^1.0.2",
"stream-via": "^1.0.4"
}
},
"command-line-args": {
@ -230,9 +230,9 @@
"integrity": "sha512-aUdPvQRAyBvQd2n7jXcsMDz68ckBJELXNzBybCHOibUWEg0mWTnaYCSRU8h9R+aNRSvDihJtssSRCiDRpLaezA==",
"dev": true,
"requires": {
"array-back": "2.0.0",
"find-replace": "1.0.3",
"typical": "2.6.1"
"array-back": "^2.0.0",
"find-replace": "^1.0.3",
"typical": "^2.6.1"
}
},
"command-line-tool": {
@ -241,11 +241,11 @@
"integrity": "sha1-yoB5KuIGnPfKpWLAy8LNEYERIqA=",
"dev": true,
"requires": {
"ansi-escape-sequences": "3.0.0",
"array-back": "1.0.4",
"command-line-args": "4.0.7",
"command-line-usage": "4.1.0",
"typical": "2.6.1"
"ansi-escape-sequences": "^3.0.0",
"array-back": "^1.0.4",
"command-line-args": "^4.0.1",
"command-line-usage": "^4.0.0",
"typical": "^2.6.0"
},
"dependencies": {
"array-back": {
@ -254,7 +254,7 @@
"integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
"dev": true,
"requires": {
"typical": "2.6.1"
"typical": "^2.6.0"
}
}
}
@ -265,10 +265,10 @@
"integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==",
"dev": true,
"requires": {
"ansi-escape-sequences": "4.0.0",
"array-back": "2.0.0",
"table-layout": "0.4.4",
"typical": "2.6.1"
"ansi-escape-sequences": "^4.0.0",
"array-back": "^2.0.0",
"table-layout": "^0.4.2",
"typical": "^2.6.1"
},
"dependencies": {
"ansi-escape-sequences": {
@ -277,7 +277,7 @@
"integrity": "sha512-v+0wW9Wezwsyb0uF4aBVCjmSqit3Ru7PZFziGF0o2KwTvN2zWfTi3BRLq9EkJFdg3eBbyERXGTntVpBxH1J68Q==",
"dev": true,
"requires": {
"array-back": "2.0.0"
"array-back": "^2.0.0"
}
}
}
@ -300,7 +300,7 @@
"integrity": "sha1-ZnZjWQUFooO/JqSE1oSJ10xUhdo=",
"dev": true,
"requires": {
"walk-back": "2.0.1"
"walk-back": "^2.0.1"
},
"dependencies": {
"walk-back": {
@ -317,11 +317,11 @@
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"dev": true,
"requires": {
"cipher-base": "1.0.4",
"inherits": "2.0.3",
"md5.js": "1.3.4",
"ripemd160": "2.0.2",
"sha.js": "2.4.11"
"cipher-base": "^1.0.1",
"inherits": "^2.0.1",
"md5.js": "^1.3.4",
"ripemd160": "^2.0.1",
"sha.js": "^2.4.0"
}
},
"create-hmac": {
@ -330,12 +330,12 @@
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"dev": true,
"requires": {
"cipher-base": "1.0.4",
"create-hash": "1.2.0",
"inherits": "2.0.3",
"ripemd160": "2.0.2",
"safe-buffer": "5.1.2",
"sha.js": "2.4.11"
"cipher-base": "^1.0.3",
"create-hash": "^1.1.0",
"inherits": "^2.0.1",
"ripemd160": "^2.0.0",
"safe-buffer": "^5.0.1",
"sha.js": "^2.4.8"
}
},
"crypto": {
@ -380,18 +380,18 @@
"integrity": "sha512-79w644JdsB2TthYpVl2bDurX7i9Abaegg2E7X46Ajc135aASTMXxrHzJ9mOa5X5nbmnXwlBYiF68K+1baX+BzQ==",
"dev": true,
"requires": {
"array-back": "2.0.0",
"cache-point": "0.4.1",
"common-sequence": "1.0.2",
"file-set": "2.0.0",
"handlebars": "4.0.11",
"marked": "0.3.19",
"object-get": "2.1.0",
"reduce-flatten": "1.0.1",
"reduce-unique": "1.0.0",
"reduce-without": "1.0.1",
"test-value": "3.0.0",
"walk-back": "3.0.0"
"array-back": "^2.0.0",
"cache-point": "^0.4.1",
"common-sequence": "^1.0.2",
"file-set": "^2.0.0",
"handlebars": "^4.0.11",
"marked": "^0.3.16",
"object-get": "^2.1.0",
"reduce-flatten": "^1.0.1",
"reduce-unique": "^1.0.0",
"reduce-without": "^1.0.1",
"test-value": "^3.0.0",
"walk-back": "^3.0.0"
},
"dependencies": {
"test-value": {
@ -400,8 +400,8 @@
"integrity": "sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ==",
"dev": true,
"requires": {
"array-back": "2.0.0",
"typical": "2.6.1"
"array-back": "^2.0.0",
"typical": "^2.6.1"
}
}
}
@ -412,9 +412,9 @@
"integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=",
"dev": true,
"requires": {
"browserify-aes": "1.2.0",
"create-hash": "1.2.0",
"create-hmac": "1.1.7"
"browserify-aes": "^1.0.6",
"create-hash": "^1.1.2",
"create-hmac": "^1.1.4"
}
},
"elliptic": {
@ -423,13 +423,13 @@
"integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=",
"dev": true,
"requires": {
"bn.js": "4.11.8",
"brorand": "1.1.0",
"hash.js": "1.1.4",
"hmac-drbg": "1.0.1",
"inherits": "2.0.3",
"minimalistic-assert": "1.0.1",
"minimalistic-crypto-utils": "1.0.1"
"bn.js": "^4.4.0",
"brorand": "^1.0.1",
"hash.js": "^1.0.0",
"hmac-drbg": "^1.0.0",
"inherits": "^2.0.1",
"minimalistic-assert": "^1.0.0",
"minimalistic-crypto-utils": "^1.0.0"
}
},
"escape-string-regexp": {
@ -444,8 +444,8 @@
"integrity": "sha1-/V3ux2qXpRIKnNOnyxF3oJI7EdI=",
"dev": true,
"requires": {
"acorn": "3.3.0",
"acorn-jsx": "3.0.1"
"acorn": "^3.3.0",
"acorn-jsx": "^3.0.0"
}
},
"ethereumjs-util": {
@ -454,13 +454,13 @@
"integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==",
"dev": true,
"requires": {
"bn.js": "4.11.8",
"create-hash": "1.2.0",
"ethjs-util": "0.1.6",
"keccak": "1.4.0",
"rlp": "2.1.0",
"safe-buffer": "5.1.2",
"secp256k1": "3.5.0"
"bn.js": "^4.11.0",
"create-hash": "^1.1.2",
"ethjs-util": "^0.1.3",
"keccak": "^1.0.2",
"rlp": "^2.0.0",
"safe-buffer": "^5.1.1",
"secp256k1": "^3.0.1"
}
},
"ethjs-util": {
@ -479,8 +479,8 @@
"integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
"dev": true,
"requires": {
"md5.js": "1.3.4",
"safe-buffer": "5.1.2"
"md5.js": "^1.3.4",
"safe-buffer": "^5.1.1"
}
},
"file-set": {
@ -489,8 +489,8 @@
"integrity": "sha512-cCWXfw+nrYoIoUVmEF7Xsw91lGWuObtSnTEZ7AmdvZou1A/6Xx237HfxdQyC/ayKRvQSMbNOBwg62OjN5JxbXw==",
"dev": true,
"requires": {
"array-back": "2.0.0",
"glob": "7.1.2"
"array-back": "^2.0.0",
"glob": "^7.1.2"
}
},
"find-replace": {
@ -499,8 +499,8 @@
"integrity": "sha1-uI5zZNLZyVlVnziMZmcNYTBEH6A=",
"dev": true,
"requires": {
"array-back": "1.0.4",
"test-value": "2.1.0"
"array-back": "^1.0.4",
"test-value": "^2.1.0"
},
"dependencies": {
"array-back": {
@ -509,7 +509,7 @@
"integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
"dev": true,
"requires": {
"typical": "2.6.1"
"typical": "^2.6.0"
}
}
}
@ -532,12 +532,12 @@
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"dev": true,
"requires": {
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
"inherits": "2.0.3",
"minimatch": "3.0.4",
"once": "1.4.0",
"path-is-absolute": "1.0.1"
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"graceful-fs": {
@ -553,10 +553,10 @@
"integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=",
"dev": true,
"requires": {
"async": "1.5.2",
"optimist": "0.6.1",
"source-map": "0.4.4",
"uglify-js": "2.8.29"
"async": "^1.4.0",
"optimist": "^0.6.1",
"source-map": "^0.4.4",
"uglify-js": "^2.6"
}
},
"hash-base": {
@ -565,8 +565,8 @@
"integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
"dev": true,
"requires": {
"inherits": "2.0.3",
"safe-buffer": "5.1.2"
"inherits": "^2.0.1",
"safe-buffer": "^5.0.1"
}
},
"hash.js": {
@ -575,8 +575,8 @@
"integrity": "sha512-A6RlQvvZEtFS5fLU43IDu0QUmBy+fDO9VMdTXvufKwIkt/rFfvICAViCax5fbDO4zdNzaC3/27ZhKUok5bAJyw==",
"dev": true,
"requires": {
"inherits": "2.0.3",
"minimalistic-assert": "1.0.1"
"inherits": "^2.0.3",
"minimalistic-assert": "^1.0.0"
}
},
"hmac-drbg": {
@ -585,9 +585,9 @@
"integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
"dev": true,
"requires": {
"hash.js": "1.1.4",
"minimalistic-assert": "1.0.1",
"minimalistic-crypto-utils": "1.0.1"
"hash.js": "^1.0.3",
"minimalistic-assert": "^1.0.0",
"minimalistic-crypto-utils": "^1.0.1"
}
},
"inflight": {
@ -596,8 +596,8 @@
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "1.4.0",
"wrappy": "1.0.2"
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
@ -629,18 +629,18 @@
"integrity": "sha1-qAcRlSi0AJzLyrSbdSL2P+xs0L0=",
"dev": true,
"requires": {
"bluebird": "3.4.7",
"catharsis": "0.8.9",
"escape-string-regexp": "1.0.5",
"espree": "3.1.7",
"js2xmlparser": "1.0.0",
"klaw": "1.3.1",
"marked": "0.3.19",
"mkdirp": "0.5.1",
"requizzle": "0.2.1",
"strip-json-comments": "2.0.1",
"bluebird": "~3.4.6",
"catharsis": "~0.8.8",
"escape-string-regexp": "~1.0.5",
"espree": "~3.1.7",
"js2xmlparser": "~1.0.0",
"klaw": "~1.3.0",
"marked": "~0.3.6",
"mkdirp": "~0.5.1",
"requizzle": "~0.2.1",
"strip-json-comments": "~2.0.1",
"taffydb": "2.6.2",
"underscore": "1.8.3"
"underscore": "~1.8.3"
}
},
"jsdoc-api": {
@ -649,15 +649,15 @@
"integrity": "sha1-DVJwAjX4Zb1Ki61evB77Vi/IrSo=",
"dev": true,
"requires": {
"array-back": "1.0.4",
"cache-point": "0.4.1",
"collect-all": "1.0.3",
"file-set": "1.1.1",
"fs-then-native": "2.0.0",
"jsdoc-75lb": "3.6.0",
"object-to-spawn-args": "1.1.1",
"temp-path": "1.0.0",
"walk-back": "2.0.1"
"array-back": "^1.0.4",
"cache-point": "~0.4.0",
"collect-all": "^1.0.2",
"file-set": "^1.1.1",
"fs-then-native": "^2.0.0",
"jsdoc-75lb": "^3.6.0",
"object-to-spawn-args": "^1.1.0",
"temp-path": "^1.0.0",
"walk-back": "^2.0.1"
},
"dependencies": {
"array-back": {
@ -666,7 +666,7 @@
"integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
"dev": true,
"requires": {
"typical": "2.6.1"
"typical": "^2.6.0"
}
},
"file-set": {
@ -675,8 +675,8 @@
"integrity": "sha1-0+xwwIDsjxjyBLod4QZ4DJBWkms=",
"dev": true,
"requires": {
"array-back": "1.0.4",
"glob": "7.1.2"
"array-back": "^1.0.3",
"glob": "^7.1.0"
}
},
"walk-back": {
@ -693,12 +693,12 @@
"integrity": "sha512-btZLp4wYl90vcAfgk4hoGQbO17iBVrhh3LJRMKZNtZgniO3F8H2CjxXld0owBIB1XxN+j3bAcWZnZKMnSj3iMA==",
"dev": true,
"requires": {
"array-back": "2.0.0",
"lodash.omit": "4.5.0",
"lodash.pick": "4.4.0",
"reduce-extract": "1.0.0",
"sort-array": "2.0.0",
"test-value": "3.0.0"
"array-back": "^2.0.0",
"lodash.omit": "^4.5.0",
"lodash.pick": "^4.4.0",
"reduce-extract": "^1.0.0",
"sort-array": "^2.0.0",
"test-value": "^3.0.0"
},
"dependencies": {
"test-value": {
@ -707,8 +707,8 @@
"integrity": "sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ==",
"dev": true,
"requires": {
"array-back": "2.0.0",
"typical": "2.6.1"
"array-back": "^2.0.0",
"typical": "^2.6.1"
}
}
}
@ -719,13 +719,13 @@
"integrity": "sha512-NDD+dpLiF9SYJXFcYPutKi/K8pRtIHHmVyQJzUArYQCoVhNISKeIVK5Pe78mi7K5s16/Nk7EviN2xxlJJ+S5Bw==",
"dev": true,
"requires": {
"array-back": "2.0.0",
"command-line-tool": "0.7.0",
"config-master": "3.1.0",
"dmd": "3.0.12",
"jsdoc-api": "3.0.0",
"jsdoc-parse": "3.0.1",
"walk-back": "3.0.0"
"array-back": "^2.0.0",
"command-line-tool": "^0.7.0",
"config-master": "^3.1.0",
"dmd": "^3.0.9",
"jsdoc-api": "^3.0.0",
"jsdoc-parse": "^3.0.1",
"walk-back": "^3.0.0"
}
},
"keccak": {
@ -734,10 +734,10 @@
"integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==",
"dev": true,
"requires": {
"bindings": "1.3.0",
"inherits": "2.0.3",
"nan": "2.10.0",
"safe-buffer": "5.1.2"
"bindings": "^1.2.1",
"inherits": "^2.0.3",
"nan": "^2.2.1",
"safe-buffer": "^5.1.0"
}
},
"kind-of": {
@ -746,7 +746,7 @@
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"dev": true,
"requires": {
"is-buffer": "1.1.6"
"is-buffer": "^1.1.5"
},
"dependencies": {
"is-buffer": {
@ -763,7 +763,7 @@
"integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
"dev": true,
"requires": {
"graceful-fs": "4.1.11"
"graceful-fs": "^4.1.9"
}
},
"lazy-cache": {
@ -815,8 +815,8 @@
"integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
"dev": true,
"requires": {
"hash-base": "3.0.4",
"inherits": "2.0.3"
"hash-base": "^3.0.0",
"inherits": "^2.0.1"
}
},
"minimalistic-assert": {
@ -837,7 +837,7 @@
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "1.1.11"
"brace-expansion": "^1.1.7"
}
},
"minimist": {
@ -899,7 +899,7 @@
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1.0.2"
"wrappy": "1"
}
},
"optimist": {
@ -908,8 +908,8 @@
"integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
"dev": true,
"requires": {
"minimist": "0.0.10",
"wordwrap": "0.0.3"
"minimist": "~0.0.1",
"wordwrap": "~0.0.2"
}
},
"path-is-absolute": {
@ -924,7 +924,7 @@
"integrity": "sha1-Z/I4W+2mUGG19fQxJmLosIDKFSU=",
"dev": true,
"requires": {
"test-value": "1.1.0"
"test-value": "^1.0.1"
},
"dependencies": {
"array-back": {
@ -933,7 +933,7 @@
"integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
"dev": true,
"requires": {
"typical": "2.6.1"
"typical": "^2.6.0"
}
},
"test-value": {
@ -942,8 +942,8 @@
"integrity": "sha1-oJE29y7AQ9J8iTcHwrFZv6196T8=",
"dev": true,
"requires": {
"array-back": "1.0.4",
"typical": "2.6.1"
"array-back": "^1.0.2",
"typical": "^2.4.2"
}
}
}
@ -966,7 +966,7 @@
"integrity": "sha1-aK0OrRGFXJo31OglbBW7+Hly/Iw=",
"dev": true,
"requires": {
"test-value": "2.1.0"
"test-value": "^2.0.0"
}
},
"repeat-string": {
@ -981,7 +981,7 @@
"integrity": "sha1-aUPDUwxNmn5G8c3dUcFY/GcM294=",
"dev": true,
"requires": {
"underscore": "1.6.0"
"underscore": "~1.6.0"
},
"dependencies": {
"underscore": {
@ -998,7 +998,7 @@
"integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=",
"dev": true,
"requires": {
"through": "2.3.8"
"through": "~2.3.4"
}
},
"right-align": {
@ -1008,7 +1008,7 @@
"dev": true,
"optional": true,
"requires": {
"align-text": "0.1.4"
"align-text": "^0.1.1"
}
},
"ripemd160": {
@ -1017,8 +1017,8 @@
"integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
"dev": true,
"requires": {
"hash-base": "3.0.4",
"inherits": "2.0.3"
"hash-base": "^3.0.0",
"inherits": "^2.0.1"
}
},
"rlp": {
@ -1027,7 +1027,7 @@
"integrity": "sha512-93U7IKH5j7nmXFVg19MeNBGzQW5uXW1pmCuKY8veeKIhYTE32C2d0mOegfiIAfXcHOKJjjPlJisn8iHDF5AezA==",
"dev": true,
"requires": {
"safe-buffer": "5.1.2"
"safe-buffer": "^5.1.1"
}
},
"safe-buffer": {
@ -1042,14 +1042,14 @@
"integrity": "sha512-e5QIJl8W7Y4tT6LHffVcZAxJjvpgE5Owawv6/XCYPQljE9aP2NFFddQ8OYMKhdLshNu88FfL3qCN3/xYkXGRsA==",
"dev": true,
"requires": {
"bindings": "1.3.0",
"bip66": "1.1.5",
"bn.js": "4.11.8",
"create-hash": "1.2.0",
"drbg.js": "1.0.1",
"elliptic": "6.4.0",
"nan": "2.10.0",
"safe-buffer": "5.1.2"
"bindings": "^1.2.1",
"bip66": "^1.1.3",
"bn.js": "^4.11.3",
"create-hash": "^1.1.2",
"drbg.js": "^1.0.1",
"elliptic": "^6.2.3",
"nan": "^2.2.1",
"safe-buffer": "^5.1.0"
}
},
"sha.js": {
@ -1058,8 +1058,8 @@
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"dev": true,
"requires": {
"inherits": "2.0.3",
"safe-buffer": "5.1.2"
"inherits": "^2.0.1",
"safe-buffer": "^5.0.1"
}
},
"sigmund": {
@ -1074,9 +1074,9 @@
"integrity": "sha1-OKnG2if9fRR7QuYFVPKBGHtN9HI=",
"dev": true,
"requires": {
"array-back": "1.0.4",
"object-get": "2.1.0",
"typical": "2.6.1"
"array-back": "^1.0.4",
"object-get": "^2.1.0",
"typical": "^2.6.0"
},
"dependencies": {
"array-back": {
@ -1085,7 +1085,7 @@
"integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
"dev": true,
"requires": {
"typical": "2.6.1"
"typical": "^2.6.0"
}
}
}
@ -1096,7 +1096,7 @@
"integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
"dev": true,
"requires": {
"amdefine": "1.0.1"
"amdefine": ">=0.0.4"
}
},
"stream-connect": {
@ -1105,7 +1105,7 @@
"integrity": "sha1-GLyB8u2zW4tdmoAJIAqYUxRCipc=",
"dev": true,
"requires": {
"array-back": "1.0.4"
"array-back": "^1.0.2"
},
"dependencies": {
"array-back": {
@ -1114,7 +1114,7 @@
"integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
"dev": true,
"requires": {
"typical": "2.6.1"
"typical": "^2.6.0"
}
}
}
@ -1146,11 +1146,11 @@
"integrity": "sha512-uNaR3SRMJwfdp9OUr36eyEi6LLsbcTqTO/hfTsNviKsNeyMBPICJCC7QXRF3+07bAP6FRwA8rczJPBqXDc0CkQ==",
"dev": true,
"requires": {
"array-back": "2.0.0",
"deep-extend": "0.6.0",
"lodash.padend": "4.6.1",
"typical": "2.6.1",
"wordwrapjs": "3.0.0"
"array-back": "^2.0.0",
"deep-extend": "~0.6.0",
"lodash.padend": "^4.6.1",
"typical": "^2.6.1",
"wordwrapjs": "^3.0.0"
}
},
"taffydb": {
@ -1165,13 +1165,13 @@
"integrity": "sha1-SJPdU+KApfWMDOswwsDrs7zVHh8=",
"dev": true,
"requires": {
"deep-equal": "0.2.2",
"defined": "0.0.0",
"glob": "3.2.11",
"inherits": "2.0.3",
"object-inspect": "0.4.0",
"resumer": "0.0.0",
"through": "2.3.8"
"deep-equal": "~0.2.0",
"defined": "~0.0.0",
"glob": "~3.2.9",
"inherits": "~2.0.1",
"object-inspect": "~0.4.0",
"resumer": "~0.0.0",
"through": "~2.3.4"
},
"dependencies": {
"glob": {
@ -1180,8 +1180,8 @@
"integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=",
"dev": true,
"requires": {
"inherits": "2.0.3",
"minimatch": "0.3.0"
"inherits": "2",
"minimatch": "0.3"
}
},
"minimatch": {
@ -1190,8 +1190,8 @@
"integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=",
"dev": true,
"requires": {
"lru-cache": "2.7.3",
"sigmund": "1.0.1"
"lru-cache": "2",
"sigmund": "~1.0.0"
}
}
}
@ -1208,8 +1208,8 @@
"integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=",
"dev": true,
"requires": {
"array-back": "1.0.4",
"typical": "2.6.1"
"array-back": "^1.0.3",
"typical": "^2.6.0"
},
"dependencies": {
"array-back": {
@ -1218,7 +1218,7 @@
"integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
"dev": true,
"requires": {
"typical": "2.6.1"
"typical": "^2.6.0"
}
}
}
@ -1229,6 +1229,11 @@
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
"dev": true
},
"treeify": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz",
"integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A=="
},
"typical": {
"version": "2.6.1",
"resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
@ -1242,9 +1247,9 @@
"dev": true,
"optional": true,
"requires": {
"source-map": "0.5.7",
"uglify-to-browserify": "1.0.2",
"yargs": "3.10.0"
"source-map": "~0.5.1",
"uglify-to-browserify": "~1.0.0",
"yargs": "~3.10.0"
},
"dependencies": {
"source-map": {
@ -1311,8 +1316,8 @@
"integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==",
"dev": true,
"requires": {
"reduce-flatten": "1.0.1",
"typical": "2.6.1"
"reduce-flatten": "^1.0.1",
"typical": "^2.6.1"
}
},
"wrappy": {
@ -1328,9 +1333,9 @@
"dev": true,
"optional": true,
"requires": {
"camelcase": "1.2.1",
"cliui": "2.1.0",
"decamelize": "1.2.0",
"camelcase": "^1.0.2",
"cliui": "^2.1.0",
"decamelize": "^1.0.0",
"window-size": "0.1.0"
}
}

View File

@ -47,6 +47,7 @@
"dependencies": {
"buffer-reverse": "^1.0.1",
"crypto-js": "^3.1.9-1",
"is-buffer": "^2.0.3"
"is-buffer": "^2.0.3",
"treeify": "^1.1.0"
}
}

View File

@ -309,3 +309,20 @@ test('crypto-js bufferify', t => {
t.deepEqual(leaves.map(MerkleTree.bufferify), leaves.map(bufferifyCryptoJS))
})
test('print', t => {
t.plan(1)
const leaves = ['a', 'b', 'c'].map(x => sha3(x))
const tree = new MerkleTree(leaves, sha256)
const str = MerkleTree.print(tree, {log: false})
t.equal(str,
`└─ 311d2e46f49b15fff8b746b74ad57f2cc9e0d9939fda94387141a2d3fdf187ae
176f0f307632fdd5831875eb709e2f68d770b102262998b214ddeb3f04164ae1
3ac225168df54212a25c1c01fd35bebfea408fdac2e31ddd6f80a4bbf9a5f1cb
b5553de315e0edf504d9150af82dafa5c4667fa618ed0a6f19c69b41166c5510
0b42b6393c1f53060fe3ddbfcd7aadcca894465a5a438f69c87d790b2299b9b2
0b42b6393c1f53060fe3ddbfcd7aadcca894465a5a438f69c87d790b2299b9b2
`)
})