├── .gitignore ├── .node-version ├── LICENSE ├── Makefile ├── README.md ├── contracts ├── MerkleProof.sol └── Migrations.sol ├── migrations ├── 1_initial_migration.js └── 2_deploy_contracts.js ├── package-lock.json ├── package.json ├── test └── merkleproof.js ├── truffle-config.js └── truffle.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | build 4 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 11.15.0 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT license 2 | 3 | Copyright (C) 2018 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 9 | of the Software, and to permit persons to whom the Software is furnished to do 10 | so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: build 2 | 3 | .PHONY: build 4 | build: 5 | @truffle migrate 6 | 7 | .PHONY: start/testrpc 8 | start/testrpc: 9 | @ganache-cli -m "raise fold coral resemble gather program legend regular rival learn vivid trust" 10 | 11 | .PHONY: deploy 12 | deploy: 13 | @truffle deploy 14 | 15 | .PHONY: test 16 | test: 17 | @truffle test 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MerkleTree.js Solidity example 2 | 3 | > Construct merkle trees with [MerkleTree.js](https://github.com/miguelmota/merkletreejs) and verify merkle proofs in [Solidity](https://github.com/ethereum/solidity). 4 | 5 | ## Example 6 | 7 | [`contracts/MerkleProof.sol`](./contracts/MerkleProof.sol) 8 | 9 | ```solidity 10 | pragma solidity ^0.5.2; 11 | 12 | contract MerkleProof { 13 | function verify( 14 | bytes32 root, 15 | bytes32 leaf, 16 | bytes32[] memory proof 17 | ) 18 | public 19 | pure 20 | returns (bool) 21 | { 22 | bytes32 computedHash = leaf; 23 | 24 | for (uint256 i = 0; i < proof.length; i++) { 25 | bytes32 proofElement = proof[i]; 26 | 27 | if (computedHash <= proofElement) { 28 | // Hash(current computed hash + current element of the proof) 29 | computedHash = keccak256(abi.encodePacked(computedHash, proofElement)); 30 | } else { 31 | // Hash(current element of the proof + current computed hash) 32 | computedHash = keccak256(abi.encodePacked(proofElement, computedHash)); 33 | } 34 | } 35 | 36 | // Check if the computed hash (root) is equal to the provided root 37 | return computedHash == root; 38 | } 39 | } 40 | ``` 41 | 42 | [`test/merkleproof.js`](./test/merkleproof.js) 43 | 44 | ```js 45 | const MerkleProof = artifacts.require('MerkleProof') 46 | const MerkleTree = require('merkletreejs') 47 | const keccak256 = require('keccak256') 48 | 49 | const contract = await MerkleProof.new() 50 | 51 | const leaves = ['a', 'b', 'c', 'd'].map(v => keccak256(v)) 52 | const tree = new MerkleTree(leaves, keccak256, { sort: true }) 53 | const root = tree.getHexRoot() 54 | const leaf = keccak256('a') 55 | const proof = tree.getHexProof(leaf) 56 | console.log(await contract.verify.call(root, leaf, proof)) // true 57 | 58 | const badLeaves = ['a', 'b', 'x', 'd'].map(v => keccak256(v)) 59 | const badTree = new MerkleTree(badLeaves, keccak256, { sort: true }) 60 | const badProof = badTree.getHexProof(leaf) 61 | console.log(await contract.verify.call(root, leaf, badProof)) // false 62 | ``` 63 | 64 | ## Test 65 | 66 | ```bash 67 | make test 68 | ``` 69 | 70 | ## License 71 | 72 | MIT 73 | -------------------------------------------------------------------------------- /contracts/MerkleProof.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.2; 2 | 3 | contract MerkleProof { 4 | function verify( 5 | bytes32 root, 6 | bytes32 leaf, 7 | bytes32[] memory proof 8 | ) 9 | public 10 | pure 11 | returns (bool) 12 | { 13 | bytes32 computedHash = leaf; 14 | 15 | for (uint256 i = 0; i < proof.length; i++) { 16 | bytes32 proofElement = proof[i]; 17 | 18 | if (computedHash <= proofElement) { 19 | // Hash(current computed hash + current element of the proof) 20 | computedHash = keccak256(abi.encodePacked(computedHash, proofElement)); 21 | } else { 22 | // Hash(current element of the proof + current computed hash) 23 | computedHash = keccak256(abi.encodePacked(proofElement, computedHash)); 24 | } 25 | } 26 | 27 | // Check if the computed hash (root) is equal to the provided root 28 | return computedHash == root; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.5.2; 2 | 3 | contract Migrations { 4 | address public owner; 5 | uint public last_completed_migration; 6 | 7 | constructor() public { 8 | owner = msg.sender; 9 | } 10 | 11 | modifier restricted() { 12 | if (msg.sender == owner) _; 13 | } 14 | 15 | function setCompleted(uint completed) public restricted { 16 | last_completed_migration = completed; 17 | } 18 | 19 | function upgrade(address new_address) public restricted { 20 | Migrations upgraded = Migrations(new_address); 21 | upgraded.setCompleted(last_completed_migration); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | var Migrations = artifacts.require("./Migrations.sol"); 2 | 3 | module.exports = function(deployer) { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /migrations/2_deploy_contracts.js: -------------------------------------------------------------------------------- 1 | const MerkleProof = artifacts.require('./MerkleProof.sol') 2 | 3 | module.exports = (deployer, network, accounts) => { 4 | deployer.then(async () => { 5 | await deployer.deploy(MerkleProof) 6 | }) 7 | } 8 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "merkletreejs-solidity", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "accepts": { 8 | "version": "1.3.5", 9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", 10 | "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", 11 | "requires": { 12 | "mime-types": "~2.1.18", 13 | "negotiator": "0.6.1" 14 | } 15 | }, 16 | "ajv": { 17 | "version": "5.5.2", 18 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", 19 | "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", 20 | "requires": { 21 | "co": "^4.6.0", 22 | "fast-deep-equal": "^1.0.0", 23 | "fast-json-stable-stringify": "^2.0.0", 24 | "json-schema-traverse": "^0.3.0" 25 | } 26 | }, 27 | "app-module-path": { 28 | "version": "2.2.0", 29 | "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", 30 | "integrity": "sha1-ZBqlXft9am8KgUHEucCqULbCTdU=", 31 | "dev": true 32 | }, 33 | "array-flatten": { 34 | "version": "1.1.1", 35 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 36 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" 37 | }, 38 | "asn1": { 39 | "version": "0.2.4", 40 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 41 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 42 | "requires": { 43 | "safer-buffer": "~2.1.0" 44 | } 45 | }, 46 | "assert-plus": { 47 | "version": "1.0.0", 48 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 49 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 50 | }, 51 | "async-limiter": { 52 | "version": "1.0.0", 53 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", 54 | "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" 55 | }, 56 | "asynckit": { 57 | "version": "0.4.0", 58 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 59 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 60 | }, 61 | "aws-sign2": { 62 | "version": "0.7.0", 63 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 64 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 65 | }, 66 | "aws4": { 67 | "version": "1.8.0", 68 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", 69 | "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" 70 | }, 71 | "balanced-match": { 72 | "version": "1.0.2", 73 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", 74 | "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", 75 | "dev": true 76 | }, 77 | "bcrypt-pbkdf": { 78 | "version": "1.0.2", 79 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 80 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 81 | "requires": { 82 | "tweetnacl": "^0.14.3" 83 | } 84 | }, 85 | "bindings": { 86 | "version": "1.3.0", 87 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", 88 | "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" 89 | }, 90 | "bip66": { 91 | "version": "1.1.5", 92 | "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", 93 | "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", 94 | "requires": { 95 | "safe-buffer": "^5.0.1" 96 | } 97 | }, 98 | "bn.js": { 99 | "version": "4.11.8", 100 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", 101 | "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" 102 | }, 103 | "body-parser": { 104 | "version": "1.18.3", 105 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", 106 | "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", 107 | "requires": { 108 | "bytes": "3.0.0", 109 | "content-type": "~1.0.4", 110 | "debug": "2.6.9", 111 | "depd": "~1.1.2", 112 | "http-errors": "~1.6.3", 113 | "iconv-lite": "0.4.23", 114 | "on-finished": "~2.3.0", 115 | "qs": "6.5.2", 116 | "raw-body": "2.3.3", 117 | "type-is": "~1.6.16" 118 | } 119 | }, 120 | "brace-expansion": { 121 | "version": "1.1.11", 122 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 123 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 124 | "dev": true, 125 | "requires": { 126 | "balanced-match": "^1.0.0", 127 | "concat-map": "0.0.1" 128 | } 129 | }, 130 | "brorand": { 131 | "version": "1.1.0", 132 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", 133 | "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" 134 | }, 135 | "browser-stdout": { 136 | "version": "1.3.1", 137 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 138 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 139 | "dev": true 140 | }, 141 | "browserify-aes": { 142 | "version": "1.2.0", 143 | "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", 144 | "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", 145 | "requires": { 146 | "buffer-xor": "^1.0.3", 147 | "cipher-base": "^1.0.0", 148 | "create-hash": "^1.1.0", 149 | "evp_bytestokey": "^1.0.3", 150 | "inherits": "^2.0.1", 151 | "safe-buffer": "^5.0.1" 152 | } 153 | }, 154 | "browserify-sha3": { 155 | "version": "0.0.1", 156 | "resolved": "https://registry.npmjs.org/browserify-sha3/-/browserify-sha3-0.0.1.tgz", 157 | "integrity": "sha1-P/NKMAbvFcD7NWflQbkaI0ASPRE=", 158 | "requires": { 159 | "js-sha3": "^0.3.1" 160 | } 161 | }, 162 | "buffer-reverse": { 163 | "version": "1.0.1", 164 | "resolved": "https://registry.npmjs.org/buffer-reverse/-/buffer-reverse-1.0.1.tgz", 165 | "integrity": "sha1-SSg8jvpvkBvAH6MwTQYCeXGuL2A=" 166 | }, 167 | "buffer-to-arraybuffer": { 168 | "version": "0.0.5", 169 | "resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz", 170 | "integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=" 171 | }, 172 | "buffer-xor": { 173 | "version": "1.0.3", 174 | "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", 175 | "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" 176 | }, 177 | "bytes": { 178 | "version": "3.0.0", 179 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", 180 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" 181 | }, 182 | "caseless": { 183 | "version": "0.12.0", 184 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 185 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 186 | }, 187 | "cipher-base": { 188 | "version": "1.0.4", 189 | "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", 190 | "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", 191 | "requires": { 192 | "inherits": "^2.0.1", 193 | "safe-buffer": "^5.0.1" 194 | } 195 | }, 196 | "co": { 197 | "version": "4.6.0", 198 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 199 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" 200 | }, 201 | "combined-stream": { 202 | "version": "1.0.7", 203 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", 204 | "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", 205 | "requires": { 206 | "delayed-stream": "~1.0.0" 207 | } 208 | }, 209 | "commander": { 210 | "version": "2.15.1", 211 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", 212 | "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", 213 | "dev": true 214 | }, 215 | "concat-map": { 216 | "version": "0.0.1", 217 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 218 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 219 | "dev": true 220 | }, 221 | "content-disposition": { 222 | "version": "0.5.2", 223 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", 224 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" 225 | }, 226 | "content-type": { 227 | "version": "1.0.4", 228 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", 229 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" 230 | }, 231 | "cookie": { 232 | "version": "0.3.1", 233 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", 234 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" 235 | }, 236 | "cookie-signature": { 237 | "version": "1.0.6", 238 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 239 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" 240 | }, 241 | "core-util-is": { 242 | "version": "1.0.2", 243 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 244 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 245 | }, 246 | "cors": { 247 | "version": "2.8.4", 248 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", 249 | "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", 250 | "requires": { 251 | "object-assign": "^4", 252 | "vary": "^1" 253 | } 254 | }, 255 | "create-hash": { 256 | "version": "1.2.0", 257 | "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", 258 | "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", 259 | "requires": { 260 | "cipher-base": "^1.0.1", 261 | "inherits": "^2.0.1", 262 | "md5.js": "^1.3.4", 263 | "ripemd160": "^2.0.1", 264 | "sha.js": "^2.4.0" 265 | } 266 | }, 267 | "create-hmac": { 268 | "version": "1.1.7", 269 | "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", 270 | "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", 271 | "requires": { 272 | "cipher-base": "^1.0.3", 273 | "create-hash": "^1.1.0", 274 | "inherits": "^2.0.1", 275 | "ripemd160": "^2.0.0", 276 | "safe-buffer": "^5.0.1", 277 | "sha.js": "^2.4.8" 278 | } 279 | }, 280 | "crypto": { 281 | "version": "1.0.1", 282 | "resolved": "https://registry.npmjs.org/crypto/-/crypto-1.0.1.tgz", 283 | "integrity": "sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==" 284 | }, 285 | "crypto-js": { 286 | "version": "3.1.9-1", 287 | "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz", 288 | "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg=" 289 | }, 290 | "dashdash": { 291 | "version": "1.14.1", 292 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 293 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 294 | "requires": { 295 | "assert-plus": "^1.0.0" 296 | } 297 | }, 298 | "debug": { 299 | "version": "2.6.9", 300 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 301 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 302 | "requires": { 303 | "ms": "2.0.0" 304 | } 305 | }, 306 | "decode-uri-component": { 307 | "version": "0.2.0", 308 | "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", 309 | "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=" 310 | }, 311 | "decompress-response": { 312 | "version": "3.3.0", 313 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", 314 | "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", 315 | "requires": { 316 | "mimic-response": "^1.0.0" 317 | } 318 | }, 319 | "delayed-stream": { 320 | "version": "1.0.0", 321 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 322 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 323 | }, 324 | "depd": { 325 | "version": "1.1.2", 326 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", 327 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" 328 | }, 329 | "destroy": { 330 | "version": "1.0.4", 331 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", 332 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" 333 | }, 334 | "diff": { 335 | "version": "3.5.0", 336 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", 337 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", 338 | "dev": true 339 | }, 340 | "dom-walk": { 341 | "version": "0.1.1", 342 | "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz", 343 | "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" 344 | }, 345 | "drbg.js": { 346 | "version": "1.0.1", 347 | "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", 348 | "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", 349 | "requires": { 350 | "browserify-aes": "^1.0.6", 351 | "create-hash": "^1.1.2", 352 | "create-hmac": "^1.1.4" 353 | } 354 | }, 355 | "ecc-jsbn": { 356 | "version": "0.1.2", 357 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 358 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 359 | "requires": { 360 | "jsbn": "~0.1.0", 361 | "safer-buffer": "^2.1.0" 362 | } 363 | }, 364 | "ee-first": { 365 | "version": "1.1.1", 366 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 367 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" 368 | }, 369 | "elliptic": { 370 | "version": "6.4.1", 371 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", 372 | "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", 373 | "requires": { 374 | "bn.js": "^4.4.0", 375 | "brorand": "^1.0.1", 376 | "hash.js": "^1.0.0", 377 | "hmac-drbg": "^1.0.0", 378 | "inherits": "^2.0.1", 379 | "minimalistic-assert": "^1.0.0", 380 | "minimalistic-crypto-utils": "^1.0.0" 381 | } 382 | }, 383 | "encodeurl": { 384 | "version": "1.0.2", 385 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 386 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=" 387 | }, 388 | "escape-html": { 389 | "version": "1.0.3", 390 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 391 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" 392 | }, 393 | "escape-string-regexp": { 394 | "version": "1.0.5", 395 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 396 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 397 | "dev": true 398 | }, 399 | "etag": { 400 | "version": "1.8.1", 401 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 402 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" 403 | }, 404 | "eth-lib": { 405 | "version": "0.1.27", 406 | "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.1.27.tgz", 407 | "integrity": "sha512-B8czsfkJYzn2UIEMwjc7Mbj+Cy72V+/OXH/tb44LV8jhrjizQJJ325xMOMyk3+ETa6r6oi0jsUY14+om8mQMWA==", 408 | "requires": { 409 | "bn.js": "^4.11.6", 410 | "elliptic": "^6.4.0", 411 | "keccakjs": "^0.2.1", 412 | "nano-json-stream-parser": "^0.1.2", 413 | "servify": "^0.1.12", 414 | "ws": "^3.0.0", 415 | "xhr-request-promise": "^0.1.2" 416 | } 417 | }, 418 | "ethereumjs-util": { 419 | "version": "6.0.0", 420 | "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.0.0.tgz", 421 | "integrity": "sha512-E3yKUyl0Fs95nvTFQZe/ZSNcofhDzUsDlA5y2uoRmf1+Ec7gpGhNCsgKkZBRh7Br5op8mJcYF/jFbmjj909+nQ==", 422 | "requires": { 423 | "bn.js": "^4.11.0", 424 | "create-hash": "^1.1.2", 425 | "ethjs-util": "^0.1.6", 426 | "keccak": "^1.0.2", 427 | "rlp": "^2.0.0", 428 | "safe-buffer": "^5.1.1", 429 | "secp256k1": "^3.0.1" 430 | } 431 | }, 432 | "ethjs-unit": { 433 | "version": "0.1.6", 434 | "resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz", 435 | "integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=", 436 | "requires": { 437 | "bn.js": "4.11.6", 438 | "number-to-bn": "1.7.0" 439 | }, 440 | "dependencies": { 441 | "bn.js": { 442 | "version": "4.11.6", 443 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", 444 | "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" 445 | } 446 | } 447 | }, 448 | "ethjs-util": { 449 | "version": "0.1.6", 450 | "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", 451 | "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", 452 | "requires": { 453 | "is-hex-prefixed": "1.0.0", 454 | "strip-hex-prefix": "1.0.0" 455 | } 456 | }, 457 | "evp_bytestokey": { 458 | "version": "1.0.3", 459 | "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", 460 | "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", 461 | "requires": { 462 | "md5.js": "^1.3.4", 463 | "safe-buffer": "^5.1.1" 464 | } 465 | }, 466 | "express": { 467 | "version": "4.16.4", 468 | "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", 469 | "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", 470 | "requires": { 471 | "accepts": "~1.3.5", 472 | "array-flatten": "1.1.1", 473 | "body-parser": "1.18.3", 474 | "content-disposition": "0.5.2", 475 | "content-type": "~1.0.4", 476 | "cookie": "0.3.1", 477 | "cookie-signature": "1.0.6", 478 | "debug": "2.6.9", 479 | "depd": "~1.1.2", 480 | "encodeurl": "~1.0.2", 481 | "escape-html": "~1.0.3", 482 | "etag": "~1.8.1", 483 | "finalhandler": "1.1.1", 484 | "fresh": "0.5.2", 485 | "merge-descriptors": "1.0.1", 486 | "methods": "~1.1.2", 487 | "on-finished": "~2.3.0", 488 | "parseurl": "~1.3.2", 489 | "path-to-regexp": "0.1.7", 490 | "proxy-addr": "~2.0.4", 491 | "qs": "6.5.2", 492 | "range-parser": "~1.2.0", 493 | "safe-buffer": "5.1.2", 494 | "send": "0.16.2", 495 | "serve-static": "1.13.2", 496 | "setprototypeof": "1.1.0", 497 | "statuses": "~1.4.0", 498 | "type-is": "~1.6.16", 499 | "utils-merge": "1.0.1", 500 | "vary": "~1.1.2" 501 | }, 502 | "dependencies": { 503 | "statuses": { 504 | "version": "1.4.0", 505 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 506 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" 507 | } 508 | } 509 | }, 510 | "extend": { 511 | "version": "3.0.2", 512 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 513 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 514 | }, 515 | "extsprintf": { 516 | "version": "1.3.0", 517 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 518 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 519 | }, 520 | "fast-deep-equal": { 521 | "version": "1.1.0", 522 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", 523 | "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=" 524 | }, 525 | "fast-json-stable-stringify": { 526 | "version": "2.0.0", 527 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 528 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 529 | }, 530 | "finalhandler": { 531 | "version": "1.1.1", 532 | "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", 533 | "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", 534 | "requires": { 535 | "debug": "2.6.9", 536 | "encodeurl": "~1.0.2", 537 | "escape-html": "~1.0.3", 538 | "on-finished": "~2.3.0", 539 | "parseurl": "~1.3.2", 540 | "statuses": "~1.4.0", 541 | "unpipe": "~1.0.0" 542 | }, 543 | "dependencies": { 544 | "statuses": { 545 | "version": "1.4.0", 546 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 547 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" 548 | } 549 | } 550 | }, 551 | "for-each": { 552 | "version": "0.3.3", 553 | "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", 554 | "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", 555 | "requires": { 556 | "is-callable": "^1.1.3" 557 | } 558 | }, 559 | "forever-agent": { 560 | "version": "0.6.1", 561 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 562 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 563 | }, 564 | "form-data": { 565 | "version": "2.3.3", 566 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 567 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 568 | "requires": { 569 | "asynckit": "^0.4.0", 570 | "combined-stream": "^1.0.6", 571 | "mime-types": "^2.1.12" 572 | } 573 | }, 574 | "forwarded": { 575 | "version": "0.1.2", 576 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", 577 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=" 578 | }, 579 | "fresh": { 580 | "version": "0.5.2", 581 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 582 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" 583 | }, 584 | "fs.realpath": { 585 | "version": "1.0.0", 586 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 587 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 588 | "dev": true 589 | }, 590 | "getpass": { 591 | "version": "0.1.7", 592 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 593 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 594 | "requires": { 595 | "assert-plus": "^1.0.0" 596 | } 597 | }, 598 | "glob": { 599 | "version": "7.1.2", 600 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 601 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 602 | "dev": true, 603 | "requires": { 604 | "fs.realpath": "^1.0.0", 605 | "inflight": "^1.0.4", 606 | "inherits": "2", 607 | "minimatch": "^3.0.4", 608 | "once": "^1.3.0", 609 | "path-is-absolute": "^1.0.0" 610 | } 611 | }, 612 | "global": { 613 | "version": "4.3.2", 614 | "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", 615 | "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=", 616 | "requires": { 617 | "min-document": "^2.19.0", 618 | "process": "~0.5.1" 619 | } 620 | }, 621 | "growl": { 622 | "version": "1.10.5", 623 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 624 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 625 | "dev": true 626 | }, 627 | "har-schema": { 628 | "version": "2.0.0", 629 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 630 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 631 | }, 632 | "har-validator": { 633 | "version": "5.1.0", 634 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", 635 | "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", 636 | "requires": { 637 | "ajv": "^5.3.0", 638 | "har-schema": "^2.0.0" 639 | } 640 | }, 641 | "has-flag": { 642 | "version": "3.0.0", 643 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 644 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 645 | "dev": true 646 | }, 647 | "hash-base": { 648 | "version": "3.0.4", 649 | "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", 650 | "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", 651 | "requires": { 652 | "inherits": "^2.0.1", 653 | "safe-buffer": "^5.0.1" 654 | } 655 | }, 656 | "hash.js": { 657 | "version": "1.1.5", 658 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", 659 | "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", 660 | "requires": { 661 | "inherits": "^2.0.3", 662 | "minimalistic-assert": "^1.0.1" 663 | } 664 | }, 665 | "he": { 666 | "version": "1.1.1", 667 | "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", 668 | "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", 669 | "dev": true 670 | }, 671 | "hmac-drbg": { 672 | "version": "1.0.1", 673 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", 674 | "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", 675 | "requires": { 676 | "hash.js": "^1.0.3", 677 | "minimalistic-assert": "^1.0.0", 678 | "minimalistic-crypto-utils": "^1.0.1" 679 | } 680 | }, 681 | "http-errors": { 682 | "version": "1.6.3", 683 | "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", 684 | "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", 685 | "requires": { 686 | "depd": "~1.1.2", 687 | "inherits": "2.0.3", 688 | "setprototypeof": "1.1.0", 689 | "statuses": ">= 1.4.0 < 2" 690 | } 691 | }, 692 | "http-signature": { 693 | "version": "1.2.0", 694 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 695 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 696 | "requires": { 697 | "assert-plus": "^1.0.0", 698 | "jsprim": "^1.2.2", 699 | "sshpk": "^1.7.0" 700 | } 701 | }, 702 | "iconv-lite": { 703 | "version": "0.4.23", 704 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", 705 | "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", 706 | "requires": { 707 | "safer-buffer": ">= 2.1.2 < 3" 708 | } 709 | }, 710 | "inflight": { 711 | "version": "1.0.6", 712 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 713 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 714 | "dev": true, 715 | "requires": { 716 | "once": "^1.3.0", 717 | "wrappy": "1" 718 | } 719 | }, 720 | "inherits": { 721 | "version": "2.0.3", 722 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 723 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 724 | }, 725 | "ipaddr.js": { 726 | "version": "1.8.0", 727 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", 728 | "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" 729 | }, 730 | "is-buffer": { 731 | "version": "2.0.3", 732 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", 733 | "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" 734 | }, 735 | "is-callable": { 736 | "version": "1.1.4", 737 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", 738 | "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" 739 | }, 740 | "is-function": { 741 | "version": "1.0.1", 742 | "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", 743 | "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=" 744 | }, 745 | "is-hex-prefixed": { 746 | "version": "1.0.0", 747 | "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", 748 | "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" 749 | }, 750 | "is-typedarray": { 751 | "version": "1.0.0", 752 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 753 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 754 | }, 755 | "isstream": { 756 | "version": "0.1.2", 757 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 758 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 759 | }, 760 | "js-sha3": { 761 | "version": "0.3.1", 762 | "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.3.1.tgz", 763 | "integrity": "sha1-hhIoAhQvCChQKg0d7h2V4lO7AkM=" 764 | }, 765 | "jsbn": { 766 | "version": "0.1.1", 767 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 768 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" 769 | }, 770 | "json-schema": { 771 | "version": "0.2.3", 772 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 773 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 774 | }, 775 | "json-schema-traverse": { 776 | "version": "0.3.1", 777 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 778 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" 779 | }, 780 | "json-stringify-safe": { 781 | "version": "5.0.1", 782 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 783 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 784 | }, 785 | "jsprim": { 786 | "version": "1.4.1", 787 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 788 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 789 | "requires": { 790 | "assert-plus": "1.0.0", 791 | "extsprintf": "1.3.0", 792 | "json-schema": "0.2.3", 793 | "verror": "1.10.0" 794 | } 795 | }, 796 | "keccak": { 797 | "version": "1.4.0", 798 | "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz", 799 | "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==", 800 | "requires": { 801 | "bindings": "^1.2.1", 802 | "inherits": "^2.0.3", 803 | "nan": "^2.2.1", 804 | "safe-buffer": "^5.1.0" 805 | } 806 | }, 807 | "keccak256": { 808 | "version": "1.0.0", 809 | "resolved": "https://registry.npmjs.org/keccak256/-/keccak256-1.0.0.tgz", 810 | "integrity": "sha512-8qv2vJdQk+Aa2tFXo8zYodm+6DgXqUOqvNJhj1p1V2pxQJT1oNKxNF+zWfhtKXNLZdLvyxjB/dvd9GwcvTHSQQ==", 811 | "requires": { 812 | "bn.js": "^4.11.8", 813 | "keccak": "^1.4.0" 814 | } 815 | }, 816 | "keccakjs": { 817 | "version": "0.2.1", 818 | "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.1.tgz", 819 | "integrity": "sha1-HWM6+QfvMFu/ny+mFtVsRFYd+k0=", 820 | "requires": { 821 | "browserify-sha3": "^0.0.1", 822 | "sha3": "^1.1.0" 823 | } 824 | }, 825 | "md5.js": { 826 | "version": "1.3.5", 827 | "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", 828 | "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", 829 | "requires": { 830 | "hash-base": "^3.0.0", 831 | "inherits": "^2.0.1", 832 | "safe-buffer": "^5.1.2" 833 | } 834 | }, 835 | "media-typer": { 836 | "version": "0.3.0", 837 | "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 838 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" 839 | }, 840 | "merge-descriptors": { 841 | "version": "1.0.1", 842 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 843 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" 844 | }, 845 | "merkle-lib": { 846 | "version": "2.0.10", 847 | "resolved": "https://registry.npmjs.org/merkle-lib/-/merkle-lib-2.0.10.tgz", 848 | "integrity": "sha1-grjbrnXieneFOItz+ddyXQ9vMyY=" 849 | }, 850 | "merkletreejs": { 851 | "version": "0.1.6", 852 | "resolved": "https://registry.npmjs.org/merkletreejs/-/merkletreejs-0.1.6.tgz", 853 | "integrity": "sha512-avzBcnIc5j3jBuNNY6NIpAZg1G24IWZPhZUlwoPILnC7uf/Xj4mgW9rA99/zSJn/Nf56TIAUS8Ooiy2nsUIYKg==", 854 | "requires": { 855 | "buffer-reverse": "^1.0.1", 856 | "crypto-js": "^3.1.9-1", 857 | "is-buffer": "^2.0.3", 858 | "merkle-lib": "^2.0.10", 859 | "treeify": "^1.1.0" 860 | } 861 | }, 862 | "methods": { 863 | "version": "1.1.2", 864 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 865 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=" 866 | }, 867 | "mime": { 868 | "version": "1.4.1", 869 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", 870 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" 871 | }, 872 | "mime-db": { 873 | "version": "1.37.0", 874 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", 875 | "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" 876 | }, 877 | "mime-types": { 878 | "version": "2.1.21", 879 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", 880 | "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", 881 | "requires": { 882 | "mime-db": "~1.37.0" 883 | } 884 | }, 885 | "mimic-response": { 886 | "version": "1.0.1", 887 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", 888 | "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" 889 | }, 890 | "min-document": { 891 | "version": "2.19.0", 892 | "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz", 893 | "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=", 894 | "requires": { 895 | "dom-walk": "^0.1.0" 896 | } 897 | }, 898 | "minimalistic-assert": { 899 | "version": "1.0.1", 900 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", 901 | "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" 902 | }, 903 | "minimalistic-crypto-utils": { 904 | "version": "1.0.1", 905 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", 906 | "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" 907 | }, 908 | "minimatch": { 909 | "version": "3.0.4", 910 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 911 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 912 | "dev": true, 913 | "requires": { 914 | "brace-expansion": "^1.1.7" 915 | } 916 | }, 917 | "minimist": { 918 | "version": "0.0.8", 919 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 920 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 921 | "dev": true 922 | }, 923 | "mkdirp": { 924 | "version": "0.5.1", 925 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 926 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 927 | "dev": true, 928 | "requires": { 929 | "minimist": "0.0.8" 930 | } 931 | }, 932 | "mocha": { 933 | "version": "5.2.0", 934 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", 935 | "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", 936 | "dev": true, 937 | "requires": { 938 | "browser-stdout": "1.3.1", 939 | "commander": "2.15.1", 940 | "debug": "3.1.0", 941 | "diff": "3.5.0", 942 | "escape-string-regexp": "1.0.5", 943 | "glob": "7.1.2", 944 | "growl": "1.10.5", 945 | "he": "1.1.1", 946 | "minimatch": "3.0.4", 947 | "mkdirp": "0.5.1", 948 | "supports-color": "5.4.0" 949 | }, 950 | "dependencies": { 951 | "debug": { 952 | "version": "3.1.0", 953 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 954 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 955 | "dev": true, 956 | "requires": { 957 | "ms": "2.0.0" 958 | } 959 | } 960 | } 961 | }, 962 | "moment": { 963 | "version": "2.22.2", 964 | "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", 965 | "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=" 966 | }, 967 | "ms": { 968 | "version": "2.0.0", 969 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 970 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 971 | }, 972 | "nan": { 973 | "version": "2.11.1", 974 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", 975 | "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==" 976 | }, 977 | "nano-json-stream-parser": { 978 | "version": "0.1.2", 979 | "resolved": "https://registry.npmjs.org/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz", 980 | "integrity": "sha1-DMj20OK2IrR5xA1JnEbWS3Vcb18=" 981 | }, 982 | "negotiator": { 983 | "version": "0.6.1", 984 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", 985 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" 986 | }, 987 | "number-to-bn": { 988 | "version": "1.7.0", 989 | "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", 990 | "integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=", 991 | "requires": { 992 | "bn.js": "4.11.6", 993 | "strip-hex-prefix": "1.0.0" 994 | }, 995 | "dependencies": { 996 | "bn.js": { 997 | "version": "4.11.6", 998 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", 999 | "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" 1000 | } 1001 | } 1002 | }, 1003 | "oauth-sign": { 1004 | "version": "0.9.0", 1005 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 1006 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" 1007 | }, 1008 | "object-assign": { 1009 | "version": "4.1.1", 1010 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1011 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 1012 | }, 1013 | "on-finished": { 1014 | "version": "2.3.0", 1015 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", 1016 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", 1017 | "requires": { 1018 | "ee-first": "1.1.1" 1019 | } 1020 | }, 1021 | "once": { 1022 | "version": "1.4.0", 1023 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1024 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1025 | "requires": { 1026 | "wrappy": "1" 1027 | } 1028 | }, 1029 | "original-require": { 1030 | "version": "1.0.1", 1031 | "resolved": "https://registry.npmjs.org/original-require/-/original-require-1.0.1.tgz", 1032 | "integrity": "sha1-DxMEcVhM0zURxew4yNWSE/msXiA=", 1033 | "dev": true 1034 | }, 1035 | "parse-headers": { 1036 | "version": "2.0.1", 1037 | "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.1.tgz", 1038 | "integrity": "sha1-aug6eqJanZtwCswoaYzR8e1+lTY=", 1039 | "requires": { 1040 | "for-each": "^0.3.2", 1041 | "trim": "0.0.1" 1042 | } 1043 | }, 1044 | "parseurl": { 1045 | "version": "1.3.2", 1046 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", 1047 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" 1048 | }, 1049 | "path-is-absolute": { 1050 | "version": "1.0.1", 1051 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1052 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1053 | "dev": true 1054 | }, 1055 | "path-to-regexp": { 1056 | "version": "0.1.7", 1057 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", 1058 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" 1059 | }, 1060 | "performance-now": { 1061 | "version": "2.1.0", 1062 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 1063 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 1064 | }, 1065 | "process": { 1066 | "version": "0.5.2", 1067 | "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz", 1068 | "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=" 1069 | }, 1070 | "proxy-addr": { 1071 | "version": "2.0.4", 1072 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", 1073 | "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", 1074 | "requires": { 1075 | "forwarded": "~0.1.2", 1076 | "ipaddr.js": "1.8.0" 1077 | } 1078 | }, 1079 | "psl": { 1080 | "version": "1.1.29", 1081 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", 1082 | "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" 1083 | }, 1084 | "punycode": { 1085 | "version": "1.4.1", 1086 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 1087 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" 1088 | }, 1089 | "qs": { 1090 | "version": "6.5.2", 1091 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 1092 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 1093 | }, 1094 | "query-string": { 1095 | "version": "5.1.1", 1096 | "resolved": "http://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", 1097 | "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", 1098 | "requires": { 1099 | "decode-uri-component": "^0.2.0", 1100 | "object-assign": "^4.1.0", 1101 | "strict-uri-encode": "^1.0.0" 1102 | } 1103 | }, 1104 | "randomhex": { 1105 | "version": "0.1.5", 1106 | "resolved": "https://registry.npmjs.org/randomhex/-/randomhex-0.1.5.tgz", 1107 | "integrity": "sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU=" 1108 | }, 1109 | "range-parser": { 1110 | "version": "1.2.0", 1111 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", 1112 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" 1113 | }, 1114 | "raw-body": { 1115 | "version": "2.3.3", 1116 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", 1117 | "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", 1118 | "requires": { 1119 | "bytes": "3.0.0", 1120 | "http-errors": "1.6.3", 1121 | "iconv-lite": "0.4.23", 1122 | "unpipe": "1.0.0" 1123 | } 1124 | }, 1125 | "request": { 1126 | "version": "2.88.0", 1127 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", 1128 | "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", 1129 | "requires": { 1130 | "aws-sign2": "~0.7.0", 1131 | "aws4": "^1.8.0", 1132 | "caseless": "~0.12.0", 1133 | "combined-stream": "~1.0.6", 1134 | "extend": "~3.0.2", 1135 | "forever-agent": "~0.6.1", 1136 | "form-data": "~2.3.2", 1137 | "har-validator": "~5.1.0", 1138 | "http-signature": "~1.2.0", 1139 | "is-typedarray": "~1.0.0", 1140 | "isstream": "~0.1.2", 1141 | "json-stringify-safe": "~5.0.1", 1142 | "mime-types": "~2.1.19", 1143 | "oauth-sign": "~0.9.0", 1144 | "performance-now": "^2.1.0", 1145 | "qs": "~6.5.2", 1146 | "safe-buffer": "^5.1.2", 1147 | "tough-cookie": "~2.4.3", 1148 | "tunnel-agent": "^0.6.0", 1149 | "uuid": "^3.3.2" 1150 | } 1151 | }, 1152 | "ripemd160": { 1153 | "version": "2.0.2", 1154 | "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", 1155 | "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", 1156 | "requires": { 1157 | "hash-base": "^3.0.0", 1158 | "inherits": "^2.0.1" 1159 | } 1160 | }, 1161 | "rlp": { 1162 | "version": "2.1.0", 1163 | "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.1.0.tgz", 1164 | "integrity": "sha512-93U7IKH5j7nmXFVg19MeNBGzQW5uXW1pmCuKY8veeKIhYTE32C2d0mOegfiIAfXcHOKJjjPlJisn8iHDF5AezA==", 1165 | "requires": { 1166 | "safe-buffer": "^5.1.1" 1167 | } 1168 | }, 1169 | "safe-buffer": { 1170 | "version": "5.1.2", 1171 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1172 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 1173 | }, 1174 | "safer-buffer": { 1175 | "version": "2.1.2", 1176 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1177 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1178 | }, 1179 | "secp256k1": { 1180 | "version": "3.5.2", 1181 | "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.2.tgz", 1182 | "integrity": "sha512-iin3kojdybY6NArd+UFsoTuapOF7bnJNf2UbcWXaY3z+E1sJDipl60vtzB5hbO/uquBu7z0fd4VC4Irp+xoFVQ==", 1183 | "requires": { 1184 | "bindings": "^1.2.1", 1185 | "bip66": "^1.1.3", 1186 | "bn.js": "^4.11.3", 1187 | "create-hash": "^1.1.2", 1188 | "drbg.js": "^1.0.1", 1189 | "elliptic": "^6.2.3", 1190 | "nan": "^2.2.1", 1191 | "safe-buffer": "^5.1.0" 1192 | } 1193 | }, 1194 | "send": { 1195 | "version": "0.16.2", 1196 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", 1197 | "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", 1198 | "requires": { 1199 | "debug": "2.6.9", 1200 | "depd": "~1.1.2", 1201 | "destroy": "~1.0.4", 1202 | "encodeurl": "~1.0.2", 1203 | "escape-html": "~1.0.3", 1204 | "etag": "~1.8.1", 1205 | "fresh": "0.5.2", 1206 | "http-errors": "~1.6.2", 1207 | "mime": "1.4.1", 1208 | "ms": "2.0.0", 1209 | "on-finished": "~2.3.0", 1210 | "range-parser": "~1.2.0", 1211 | "statuses": "~1.4.0" 1212 | }, 1213 | "dependencies": { 1214 | "statuses": { 1215 | "version": "1.4.0", 1216 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", 1217 | "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" 1218 | } 1219 | } 1220 | }, 1221 | "serve-static": { 1222 | "version": "1.13.2", 1223 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", 1224 | "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", 1225 | "requires": { 1226 | "encodeurl": "~1.0.2", 1227 | "escape-html": "~1.0.3", 1228 | "parseurl": "~1.3.2", 1229 | "send": "0.16.2" 1230 | } 1231 | }, 1232 | "servify": { 1233 | "version": "0.1.12", 1234 | "resolved": "https://registry.npmjs.org/servify/-/servify-0.1.12.tgz", 1235 | "integrity": "sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==", 1236 | "requires": { 1237 | "body-parser": "^1.16.0", 1238 | "cors": "^2.8.1", 1239 | "express": "^4.14.0", 1240 | "request": "^2.79.0", 1241 | "xhr": "^2.3.3" 1242 | } 1243 | }, 1244 | "setprototypeof": { 1245 | "version": "1.1.0", 1246 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", 1247 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" 1248 | }, 1249 | "sha.js": { 1250 | "version": "2.4.11", 1251 | "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", 1252 | "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", 1253 | "requires": { 1254 | "inherits": "^2.0.1", 1255 | "safe-buffer": "^5.0.1" 1256 | } 1257 | }, 1258 | "sha3": { 1259 | "version": "1.2.2", 1260 | "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.2.tgz", 1261 | "integrity": "sha1-pmxQmN5MJbyIM27ItIF9AFvKe6k=", 1262 | "requires": { 1263 | "nan": "2.10.0" 1264 | }, 1265 | "dependencies": { 1266 | "nan": { 1267 | "version": "2.10.0", 1268 | "resolved": "http://registry.npmjs.org/nan/-/nan-2.10.0.tgz", 1269 | "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" 1270 | } 1271 | } 1272 | }, 1273 | "simple-concat": { 1274 | "version": "1.0.0", 1275 | "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", 1276 | "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" 1277 | }, 1278 | "simple-get": { 1279 | "version": "2.8.1", 1280 | "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz", 1281 | "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==", 1282 | "requires": { 1283 | "decompress-response": "^3.3.0", 1284 | "once": "^1.3.1", 1285 | "simple-concat": "^1.0.0" 1286 | } 1287 | }, 1288 | "sshpk": { 1289 | "version": "1.15.1", 1290 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.1.tgz", 1291 | "integrity": "sha512-mSdgNUaidk+dRU5MhYtN9zebdzF2iG0cNPWy8HG+W8y+fT1JnSkh0fzzpjOa0L7P8i1Rscz38t0h4gPcKz43xA==", 1292 | "requires": { 1293 | "asn1": "~0.2.3", 1294 | "assert-plus": "^1.0.0", 1295 | "bcrypt-pbkdf": "^1.0.0", 1296 | "dashdash": "^1.12.0", 1297 | "ecc-jsbn": "~0.1.1", 1298 | "getpass": "^0.1.1", 1299 | "jsbn": "~0.1.0", 1300 | "safer-buffer": "^2.0.2", 1301 | "tweetnacl": "~0.14.0" 1302 | } 1303 | }, 1304 | "statuses": { 1305 | "version": "1.5.0", 1306 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", 1307 | "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" 1308 | }, 1309 | "strict-uri-encode": { 1310 | "version": "1.1.0", 1311 | "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", 1312 | "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" 1313 | }, 1314 | "strip-hex-prefix": { 1315 | "version": "1.0.0", 1316 | "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", 1317 | "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", 1318 | "requires": { 1319 | "is-hex-prefixed": "1.0.0" 1320 | } 1321 | }, 1322 | "supports-color": { 1323 | "version": "5.4.0", 1324 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", 1325 | "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", 1326 | "dev": true, 1327 | "requires": { 1328 | "has-flag": "^3.0.0" 1329 | } 1330 | }, 1331 | "timed-out": { 1332 | "version": "4.0.1", 1333 | "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", 1334 | "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" 1335 | }, 1336 | "tough-cookie": { 1337 | "version": "2.4.3", 1338 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", 1339 | "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", 1340 | "requires": { 1341 | "psl": "^1.1.24", 1342 | "punycode": "^1.4.1" 1343 | } 1344 | }, 1345 | "treeify": { 1346 | "version": "1.1.0", 1347 | "resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz", 1348 | "integrity": "sha512-1m4RA7xVAJrSGrrXGs0L3YTwyvBs2S8PbRHaLZAkFw7JR8oIFwYtysxlBZhYIa7xSyiYJKZ3iGrrk55cGA3i9A==" 1349 | }, 1350 | "trim": { 1351 | "version": "0.0.1", 1352 | "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", 1353 | "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=" 1354 | }, 1355 | "truffle": { 1356 | "version": "5.0.44", 1357 | "resolved": "https://registry.npmjs.org/truffle/-/truffle-5.0.44.tgz", 1358 | "integrity": "sha512-nbJAu5P76AU7wZxbQl/yPhf8g8gXMkVQtWZGRec5lz6w4fc4cOLrbAD6G6IJYVJqK3s8FTIjox0YKsI/Az/O6w==", 1359 | "dev": true, 1360 | "requires": { 1361 | "app-module-path": "^2.2.0", 1362 | "mocha": "5.2.0", 1363 | "original-require": "1.0.1" 1364 | } 1365 | }, 1366 | "tunnel-agent": { 1367 | "version": "0.6.0", 1368 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 1369 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 1370 | "requires": { 1371 | "safe-buffer": "^5.0.1" 1372 | } 1373 | }, 1374 | "tweetnacl": { 1375 | "version": "0.14.5", 1376 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 1377 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" 1378 | }, 1379 | "type-is": { 1380 | "version": "1.6.16", 1381 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", 1382 | "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", 1383 | "requires": { 1384 | "media-typer": "0.3.0", 1385 | "mime-types": "~2.1.18" 1386 | } 1387 | }, 1388 | "ultron": { 1389 | "version": "1.1.1", 1390 | "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", 1391 | "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" 1392 | }, 1393 | "underscore": { 1394 | "version": "1.8.3", 1395 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.8.3.tgz", 1396 | "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=" 1397 | }, 1398 | "unpipe": { 1399 | "version": "1.0.0", 1400 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1401 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=" 1402 | }, 1403 | "url-set-query": { 1404 | "version": "1.0.0", 1405 | "resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz", 1406 | "integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=" 1407 | }, 1408 | "utf8": { 1409 | "version": "2.1.1", 1410 | "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", 1411 | "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=" 1412 | }, 1413 | "utils-merge": { 1414 | "version": "1.0.1", 1415 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 1416 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" 1417 | }, 1418 | "uuid": { 1419 | "version": "3.3.2", 1420 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", 1421 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" 1422 | }, 1423 | "vary": { 1424 | "version": "1.1.2", 1425 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 1426 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" 1427 | }, 1428 | "verror": { 1429 | "version": "1.10.0", 1430 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 1431 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 1432 | "requires": { 1433 | "assert-plus": "^1.0.0", 1434 | "core-util-is": "1.0.2", 1435 | "extsprintf": "^1.2.0" 1436 | } 1437 | }, 1438 | "web3-utils": { 1439 | "version": "1.0.0-beta.36", 1440 | "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.36.tgz", 1441 | "integrity": "sha512-7ri74lG5fS2Th0fhYvTtiEHMB1Pmf2p7dQx1COQ3OHNI/CHNEMjzoNMEbBU6FAENrywfoFur40K4m0AOmEUq5A==", 1442 | "requires": { 1443 | "bn.js": "4.11.6", 1444 | "eth-lib": "0.1.27", 1445 | "ethjs-unit": "0.1.6", 1446 | "number-to-bn": "1.7.0", 1447 | "randomhex": "0.1.5", 1448 | "underscore": "1.8.3", 1449 | "utf8": "2.1.1" 1450 | }, 1451 | "dependencies": { 1452 | "bn.js": { 1453 | "version": "4.11.6", 1454 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", 1455 | "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=" 1456 | } 1457 | } 1458 | }, 1459 | "wrappy": { 1460 | "version": "1.0.2", 1461 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1462 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 1463 | }, 1464 | "ws": { 1465 | "version": "3.3.3", 1466 | "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", 1467 | "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", 1468 | "requires": { 1469 | "async-limiter": "~1.0.0", 1470 | "safe-buffer": "~5.1.0", 1471 | "ultron": "~1.1.0" 1472 | } 1473 | }, 1474 | "xhr": { 1475 | "version": "2.5.0", 1476 | "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz", 1477 | "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==", 1478 | "requires": { 1479 | "global": "~4.3.0", 1480 | "is-function": "^1.0.1", 1481 | "parse-headers": "^2.0.0", 1482 | "xtend": "^4.0.0" 1483 | } 1484 | }, 1485 | "xhr-request": { 1486 | "version": "1.1.0", 1487 | "resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz", 1488 | "integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==", 1489 | "requires": { 1490 | "buffer-to-arraybuffer": "^0.0.5", 1491 | "object-assign": "^4.1.1", 1492 | "query-string": "^5.0.1", 1493 | "simple-get": "^2.7.0", 1494 | "timed-out": "^4.0.1", 1495 | "url-set-query": "^1.0.0", 1496 | "xhr": "^2.0.4" 1497 | } 1498 | }, 1499 | "xhr-request-promise": { 1500 | "version": "0.1.2", 1501 | "resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz", 1502 | "integrity": "sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0=", 1503 | "requires": { 1504 | "xhr-request": "^1.0.1" 1505 | } 1506 | }, 1507 | "xtend": { 1508 | "version": "4.0.1", 1509 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 1510 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" 1511 | } 1512 | } 1513 | } 1514 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "merkletreejs-solidity", 3 | "version": "1.0.0", 4 | "description": "> Construct merkle trees with [MerkleTree.js](https://github.com/miguelmota/merkletreejs) and verify merkle proofs in [Solidity](https://github.com/ethereum/solidity).", 5 | "main": "index.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "dependencies": { 10 | "bn.js": "^4.11.8", 11 | "crypto": "^1.0.1", 12 | "ethereumjs-util": "^6.0.0", 13 | "keccak256": "^1.0.0", 14 | "merkletreejs": "^0.1.6", 15 | "moment": "^2.22.2", 16 | "web3-utils": "^1.0.0-beta.36" 17 | }, 18 | "devDependencies": { 19 | "truffle": "^5.0.44" 20 | }, 21 | "scripts": { 22 | "test": "truffle test" 23 | }, 24 | "repository": { 25 | "type": "git", 26 | "url": "git+https://github.com/miguelmota/merkletreejs-solidity.git" 27 | }, 28 | "author": "", 29 | "license": "MIT", 30 | "bugs": { 31 | "url": "https://github.com/miguelmota/merkletreejs-solidity/issues" 32 | }, 33 | "homepage": "https://github.com/miguelmota/merkletreejs-solidity#readme" 34 | } 35 | -------------------------------------------------------------------------------- /test/merkleproof.js: -------------------------------------------------------------------------------- 1 | const MerkleProof = artifacts.require('MerkleProof') 2 | const { MerkleTree } = require('merkletreejs') 3 | const keccak256 = require('keccak256') 4 | 5 | const buf2hex = x => '0x'+x.toString('hex') 6 | 7 | contract('Contracts', (accounts) => { 8 | let contract 9 | 10 | before('setup', async () => { 11 | contract = await MerkleProof.new() 12 | }) 13 | 14 | context('MerkleProof', () => { 15 | describe('merkle proofs', () => { 16 | it('should return true for valid merkle proof (example)', async () => { 17 | const leaves = ['a', 'b', 'c', 'd'].map(v => keccak256(v)) 18 | const tree = new MerkleTree(leaves, keccak256, { sort: true }) 19 | const root = tree.getHexRoot() 20 | const leaf = keccak256('a') 21 | const proof = tree.getHexProof(leaf) 22 | 23 | const verified = await contract.verify.call(root, leaf, proof) 24 | assert.equal(verified, true) 25 | 26 | const badLeaves = ['a', 'b', 'x', 'd'].map(v => keccak256(v)) 27 | const badTree = new MerkleTree(badLeaves, keccak256, { sort: true }) 28 | const badProof = badTree.getHexProof(leaf) 29 | 30 | const badVerified = await contract.verify.call(root, leaf, badProof) 31 | assert.equal(badVerified, false) 32 | }) 33 | 34 | it('should return true for valid merkle proof', async () => { 35 | const leaves = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'].map(v => keccak256(v)) 36 | const tree = new MerkleTree(leaves, keccak256, { sort: true }) 37 | const root = tree.getRoot() 38 | const hexroot = buf2hex(root) 39 | const leaf = keccak256('d') 40 | const hexleaf = buf2hex(keccak256('d')) 41 | const proof = tree.getProof(keccak256('d')) 42 | const hexproof = tree.getProof(keccak256('d')).map(x => buf2hex(x.data)) 43 | 44 | const verified = await contract.verify.call(hexroot, hexleaf, hexproof) 45 | assert.equal(verified, true) 46 | 47 | assert.equal(tree.verify(proof, leaf, root), true) 48 | }) 49 | 50 | it('should return false for invalid merkle proof', async () => { 51 | const leaves = ['a', 'b', 'c', 'd'].map(v => keccak256(v)) 52 | const tree = new MerkleTree(leaves, keccak256, { sort: true }) 53 | const root = buf2hex(tree.getRoot()) 54 | const leaf = buf2hex(keccak256('b')) 55 | 56 | const badLeaves = ['a', 'b', 'c', 'x'].map(v => keccak256(v)) 57 | const badTree = new MerkleTree(badLeaves, keccak256) 58 | const badProof = badTree.getProof(keccak256('b')).map(x => buf2hex(x.data)) 59 | 60 | const verified = await contract.verify.call(root, leaf, badProof) 61 | assert.equal(verified, false) 62 | }) 63 | 64 | it('should return false for a merkle proof of invalid length', async () => { 65 | const leaves = ['a', 'b', 'c'].map(v => keccak256(v)) 66 | const tree = new MerkleTree(leaves, keccak256, { sort: true }) 67 | const root = buf2hex(tree.getRoot()) 68 | const leaf = buf2hex(keccak256('c')) 69 | const proof = tree.getProof(keccak256('c')) 70 | const badProof = proof.slice(0, proof.length-2).map(x => buf2hex(x.data)) 71 | 72 | const verified = await contract.verify.call(root, leaf, badProof) 73 | assert.equal(verified, false) 74 | }) 75 | 76 | it('should return true for valid merkle proof (SO#63509)', async () => { 77 | const leaves = ['0x00000a86986e8ba3557992df02883e4a646e8f25 50000000000000000000', '0x00009c99bffc538de01866f74cfec4819dc467f3 75000000000000000000', '0x00035a5f2c595c3bb53aae4528038dd7a85641c3 50000000000000000000', '0x1e27c325ba246f581a6dcaa912a8e80163454c75 10000000000000000000'].map(v => keccak256(v)) 78 | const tree = new MerkleTree(leaves, keccak256, { sort: true }) 79 | const root = tree.getRoot() 80 | const hexroot = buf2hex(root) 81 | const leaf = keccak256('0x1e27c325ba246f581a6dcaa912a8e80163454c75 10000000000000000000') 82 | const hexleaf = buf2hex(leaf) 83 | const proof = tree.getProof(leaf) 84 | const hexproof = tree.getProof(leaf).map(x => buf2hex(x.data)) 85 | 86 | const verified = await contract.verify.call(hexroot, hexleaf, hexproof) 87 | assert.equal(verified, true) 88 | 89 | assert.equal(tree.verify(proof, leaf, root), true) 90 | }) 91 | }) 92 | }) 93 | }) 94 | -------------------------------------------------------------------------------- /truffle-config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * NB: since truffle-hdwallet-provider 0.0.5 you must wrap HDWallet providers in a 3 | * function when declaring them. Failure to do so will cause commands to hang. ex: 4 | * ``` 5 | * mainnet: { 6 | * provider: function() { 7 | * return new HDWalletProvider(mnemonic, 'https://mainnet.infura.io/') 8 | * }, 9 | * network_id: '1', 10 | * gas: 4500000, 11 | * gasPrice: 10000000000, 12 | * }, 13 | */ 14 | 15 | module.exports = { 16 | // See 17 | // to customize your Truffle configuration! 18 | }; 19 | -------------------------------------------------------------------------------- /truffle.js: -------------------------------------------------------------------------------- 1 | /* 2 | * NB: since truffle-hdwallet-provider 0.0.5 you must wrap HDWallet providers in a 3 | * function when declaring them. Failure to do so will cause commands to hang. ex: 4 | * ``` 5 | * mainnet: { 6 | * provider: function() { 7 | * return new HDWalletProvider(mnemonic, 'https://mainnet.infura.io/') 8 | * }, 9 | * network_id: '1', 10 | * gas: 4500000, 11 | * gasPrice: 10000000000, 12 | * }, 13 | */ 14 | 15 | module.exports = { 16 | // See 17 | // to customize your Truffle configuration! 18 | networks: { 19 | development: { 20 | host: 'localhost', 21 | port: 8545, 22 | network_id: '*', // Match any network id 23 | }, 24 | }, 25 | compilers: { 26 | solc: { 27 | version: '0.4.23', 28 | settings: { 29 | optimizer: { 30 | enabled: true, 31 | runs: 200 32 | }, 33 | }, 34 | }, 35 | }, 36 | }; 37 | --------------------------------------------------------------------------------