├── .gitignore ├── LICENSE.md ├── README.md ├── getAndVerify.js ├── getProof.js ├── img └── architecture-diagram.JPG ├── index.js ├── package-lock.json ├── package.json ├── test ├── account.js ├── log.js ├── receipt.js ├── storage.js ├── transaction.js ├── tree.js └── verify.js └── verifyProof.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | personal 3 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) [2019] [Zachary Mitton] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # deprecated 2 | I have not maintained this past the London hard fork. It stopped working for many features due to the introduction of account versioning (which broke RLP). please post an issue if you have a working fork to recomend 3 | 4 | # Eth Proof `2.0.0` 5 | 6 | This is a generalized merkle-patricia-proof module that now supports ethereum state proofs. That means you can prove _all_ Ethereum data (including that a path is `null`). If you have a single hash that you trust (i.e. blockHash), you can use this module to succinctly prove exactly what data was or was not contained in the Ethereum blockchain at that snapshot in history. 7 | 8 | ## Use 9 | 10 | #### Installation 11 | 12 | ``` 13 | npm install eth-proof 14 | ``` 15 | 16 | Allows you to make proofs in a few different ways: 17 | 18 | 1. The `Getandverify` class requests and then verifies the response data against a blockHash you trust before returning the vetted data to you. This is the main use-case for development of more trustworthy applications that need to request data from a remote node. These functions work by chaining together granular verification functions of all the connected pieces. 19 | 2. For more customized usage you can directly request the proof (`GetProof`) and then 20 | 3. Use the `Verify` class to verify individual connected pieces within it. i.e. That the a `header` contains a specific `stateRoot`, or the `accountProof` contains a specific `account` at a specific `address`. This class has all the individual methods that `GetAndVerify` is using under the hood. 21 | 22 | While the `GetAndVerify` functions are useful for _dapps / wallets / block explorers_ to validate data before showing it to users, the `Verify` functions may be needed for more complex applications like _side-chains / state-channels / plasma_. 23 | 24 | 25 | #### Instantiation 26 | 27 | The getter classes (`GetProof` and `GetAndVerify`) request data from an RPC provider. So you'll have to instantiate an instance object with the RPC endpoint. 28 | 29 | ```javascript 30 | const { GetAndVerify, GetProof, VerifyProof } = require('eth-proof') 31 | let getAndVerify = new GetAndVerify("https://mainnet.infura.io") 32 | ``` 33 | 34 | 35 | #### Gotchas 36 | 37 | For `Transaction`, `Receipt`, and `Log` proofs: Must hit an Ethereum node that is running `--syncmode full`. 38 | 39 | For `Account` and `Storage` proofs: Must hit a node that supports `eth_getProof`. This is any geth or parity node upgraded after ~ January 2019. Unfotunately, at time of this writing, neither Infura, nor any known centralized services support `eth_getProof` (Infura plans to in the near future). [updates on this](https://github.com/zmitton/eth-proof/issues/9). So run your own node. 40 | 41 | For _historic_ `Account` and `Storage` proofs (ones who's blockhash is older than "latest"), you'll have to run your node with `--gcmode archive`, otherwise the state tree throws away old data and you will get "missing node" errors. 42 | 43 | ``` 44 | geth --syncmode full --gcmode archive 45 | ``` 46 | 47 | Specifically: A node without the `full` flag will be missing historic `transactions` and `receipts`. It will return a missing transaction error if you ask for them. A node without the `archive` flag, will still be able to prove _current_ account and storage values, but it will be missing the nodes needed to prove the account and storage values at historical points in time (at particular blocks). 48 | 49 | The instance-functions make asynchronous requests using promises. 50 | 51 | ```javascript 52 | let blockHashThatITrust = '0xc32470c2459fd607246412e23b4b4d19781c1fa24a603d47a5bc066be3b5c0af' 53 | let untrustedTxHash = '0xacb81623523bbabccb1638a907686bc2f3229c70e3ab51777bef0a635f3ac03f' 54 | 55 | getAndVerify.txAgainstBlockHash(untrustedTxHash, blockHashThatITrust).then((tx)=>{ 56 | console.log(tx) 57 | }) 58 | ``` 59 | 60 | ## API 61 | 62 | #### GetAndVerify 63 | 64 | The `GetAndVerify` instance-functions take hex`string`s and return array-like `object`s of `buffer`s or, in the case of storage, simple `buffer`s 65 | 66 | ----- 67 | - `async txAgainstBlockHash(txHash, blockHash){}` 68 | - `async receiptAgainstBlockHash(txHash, blockHash){}` 69 | - `async accountAgainstBlockHash(accountAddress, blockHash){}` 70 | - `async storageAgainstBlockHash(accountAddress, position, blockHash){}` 71 | ----- 72 | 73 | They return the bare-bones objects indicated, after verifying everything about it (against a _blockHash you already trust_). The above is likely all you need for most applications. Please see the tests for sample uses. Please run only the file you are testing with `npm run test test/account.js` for example. The tests hit Infura extremely hard. Just one receipt proof for instance makes a separate request for every single receipt in the block from which the receipt resides. 74 | 75 | #### GetProof 76 | 77 | The `GetProof` instance-functions take hex`string`s and return generic `object`s with the proof information (Note: The different return `object`s have different `attributes`). 78 | 79 | ----- 80 | - `async transactionProof(txHash){}` 81 | - `async receiptProof(txHash){}` 82 | - `async accountProof(address, blockHash = null){}` 83 | - `async storageProof(address, storageAddress, blockHash = null){}` 84 | ----- 85 | 86 | Lastly just a helper for the direct RPC call as described [here](https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_getproof). Note that this `proof` is returned in a different format (which I find less directly useful). 87 | 88 | - `async eth_getProof(address, storageAddresses, blockNumber){}` 89 | 90 | #### Verify 91 | 92 | The Verifier class (`Verify`) should always be run locally/client-side so it doesn't require an RPC connection. To impliment more _advanced_ uses of the module use these class-level (static) functions. Some are _synchronous_ while others are _async_ (only because they use the async tree API under the hood. They do not make any remote calls). 93 | 94 | ## Details 95 | 96 | You can granularly *verify* the relationship between any 2 pieces of data that are connected in the architecture diagram below. However, all merkle proofs should inevitably be proven *against a blockhash* to prove there was a cost of counterfeiting it. A centralized service can easily create a fake "proof" that will fool you, if you don't have an anchor (something you already trust) to compare it against. 97 | 98 | 99 | 100 | Establishing trust of a blockHash is a whole other issue. It relies on trust of a chain, which should ultimately rely on a set of heuristics involving expected total work at the current moment in time. This tool doesn't deal with that. It will however enable you to prove data against a `workChain` in later version. 101 | 102 | The functions will look something like: `getAndVerify.txAgainstWorkChain(txHash, workChain){}`. 103 | 104 | So Proving work on the _"workChain"_ has very different properties and will be a separate project of its own. But _this_ module we be able verify _against_ the workChain (who's trust was establised elsewhere) 105 | 106 | This module does not include an on-chain verification of the Merkle Patricia Tree. 107 | However those have been made and can be found [here](https://github.com/ConsenSys/rb-relay/blob/master/contracts/MerklePatriciaProof.sol) and [here](https://github.com/lorenzb/proveth/blob/master/onchain/ProvethVerifier.sol). I can not the current state or security of these other tools. 108 | 109 | ## Formating 110 | 111 | The data formats used/returned are *eth-object*s [documented here](https://github.com/zmitton/eth-object). 112 | 113 | They are `account`, `header`, `log`, `proof`, `receipt`, and `transaction`. Eth-objects mimic the native Ethereum format used in RLP. They are _arrays of byteArrays and nested arrays (of the same)_. An account will look something like this: 114 | 115 | ``` 116 | [ 117 | , 118 | , 119 | , 120 | , 121 | ] 122 | ``` 123 | 124 | But they can be dug into as arrays _or_ using named helper methods for each expected property: 125 | 126 | ```javascript 127 | console.log(account[0]) // => 128 | console.log(account.nonce) // => 129 | ``` 130 | 131 | They also have helpers to build/convert/view them in many other useful formats: 132 | 133 | ``` 134 | console.log(account.toJson()) 135 | // { 136 | // "nonce":"0x01", 137 | // "balance":"0x", 138 | // "storageRoot":"0xc14953a64f69632619636fbdf327e883436b9fd1b1025220e50fb70ab7d2e2a8", 139 | // "codeHash":"0xf7cf6232b8d655b92268b3565325e8897f2f82d65a4eaaf4e78fcef04e8fee6a" 140 | // } 141 | console.log(account.serialize()) // will give you the rlp encoding 142 | // 143 | console.log(account.toHex()) // rlp encoding as a hex string 144 | // "0xf8440180a0c14953a64f69632619636fbdf327e883436b9fd1b1025220e50fb70ab7d2e2a8a0f7cf6232b8d655b92268b3565325e8897f2f82d65a4eaaf4e78fcef04e8fee6a" 145 | ``` 146 | 147 | Can be created from a direct RPC result or any of the above: 148 | 149 | ``` 150 | Account.fromRpc(rpcResponseString) 151 | Account.fromHex(rlpString) 152 | Account.fromBuffer(rlpBuffer) 153 | Account.fromRaw(arrayOfBuffers) 154 | ``` 155 | 156 | ## Testing 157 | 158 | The tx and receipt tests use infura right now (because I dont have a completely full node). 159 | 160 | Its all data currently on Ethereum Mainnet. 161 | 162 | These tests hit Infura really hard because every tx or receipt proof requires multiple RPC calls (1 for each tx in the particular block). please be considerate. If you have a full archive node, re-point the rpc calls locally or use `it.only` to perform only one tests at a time. 163 | 164 | Thanks to @simon-jentzsch, for EIP-1186 to make this data available from Geth and Parity clients. 165 | 166 | ## How it Works 167 | 168 | Binary merkle proofs are explained pretty well in [this video](https://www.youtube.com/watch?v=5WGgoVmfIik&t=283) by Joseph chow. [Ethereum's Merkle Patricia Tree](https://github.com/ethereum/wiki/wiki/Patricia-Tree) is different, but the concept is the same. 169 | 170 | Proving absence: This is a really cool feature of Merkle Patricia Trees. You can prove a key is undefined (whether it is non-existent in the tree or is explicitly set to `null`). Null-proofs are currently working in version 2! I don't know of any tools besides this one that support them. 171 | 172 | An important design decision I made (and implemented in the [merkle-patricia-tree](https://github.com/ethereumjs/merkle-patricia-tree/pull/82/files#diff-f2fabd87f37321748a5499f0df52f235R52) module underlaying this one), was to represent the proof as _itself_ a Patricia Tree (a _sparse_ one), in order to verify it. 173 | 174 | The steps: 175 | 176 | - 1 create a new tree from scratch 177 | - 2 `put`the nodes from proof into the flat key value DB (at `keccak(value)` -> `value`) 178 | - 3 Set the tree root to the known value 179 | - 4 perform a standard `get` on this tree 180 | 181 | This affords a few interesting optimizations: First, it enabled me to recycle the tree-traversal code already being used, eliminating the hardest part, and avoiding have 2 versions of the same logic. Second it enabled null-proofs to be done with a simple amendment to the tree instead of inventing logic that I don't believe had been authored anywhere yet. Third, it allowed proofs to be combined and therefore compressed/optimized. The nodes could now be communicated in an order, eliminating the need to communicate the same nodes twice between different proofs. 182 | 183 | Lastly, This approach seems to extend much farther than I had originally thought: This sparse tree will actually support `put`, which means that it can be used as a drop-in replacement database for the EVM. An O(log(n)) replacement for the entire state database that is 184 | 185 | ## End Game 186 | 187 | To complete the functionality attempted by this tool, a "light-client" tool (that downloads all the hashes and validates the work between them) will have to be built. The output of which might be a "workChain" which can interface with eth-proof to finally begin to leverage some of the really useful security properties of PoW blockchains. 188 | 189 | We would like to find the right context to run an EVM implementation directly on a proof tree. 190 | 191 | long term goal is are light clients that can validate an entire state transition. It would just need a proof containing all data touched during the state transition (tx). Unfortunately Ethereum removed the `receipt.postTransactioState` root which could have been useful for this :( 192 | 193 | We also would like for wallets that only display data that has been verified. 194 | 195 | We are finding it useful to relay ethereum to itself. You can make proofs about any historical information and information not usually available to the EVM can be made available. Layer 2 solutions like Truebit and Plasma could greatly benefit from this functionality. 196 | -------------------------------------------------------------------------------- /getAndVerify.js: -------------------------------------------------------------------------------- 1 | const GetProof = require('./getProof') 2 | const VerifyProof = require('./verifyProof') 3 | const { toBuffer } = require('eth-util-lite') 4 | 5 | class GetAndVerify{ 6 | constructor(rpcProvider = "https://mainnet.infura.io"){ 7 | this.get = new GetProof(rpcProvider) 8 | } 9 | 10 | async txAgainstBlockHash(txHash, trustedBlockHash){ 11 | let resp = await this.get.transactionProof(txHash) 12 | let blockHashFromHeader = VerifyProof.getBlockHashFromHeader(resp.header) 13 | if(!toBuffer(trustedBlockHash).equals(blockHashFromHeader)) throw new Error('BlockHash mismatch') 14 | let txRootFromHeader = VerifyProof.getTxsRootFromHeader(resp.header) 15 | let txRootFromProof = VerifyProof.getRootFromProof(resp.txProof) 16 | if(!txRootFromHeader.equals(txRootFromProof)) throw new Error('TxRoot mismatch') 17 | return VerifyProof.getTxFromTxProofAt(resp.txProof, resp.txIndex) 18 | } 19 | async receiptAgainstBlockHash(txHash, trustedBlockHash){ 20 | let resp = await this.get.receiptProof(txHash) 21 | let blockHashFromHeader = VerifyProof.getBlockHashFromHeader(resp.header) 22 | if(!toBuffer(trustedBlockHash).equals(blockHashFromHeader)) throw new Error('BlockHash mismatch') 23 | let receiptsRoot = VerifyProof.getReceiptsRootFromHeader(resp.header) 24 | let receiptsRootFromProof = VerifyProof.getRootFromProof(resp.receiptProof) 25 | if(!receiptsRoot.equals(receiptsRootFromProof)) throw new Error('ReceiptsRoot mismatch') 26 | return VerifyProof.getReceiptFromReceiptProofAt(resp.receiptProof, resp.txIndex) 27 | } 28 | async accountAgainstBlockHash(accountAddress, trustedBlockHash){ 29 | let resp = await this.get.accountProof(accountAddress, trustedBlockHash) 30 | let blockHashFromHeader = VerifyProof.getBlockHashFromHeader(resp.header) 31 | if(!toBuffer(trustedBlockHash).equals(blockHashFromHeader)) throw new Error('BlockHash mismatch') 32 | let stateRoot = VerifyProof.getStateRootFromHeader(resp.header) 33 | let stateRootFromProof = VerifyProof.getRootFromProof(resp.accountProof) 34 | if(!stateRoot.equals(stateRootFromProof)) throw new Error('StateRoot mismatch') 35 | return VerifyProof.getAccountFromProofAt(resp.accountProof, accountAddress) 36 | } 37 | async storageAgainstBlockHash(accountAddress, position, trustedBlockHash){ 38 | let resp = await this.get.storageProof(accountAddress, position, trustedBlockHash) 39 | let blockHashFromHeader = VerifyProof.getBlockHashFromHeader(resp.header) 40 | if(!toBuffer(trustedBlockHash).equals(blockHashFromHeader)) throw new Error('BlockHash mismatch') 41 | let stateRoot = VerifyProof.getStateRootFromHeader(resp.header) 42 | let stateRootFromProof = VerifyProof.getRootFromProof(resp.accountProof) 43 | if(!stateRoot.equals(stateRootFromProof)) throw new Error('StateRoot mismatch') 44 | let account = await VerifyProof.getAccountFromProofAt(resp.accountProof, accountAddress) 45 | let storageRoot = VerifyProof.accountContainsStorageRoot(account) 46 | let storageRootFromProof = VerifyProof.getRootFromProof(resp.storageProof) 47 | if(!storageRoot.equals(storageRootFromProof)) throw new Error('StorageRoot mismatch') 48 | return VerifyProof.getStorageFromStorageProofAt(resp.storageProof, position) 49 | } 50 | 51 | async _logAgainstBlockHash(txHash, indexOfLog, trustedBlockHash){ 52 | // untested as of yet 53 | let resp = await this.get.receiptProof(txHash) 54 | let blockHashFromHeader = VerifyProof.getBlockHashFromHeader(resp.header) 55 | if(!toBuffer(trustedBlockHash).equals(blockHashFromHeader)) throw new Error('BlockHash mismatch') 56 | let receiptsRoot = VerifyProof.getReceiptsRootFromHeader(resp.header) 57 | let receiptsRootFromProof = VerifyProof.getRootFromProof(resp.receiptProof) 58 | if(!receiptsRoot.equals(receiptsRootFromProof)) throw new Error('ReceiptsRoot mismatch') 59 | let receipt = await VerifyProof.getReceiptFromReceiptProofAt(resp.receiptProof, resp.txIndex) 60 | return VerifyProof.receiptContainsLogAt(receipt, indexOfLog) 61 | } 62 | } 63 | 64 | module.exports = GetAndVerify 65 | -------------------------------------------------------------------------------- /getProof.js: -------------------------------------------------------------------------------- 1 | const { encode } = require('eth-util-lite') 2 | const { promisfy } = require('promisfy') 3 | 4 | const Tree = require('merkle-patricia-tree') 5 | 6 | const Rpc = require('isomorphic-rpc') 7 | 8 | const { Header, Proof, Receipt, Transaction } = require('eth-object') 9 | 10 | 11 | module.exports = class GetProof{ 12 | constructor(rpcProvider = "https://mainnet.infura.io"){ 13 | this.rpc = new Rpc(rpcProvider) 14 | this.eth_getProof = this.rpc.eth_getProof 15 | } 16 | 17 | async transactionProof(txHash){ 18 | let targetTx = await this.rpc.eth_getTransactionByHash(txHash) 19 | if(!targetTx){ throw new Error("Tx not found. Use archive node")} 20 | 21 | let rpcBlock = await this.rpc.eth_getBlockByHash(targetTx.blockHash, true) 22 | 23 | let tree = new Tree(); 24 | 25 | await Promise.all(rpcBlock.transactions.map((siblingTx, index) => { 26 | let siblingPath = encode(index) 27 | let serializedSiblingTx = Transaction.fromRpc(siblingTx).serialize() 28 | return promisfy(tree.put, tree)(siblingPath, serializedSiblingTx) 29 | })) 30 | 31 | let [_,__,stack] = await promisfy(tree.findPath, tree)(encode(targetTx.transactionIndex)) 32 | 33 | return { 34 | header: Header.fromRpc(rpcBlock), 35 | txProof: Proof.fromStack(stack), 36 | txIndex: targetTx.transactionIndex, 37 | } 38 | } 39 | async receiptProof(txHash){ 40 | let targetReceipt = await this.rpc.eth_getTransactionReceipt(txHash) 41 | if(!targetReceipt){ throw new Error("txhash/targetReceipt not found. (use Archive node)")} 42 | 43 | let rpcBlock = await this.rpc.eth_getBlockByHash(targetReceipt.blockHash, false) 44 | 45 | let receipts = await Promise.all(rpcBlock.transactions.map((siblingTxHash) => { 46 | return this.rpc.eth_getTransactionReceipt(siblingTxHash) 47 | })) 48 | 49 | let tree = new Tree(); 50 | 51 | await Promise.all(receipts.map((siblingReceipt, index) => { 52 | let siblingPath = encode(index) 53 | let serializedReceipt = Receipt.fromRpc(siblingReceipt).serialize() 54 | return promisfy(tree.put, tree)(siblingPath, serializedReceipt) 55 | })) 56 | 57 | let [_,__,stack] = await promisfy(tree.findPath, tree)(encode(targetReceipt.transactionIndex)) 58 | 59 | return { 60 | header: Header.fromRpc(rpcBlock), 61 | receiptProof: Proof.fromStack(stack), 62 | txIndex: targetReceipt.transactionIndex, 63 | } 64 | } 65 | async accountProof(address, blockHash = null){ 66 | let rpcBlock, rpcProof 67 | if(blockHash){ 68 | rpcBlock = await this.rpc.eth_getBlockByHash(blockHash, false) 69 | }else{ 70 | rpcBlock = await this.rpc.eth_getBlockByNumber('latest', false) 71 | } 72 | rpcProof = await this.eth_getProof(address, [], rpcBlock.number) 73 | 74 | return { 75 | header: Header.fromRpc(rpcBlock), 76 | accountProof: Proof.fromRpc(rpcProof.accountProof), 77 | } 78 | } 79 | async storageProof(address, storageAddress, blockHash = null){ 80 | let rpcBlock, rpcProof 81 | if(blockHash){ 82 | rpcBlock = await this.rpc.eth_getBlockByHash(blockHash, false) 83 | }else{ 84 | rpcBlock = await this.rpc.eth_getBlockByNumber('latest', false) 85 | } 86 | rpcProof = await this.eth_getProof(address, [storageAddress], rpcBlock.number) 87 | 88 | return { 89 | header: Header.fromRpc(rpcBlock), 90 | accountProof: Proof.fromRpc(rpcProof.accountProof), 91 | storageProof: Proof.fromRpc(rpcProof.storageProof[0].proof), 92 | } 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /img/architecture-diagram.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zmitton/eth-proof/e5bf698692d573bb63c478d011e59e72ff35f3f0/img/architecture-diagram.JPG -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const GetAndVerify = require('./getAndVerify.js') 2 | const GetProof = require('./getProof.js') 3 | const VerifyProof = require('./verifyProof.js') 4 | const ProofUtil = require('eth-util-lite') // maybe remove this in future version 5 | 6 | module.exports = { GetAndVerify, GetProof, VerifyProof, ProofUtil} 7 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eth-proof", 3 | "version": "2.1.5", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@types/node": { 8 | "version": "14.14.14", 9 | "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.14.tgz", 10 | "integrity": "sha512-UHnOPWVWV1z+VV8k6L1HhG7UbGBgIdghqF3l9Ny9ApPghbjICXkUJSd/b9gOgQfjM1r+37cipdw/HJ3F6ICEnQ==" 11 | }, 12 | "@types/pbkdf2": { 13 | "version": "3.1.0", 14 | "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", 15 | "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", 16 | "requires": { 17 | "@types/node": "*" 18 | } 19 | }, 20 | "@types/secp256k1": { 21 | "version": "4.0.1", 22 | "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.1.tgz", 23 | "integrity": "sha512-+ZjSA8ELlOp8SlKi0YLB2tz9d5iPNEmOBd+8Rz21wTMdaXQIa9b6TEnD6l5qKOCypE7FSyPyck12qZJxSDNoog==", 24 | "requires": { 25 | "@types/node": "*" 26 | } 27 | }, 28 | "abstract-leveldown": { 29 | "version": "5.0.0", 30 | "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", 31 | "integrity": "sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==", 32 | "requires": { 33 | "xtend": "~4.0.0" 34 | } 35 | }, 36 | "ansi-colors": { 37 | "version": "3.2.3", 38 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", 39 | "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", 40 | "dev": true 41 | }, 42 | "ansi-regex": { 43 | "version": "3.0.0", 44 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 45 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 46 | "dev": true 47 | }, 48 | "ansi-styles": { 49 | "version": "3.2.1", 50 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 51 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 52 | "dev": true, 53 | "requires": { 54 | "color-convert": "^1.9.0" 55 | } 56 | }, 57 | "argparse": { 58 | "version": "1.0.10", 59 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 60 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 61 | "dev": true, 62 | "requires": { 63 | "sprintf-js": "~1.0.2" 64 | } 65 | }, 66 | "assertion-error": { 67 | "version": "1.1.0", 68 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", 69 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", 70 | "dev": true 71 | }, 72 | "async": { 73 | "version": "2.6.3", 74 | "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", 75 | "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", 76 | "requires": { 77 | "lodash": "^4.17.14" 78 | } 79 | }, 80 | "balanced-match": { 81 | "version": "1.0.0", 82 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 83 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 84 | "dev": true 85 | }, 86 | "base-x": { 87 | "version": "3.0.8", 88 | "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", 89 | "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", 90 | "requires": { 91 | "safe-buffer": "^5.0.1" 92 | } 93 | }, 94 | "base64-js": { 95 | "version": "1.5.1", 96 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", 97 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" 98 | }, 99 | "blakejs": { 100 | "version": "1.1.0", 101 | "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", 102 | "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" 103 | }, 104 | "bn.js": { 105 | "version": "4.11.8", 106 | "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", 107 | "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" 108 | }, 109 | "brace-expansion": { 110 | "version": "1.1.11", 111 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 112 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 113 | "dev": true, 114 | "requires": { 115 | "balanced-match": "^1.0.0", 116 | "concat-map": "0.0.1" 117 | } 118 | }, 119 | "brorand": { 120 | "version": "1.1.0", 121 | "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", 122 | "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" 123 | }, 124 | "browser-stdout": { 125 | "version": "1.3.1", 126 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 127 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 128 | "dev": true 129 | }, 130 | "browserify-aes": { 131 | "version": "1.2.0", 132 | "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", 133 | "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", 134 | "requires": { 135 | "buffer-xor": "^1.0.3", 136 | "cipher-base": "^1.0.0", 137 | "create-hash": "^1.1.0", 138 | "evp_bytestokey": "^1.0.3", 139 | "inherits": "^2.0.1", 140 | "safe-buffer": "^5.0.1" 141 | } 142 | }, 143 | "bs58": { 144 | "version": "4.0.1", 145 | "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", 146 | "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", 147 | "requires": { 148 | "base-x": "^3.0.2" 149 | } 150 | }, 151 | "bs58check": { 152 | "version": "2.1.2", 153 | "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", 154 | "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", 155 | "requires": { 156 | "bs58": "^4.0.0", 157 | "create-hash": "^1.1.0", 158 | "safe-buffer": "^5.1.2" 159 | } 160 | }, 161 | "buffer": { 162 | "version": "6.0.3", 163 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", 164 | "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", 165 | "requires": { 166 | "base64-js": "^1.3.1", 167 | "ieee754": "^1.2.1" 168 | } 169 | }, 170 | "buffer-xor": { 171 | "version": "1.0.3", 172 | "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", 173 | "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" 174 | }, 175 | "call-bind": { 176 | "version": "1.0.0", 177 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", 178 | "integrity": "sha512-AEXsYIyyDY3MCzbwdhzG3Jx1R0J2wetQyUynn6dYHAO+bg8l1k7jwZtRv4ryryFs7EP+NDlikJlVe59jr0cM2w==", 179 | "dev": true, 180 | "requires": { 181 | "function-bind": "^1.1.1", 182 | "get-intrinsic": "^1.0.0" 183 | } 184 | }, 185 | "camelcase": { 186 | "version": "5.3.1", 187 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", 188 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", 189 | "dev": true 190 | }, 191 | "chai": { 192 | "version": "4.2.0", 193 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", 194 | "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", 195 | "dev": true, 196 | "requires": { 197 | "assertion-error": "^1.1.0", 198 | "check-error": "^1.0.2", 199 | "deep-eql": "^3.0.1", 200 | "get-func-name": "^2.0.0", 201 | "pathval": "^1.1.0", 202 | "type-detect": "^4.0.5" 203 | } 204 | }, 205 | "chalk": { 206 | "version": "2.4.2", 207 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 208 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 209 | "dev": true, 210 | "requires": { 211 | "ansi-styles": "^3.2.1", 212 | "escape-string-regexp": "^1.0.5", 213 | "supports-color": "^5.3.0" 214 | }, 215 | "dependencies": { 216 | "supports-color": { 217 | "version": "5.5.0", 218 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 219 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 220 | "dev": true, 221 | "requires": { 222 | "has-flag": "^3.0.0" 223 | } 224 | } 225 | } 226 | }, 227 | "check-error": { 228 | "version": "1.0.2", 229 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", 230 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", 231 | "dev": true 232 | }, 233 | "cipher-base": { 234 | "version": "1.0.4", 235 | "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", 236 | "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", 237 | "requires": { 238 | "inherits": "^2.0.1", 239 | "safe-buffer": "^5.0.1" 240 | } 241 | }, 242 | "cliui": { 243 | "version": "5.0.0", 244 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", 245 | "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", 246 | "dev": true, 247 | "requires": { 248 | "string-width": "^3.1.0", 249 | "strip-ansi": "^5.2.0", 250 | "wrap-ansi": "^5.1.0" 251 | }, 252 | "dependencies": { 253 | "ansi-regex": { 254 | "version": "4.1.0", 255 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 256 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 257 | "dev": true 258 | }, 259 | "string-width": { 260 | "version": "3.1.0", 261 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 262 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 263 | "dev": true, 264 | "requires": { 265 | "emoji-regex": "^7.0.1", 266 | "is-fullwidth-code-point": "^2.0.0", 267 | "strip-ansi": "^5.1.0" 268 | } 269 | }, 270 | "strip-ansi": { 271 | "version": "5.2.0", 272 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 273 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 274 | "dev": true, 275 | "requires": { 276 | "ansi-regex": "^4.1.0" 277 | } 278 | } 279 | } 280 | }, 281 | "color-convert": { 282 | "version": "1.9.3", 283 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 284 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 285 | "dev": true, 286 | "requires": { 287 | "color-name": "1.1.3" 288 | } 289 | }, 290 | "color-name": { 291 | "version": "1.1.3", 292 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 293 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 294 | "dev": true 295 | }, 296 | "concat-map": { 297 | "version": "0.0.1", 298 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 299 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 300 | "dev": true 301 | }, 302 | "core-util-is": { 303 | "version": "1.0.2", 304 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 305 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 306 | }, 307 | "create-hash": { 308 | "version": "1.2.0", 309 | "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", 310 | "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", 311 | "requires": { 312 | "cipher-base": "^1.0.1", 313 | "inherits": "^2.0.1", 314 | "md5.js": "^1.3.4", 315 | "ripemd160": "^2.0.1", 316 | "sha.js": "^2.4.0" 317 | } 318 | }, 319 | "create-hmac": { 320 | "version": "1.1.7", 321 | "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", 322 | "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", 323 | "requires": { 324 | "cipher-base": "^1.0.3", 325 | "create-hash": "^1.1.0", 326 | "inherits": "^2.0.1", 327 | "ripemd160": "^2.0.0", 328 | "safe-buffer": "^5.0.1", 329 | "sha.js": "^2.4.8" 330 | } 331 | }, 332 | "debug": { 333 | "version": "3.2.6", 334 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 335 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 336 | "dev": true, 337 | "requires": { 338 | "ms": "^2.1.1" 339 | } 340 | }, 341 | "decamelize": { 342 | "version": "1.2.0", 343 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 344 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 345 | "dev": true 346 | }, 347 | "deep-eql": { 348 | "version": "3.0.1", 349 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", 350 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", 351 | "dev": true, 352 | "requires": { 353 | "type-detect": "^4.0.0" 354 | } 355 | }, 356 | "deferred-leveldown": { 357 | "version": "4.0.2", 358 | "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz", 359 | "integrity": "sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww==", 360 | "requires": { 361 | "abstract-leveldown": "~5.0.0", 362 | "inherits": "^2.0.3" 363 | } 364 | }, 365 | "define-properties": { 366 | "version": "1.1.3", 367 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", 368 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 369 | "dev": true, 370 | "requires": { 371 | "object-keys": "^1.0.12" 372 | } 373 | }, 374 | "diff": { 375 | "version": "3.5.0", 376 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", 377 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", 378 | "dev": true 379 | }, 380 | "elliptic": { 381 | "version": "6.5.3", 382 | "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", 383 | "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", 384 | "requires": { 385 | "bn.js": "^4.4.0", 386 | "brorand": "^1.0.1", 387 | "hash.js": "^1.0.0", 388 | "hmac-drbg": "^1.0.0", 389 | "inherits": "^2.0.1", 390 | "minimalistic-assert": "^1.0.0", 391 | "minimalistic-crypto-utils": "^1.0.0" 392 | } 393 | }, 394 | "emoji-regex": { 395 | "version": "7.0.3", 396 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 397 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 398 | "dev": true 399 | }, 400 | "encoding": { 401 | "version": "0.1.13", 402 | "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", 403 | "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", 404 | "requires": { 405 | "iconv-lite": "^0.6.2" 406 | } 407 | }, 408 | "encoding-down": { 409 | "version": "5.0.4", 410 | "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-5.0.4.tgz", 411 | "integrity": "sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw==", 412 | "requires": { 413 | "abstract-leveldown": "^5.0.0", 414 | "inherits": "^2.0.3", 415 | "level-codec": "^9.0.0", 416 | "level-errors": "^2.0.0", 417 | "xtend": "^4.0.1" 418 | } 419 | }, 420 | "errno": { 421 | "version": "0.1.8", 422 | "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", 423 | "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", 424 | "requires": { 425 | "prr": "~1.0.1" 426 | } 427 | }, 428 | "es-abstract": { 429 | "version": "1.18.0-next.1", 430 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0-next.1.tgz", 431 | "integrity": "sha512-I4UGspA0wpZXWENrdA0uHbnhte683t3qT/1VFH9aX2dA5PPSf6QW5HHXf5HImaqPmjXaVeVk4RGWnaylmV7uAA==", 432 | "dev": true, 433 | "requires": { 434 | "es-to-primitive": "^1.2.1", 435 | "function-bind": "^1.1.1", 436 | "has": "^1.0.3", 437 | "has-symbols": "^1.0.1", 438 | "is-callable": "^1.2.2", 439 | "is-negative-zero": "^2.0.0", 440 | "is-regex": "^1.1.1", 441 | "object-inspect": "^1.8.0", 442 | "object-keys": "^1.1.1", 443 | "object.assign": "^4.1.1", 444 | "string.prototype.trimend": "^1.0.1", 445 | "string.prototype.trimstart": "^1.0.1" 446 | }, 447 | "dependencies": { 448 | "object.assign": { 449 | "version": "4.1.2", 450 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", 451 | "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", 452 | "dev": true, 453 | "requires": { 454 | "call-bind": "^1.0.0", 455 | "define-properties": "^1.1.3", 456 | "has-symbols": "^1.0.1", 457 | "object-keys": "^1.1.1" 458 | } 459 | } 460 | } 461 | }, 462 | "es-to-primitive": { 463 | "version": "1.2.1", 464 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", 465 | "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", 466 | "dev": true, 467 | "requires": { 468 | "is-callable": "^1.1.4", 469 | "is-date-object": "^1.0.1", 470 | "is-symbol": "^1.0.2" 471 | } 472 | }, 473 | "escape-string-regexp": { 474 | "version": "1.0.5", 475 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 476 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 477 | "dev": true 478 | }, 479 | "esprima": { 480 | "version": "4.0.1", 481 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 482 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 483 | "dev": true 484 | }, 485 | "eth-object": { 486 | "version": "1.0.3", 487 | "resolved": "https://registry.npmjs.org/eth-object/-/eth-object-1.0.3.tgz", 488 | "integrity": "sha512-VOWso/tO0Pz66wNlzUveYN0FgaqHQGVr+n60GL6QWQSUW3kwTyyaMxrHNnaDCeq/61YvMUxygGr9FJsnmWKqEg==", 489 | "requires": { 490 | "eth-util-lite": "^1.0.1" 491 | } 492 | }, 493 | "eth-util-lite": { 494 | "version": "1.0.1", 495 | "resolved": "https://registry.npmjs.org/eth-util-lite/-/eth-util-lite-1.0.1.tgz", 496 | "integrity": "sha512-I9zp4kqxEjYhyvpAlap4uupvlwIgCUMDcZCaPNcny6wYUA2hhBkNlAwsMaqhTa19LpYVWsd9TABdx8M1ZUrJ2A==", 497 | "requires": { 498 | "bn.js": "^4.11.8", 499 | "js-sha3": "^0.8.0", 500 | "rlp": "^2.2.3", 501 | "safe-buffer": "^5.1.2" 502 | } 503 | }, 504 | "ethereum-cryptography": { 505 | "version": "0.1.3", 506 | "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", 507 | "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", 508 | "requires": { 509 | "@types/pbkdf2": "^3.0.0", 510 | "@types/secp256k1": "^4.0.1", 511 | "blakejs": "^1.1.0", 512 | "browserify-aes": "^1.2.0", 513 | "bs58check": "^2.1.2", 514 | "create-hash": "^1.2.0", 515 | "create-hmac": "^1.1.7", 516 | "hash.js": "^1.1.7", 517 | "keccak": "^3.0.0", 518 | "pbkdf2": "^3.0.17", 519 | "randombytes": "^2.1.0", 520 | "safe-buffer": "^5.1.2", 521 | "scrypt-js": "^3.0.0", 522 | "secp256k1": "^4.0.1", 523 | "setimmediate": "^1.0.5" 524 | } 525 | }, 526 | "ethereumjs-util": { 527 | "version": "5.2.1", 528 | "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", 529 | "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", 530 | "requires": { 531 | "bn.js": "^4.11.0", 532 | "create-hash": "^1.1.2", 533 | "elliptic": "^6.5.2", 534 | "ethereum-cryptography": "^0.1.3", 535 | "ethjs-util": "^0.1.3", 536 | "rlp": "^2.0.0", 537 | "safe-buffer": "^5.1.1" 538 | } 539 | }, 540 | "ethjs-util": { 541 | "version": "0.1.6", 542 | "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", 543 | "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", 544 | "requires": { 545 | "is-hex-prefixed": "1.0.0", 546 | "strip-hex-prefix": "1.0.0" 547 | } 548 | }, 549 | "evp_bytestokey": { 550 | "version": "1.0.3", 551 | "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", 552 | "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", 553 | "requires": { 554 | "md5.js": "^1.3.4", 555 | "safe-buffer": "^5.1.1" 556 | } 557 | }, 558 | "find-up": { 559 | "version": "3.0.0", 560 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", 561 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", 562 | "dev": true, 563 | "requires": { 564 | "locate-path": "^3.0.0" 565 | } 566 | }, 567 | "flat": { 568 | "version": "4.1.1", 569 | "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", 570 | "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", 571 | "dev": true, 572 | "requires": { 573 | "is-buffer": "~2.0.3" 574 | } 575 | }, 576 | "fs.realpath": { 577 | "version": "1.0.0", 578 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 579 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 580 | "dev": true 581 | }, 582 | "function-bind": { 583 | "version": "1.1.1", 584 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 585 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 586 | "dev": true 587 | }, 588 | "functional-red-black-tree": { 589 | "version": "1.0.1", 590 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 591 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" 592 | }, 593 | "get-caller-file": { 594 | "version": "2.0.5", 595 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 596 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 597 | "dev": true 598 | }, 599 | "get-func-name": { 600 | "version": "2.0.0", 601 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", 602 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", 603 | "dev": true 604 | }, 605 | "get-intrinsic": { 606 | "version": "1.0.2", 607 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.0.2.tgz", 608 | "integrity": "sha512-aeX0vrFm21ILl3+JpFFRNe9aUvp6VFZb2/CTbgLb8j75kOhvoNYjt9d8KA/tJG4gSo8nzEDedRl0h7vDmBYRVg==", 609 | "dev": true, 610 | "requires": { 611 | "function-bind": "^1.1.1", 612 | "has": "^1.0.3", 613 | "has-symbols": "^1.0.1" 614 | } 615 | }, 616 | "glob": { 617 | "version": "7.1.3", 618 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", 619 | "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", 620 | "dev": true, 621 | "requires": { 622 | "fs.realpath": "^1.0.0", 623 | "inflight": "^1.0.4", 624 | "inherits": "2", 625 | "minimatch": "^3.0.4", 626 | "once": "^1.3.0", 627 | "path-is-absolute": "^1.0.0" 628 | } 629 | }, 630 | "growl": { 631 | "version": "1.10.5", 632 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 633 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 634 | "dev": true 635 | }, 636 | "has": { 637 | "version": "1.0.3", 638 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 639 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 640 | "dev": true, 641 | "requires": { 642 | "function-bind": "^1.1.1" 643 | } 644 | }, 645 | "has-flag": { 646 | "version": "3.0.0", 647 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 648 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 649 | "dev": true 650 | }, 651 | "has-symbols": { 652 | "version": "1.0.1", 653 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", 654 | "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", 655 | "dev": true 656 | }, 657 | "hash-base": { 658 | "version": "3.1.0", 659 | "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", 660 | "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", 661 | "requires": { 662 | "inherits": "^2.0.4", 663 | "readable-stream": "^3.6.0", 664 | "safe-buffer": "^5.2.0" 665 | } 666 | }, 667 | "hash.js": { 668 | "version": "1.1.7", 669 | "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", 670 | "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", 671 | "requires": { 672 | "inherits": "^2.0.3", 673 | "minimalistic-assert": "^1.0.1" 674 | } 675 | }, 676 | "he": { 677 | "version": "1.2.0", 678 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 679 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 680 | "dev": true 681 | }, 682 | "hmac-drbg": { 683 | "version": "1.0.1", 684 | "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", 685 | "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", 686 | "requires": { 687 | "hash.js": "^1.0.3", 688 | "minimalistic-assert": "^1.0.0", 689 | "minimalistic-crypto-utils": "^1.0.1" 690 | } 691 | }, 692 | "iconv-lite": { 693 | "version": "0.6.2", 694 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", 695 | "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", 696 | "requires": { 697 | "safer-buffer": ">= 2.1.2 < 3.0.0" 698 | } 699 | }, 700 | "ieee754": { 701 | "version": "1.2.1", 702 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 703 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" 704 | }, 705 | "immediate": { 706 | "version": "3.2.3", 707 | "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.2.3.tgz", 708 | "integrity": "sha1-0UD6j2FGWb1lQSMwl92qwlzdmRw=" 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.4", 722 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 723 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 724 | }, 725 | "is-buffer": { 726 | "version": "2.0.5", 727 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", 728 | "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", 729 | "dev": true 730 | }, 731 | "is-callable": { 732 | "version": "1.2.2", 733 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.2.tgz", 734 | "integrity": "sha512-dnMqspv5nU3LoewK2N/y7KLtxtakvTuaCsU9FU50/QDmdbHNy/4/JuRtMHqRU22o3q+W89YQndQEeCVwK+3qrA==", 735 | "dev": true 736 | }, 737 | "is-date-object": { 738 | "version": "1.0.2", 739 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", 740 | "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", 741 | "dev": true 742 | }, 743 | "is-fullwidth-code-point": { 744 | "version": "2.0.0", 745 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 746 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 747 | "dev": true 748 | }, 749 | "is-hex-prefixed": { 750 | "version": "1.0.0", 751 | "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", 752 | "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" 753 | }, 754 | "is-negative-zero": { 755 | "version": "2.0.1", 756 | "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", 757 | "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", 758 | "dev": true 759 | }, 760 | "is-regex": { 761 | "version": "1.1.1", 762 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.1.tgz", 763 | "integrity": "sha512-1+QkEcxiLlB7VEyFtyBg94e08OAsvq7FUBgApTq/w2ymCLyKJgDPsybBENVtA7XCQEgEXxKPonG+mvYRxh/LIg==", 764 | "dev": true, 765 | "requires": { 766 | "has-symbols": "^1.0.1" 767 | } 768 | }, 769 | "is-stream": { 770 | "version": "1.1.0", 771 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 772 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" 773 | }, 774 | "is-symbol": { 775 | "version": "1.0.3", 776 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", 777 | "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", 778 | "dev": true, 779 | "requires": { 780 | "has-symbols": "^1.0.1" 781 | } 782 | }, 783 | "isarray": { 784 | "version": "1.0.0", 785 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 786 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 787 | }, 788 | "isexe": { 789 | "version": "2.0.0", 790 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 791 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 792 | "dev": true 793 | }, 794 | "isomorphic-fetch": { 795 | "version": "2.2.1", 796 | "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", 797 | "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", 798 | "requires": { 799 | "node-fetch": "^1.0.1", 800 | "whatwg-fetch": ">=0.10.0" 801 | } 802 | }, 803 | "isomorphic-rpc": { 804 | "version": "1.2.1", 805 | "resolved": "https://registry.npmjs.org/isomorphic-rpc/-/isomorphic-rpc-1.2.1.tgz", 806 | "integrity": "sha512-n5JblWJ9H2ZfKyXQgizxnXShu/OOp/sO+4VrQcXQuCJFYmdB/jv+7AtS2miihoIM9RrLlphAhmx0qLE8APOqCw==", 807 | "requires": { 808 | "isomorphic-fetch": "^2.2.1" 809 | } 810 | }, 811 | "js-sha3": { 812 | "version": "0.8.0", 813 | "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", 814 | "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" 815 | }, 816 | "js-yaml": { 817 | "version": "3.13.1", 818 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 819 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 820 | "dev": true, 821 | "requires": { 822 | "argparse": "^1.0.7", 823 | "esprima": "^4.0.0" 824 | } 825 | }, 826 | "keccak": { 827 | "version": "3.0.1", 828 | "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", 829 | "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", 830 | "requires": { 831 | "node-addon-api": "^2.0.0", 832 | "node-gyp-build": "^4.2.0" 833 | } 834 | }, 835 | "level-codec": { 836 | "version": "9.0.2", 837 | "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", 838 | "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", 839 | "requires": { 840 | "buffer": "^5.6.0" 841 | }, 842 | "dependencies": { 843 | "buffer": { 844 | "version": "5.7.1", 845 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", 846 | "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", 847 | "requires": { 848 | "base64-js": "^1.3.1", 849 | "ieee754": "^1.1.13" 850 | } 851 | } 852 | } 853 | }, 854 | "level-errors": { 855 | "version": "2.0.1", 856 | "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", 857 | "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", 858 | "requires": { 859 | "errno": "~0.1.1" 860 | } 861 | }, 862 | "level-iterator-stream": { 863 | "version": "3.0.1", 864 | "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz", 865 | "integrity": "sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g==", 866 | "requires": { 867 | "inherits": "^2.0.1", 868 | "readable-stream": "^2.3.6", 869 | "xtend": "^4.0.0" 870 | }, 871 | "dependencies": { 872 | "readable-stream": { 873 | "version": "2.3.7", 874 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 875 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 876 | "requires": { 877 | "core-util-is": "~1.0.0", 878 | "inherits": "~2.0.3", 879 | "isarray": "~1.0.0", 880 | "process-nextick-args": "~2.0.0", 881 | "safe-buffer": "~5.1.1", 882 | "string_decoder": "~1.1.1", 883 | "util-deprecate": "~1.0.1" 884 | } 885 | }, 886 | "safe-buffer": { 887 | "version": "5.1.2", 888 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 889 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 890 | }, 891 | "string_decoder": { 892 | "version": "1.1.1", 893 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 894 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 895 | "requires": { 896 | "safe-buffer": "~5.1.0" 897 | } 898 | } 899 | } 900 | }, 901 | "level-mem": { 902 | "version": "3.0.1", 903 | "resolved": "https://registry.npmjs.org/level-mem/-/level-mem-3.0.1.tgz", 904 | "integrity": "sha512-LbtfK9+3Ug1UmvvhR2DqLqXiPW1OJ5jEh0a3m9ZgAipiwpSxGj/qaVVy54RG5vAQN1nCuXqjvprCuKSCxcJHBg==", 905 | "requires": { 906 | "level-packager": "~4.0.0", 907 | "memdown": "~3.0.0" 908 | } 909 | }, 910 | "level-packager": { 911 | "version": "4.0.1", 912 | "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-4.0.1.tgz", 913 | "integrity": "sha512-svCRKfYLn9/4CoFfi+d8krOtrp6RoX8+xm0Na5cgXMqSyRru0AnDYdLl+YI8u1FyS6gGZ94ILLZDE5dh2but3Q==", 914 | "requires": { 915 | "encoding-down": "~5.0.0", 916 | "levelup": "^3.0.0" 917 | } 918 | }, 919 | "level-ws": { 920 | "version": "1.0.0", 921 | "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-1.0.0.tgz", 922 | "integrity": "sha512-RXEfCmkd6WWFlArh3X8ONvQPm8jNpfA0s/36M4QzLqrLEIt1iJE9WBHLZ5vZJK6haMjJPJGJCQWfjMNnRcq/9Q==", 923 | "requires": { 924 | "inherits": "^2.0.3", 925 | "readable-stream": "^2.2.8", 926 | "xtend": "^4.0.1" 927 | }, 928 | "dependencies": { 929 | "readable-stream": { 930 | "version": "2.3.7", 931 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 932 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 933 | "requires": { 934 | "core-util-is": "~1.0.0", 935 | "inherits": "~2.0.3", 936 | "isarray": "~1.0.0", 937 | "process-nextick-args": "~2.0.0", 938 | "safe-buffer": "~5.1.1", 939 | "string_decoder": "~1.1.1", 940 | "util-deprecate": "~1.0.1" 941 | } 942 | }, 943 | "safe-buffer": { 944 | "version": "5.1.2", 945 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 946 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 947 | }, 948 | "string_decoder": { 949 | "version": "1.1.1", 950 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 951 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 952 | "requires": { 953 | "safe-buffer": "~5.1.0" 954 | } 955 | } 956 | } 957 | }, 958 | "levelup": { 959 | "version": "3.1.1", 960 | "resolved": "https://registry.npmjs.org/levelup/-/levelup-3.1.1.tgz", 961 | "integrity": "sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg==", 962 | "requires": { 963 | "deferred-leveldown": "~4.0.0", 964 | "level-errors": "~2.0.0", 965 | "level-iterator-stream": "~3.0.0", 966 | "xtend": "~4.0.0" 967 | } 968 | }, 969 | "locate-path": { 970 | "version": "3.0.0", 971 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", 972 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", 973 | "dev": true, 974 | "requires": { 975 | "p-locate": "^3.0.0", 976 | "path-exists": "^3.0.0" 977 | } 978 | }, 979 | "lodash": { 980 | "version": "4.17.20", 981 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", 982 | "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" 983 | }, 984 | "log-symbols": { 985 | "version": "2.2.0", 986 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", 987 | "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", 988 | "dev": true, 989 | "requires": { 990 | "chalk": "^2.0.1" 991 | } 992 | }, 993 | "ltgt": { 994 | "version": "2.2.1", 995 | "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", 996 | "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=" 997 | }, 998 | "md5.js": { 999 | "version": "1.3.5", 1000 | "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", 1001 | "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", 1002 | "requires": { 1003 | "hash-base": "^3.0.0", 1004 | "inherits": "^2.0.1", 1005 | "safe-buffer": "^5.1.2" 1006 | } 1007 | }, 1008 | "memdown": { 1009 | "version": "3.0.0", 1010 | "resolved": "https://registry.npmjs.org/memdown/-/memdown-3.0.0.tgz", 1011 | "integrity": "sha512-tbV02LfZMWLcHcq4tw++NuqMO+FZX8tNJEiD2aNRm48ZZusVg5N8NART+dmBkepJVye986oixErf7jfXboMGMA==", 1012 | "requires": { 1013 | "abstract-leveldown": "~5.0.0", 1014 | "functional-red-black-tree": "~1.0.1", 1015 | "immediate": "~3.2.3", 1016 | "inherits": "~2.0.1", 1017 | "ltgt": "~2.2.0", 1018 | "safe-buffer": "~5.1.1" 1019 | }, 1020 | "dependencies": { 1021 | "safe-buffer": { 1022 | "version": "5.1.2", 1023 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1024 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 1025 | } 1026 | } 1027 | }, 1028 | "merkle-patricia-tree": { 1029 | "version": "github:zmitton/merkle-patricia-tree#3e33005b879d839dea2239cae9e65171f2cc17a2", 1030 | "from": "github:zmitton/merkle-patricia-tree#build", 1031 | "requires": { 1032 | "async": "^2.6.1", 1033 | "ethereumjs-util": "^5.2.0", 1034 | "level-mem": "^3.0.1", 1035 | "level-ws": "^1.0.0", 1036 | "readable-stream": "^3.0.6", 1037 | "rlp": "^2.0.0", 1038 | "semaphore": ">=1.0.1" 1039 | } 1040 | }, 1041 | "minimalistic-assert": { 1042 | "version": "1.0.1", 1043 | "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", 1044 | "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" 1045 | }, 1046 | "minimalistic-crypto-utils": { 1047 | "version": "1.0.1", 1048 | "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", 1049 | "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" 1050 | }, 1051 | "minimatch": { 1052 | "version": "3.0.4", 1053 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1054 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1055 | "dev": true, 1056 | "requires": { 1057 | "brace-expansion": "^1.1.7" 1058 | } 1059 | }, 1060 | "minimist": { 1061 | "version": "1.2.5", 1062 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", 1063 | "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", 1064 | "dev": true 1065 | }, 1066 | "mkdirp": { 1067 | "version": "0.5.4", 1068 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", 1069 | "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", 1070 | "dev": true, 1071 | "requires": { 1072 | "minimist": "^1.2.5" 1073 | } 1074 | }, 1075 | "mocha": { 1076 | "version": "6.2.3", 1077 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", 1078 | "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", 1079 | "dev": true, 1080 | "requires": { 1081 | "ansi-colors": "3.2.3", 1082 | "browser-stdout": "1.3.1", 1083 | "debug": "3.2.6", 1084 | "diff": "3.5.0", 1085 | "escape-string-regexp": "1.0.5", 1086 | "find-up": "3.0.0", 1087 | "glob": "7.1.3", 1088 | "growl": "1.10.5", 1089 | "he": "1.2.0", 1090 | "js-yaml": "3.13.1", 1091 | "log-symbols": "2.2.0", 1092 | "minimatch": "3.0.4", 1093 | "mkdirp": "0.5.4", 1094 | "ms": "2.1.1", 1095 | "node-environment-flags": "1.0.5", 1096 | "object.assign": "4.1.0", 1097 | "strip-json-comments": "2.0.1", 1098 | "supports-color": "6.0.0", 1099 | "which": "1.3.1", 1100 | "wide-align": "1.1.3", 1101 | "yargs": "13.3.2", 1102 | "yargs-parser": "13.1.2", 1103 | "yargs-unparser": "1.6.0" 1104 | } 1105 | }, 1106 | "ms": { 1107 | "version": "2.1.1", 1108 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 1109 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", 1110 | "dev": true 1111 | }, 1112 | "node-addon-api": { 1113 | "version": "2.0.2", 1114 | "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", 1115 | "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" 1116 | }, 1117 | "node-environment-flags": { 1118 | "version": "1.0.5", 1119 | "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", 1120 | "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", 1121 | "dev": true, 1122 | "requires": { 1123 | "object.getownpropertydescriptors": "^2.0.3", 1124 | "semver": "^5.7.0" 1125 | } 1126 | }, 1127 | "node-fetch": { 1128 | "version": "1.7.3", 1129 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", 1130 | "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", 1131 | "requires": { 1132 | "encoding": "^0.1.11", 1133 | "is-stream": "^1.0.1" 1134 | } 1135 | }, 1136 | "node-gyp-build": { 1137 | "version": "4.2.3", 1138 | "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", 1139 | "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" 1140 | }, 1141 | "object-inspect": { 1142 | "version": "1.9.0", 1143 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.9.0.tgz", 1144 | "integrity": "sha512-i3Bp9iTqwhaLZBxGkRfo5ZbE07BQRT7MGu8+nNgwW9ItGp1TzCTw2DLEoWwjClxBjOFI/hWljTAmYGCEwmtnOw==", 1145 | "dev": true 1146 | }, 1147 | "object-keys": { 1148 | "version": "1.1.1", 1149 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 1150 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 1151 | "dev": true 1152 | }, 1153 | "object.assign": { 1154 | "version": "4.1.0", 1155 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", 1156 | "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", 1157 | "dev": true, 1158 | "requires": { 1159 | "define-properties": "^1.1.2", 1160 | "function-bind": "^1.1.1", 1161 | "has-symbols": "^1.0.0", 1162 | "object-keys": "^1.0.11" 1163 | } 1164 | }, 1165 | "object.getownpropertydescriptors": { 1166 | "version": "2.1.1", 1167 | "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.1.tgz", 1168 | "integrity": "sha512-6DtXgZ/lIZ9hqx4GtZETobXLR/ZLaa0aqV0kzbn80Rf8Z2e/XFnhA0I7p07N2wH8bBBltr2xQPi6sbKWAY2Eng==", 1169 | "dev": true, 1170 | "requires": { 1171 | "call-bind": "^1.0.0", 1172 | "define-properties": "^1.1.3", 1173 | "es-abstract": "^1.18.0-next.1" 1174 | } 1175 | }, 1176 | "once": { 1177 | "version": "1.4.0", 1178 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1179 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1180 | "dev": true, 1181 | "requires": { 1182 | "wrappy": "1" 1183 | } 1184 | }, 1185 | "p-limit": { 1186 | "version": "2.3.0", 1187 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", 1188 | "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", 1189 | "dev": true, 1190 | "requires": { 1191 | "p-try": "^2.0.0" 1192 | } 1193 | }, 1194 | "p-locate": { 1195 | "version": "3.0.0", 1196 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", 1197 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", 1198 | "dev": true, 1199 | "requires": { 1200 | "p-limit": "^2.0.0" 1201 | } 1202 | }, 1203 | "p-try": { 1204 | "version": "2.2.0", 1205 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 1206 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 1207 | "dev": true 1208 | }, 1209 | "path-exists": { 1210 | "version": "3.0.0", 1211 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 1212 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 1213 | "dev": true 1214 | }, 1215 | "path-is-absolute": { 1216 | "version": "1.0.1", 1217 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1218 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1219 | "dev": true 1220 | }, 1221 | "pathval": { 1222 | "version": "1.1.0", 1223 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", 1224 | "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", 1225 | "dev": true 1226 | }, 1227 | "pbkdf2": { 1228 | "version": "3.1.1", 1229 | "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", 1230 | "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", 1231 | "requires": { 1232 | "create-hash": "^1.1.2", 1233 | "create-hmac": "^1.1.4", 1234 | "ripemd160": "^2.0.1", 1235 | "safe-buffer": "^5.0.1", 1236 | "sha.js": "^2.4.8" 1237 | } 1238 | }, 1239 | "process-nextick-args": { 1240 | "version": "2.0.1", 1241 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 1242 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 1243 | }, 1244 | "promisfy": { 1245 | "version": "1.2.0", 1246 | "resolved": "https://registry.npmjs.org/promisfy/-/promisfy-1.2.0.tgz", 1247 | "integrity": "sha512-9S6NY6pVlmrvQX/KIZn4V8EPcKNAC0l5nEKXTa5K1/uzqnMOn4ivWtQY+IbSE/f9uLUa1T/kbDsASSzi05X3dA==" 1248 | }, 1249 | "prr": { 1250 | "version": "1.0.1", 1251 | "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", 1252 | "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" 1253 | }, 1254 | "randombytes": { 1255 | "version": "2.1.0", 1256 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 1257 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 1258 | "requires": { 1259 | "safe-buffer": "^5.1.0" 1260 | } 1261 | }, 1262 | "readable-stream": { 1263 | "version": "3.6.0", 1264 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", 1265 | "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", 1266 | "requires": { 1267 | "inherits": "^2.0.3", 1268 | "string_decoder": "^1.1.1", 1269 | "util-deprecate": "^1.0.1" 1270 | } 1271 | }, 1272 | "require-directory": { 1273 | "version": "2.1.1", 1274 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1275 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 1276 | "dev": true 1277 | }, 1278 | "require-main-filename": { 1279 | "version": "2.0.0", 1280 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", 1281 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", 1282 | "dev": true 1283 | }, 1284 | "ripemd160": { 1285 | "version": "2.0.2", 1286 | "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", 1287 | "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", 1288 | "requires": { 1289 | "hash-base": "^3.0.0", 1290 | "inherits": "^2.0.1" 1291 | } 1292 | }, 1293 | "rlp": { 1294 | "version": "2.2.3", 1295 | "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.3.tgz", 1296 | "integrity": "sha512-l6YVrI7+d2vpW6D6rS05x2Xrmq8oW7v3pieZOJKBEdjuTF4Kz/iwk55Zyh1Zaz+KOB2kC8+2jZlp2u9L4tTzCQ==", 1297 | "requires": { 1298 | "bn.js": "^4.11.1", 1299 | "safe-buffer": "^5.1.1" 1300 | } 1301 | }, 1302 | "safe-buffer": { 1303 | "version": "5.2.0", 1304 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", 1305 | "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" 1306 | }, 1307 | "safer-buffer": { 1308 | "version": "2.1.2", 1309 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1310 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1311 | }, 1312 | "scrypt-js": { 1313 | "version": "3.0.1", 1314 | "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", 1315 | "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" 1316 | }, 1317 | "secp256k1": { 1318 | "version": "4.0.2", 1319 | "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", 1320 | "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", 1321 | "requires": { 1322 | "elliptic": "^6.5.2", 1323 | "node-addon-api": "^2.0.0", 1324 | "node-gyp-build": "^4.2.0" 1325 | } 1326 | }, 1327 | "semaphore": { 1328 | "version": "1.1.0", 1329 | "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", 1330 | "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==" 1331 | }, 1332 | "semver": { 1333 | "version": "5.7.1", 1334 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1335 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 1336 | "dev": true 1337 | }, 1338 | "set-blocking": { 1339 | "version": "2.0.0", 1340 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 1341 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", 1342 | "dev": true 1343 | }, 1344 | "setimmediate": { 1345 | "version": "1.0.5", 1346 | "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", 1347 | "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" 1348 | }, 1349 | "sha.js": { 1350 | "version": "2.4.11", 1351 | "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", 1352 | "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", 1353 | "requires": { 1354 | "inherits": "^2.0.1", 1355 | "safe-buffer": "^5.0.1" 1356 | } 1357 | }, 1358 | "should": { 1359 | "version": "13.2.3", 1360 | "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", 1361 | "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", 1362 | "dev": true, 1363 | "requires": { 1364 | "should-equal": "^2.0.0", 1365 | "should-format": "^3.0.3", 1366 | "should-type": "^1.4.0", 1367 | "should-type-adaptors": "^1.0.1", 1368 | "should-util": "^1.0.0" 1369 | } 1370 | }, 1371 | "should-equal": { 1372 | "version": "2.0.0", 1373 | "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", 1374 | "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", 1375 | "dev": true, 1376 | "requires": { 1377 | "should-type": "^1.4.0" 1378 | } 1379 | }, 1380 | "should-format": { 1381 | "version": "3.0.3", 1382 | "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", 1383 | "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", 1384 | "dev": true, 1385 | "requires": { 1386 | "should-type": "^1.3.0", 1387 | "should-type-adaptors": "^1.0.1" 1388 | } 1389 | }, 1390 | "should-type": { 1391 | "version": "1.4.0", 1392 | "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", 1393 | "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", 1394 | "dev": true 1395 | }, 1396 | "should-type-adaptors": { 1397 | "version": "1.1.0", 1398 | "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", 1399 | "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", 1400 | "dev": true, 1401 | "requires": { 1402 | "should-type": "^1.3.0", 1403 | "should-util": "^1.0.0" 1404 | } 1405 | }, 1406 | "should-util": { 1407 | "version": "1.0.1", 1408 | "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", 1409 | "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", 1410 | "dev": true 1411 | }, 1412 | "sprintf-js": { 1413 | "version": "1.0.3", 1414 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1415 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 1416 | "dev": true 1417 | }, 1418 | "string-width": { 1419 | "version": "2.1.1", 1420 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 1421 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 1422 | "dev": true, 1423 | "requires": { 1424 | "is-fullwidth-code-point": "^2.0.0", 1425 | "strip-ansi": "^4.0.0" 1426 | } 1427 | }, 1428 | "string.prototype.trimend": { 1429 | "version": "1.0.3", 1430 | "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.3.tgz", 1431 | "integrity": "sha512-ayH0pB+uf0U28CtjlLvL7NaohvR1amUvVZk+y3DYb0Ey2PUV5zPkkKy9+U1ndVEIXO8hNg18eIv9Jntbii+dKw==", 1432 | "dev": true, 1433 | "requires": { 1434 | "call-bind": "^1.0.0", 1435 | "define-properties": "^1.1.3" 1436 | } 1437 | }, 1438 | "string.prototype.trimstart": { 1439 | "version": "1.0.3", 1440 | "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.3.tgz", 1441 | "integrity": "sha512-oBIBUy5lea5tt0ovtOFiEQaBkoBBkyJhZXzJYrSmDo5IUUqbOPvVezuRs/agBIdZ2p2Eo1FD6bD9USyBLfl3xg==", 1442 | "dev": true, 1443 | "requires": { 1444 | "call-bind": "^1.0.0", 1445 | "define-properties": "^1.1.3" 1446 | } 1447 | }, 1448 | "string_decoder": { 1449 | "version": "1.3.0", 1450 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", 1451 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", 1452 | "requires": { 1453 | "safe-buffer": "~5.2.0" 1454 | } 1455 | }, 1456 | "strip-ansi": { 1457 | "version": "4.0.0", 1458 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 1459 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 1460 | "dev": true, 1461 | "requires": { 1462 | "ansi-regex": "^3.0.0" 1463 | } 1464 | }, 1465 | "strip-hex-prefix": { 1466 | "version": "1.0.0", 1467 | "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", 1468 | "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", 1469 | "requires": { 1470 | "is-hex-prefixed": "1.0.0" 1471 | } 1472 | }, 1473 | "strip-json-comments": { 1474 | "version": "2.0.1", 1475 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1476 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 1477 | "dev": true 1478 | }, 1479 | "supports-color": { 1480 | "version": "6.0.0", 1481 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", 1482 | "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", 1483 | "dev": true, 1484 | "requires": { 1485 | "has-flag": "^3.0.0" 1486 | } 1487 | }, 1488 | "type-detect": { 1489 | "version": "4.0.8", 1490 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", 1491 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", 1492 | "dev": true 1493 | }, 1494 | "util-deprecate": { 1495 | "version": "1.0.2", 1496 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1497 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 1498 | }, 1499 | "whatwg-fetch": { 1500 | "version": "3.5.0", 1501 | "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.5.0.tgz", 1502 | "integrity": "sha512-jXkLtsR42xhXg7akoDKvKWE40eJeI+2KZqcp2h3NsOrRnDvtWX36KcKl30dy+hxECivdk2BVUHVNrPtoMBUx6A==" 1503 | }, 1504 | "which": { 1505 | "version": "1.3.1", 1506 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 1507 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 1508 | "dev": true, 1509 | "requires": { 1510 | "isexe": "^2.0.0" 1511 | } 1512 | }, 1513 | "which-module": { 1514 | "version": "2.0.0", 1515 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", 1516 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", 1517 | "dev": true 1518 | }, 1519 | "wide-align": { 1520 | "version": "1.1.3", 1521 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 1522 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 1523 | "dev": true, 1524 | "requires": { 1525 | "string-width": "^1.0.2 || 2" 1526 | } 1527 | }, 1528 | "wrap-ansi": { 1529 | "version": "5.1.0", 1530 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", 1531 | "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", 1532 | "dev": true, 1533 | "requires": { 1534 | "ansi-styles": "^3.2.0", 1535 | "string-width": "^3.0.0", 1536 | "strip-ansi": "^5.0.0" 1537 | }, 1538 | "dependencies": { 1539 | "ansi-regex": { 1540 | "version": "4.1.0", 1541 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 1542 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 1543 | "dev": true 1544 | }, 1545 | "string-width": { 1546 | "version": "3.1.0", 1547 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 1548 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 1549 | "dev": true, 1550 | "requires": { 1551 | "emoji-regex": "^7.0.1", 1552 | "is-fullwidth-code-point": "^2.0.0", 1553 | "strip-ansi": "^5.1.0" 1554 | } 1555 | }, 1556 | "strip-ansi": { 1557 | "version": "5.2.0", 1558 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1559 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1560 | "dev": true, 1561 | "requires": { 1562 | "ansi-regex": "^4.1.0" 1563 | } 1564 | } 1565 | } 1566 | }, 1567 | "wrappy": { 1568 | "version": "1.0.2", 1569 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1570 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 1571 | "dev": true 1572 | }, 1573 | "xtend": { 1574 | "version": "4.0.2", 1575 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", 1576 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" 1577 | }, 1578 | "y18n": { 1579 | "version": "4.0.1", 1580 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", 1581 | "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", 1582 | "dev": true 1583 | }, 1584 | "yargs": { 1585 | "version": "13.3.2", 1586 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", 1587 | "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", 1588 | "dev": true, 1589 | "requires": { 1590 | "cliui": "^5.0.0", 1591 | "find-up": "^3.0.0", 1592 | "get-caller-file": "^2.0.1", 1593 | "require-directory": "^2.1.1", 1594 | "require-main-filename": "^2.0.0", 1595 | "set-blocking": "^2.0.0", 1596 | "string-width": "^3.0.0", 1597 | "which-module": "^2.0.0", 1598 | "y18n": "^4.0.0", 1599 | "yargs-parser": "^13.1.2" 1600 | }, 1601 | "dependencies": { 1602 | "ansi-regex": { 1603 | "version": "4.1.0", 1604 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 1605 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 1606 | "dev": true 1607 | }, 1608 | "string-width": { 1609 | "version": "3.1.0", 1610 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 1611 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 1612 | "dev": true, 1613 | "requires": { 1614 | "emoji-regex": "^7.0.1", 1615 | "is-fullwidth-code-point": "^2.0.0", 1616 | "strip-ansi": "^5.1.0" 1617 | } 1618 | }, 1619 | "strip-ansi": { 1620 | "version": "5.2.0", 1621 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1622 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1623 | "dev": true, 1624 | "requires": { 1625 | "ansi-regex": "^4.1.0" 1626 | } 1627 | } 1628 | } 1629 | }, 1630 | "yargs-parser": { 1631 | "version": "13.1.2", 1632 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", 1633 | "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", 1634 | "dev": true, 1635 | "requires": { 1636 | "camelcase": "^5.0.0", 1637 | "decamelize": "^1.2.0" 1638 | } 1639 | }, 1640 | "yargs-unparser": { 1641 | "version": "1.6.0", 1642 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", 1643 | "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", 1644 | "dev": true, 1645 | "requires": { 1646 | "flat": "^4.1.0", 1647 | "lodash": "^4.17.15", 1648 | "yargs": "^13.3.0" 1649 | } 1650 | } 1651 | } 1652 | } 1653 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eth-proof", 3 | "version": "2.1.6", 4 | "description": "Proving things in the Ethereum Patricia Trie (tree)", 5 | "main": "index.js", 6 | "dependencies": { 7 | "buffer": "^6.0.3", 8 | "eth-object": "^1.0.3", 9 | "eth-util-lite": "^1.0.1", 10 | "isomorphic-rpc": "^1.2.1", 11 | "merkle-patricia-tree": "github:zmitton/merkle-patricia-tree#build", 12 | "promisfy": "^1.2.0" 13 | }, 14 | "scripts": { 15 | "test": "node_modules/.bin/mocha --require should --timeout 25000" 16 | }, 17 | "author": "zac mitton", 18 | "license": "MIT", 19 | "devDependencies": { 20 | "chai": "^4.2.0", 21 | "mocha": "^6.2.3", 22 | "should": "^13.2.3" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /test/account.js: -------------------------------------------------------------------------------- 1 | const { keccak, encode, toBuffer } = require('eth-util-lite') 2 | const { Account } = require('eth-object') 3 | const { GetAndVerify } = require('./../index') 4 | 5 | const getAndVerify = new GetAndVerify(process.env.ETHPROOFENDPOINT) 6 | 7 | before(() => { 8 | if(!process.env.ETHPROOFENDPOINT){ 9 | throw new Error('To run tests, set an ETHPROOFENDPOINT environment variable' + 10 | ' using something like `export ETHPROOFENDPOINT="https://mainnet.infura.io/v3/yourInfuraApiToken`.' + 11 | ' you will need to have a free infura API token (if you are note running your own archive node)' + 12 | ' because the tests will otherwise be rate-limited by Infura.') 13 | } 14 | }) 15 | 16 | describe('Account GetAndVerify Against BlockHash', () => { 17 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 18 | let blockHash = '0xb7964f87a97582605af695710ad252afa018a97384ba9438cf24e42fa9f0efc9' 19 | let accountAddress = '0x9cc9bf39a84998089050a90087e597c26758685d' 20 | let account = await getAndVerify.accountAgainstBlockHash(accountAddress, blockHash) 21 | // console.log("\nONLY ONE TEST IS CURRENTLY ENABLED. PLEASE SELECT ONE TEST AT A TIME\n") 22 | console.log("\naccount:\n\n", account) 23 | console.log("\naccount.raw:\n\n", account.raw) 24 | console.log("\naccount.object:\n\n", account.object) 25 | console.log("\naccount.hex:\n\n", account.hex) 26 | console.log("\naccount.buffer:\n\n", account.buffer) 27 | console.log("\naccount.json:\n\n", account.json) 28 | // console.log("\nSERIALIZE():\n", account.serialize()) 29 | // console.log("\nTOBUFFER():\n", account.toBuffer()) 30 | // console.log("\nTOHEX():\n", account.toHex()) 31 | // console.log("\nTOOBJECT():\n", account.toObject()) 32 | // console.log("\nTOSTRING():\n", account.toString()) 33 | // console.log("\nTOJSON():\n", account.toJson()) 34 | // console.log("\nULEs():\n", Account.fields) 35 | }); 36 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 37 | let blockHash = '0x7315156cc8347cf9bfac8a4cd1db6f5d4727b06b3fe14feba62381335b2d14d5' 38 | let accountAddress = '0x9cc9bf39a84998089050a90087e597c26758685d' 39 | let account = await getAndVerify.accountAgainstBlockHash(accountAddress, blockHash) 40 | }); 41 | it('should be able to prove an account does not exist', async () => { 42 | let blockHashBlockZero = '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' 43 | let emptyAccountAddress = '0x0000000000000000000000000000000000000000' 44 | let account = await getAndVerify.accountAgainstBlockHash(emptyAccountAddress, blockHashBlockZero) 45 | // console.log(account) 46 | }); 47 | //standard accounts validated by random legitimate blockhash 48 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 49 | let blockHash = '0x7315156cc8347cf9bfac8a4cd1db6f5d4727b06b3fe14feba62381335b2d14d5' 50 | let accountAddress = '0x2a956e2fdcf3e338d0e925c68bcb73e7c8bb86c4' 51 | let account = await getAndVerify.accountAgainstBlockHash(accountAddress, blockHash) 52 | // console.log(account) 53 | }); 54 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 55 | let blockHash = '0x7315156cc8347cf9bfac8a4cd1db6f5d4727b06b3fe14feba62381335b2d14d5' 56 | let accountAddress = '0x1F4E7Db8514Ec4E99467a8d2ee3a63094a904e7A' 57 | let account = await getAndVerify.accountAgainstBlockHash(accountAddress, blockHash) 58 | // console.log(account) 59 | }); 60 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 61 | let blockHash = '0x7315156cc8347cf9bfac8a4cd1db6f5d4727b06b3fe14feba62381335b2d14d5' 62 | let accountAddress = '0x1F4E7Db8514Ec4E99467a8d2ee3a63094a904e7A' 63 | let account = await getAndVerify.accountAgainstBlockHash(accountAddress, blockHash) 64 | // console.log(account) 65 | }); 66 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 67 | let blockHash = '0x7315156cc8347cf9bfac8a4cd1db6f5d4727b06b3fe14feba62381335b2d14d5' 68 | let accountAddress = '0x0087194a367D4D508D9a97846264f69d81e419ca' 69 | let account = await getAndVerify.accountAgainstBlockHash(accountAddress, blockHash) 70 | // console.log(account) 71 | }); 72 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 73 | let blockHash = '0x7315156cc8347cf9bfac8a4cd1db6f5d4727b06b3fe14feba62381335b2d14d5' 74 | let accountAddress = '0x0d8775f648430679a709e98d2b0cb6250d2887ef' 75 | let account = await getAndVerify.accountAgainstBlockHash(accountAddress, blockHash) 76 | // console.log(account) 77 | }); 78 | 79 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 80 | let blockHash = '0x7315156cc8347cf9bfac8a4cd1db6f5d4727b06b3fe14feba62381335b2d14d5' 81 | let accountAddress = '0xc1cdc601f89c0428b31302d187e0dc08ad7d1c57' 82 | let account = await getAndVerify.accountAgainstBlockHash(accountAddress, blockHash) 83 | // console.log(account) 84 | }); 85 | 86 | it('should be able to prove an account did not exist at a given time', async () => { 87 | // proof of absence : the following account didnt exist durring block 0 88 | let blockHashBlockZero = '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' 89 | let accountAddress = '0x9cc9bf39a84998089050a90087e597c26758685d' 90 | let account = await getAndVerify.accountAgainstBlockHash(accountAddress, blockHashBlockZero) 91 | // console.log(account) 92 | encode(account).equals(Account.NULL.toBuffer()).should.be.true() 93 | 94 | }); 95 | it('should be able to prove an account did not exist at a given time', async () => { 96 | let blockHashBlockZero = '0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3' 97 | let accountAddress = '0xdeadbeef00123456789012345678901234567890' 98 | let account = await getAndVerify.accountAgainstBlockHash(accountAddress, blockHashBlockZero) 99 | // console.log(account) 100 | encode(account).equals(Account.NULL.toBuffer()).should.be.true() 101 | 102 | account[0].equals(toBuffer()).should.be.true() 103 | account[1].equals(toBuffer()).should.be.true() 104 | account[2].equals(keccak(encode())).should.be.true() 105 | account[3].equals(keccak()).should.be.true() 106 | }); 107 | }); 108 | -------------------------------------------------------------------------------- /test/log.js: -------------------------------------------------------------------------------- 1 | // const Web3 = require('web3') 2 | const { GetAndVerify, VerifyProof } = require('./../index') 3 | 4 | const getAndVerify = new GetAndVerify(process.env.ETHPROOFENDPOINT) 5 | 6 | //should need utils 7 | describe('Log GetAndVerify Against BlockHash', () => { 8 | 9 | // it('should be able to request a log proof from web3 and verify it', async () => { 10 | // let prf = await getAndVerify.getLogProof('0x8d0da05c3256da94a4213149de3e17fae7d1fd1b86fd4e57557527325ba87adc', 0) 11 | // VerifyProof.log(prf.rlpLogIndex, prf.value, prf.rlpTxIndex, prf.receipt, prf.branch, prf.header, prf.blockHash).should.be.true() 12 | // }); 13 | 14 | // it('requesting proof from non-existant tx should throw error', async () => { 15 | // await getAndVerify.getTransactionProof('0x1234').should.be.rejectedWith(Error) 16 | // await getAndVerify.getTransactionProof('0x12345678a9ea9f274b174205adde3243eec74589bef9a0e78a433763b2f8caa3').should.be.rejectedWith(Error) 17 | // }); 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /test/receipt.js: -------------------------------------------------------------------------------- 1 | const { GetAndVerify } = require('./../index') 2 | const getAndVerify = new GetAndVerify(process.env.ETHPROOFENDPOINT) 3 | const { encode, toHex } = require('eth-util-lite') 4 | 5 | describe('Receipt GetAndVerify Against BlockHash', () => { 6 | 7 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 8 | let blockHash = '0xc32470c2459fd607246412e23b4b4d19781c1fa24a603d47a5bc066be3b5c0af' 9 | let txHash = '0xacb81623523bbabccb1638a907686bc2f3229c70e3ab51777bef0a635f3ac03f' 10 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 11 | // console.log("r ", toHex(encode(receipt.setOfLogs[0]))) 12 | }); 13 | it('should be able to request a proof for 0xc55e2b90 and verify it', async () => { 14 | let blockHash = '0xc0f4906fea23cf6f3cce98cb44e8e1449e455b28d684dfa9ff65426495584de6' 15 | let txHash = '0xc55e2b90168af6972193c1f86fa4d7d7b31a29c156665d15b9cd48618b5177ef' 16 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 17 | // console.log("TX ", tx) 18 | }); 19 | 20 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 21 | let blockHash = '0xb60dfdd493b9e468cc429ac275a2cad4f0d0db03cc55cd975bdef167134cbb69' 22 | let txHash = '0x499a8636c52111a37e074c20c6133ff7af662ffd728cf5222822099fea077b4e' 23 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 24 | // console.log(prf) 25 | }); 26 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 27 | let blockHash = '0xb60dfdd493b9e468cc429ac275a2cad4f0d0db03cc55cd975bdef167134cbb69' 28 | let txHash = '0x7371ea9eae773f03c6bd886295a82e419bdc18a5899b5ecc0d6186d0ebbd2b36' 29 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 30 | // console.log(prf) 31 | }); 32 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 33 | let blockHash = '0xf82990de9b368d810ce4b858c45717737245aa965771565f8a41df4c75acc171' 34 | let txHash = '0xb53f752216120e8cbe18783f41c6d960254ad59fac16229d4eaec5f7591319de' 35 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 36 | // console.log(prf) 37 | }); 38 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 39 | let blockHash = '0x43340a6d232532c328211d8a8c0fa84af658dbff1f4906ab7a7d4e41f82fe3a3' 40 | let txHash = '0xdaa2fcc5d94f03348dc26bfacf84828ff563ccc57f6ab8260d2bd35b5d668ef8' 41 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 42 | // console.log(prf) 43 | }); 44 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 45 | let blockHash = '0x06aaa18961661ff572a8ef7314871affad8d85de6b8a6b724a137041fbb0dfea' 46 | let txHash = '0x299a93acf5b100336455ef6ecda39e22329fb750e6264c8ee44f579947349de9' 47 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 48 | // console.log(prf) 49 | }); 50 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 51 | let blockHash = '0xfb981a97ad4ce5475df40b1d10da2f0d53f292b4fd52c498b92da7b11713b546' 52 | let txHash = '0x74bdf5450025b8806d55cfbb9b393dce630232f5bf87832ae6b675db9d286ac3' 53 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 54 | // console.log(prf) 55 | }); 56 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 57 | let blockHash = '0x66534add4c3ed6de5dfecbc03c6275dfc3f3d01c99b65f4030c397bf3290cc02' 58 | let txHash = '0x4e4b9cd37d9b5bb38941983a34d1539e4930572bdaf41d1aa54ddc738630b1bb' 59 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 60 | // console.log(prf) 61 | }); 62 | 63 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 64 | let blockHash = '0xcd1b584875df23199133c6aa9644676e1055ecb0c67328d9ca897e66bad154b0' 65 | let txHash = '0x84e86114ea47d97e882411db029b5c42e7e25395f279636e4a277ec44dce23a4' 66 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 67 | // console.log(prf) 68 | }); 69 | 70 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 71 | let blockHash = '0x9390b1bf8d81984b38dfa677128026fab1a5622bab07e67086818e7db16060d8' 72 | let txHash = '0x8d0da05c3256da94a4213149de3e17fae7d1fd1b86fd4e57557527325ba87adc' 73 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 74 | // console.log(prf) 75 | }); 76 | 77 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 78 | let blockHash = '0x5edf99fd6efe492b8297fd43c603ae7820efa8d2e00900ecaa38c67a3b879348' 79 | let txHash = '0xe6c0c5e61a52b2226f7730d915e4c1baf606f34719dcfbda7164266cce111ae3' 80 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 81 | // console.log(prf) 82 | }); 83 | 84 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 85 | let blockHash = '0xb2fb12f6ba24958b50c20e330d96a4d28474594bef89cd65a33cf968278e6dc4' 86 | let txHash = '0x1e1a818d63fd4d03c6125ea4f5e99a27255728a2bad195f858635543a95f1c3f' 87 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 88 | // console.log(prf) 89 | }); 90 | 91 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 92 | let blockHash = '0xf0604916b9ce1543671c1309c52bedbe4689c67da9a571e5301b717d31d37a7d' 93 | let txHash = '0x598bf980dead5d96ca0e2325f2dbc884ada041ca2e05f8c9bdac1c60926764e0' 94 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 95 | // console.log(prf) 96 | }); 97 | 98 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 99 | let blockHash = '0xd39e271f8f898847ba586ec1a1b7d9a089865344c214e51f2e3e1ddc2fb48848' 100 | let txHash = '0xed2903beb85ffce50cec37050313951920d997199ff4a4d7b8fbc0b45ca44c84' 101 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 102 | // console.log(prf) 103 | }); 104 | 105 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 106 | let blockHash = '0x1410f41c3b6ff435a50e2ccc24dc55544c287e41184eb1923e4bfb63edd1b101' 107 | let txHash = '0x6afb931aa1008783dedf5c66dc41b1fc8f01bf34ebc183b37110a7a77523e15c' 108 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 109 | // console.log(prf) 110 | }); 111 | 112 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 113 | let blockHash = '0xea50140910517f7c489d4a853585214fbec50ba4fc54c58acce712efae07e25f' 114 | let txHash = '0xc12e727125b5733a90555a1438ec48b27ffa928b84d39775923afeb229ba1a60' 115 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 116 | // console.log(prf) 117 | }); 118 | 119 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 120 | let blockHash = '0x24bacc6e41d1a583dae370573f03d35c67b421f602af6882ca164cc8763342d6' 121 | let txHash = '0xfd7f67e10bb48c641743108096eb7aa750d17afb8ac95560d93ebcd347e74443' 122 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 123 | // console.log(prf) 124 | }); 125 | 126 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 127 | let blockHash = '0xcec8db0c358cda6512f4bfd22fcc7287d0bb08aa89e1e704e334d2d967d3b1b7' 128 | let txHash = '0xc1080d2eaf1f3e866a4c12298a0be47647665a120d8ee681520eb440a6e06f99' 129 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 130 | // console.log(prf) 131 | }); 132 | 133 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 134 | let blockHash = '0xcbc584929eed97b692a6e5c498559b60e924c6f194b1be070d3d12bee73cd2a6' 135 | let txHash = '0xe6a37c02c198f9e4c8e7831a1b6a0e6711bf372a301147da339e2f61117f58a1' 136 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 137 | // console.log(prf) 138 | }); 139 | 140 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 141 | let blockHash = '0xcbc584929eed97b692a6e5c498559b60e924c6f194b1be070d3d12bee73cd2a6' 142 | let txHash = '0x7392ee6d4bea6a0c8018de116fd2d6bf5678fdc0faae53240e7a22ab57db22d0' 143 | let receipt = await getAndVerify.receiptAgainstBlockHash(txHash, blockHash) 144 | // console.log(prf) 145 | }); 146 | }); 147 | -------------------------------------------------------------------------------- /test/storage.js: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | The contracts deployed on mainnet used for these tests: 3 | https://etherscan.io/address/0x92fd2d727ff572d0aa56493a0ebc9b9e24d15295#code 4 | 5 | pragma solidity ^0.5.3; 6 | contract Storage { 7 | uint public pos0; 8 | mapping(address => uint) public pos1; 9 | mapping(uint => mapping(uint => uint)) public pos2; 10 | bytes32 public pos3; 11 | 12 | constructor() public{ 13 | pos0 = 0x1234; 14 | 15 | pos1[0x1F4E7Db8514Ec4E99467a8d2ee3a63094a904e7A] = 0x5678; 16 | pos1[0x1234567890123456789012345678901234567890] = 0x8765; 17 | 18 | pos2[0x111][0x222] = 0x9101112; 19 | pos2[0x333][0x444] = 0x13141516; 20 | 21 | pos3 = keccak256(abi.encode()); 22 | } 23 | } 24 | 25 | https://etherscan.io/address/0x9cc9bf39a84998089050a90087e597c26758685d#code 26 | contract Storage { 27 | uint pos0; 28 | mapping(address => uint) pos1; 29 | function Storage() { 30 | pos0 = 1234; 31 | pos1[0x1f4e7db8514ec4e99467a8d2ee3a63094a904e7a] = 5678; 32 | } 33 | } 34 | **************************************************************************/ 35 | const { keccak, toBuffer, mappingAt } = require('eth-util-lite') 36 | 37 | const { GetAndVerify } = require('./../index') 38 | 39 | const getAndVerify = new GetAndVerify(process.env.ETHPROOFENDPOINT) 40 | 41 | describe('Storage GetAndVerify Against BlockHash', () => { 42 | // add test for the contract itself (account proof) and assert against known values for the code/storageRoot/value 43 | // add test like above that checks a null account for all its values 44 | 45 | it('should get and verify "pos0 = 0x1234;"', async () => { 46 | let blockHash = '0xb7964f87a97582605af695710ad252afa018a97384ba9438cf24e42fa9f0efc9' 47 | let accountAddress = '0x92fd2D727ff572d0AA56493a0Ebc9b9e24d15295' 48 | let position = '0x0' 49 | 50 | let storageValue = await getAndVerify.storageAgainstBlockHash(accountAddress, position, blockHash) 51 | storageValue.equals(toBuffer("0x1234")).should.be.true() 52 | storageValue.equals(toBuffer("0x9999")).should.be.false() 53 | }); 54 | it('should get and verify "pos0 = 0x1234;" against other blockHash', async () => { 55 | let blockHash = '0x5de2488ca9ea618d5cdd095b4abf4e0b69c2fb2b3c83b7a26e383cb6e77dfc5f' 56 | let accountAddress = '0x92fd2D727ff572d0AA56493a0Ebc9b9e24d15295' 57 | let position = '0x0' 58 | 59 | let storageValue = await getAndVerify.storageAgainstBlockHash(accountAddress, position, blockHash) 60 | 61 | storageValue.equals(toBuffer("0x1234")).should.be.true() 62 | }); 63 | it('should get and verify "pos1[0x1F4E7D...] = 0x5678;"', async () => { 64 | let blockHash = '0xb7964f87a97582605af695710ad252afa018a97384ba9438cf24e42fa9f0efc9' 65 | let accountAddress = '0x92fd2D727ff572d0AA56493a0Ebc9b9e24d15295' 66 | let position = mappingAt('0x1', '0x1F4E7Db8514Ec4E99467a8d2ee3a63094a904e7A') 67 | let storageValue = await getAndVerify.storageAgainstBlockHash(accountAddress, position, blockHash) 68 | 69 | storageValue.equals(toBuffer("0x5678")).should.be.true() 70 | }); 71 | it('should get and verify "pos1[0x1F4E7D...] = 0x5678;" against other blockHash', async () => { 72 | let blockHash = '0x5de2488ca9ea618d5cdd095b4abf4e0b69c2fb2b3c83b7a26e383cb6e77dfc5f' 73 | let accountAddress = '0x92fd2D727ff572d0AA56493a0Ebc9b9e24d15295' 74 | let position = mappingAt('0x1', '0x1F4E7Db8514Ec4E99467a8d2ee3a63094a904e7A') 75 | let storageValue = await getAndVerify.storageAgainstBlockHash(accountAddress, position, blockHash) 76 | 77 | storageValue.equals(toBuffer("0x5678")).should.be.true() 78 | }); 79 | it('should get and verify "pos1[0x123456...] = 0x8765;" against blockHash', async () => { 80 | let blockHash = '0x5de2488ca9ea618d5cdd095b4abf4e0b69c2fb2b3c83b7a26e383cb6e77dfc5f' 81 | let accountAddress = '0x92fd2D727ff572d0AA56493a0Ebc9b9e24d15295' 82 | let position = mappingAt('0x1', '0x1234567890123456789012345678901234567890') 83 | let storageValue = await getAndVerify.storageAgainstBlockHash(accountAddress, position, blockHash) 84 | 85 | storageValue.equals(toBuffer("0x8765")).should.be.true() 86 | }); 87 | it('should get and verify "pos2[0x111][0x222] = 0x9101112;" against blockHash', async () => { 88 | let blockHash = '0x5de2488ca9ea618d5cdd095b4abf4e0b69c2fb2b3c83b7a26e383cb6e77dfc5f' 89 | let accountAddress = '0x92fd2D727ff572d0AA56493a0Ebc9b9e24d15295' 90 | let position = mappingAt('0x2', '0x111', '0x222') 91 | let storageValue = await getAndVerify.storageAgainstBlockHash(accountAddress, position, blockHash) 92 | 93 | storageValue.equals(toBuffer("0x9101112")).should.be.true() 94 | }); 95 | it('should get and verify "pos2[0x333][0x444] = 0x13141516;" against blockHash', async () => { 96 | let blockHash = '0x5de2488ca9ea618d5cdd095b4abf4e0b69c2fb2b3c83b7a26e383cb6e77dfc5f' 97 | let accountAddress = '0x92fd2D727ff572d0AA56493a0Ebc9b9e24d15295' 98 | let position = mappingAt('0x2', '0x333', '0x444') 99 | let storageValue = await getAndVerify.storageAgainstBlockHash(accountAddress, position, blockHash) 100 | 101 | storageValue.equals(toBuffer("0x13141516")).should.be.true() 102 | }); 103 | it('should get and verify "pos3 = abi.encode();" against blockHash', async () => { 104 | let blockHash = '0x5de2488ca9ea618d5cdd095b4abf4e0b69c2fb2b3c83b7a26e383cb6e77dfc5f' 105 | let accountAddress = '0x92fd2D727ff572d0AA56493a0Ebc9b9e24d15295' 106 | let position = '0x3' 107 | let storageValue = await getAndVerify.storageAgainstBlockHash(accountAddress, position, blockHash) 108 | 109 | storageValue.equals(keccak()).should.be.true() 110 | }); 111 | it('should get and verify some older contract data', async () => { 112 | let blockHash = '0x5de2488ca9ea618d5cdd095b4abf4e0b69c2fb2b3c83b7a26e383cb6e77dfc5f' 113 | let accountAddress = '0x9cc9bf39a84998089050a90087e597c26758685d' 114 | let position = '0x' 115 | let storageValue = await getAndVerify.storageAgainstBlockHash(accountAddress, position, blockHash) 116 | 117 | storageValue.equals(toBuffer("0x04d2")).should.be.true() 118 | }); 119 | it('should get and verify some older contract data', async () => { 120 | let blockHash = '0x5de2488ca9ea618d5cdd095b4abf4e0b69c2fb2b3c83b7a26e383cb6e77dfc5f' 121 | let accountAddress = '0x10fbc306e84ee530856098cc490216bd5e9fa52e' 122 | let position = '0x' 123 | let storageValue = await getAndVerify.storageAgainstBlockHash(accountAddress, position, blockHash) 124 | 125 | storageValue.equals(toBuffer("0x01")).should.be.true() 126 | }); 127 | it('should get and verify some older contract data', async () => { 128 | let blockHash = '0x5de2488ca9ea618d5cdd095b4abf4e0b69c2fb2b3c83b7a26e383cb6e77dfc5f' 129 | let accountAddress = '0x10fbc306e84ee530856098cc490216bd5e9fa52e' 130 | let position = '0x01' 131 | let storageValue = await getAndVerify.storageAgainstBlockHash(accountAddress, position, blockHash) 132 | 133 | storageValue.equals(toBuffer("0x2a956e2fdcf3e338d0e925c68bcb73e7c8bb86c4")).should.be.true() 134 | }); 135 | 136 | it('should get and verify some older contract data', async () => { 137 | let blockHash = '0x5de2488ca9ea618d5cdd095b4abf4e0b69c2fb2b3c83b7a26e383cb6e77dfc5f' 138 | let accountAddress = '0x9cc9bf39a84998089050a90087e597c26758685d' 139 | let position = mappingAt('0x1','0x1f4e7db8514ec4e99467a8d2ee3a63094a904e7a') 140 | let storageValue = await getAndVerify.storageAgainstBlockHash(accountAddress, position, blockHash) 141 | 142 | storageValue.equals(toBuffer(5678)).should.be.true() 143 | }); 144 | 145 | // prove absence 146 | it('should get and verify that an undefined storage value is in fact null', async () => { 147 | let blockHash = '0x5de2488ca9ea618d5cdd095b4abf4e0b69c2fb2b3c83b7a26e383cb6e77dfc5f' 148 | // let accountAddress = '0x92fd2D727ff572d0AA56493a0Ebc9b9e24d15295' 149 | let accountAddress = '0xdeadbeef00000000000046283746191046394857' //non-existant account 150 | let position = '0x0' // <== an unset storage position 151 | let storageValue = await getAndVerify.storageAgainstBlockHash(accountAddress, position, blockHash) 152 | 153 | storageValue.equals(toBuffer()).should.be.true() 154 | storageValue.equals(toBuffer("0x1234")).should.be.false() 155 | }); 156 | it('should get and verify that an undefined storage value is in fact null', async () => { 157 | let blockHash = '0x5de2488ca9ea618d5cdd095b4abf4e0b69c2fb2b3c83b7a26e383cb6e77dfc5f' 158 | let accountAddress = '0x92fd2D727ff572d0AA56493a0Ebc9b9e24d15295' 159 | let position = '0xff' // <== an unset storage position 160 | let storageValue = await getAndVerify.storageAgainstBlockHash(accountAddress, position, blockHash) 161 | 162 | storageValue.equals(toBuffer()).should.be.true() 163 | storageValue.equals(toBuffer("0x1234")).should.be.false() 164 | }); 165 | it('should get and verify a storage slot is empty in a real contract', async () => { 166 | let blockHash = '0x5de2488ca9ea618d5cdd095b4abf4e0b69c2fb2b3c83b7a26e383cb6e77dfc5f' 167 | let accountAddress = '0x92fd2D727ff572d0AA56493a0Ebc9b9e24d15295' 168 | let position = '0x4' // <== an unset storage position 169 | let storageValue = await getAndVerify.storageAgainstBlockHash(accountAddress, position, blockHash) 170 | 171 | storageValue.equals(toBuffer()).should.be.true() 172 | }); 173 | it('should get and verify a mapping slot is empty in a real mapping', async () => { 174 | let blockHash = '0x5de2488ca9ea618d5cdd095b4abf4e0b69c2fb2b3c83b7a26e383cb6e77dfc5f' 175 | let accountAddress = '0x9cc9bf39a84998089050a90087e597c26758685d' 176 | let position = mappingAt('0x1','0x1111111111111111111111111111111111111111') //nothing here 177 | let storageValue = await getAndVerify.storageAgainstBlockHash(accountAddress, position, blockHash) 178 | storageValue.equals(toBuffer()).should.be.true() 179 | }); 180 | 181 | }); 182 | -------------------------------------------------------------------------------- /test/transaction.js: -------------------------------------------------------------------------------- 1 | const expect = require("chai").expect; 2 | const { GetAndVerify, VerifyProof } = require('./../index') 3 | // const { encode } = require('eth-util-lite') 4 | const getAndVerify = new GetAndVerify(process.env.ETHPROOFENDPOINT) 5 | 6 | //should need utils to check results 7 | 8 | describe('Transaction GetAndVerify Against blockHash', () => { 9 | //take a look at 155 (new tx). compare with pre-dao format 10 | //should be 9 elements instead of 6 or whatever idk 11 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 12 | let blockHash = '0xc32470c2459fd607246412e23b4b4d19781c1fa24a603d47a5bc066be3b5c0af' 13 | let txHash = '0xacb81623523bbabccb1638a907686bc2f3229c70e3ab51777bef0a635f3ac03f' 14 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 15 | // console.log(tx) 16 | // console.log(tx.hex) 17 | }); 18 | it('should be able to request a proof for 0xb53f7522 and verify it', async () => { 19 | let blockHash = '0xf82990de9b368d810ce4b858c45717737245aa965771565f8a41df4c75acc171' 20 | let txHash = '0xb53f752216120e8cbe18783f41c6d960254ad59fac16229d4eaec5f7591319de' 21 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 22 | // console.log(prf) 23 | }); 24 | 25 | it('should be able to request a proof for 0xc55e2b90 and verify it', async () => { 26 | let blockHash = '0xc0f4906fea23cf6f3cce98cb44e8e1449e455b28d684dfa9ff65426495584de6' 27 | let txHash = '0xc55e2b90168af6972193c1f86fa4d7d7b31a29c156665d15b9cd48618b5177ef' 28 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 29 | // console.log("TX ", tx) 30 | }); 31 | it('should be able to request a proof for 0xc55e2b90 and verify it', async () => { 32 | let blockHash = '0x06aaa18961661ff572a8ef7314871affad8d85de6b8a6b724a137041fbb0dfea' 33 | let txHash = '0x299a93acf5b100336455ef6ecda39e22329fb750e6264c8ee44f579947349de9' 34 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 35 | // console.log("TX ", tx) 36 | }); 37 | 38 | it('should be able to request a proof for 0xc55e2b90 and verify it', async () => { 39 | let blockHash = '0x06aaa18961661ff572a8ef7314871affad8d85de6b8a6b724a137041fbb0dfea' 40 | let txHash = '0x299a93acf5b100336455ef6ecda39e22329fb750e6264c8ee44f579947349de9' 41 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 42 | // console.log("TX ", tx) 43 | }); 44 | 45 | it('should be able to request a proof for ', async () => { 46 | let blockHash = '0x66534add4c3ed6de5dfecbc03c6275dfc3f3d01c99b65f4030c397bf3290cc02' 47 | let txHash = '0x4e4b9cd37d9b5bb38941983a34d1539e4930572bdaf41d1aa54ddc738630b1bb' 48 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 49 | // console.log("TX ", tx) 50 | }); 51 | 52 | 53 | it('should be able to request a proof for ', async () => { 54 | let blockHash = '0xfb981a97ad4ce5475df40b1d10da2f0d53f292b4fd52c498b92da7b11713b546' 55 | let txHash = '0x74bdf5450025b8806d55cfbb9b393dce630232f5bf87832ae6b675db9d286ac3' 56 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 57 | // console.log("TX ", tx) 58 | }); 59 | 60 | 61 | it('should be able to request a proof for ', async () => { 62 | let blockHash = '0xcd1b584875df23199133c6aa9644676e1055ecb0c67328d9ca897e66bad154b0' 63 | let txHash = '0x84e86114ea47d97e882411db029b5c42e7e25395f279636e4a277ec44dce23a4' 64 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 65 | // console.log("TX ", tx) 66 | }); 67 | 68 | it('should be able to request a proof for ', async () => { 69 | let blockHash = '0x9390b1bf8d81984b38dfa677128026fab1a5622bab07e67086818e7db16060d8' 70 | let txHash = '0x8d0da05c3256da94a4213149de3e17fae7d1fd1b86fd4e57557527325ba87adc' 71 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 72 | // console.log("TX ", tx) 73 | }); 74 | 75 | it('should be able to request a proof for ', async () => { 76 | let blockHash = '0x5edf99fd6efe492b8297fd43c603ae7820efa8d2e00900ecaa38c67a3b879348' 77 | let txHash = '0xe6c0c5e61a52b2226f7730d915e4c1baf606f34719dcfbda7164266cce111ae3' 78 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 79 | // console.log("TX ", tx) 80 | }); 81 | 82 | it('should be able to request a proof for ', async () => { 83 | let blockHash = '0xb2fb12f6ba24958b50c20e330d96a4d28474594bef89cd65a33cf968278e6dc4' 84 | let txHash = '0x1e1a818d63fd4d03c6125ea4f5e99a27255728a2bad195f858635543a95f1c3f' 85 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 86 | // console.log("TX ", tx) 87 | }); 88 | 89 | it('should be able to request a proof for ', async () => { 90 | let blockHash = '0xf0604916b9ce1543671c1309c52bedbe4689c67da9a571e5301b717d31d37a7d' 91 | let txHash = '0x598bf980dead5d96ca0e2325f2dbc884ada041ca2e05f8c9bdac1c60926764e0' 92 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 93 | // console.log("TX ", tx) 94 | }); 95 | 96 | it('should be able to request a proof for ', async () => { 97 | let blockHash = '0xd39e271f8f898847ba586ec1a1b7d9a089865344c214e51f2e3e1ddc2fb48848' 98 | let txHash = '0xed2903beb85ffce50cec37050313951920d997199ff4a4d7b8fbc0b45ca44c84' 99 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 100 | // console.log("TX ", tx) 101 | }); 102 | 103 | it('should be able to request a proof for ', async () => { 104 | let blockHash = '0x1410f41c3b6ff435a50e2ccc24dc55544c287e41184eb1923e4bfb63edd1b101' 105 | let txHash = '0x6afb931aa1008783dedf5c66dc41b1fc8f01bf34ebc183b37110a7a77523e15c' 106 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 107 | // console.log("TX ", tx) 108 | }); 109 | 110 | it('should be able to request a proof for ', async () => { 111 | let blockHash = '0xea50140910517f7c489d4a853585214fbec50ba4fc54c58acce712efae07e25f' 112 | let txHash = '0xc12e727125b5733a90555a1438ec48b27ffa928b84d39775923afeb229ba1a60' 113 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 114 | // console.log("TX ", tx) 115 | }); 116 | 117 | it('should be able to request a proof for ', async () => { 118 | let blockHash = '0x43340a6d232532c328211d8a8c0fa84af658dbff1f4906ab7a7d4e41f82fe3a3' 119 | let txHash = '0xdaa2fcc5d94f03348dc26bfacf84828ff563ccc57f6ab8260d2bd35b5d668ef8' 120 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 121 | // console.log("TX ", tx) 122 | }); 123 | 124 | it('should be able to request a proof for ', async () => { 125 | let blockHash = '0x24bacc6e41d1a583dae370573f03d35c67b421f602af6882ca164cc8763342d6' 126 | let txHash = '0xfd7f67e10bb48c641743108096eb7aa750d17afb8ac95560d93ebcd347e74443' 127 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 128 | // console.log("TX ", tx) 129 | }); 130 | 131 | it('should be able to request a proof for ', async () => { 132 | let blockHash = '0xcec8db0c358cda6512f4bfd22fcc7287d0bb08aa89e1e704e334d2d967d3b1b7' 133 | let txHash = '0xc1080d2eaf1f3e866a4c12298a0be47647665a120d8ee681520eb440a6e06f99' 134 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 135 | // console.log("TX ", tx) 136 | }); 137 | 138 | it('should be able to request a proof for ', async () => { 139 | let blockHash = '0xcbc584929eed97b692a6e5c498559b60e924c6f194b1be070d3d12bee73cd2a6' 140 | let txHash = '0xe6a37c02c198f9e4c8e7831a1b6a0e6711bf372a301147da339e2f61117f58a1' 141 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 142 | // console.log("TX ", tx) 143 | }); 144 | 145 | it('should be able to request a proof for ', async () => { 146 | let blockHash = '0xcbc584929eed97b692a6e5c498559b60e924c6f194b1be070d3d12bee73cd2a6' 147 | let txHash = '0x7392ee6d4bea6a0c8018de116fd2d6bf5678fdc0faae53240e7a22ab57db22d0' 148 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 149 | // console.log("TX ", tx) 150 | }); 151 | 152 | it('should be able to request a proof for ', async () => { 153 | let blockHash = '0xc32470c2459fd607246412e23b4b4d19781c1fa24a603d47a5bc066be3b5c0af' 154 | let txHash = '0xacb81623523bbabccb1638a907686bc2f3229c70e3ab51777bef0a635f3ac03f' 155 | let tx = await getAndVerify.txAgainstBlockHash(txHash, blockHash) 156 | // console.log("TX ", tx) 157 | }); 158 | 159 | it('requesting invalid tx hash should throw error', async () => { 160 | let blockHash = '0xc32470c2459fd607246412e23b4b4d19781c1fa24a603d47a5bc066be3b5c0af' 161 | await getAndVerify.txAgainstBlockHash("0x1234", blockHash).should.be.rejectedWith(Error) 162 | await getAndVerify.txAgainstBlockHash("0x1111111111222222222233333333334444444444555555555566666666667777", blockHash).should.be.rejectedWith(Error) 163 | }); 164 | 165 | it('should throw when attempting to prove against the wrong blockHash', async () => { 166 | let blockHashFromBlockNum4012371 = '0xc32470c2459fd607246412e23b4b4d19781c1fa24a603d47a5bc066be3b5c0af' 167 | let txFromBlockNum1008398 = '0xfd7f67e10bb48c641743108096eb7aa750d17afb8ac95560d93ebcd347e74443' 168 | await getAndVerify.txAgainstBlockHash(txFromBlockNum1008398, blockHashFromBlockNum4012371).should.be.rejectedWith(Error) 169 | // console.log("TX ", tx) 170 | }); 171 | // it('verifying a modified or different proof should throw an error', async () => { 172 | // let prf = await getAndVerify.getTransactionProof('0x4e4b9cd37d9b5bb38941983a34d1539e4930572bdaf41d1aa54ddc738630b1bb') 173 | // let otherPrf = await getAndVerify.getTransactionProof('0x74bdf5450025b8806d55cfbb9b393dce630232f5bf87832ae6b675db9d286ac3') 174 | 175 | // expect(()=>{VerifyProof.transaction(Buffer.from('80','hex'), prf.value, prf.branch, prf.header, prf.blockHash)}).to.throw() 176 | // expect(()=>{VerifyProof.transaction(encode(prf.txIndex), otherPrf.value, prf.branch, prf.header, prf.blockHash)}).to.throw() 177 | // expect(()=>{VerifyProof.transaction(otherPrf.path, prf.value, otherPrf.branch, otherPrf.header, otherPrf.blockHash)}).to.throw() 178 | // }); 179 | }); 180 | // thanks @Matthalp, arranging blockhashes into a merkle mountain range does indeed seem to be the most _optimal_ way to do this. Quite a bit better than any proposed solution in these EIPs. 181 | 182 | // From the core devs meeting they had decided to push it to the next (~8month) release. Sounds like there should be another EIP proposed using MMRs 183 | 184 | // From my initial investigation of MMRs on ethereum. The question is mostly _where_ to put them. The non-interactive proof will be significantly larger if we sit this data in a smart contract. That's because each "query" (non-interactive) would have to also include its `stateproof`(account) and its `storageProof`(less significant). I believe a proof has on the order of 500 queries. 185 | 186 | // #### Hard Fork implementation 187 | 188 | // Optimal would be to add this data right in the header. This seems like if could break a lot of things though. The `extraData` field would work, but would occupy its complete use (32byte max). I think it could be less breaky to extend the field to 64 bytes and require the first 32 to always be the MMR root. 189 | 190 | // #### Soft fork 191 | 192 | // A currently legal place to put this stuff is at the bottom of a smart contract (which can already be done today without any fork see below), but would need the ~500 extra [storage+state proofs](https://gist.github.com/zmitton/c7062cbab6ebf5ce297ed0f221518e75) leading to the MMR root. That's probably about ~2 megabytes extra. 193 | 194 | // Or it could be embedded in a transaction, and specifically the zeroith transaction of every block. Tx proofs are significantly smaller. This is especially true for the zeroith tx because it gets encoded as `<80>` and interestingly sits in the shortest (constant) path by itself in the txTree. This would cause only a total of 10kb above the the header approach. 195 | 196 | // The biggest drawback here is that its significantly harder to access from the EVM when compared to a contract that can be accessed directly (as a global in solidity for example). However it can still be used, and much cheaper/easier than earlier "skinny" versions of this proposal. 197 | 198 | // #### Velvet fork or simple smart contract: 199 | 200 | // Although this would along maximally be able to prove the work who's blocks included the MMR transaction (so never the full work)). A the same token, the sooner any MMR are getting stuffed, the better. They will only ever be able to prove work that was done after they we implemented. The contract code doesn't even need to be particularly secure, the MMR root just needs to be embedded (in any way) to the block for future software to be able to accept it 201 | 202 | 203 | -------------------------------------------------------------------------------- /test/tree.js: -------------------------------------------------------------------------------- 1 | // const { GetAndVerify } = require('./../index') 2 | 3 | // const getAndVerify = new GetAndVerify("https://mainnet.infura.io") 4 | 5 | // describe('Account GetAndVerify Against BlockHash', () => { 6 | 7 | 8 | // const Verify = require('./../verifyProof') 9 | // it('can verify an account is in a state tree with a specific stateRoot', async () => { 10 | // let address = "0x9cc9bf39a84998089050a90087e597c26758685d" 11 | // let prf = await getAndVerify.getAccountProof(address) 12 | // // console.log(prf.account) 13 | // Verify.rootContainsBranch(Branch.root(prf.accountBranch), prf.accountBranch).should.be.true() 14 | // Verify.accountBranchContainsAccountAt(prf.accountBranch, prf.account, address).should.be.true() 15 | // }); 16 | // }); 17 | -------------------------------------------------------------------------------- /test/verify.js: -------------------------------------------------------------------------------- 1 | // const expect = require("chai").expect; 2 | // const { encode } = require('eth-util-lite') 3 | // const { GetAndVerify, VerifyProof } = require('./../index') 4 | 5 | // const getAndVerify = new GetAndVerify("https://mainnet.infura.io") 6 | 7 | // describe('Account GetAndVerify Against BlockHash', () => { 8 | 9 | 10 | // const Verify = require('./../verifyProof') 11 | // const Branch = require('./../branch') 12 | // it('can verify an account is in a state tree with a specific stateRoot', async () => { 13 | // let address = "0x9cc9bf39a84998089050a90087e597c26758685d" 14 | // let prf = await getAndVerify.getAccountProof(address) 15 | // // console.log(prf.account) 16 | // Verify.rootContainsBranch(Branch.root(prf.accountBranch), prf.accountBranch).should.be.true() 17 | // Verify.accountBranchContainsAccountAt(prf.accountBranch, prf.account, address).should.be.true() 18 | // }); 19 | // it('can verify an account is in a state tree with a specific stateRoot', async () => { 20 | // let address1 = "0x9cc9bf39a84998089050a90087e597c26758685d" 21 | // let address2 = "0xc1cdc601f89c0428b31302d187e0dc08ad7d1c57" 22 | // let prf1 = await getAndVerify.getAccountProof(address1) 23 | // let prf2 = await getAndVerify.getAccountProof(address2) 24 | // // console.log(prf.account) 25 | // expect(()=>{ Verify.accountBranchContainsAccountAt(prf2.accountBranch, prf1.account, address1) }).to.throw() 26 | // expect(()=>{ Verify.accountBranchContainsAccountAt(prf2.accountBranch, prf1.account, address2) }).to.throw() 27 | // expect(()=>{ Verify.accountBranchContainsAccountAt(prf2.accountBranch, prf2.account, address1) }).to.throw() 28 | // }); 29 | 30 | // it('can verify proof from address and blockHash', async () => { 31 | // let address = "0xc1cdc601f89c0428b31302d187e0dc08ad7d1c57" 32 | 33 | // let prf = await getAndVerify.getAccountProof(address) 34 | 35 | // Verify.headerContainsStateRoot(prf.blockheader, prf.accountBranch).should.be.true() 36 | // Verify.rootContainsBranch() 37 | // // Verify.blockheaderContainsAccountBranch(prf.blockheader, prf.accountBranch).should.be.true() 38 | // Verify.accountBranchContainsAccountAtAddress(prf.accountBranch, prf.account, address).should.be.true() 39 | 40 | // expect(()=>{ 41 | // let unrelatedBlockHash = "0x0a90e277f1c1e7738783d5a56c721730d71dc2d41d5bc234ceefad538ca69c87" 42 | // Verify.blockHashContainsBlockheader(unrelatedBlockHash, prf.blockheader) 43 | // }).to.throw() 44 | // }); 45 | 46 | // it('can verify proof from address and blockHash', async () => { 47 | // let address = "0xc1cdc601f89c0428b31302d187e0dc08ad7d1c57" 48 | // let blockHash = "0x0a90e277f1c1e7738783d5a56c721730d71dc2d41d5bc234ceefad538ca69c87" 49 | 50 | // let prf = await getAndVerify.getAccountProof(address, blockHash) 51 | 52 | // Verify.blockHashContainsBlockheader(blockHash, prf.blockheader).should.be.true() 53 | // Verify.blockheaderContainsAccountBranch(prf.blockheader, prf.accountBranch).should.be.true() 54 | // Verify.accountBranchContainsAccountAtAddress(prf.accountBranch, prf.account, address).should.be.true() 55 | // }); 56 | 57 | //more accounts 58 | 59 | // it('can verify proof', async () => { 60 | // // let prf = await newPromise.reject().should.be.rejectedWith(Error) 61 | // // throw new Error() 62 | // // expect(()=>{Verify.account(prf.addressBytes, prf.accountBytes, prf.branchBytes, prf.headerBytes, prf.blockHashBytes)}).to.throw() 63 | // // prf = await getAndVerify.getAccountProof("0x1234").should.be.rejectedWith(Error) 64 | // // expect(()=>{Verify.account(prf.addressBytes, prf.accountBytes, prf.branchBytes, prf.headerBytes, prf.blockHashBytes)}).to.throw() 65 | // }); 66 | 67 | //more accounts 68 | 69 | // it('can disprove invalid proof (invalid address)', async () => { 70 | // let prf = await getAndVerify.getAccountProof("0xc1cdc601f89c0428b31302d187e0dc08ad7d1c57") 71 | // expect(()=>{ Verify.account(new Buffer('01','hex'), prf.accountBytes, prf.branchBytes, prf.headerBytes, prf.blockHashBytes) }).to.throw() 72 | // }); 73 | 74 | // it('can disprove invalid proof (invalid address)', async () => { 75 | // let prf = await getAndVerify.getAccountProof("0xc1cdc601f89c0428b31302d187e0dc08ad7d1c57") 76 | // let otherPrf = await getAndVerify.getAccountProof("0x9cc9bf39a84998089050a90087e597c26758685d") 77 | // expect(()=>{ Verify.account(otherPrf.accountBytes, prf.accountBytes, prf.branchBytes, prf.headerBytes, prf.blockHashBytes) }).to.throw() 78 | // }); 79 | 80 | // it('can verify absence', async () => { 81 | // let prf = await getAndVerify.getAccountProof("0x00000001f89c0428b31302d187e0dc08ad7d1c57") 82 | // Verify.account(prf.addressBytes, prf.accountBytes, prf.branchBytes, prf.headerBytes, prf.blockHashBytes).should.be.true() 83 | // }); 84 | 85 | // it('can disprove invalid absence proof', async () => { 86 | // let prf = await getAndVerify.getAccountProof("0x00000001f89c0428b31302d187e0dc08ad7d1c57") 87 | // let otherPrf = await getAndVerify.getAccountProof("0x9cc9bf39a84998089050a90087e597c26758685d") 88 | 89 | // Verify.account( prf.addressBytes, prf.accountBytes, prf.branchBytes, prf.headerBytes, prf.blockHashBytes).should.be.true() 90 | // expect(()=>{Verify.account(otherPrf.addressBytes, prf.accountBytes, prf.branchBytes, prf.headerBytes, prf.blockHashBytes) }).to.throw() 91 | // }); 92 | 93 | //RECEIPT 94 | // it('requesting invalid tx hash should throw error', async () => { 95 | // await getAndVerify.getReceiptProof('0x4914025aa9ea9f274b174205adde3243eec74589bef9a0e78a433763b2f8caa3').should.be.rejectedWith(Error) 96 | // await getAndVerify.getReceiptProof('0x1234').should.be.rejectedWith(Error) 97 | // }); 98 | 99 | // it('verifying a modified or different proof should throw an error', async () => { 100 | // let prf = await getAndVerify.getReceiptProof('0x4e4b9cd37d9b5bb38941983a34d1539e4930572bdaf41d1aa54ddc738630b1bb') 101 | // let otherPrf = await getAndVerify.getReceiptProof('0x74bdf5450025b8806d55cfbb9b393dce630232f5bf87832ae6b675db9d286ac3') 102 | 103 | // expect(()=>{VerifyProof.receipt(Buffer.from('80','hex'), prf.value, prf.branch, prf.header, prf.blockHash)}).to.throw() 104 | // expect(()=>{VerifyProof.receipt(encode(prf.txIndex), otherPrf.value, prf.branch, prf.header, prf.blockHash)}).to.throw() 105 | // expect(()=>{VerifyProof.receipt(otherPrf.path, prf.value, otherPrf.branch, otherPrf.header, otherPrf.blockHash)}).to.throw() 106 | // }); 107 | -------------------------------------------------------------------------------- /verifyProof.js: -------------------------------------------------------------------------------- 1 | const { keccak, encode, decode, toBuffer, toWord } = require('eth-util-lite') 2 | 3 | const Tree = require('merkle-patricia-tree') 4 | 5 | const { Account, Receipt, Transaction } = require('eth-object') 6 | 7 | const ACCOUNTS_ROOT_INDEX = 3 // within header 8 | const TXS_ROOT_INDEX = 4 // within header 9 | const RECEIPTS_ROOT_INDEX = 5 // within header 10 | 11 | const STORAGE_ROOT_INDEX = 2 // within account 12 | const SET_OF_LOGS_INDEX = 3 // within receipt 13 | 14 | class Verify{ 15 | 16 | static chainContainsBlockHash(_chain, _blockHash){ throw new Error("Feature not yet available") } 17 | 18 | static getRootFromProof(proof){ return keccak(encode(proof[0])) } 19 | 20 | static accountContainsStorageRoot(account){ 21 | return account[STORAGE_ROOT_INDEX] 22 | } 23 | static getBlockHashFromHeader(header){ 24 | return keccak(encode(header)) 25 | } 26 | static getElemFromHeaderAt(header, indexOfRoot){ 27 | return header[indexOfRoot] 28 | } 29 | static getStateRootFromHeader(header){ 30 | return this.getElemFromHeaderAt(header, ACCOUNTS_ROOT_INDEX) 31 | } 32 | static getTxsRootFromHeader(header){ 33 | return this.getElemFromHeaderAt(header, TXS_ROOT_INDEX) 34 | } 35 | static getReceiptsRootFromHeader(header){ 36 | return this.getElemFromHeaderAt(header, RECEIPTS_ROOT_INDEX) 37 | } 38 | static receiptContainsLogAt(receipt, indexOfLog){ 39 | return receipt[SET_OF_LOGS_INDEX][indexOfLog] 40 | } 41 | 42 | static async getStorageFromStorageProofAt(proof, position){ 43 | let fromProof = await this.proofContainsValueAt(proof, keccak(toWord(position))) 44 | if(!fromProof || fromProof.equals(toBuffer())){ 45 | return toBuffer() // null returned as 46 | }else{ 47 | return decode(fromProof) 48 | } 49 | } 50 | static async getAccountFromProofAt(proof, address){ 51 | let accountBuffer = await this.proofContainsValueAt(proof, keccak(address)) 52 | return Account.fromBuffer(accountBuffer) // null returned as Account.NULL 53 | } 54 | static async getTxFromTxProofAt(proof, indexOfTx){ 55 | let txBuffer = await this.proofContainsValueAt(proof, encode(indexOfTx)) 56 | return Transaction.fromBuffer(txBuffer) 57 | } 58 | static async getReceiptFromReceiptProofAt(proof, indexOfTx){ 59 | let receiptBuffer = await this.proofContainsValueAt(proof, encode(indexOfTx)) 60 | return Receipt.fromBuffer(receiptBuffer) 61 | } 62 | 63 | static async proofContainsValueAt(proof, path){ 64 | return new Promise((accept, reject) => { 65 | let encodedProof = [] 66 | for (let i = 0; i < proof.length; i++) { 67 | encodedProof.push(encode(proof[i])) 68 | } 69 | 70 | Tree.verifyProof(toBuffer(this.getRootFromProof(proof)) , path, encodedProof, (e,r)=>{ 71 | if(e){ 72 | return reject(e) 73 | }else{ 74 | return accept(r) 75 | } 76 | }) 77 | }) 78 | } 79 | } 80 | 81 | module.exports = Verify 82 | --------------------------------------------------------------------------------