UNPKG

insight-bitcore-api

Version:

An open-source bitcoin blockchain API. The Insight API provides you with a convenient, powerful and simple way to query and broadcast data on the bitcoin network and build your own services with it.

1,032 lines (882 loc) 1.69 MB
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"bitcore":[function(require,module,exports){ module.exports=require('tmvhGl'); },{}],"tmvhGl":[function(require,module,exports){ (function (Buffer){ /* One way to require files is this simple way: module.exports.Address = require('./Address'); However, that will load all classes in memory even if they are not used. Instead, we can set the 'get' property of each class to only require them when they are accessed, saving memory if they are not used in a given project. */ var requireWhenAccessed = function(name, file) { Object.defineProperty(module.exports, name, { get: function() { return require(file) } }); }; requireWhenAccessed('Bignum', 'bignum'); Object.defineProperty(module.exports, 'bignum', { get: function() { console.log('bignum (with a lower-case "b") is deprecated. Use bitcore.Bignum (capital "B") instead.'); return require('bignum'); } }); requireWhenAccessed('Base58', './lib/Base58'); Object.defineProperty(module.exports, 'base58', { get: function() { console.log('base58 (with a lower-case "b") is deprecated. Use bitcore.Base58 (capital "B") instead.'); return require('./lib/Base58'); } }); requireWhenAccessed('bufferput', 'bufferput'); requireWhenAccessed('buffertools', 'buffertools'); requireWhenAccessed('Buffers.monkey', './patches/Buffers.monkey'); requireWhenAccessed('config', './config'); requireWhenAccessed('const', './const'); requireWhenAccessed('Deserialize', './lib/Deserialize'); requireWhenAccessed('ECIES', './lib/ECIES'); requireWhenAccessed('log', './util/log'); requireWhenAccessed('networks', './networks'); requireWhenAccessed('SecureRandom', './lib/SecureRandom'); requireWhenAccessed('sjcl', './lib/sjcl'); requireWhenAccessed('util', './util/util'); requireWhenAccessed('EncodedData', './util/EncodedData'); requireWhenAccessed('VersionedData', './util/VersionedData'); requireWhenAccessed('BinaryParser', './util/BinaryParser'); requireWhenAccessed('Address', './lib/Address'); requireWhenAccessed('AuthMessage', './lib/AuthMessage'); requireWhenAccessed('HierarchicalKey', './lib/HierarchicalKey'); Object.defineProperty(module.exports, 'BIP32', { get: function() { console.log('BIP32 is deprecated. Use bitcore.HierarchicalKey instead.'); return require('./lib/HierarchicalKey'); } }); requireWhenAccessed('BIP39', './lib/BIP39'); requireWhenAccessed('BIP39WordlistEn', './lib/BIP39WordlistEn'); requireWhenAccessed('Point', './lib/Point'); requireWhenAccessed('Opcode', './lib/Opcode'); requireWhenAccessed('Script', './lib/Script'); requireWhenAccessed('Transaction', './lib/Transaction'); requireWhenAccessed('TransactionBuilder', './lib/TransactionBuilder'); requireWhenAccessed('Connection', './lib/Connection'); requireWhenAccessed('PayPro', './lib/PayPro'); requireWhenAccessed('Peer', './lib/Peer'); requireWhenAccessed('Block', './lib/Block'); requireWhenAccessed('ScriptInterpreter', './lib/ScriptInterpreter'); requireWhenAccessed('Bloom', './lib/Bloom'); requireWhenAccessed('Key', './lib/Key'); Object.defineProperty(module.exports, 'KeyModule', { get: function() { console.log('KeyModule is deprecated.'); return require('bindings')('KeyModule'); } }); requireWhenAccessed('SINKey', './lib/SINKey'); requireWhenAccessed('SIN', './lib/SIN'); requireWhenAccessed('PrivateKey', './lib/PrivateKey'); requireWhenAccessed('RpcClient', './lib/RpcClient'); requireWhenAccessed('Wallet', './lib/Wallet'); requireWhenAccessed('WalletKey', './lib/WalletKey'); requireWhenAccessed('PeerManager', './lib/PeerManager'); requireWhenAccessed('Message', './lib/Message'); requireWhenAccessed('Electrum', './lib/Electrum'); requireWhenAccessed('Armory', './lib/Armory'); requireWhenAccessed('NetworkMonitor', './lib/NetworkMonitor'); module.exports.Buffer = Buffer; }).call(this,require("buffer").Buffer) },{"./lib/Base58":"6VqyzY","./lib/HierarchicalKey":"x1O6JW","bignum":61,"bindings":87,"buffer":95}],"./config":[function(require,module,exports){ module.exports=require('4itQ50'); },{}],"4itQ50":[function(require,module,exports){ module.exports = { network: 'livenet', logger: 'normal' // none, normal, debug }; },{}],"./const":[function(require,module,exports){ module.exports=require('f08cvL'); },{}],"f08cvL":[function(require,module,exports){ MSG = { TX: 1, BLOCK: 2, FILTERED_BLOCK: 3, }; MSG.to_str = function(t) { switch (t) { case MSG.TX: return 'transaction'; case MSG.BLOCK: return 'block'; case MSG.FILTERED_BLOCK: return 'filtered block'; default: return 'unknown'; } } exports.MSG = MSG; },{}],"G+CcXD":[function(require,module,exports){ (function (Buffer){ // Address // ======= // // Handles a bitcoin address // // // Synopsis // -------- // ``` // var address = new Address('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa'); // if (address.isValid()) { // //... // } // // // Also an address can be created from // // public keys // var address = Address.fromPubKey(myPubkey); // // // Or from a ScriptPubKey (from a transaction output) // var address = Address.fromScriptPubKey(scriptPubKey); // // // Multisig address p2sh handling // var myPukeys = [pubkey0, pubkey1, pubkey2]; // var p2shAddress = Address.fromPubKeys(2, myPubkeys); // if (p2shAddress.isScript()) { //true // } // // // ``` 'use strict'; var coinUtil = require('../util'); var VersionedData = require('../util/VersionedData'); var EncodedData = require('../util/EncodedData'); var networks = require('../networks'); var Script = require('./Script'); var util = require('util'); function Address(version, hash) { if (hash && hash.length && (!Buffer.isBuffer(hash) || hash.length != 20)) throw new Error('Hash must be 20 bytes'); Address.super_.call(this, version, hash); } util.inherits(Address, VersionedData); EncodedData.applyEncodingsTo(Address); // create a pubKeyHash address Address.fromPubKey = function(pubKey, network) { if (!network) network = 'livenet'; if (pubKey.length !== 33 && pubKey.length !== 65) throw new Error('Invalid public key'); var version = networks[network].addressVersion; var hash = coinUtil.sha256ripe160(pubKey); return new Address(version, hash); }; // create an address from a Key object Address.fromKey = function(key, network) { return Address.fromPubKey(key.public, network); }; // create a p2sh m-of-n multisig address Address.fromPubKeys = function(mReq, pubKeys, network, opts) { if (!network) network = 'livenet'; for (var i in pubKeys) { var pubKey = pubKeys[i]; if (pubKey.length != 33 && pubKey.length != 65) throw new Error('Invalid public key'); } var script = Script.createMultisig(mReq, pubKeys, opts); return Address.fromScript(script, network); }; //create a p2sh address from redeemScript Address.fromScript = function(script, network) { if (!network) network = 'livenet'; if (typeof script === 'string') { script = new Script(new Buffer(script, 'hex')); } var version = networks[network].P2SHVersion; var buf = script.getBuffer(); var hash = coinUtil.sha256ripe160(buf); return new Address(version, hash); }; //extract an address from scriptPubKey Address.fromScriptPubKey = function(scriptPubKey, network) { if (typeof scriptPubKey === 'string') { scriptPubKey = new Script(new Buffer(scriptPubKey, 'hex')); } if (!network) network = 'livenet'; var ret = [], version; var payload = scriptPubKey.capture(); if (payload) { var txType = scriptPubKey.classify(); switch (txType) { case Script.TX_PUBKEY: payload[0] = coinUtil.sha256ripe160(payload[0]); version = networks[network].addressVersion; break; case Script.TX_PUBKEYHASH: version = networks[network].addressVersion; break; case Script.TX_MULTISIG: version = networks[network].addressVersion; for (var i in payload) payload[i] = coinUtil.sha256ripe160(payload[i]); break; case Script.TX_SCRIPTHASH: version = networks[network].P2SHVersion; break; } for (var i in payload) ret.push(new Address(version, payload[i])); } return ret; }; // validates the address Address.prototype.validate = function() { this.doAsBinary(function() { Address.super_.prototype.validate.apply(this); if (this.data.length !== 21) throw new Error('invalid data length'); }); if (typeof this.network() === 'undefined') throw new Error('invalid network'); }; // returns the network information (livenet or testnet, as described on networks.js) of the address Address.prototype.network = function() { var version = this.version(); var livenet = networks.livenet; var testnet = networks.testnet; var answer; if (version === livenet.addressVersion || version === livenet.P2SHVersion) answer = livenet; else if (version === testnet.addressVersion || version === testnet.P2SHVersion) answer = testnet; return answer; }; // returns true is the address is a pay-to-script (P2SH) address type. Address.prototype.isScript = function() { return this.isValid() && this.version() === this.network().P2SHVersion; }; // returns the scriptPubKey Address.prototype.getScriptPubKey = function() { var version = this.version(); var livenet = networks.livenet; var testnet = networks.testnet; var script; if (version === livenet.addressVersion || version === testnet.addressVersion) script = Script.createPubKeyHashOut(this.payload()); else if (version === livenet.P2SHVersion || version === testnet.P2SHVersion) script = Script.createP2SH(this.payload()); else throw new Error('invalid address - unknown version'); return script; }; Address.fromPubkeyHashScriptSig = function(scriptSig, network) { return Address.fromPubKey(scriptSig.chunks[1], network); }; //extract an address from scriptSig Address.fromScriptSig = function(scriptSig, network) { if (typeof scriptSig === 'string') { scriptSig = new Script(new Buffer(scriptSig, 'hex')); } if (!network) network = 'livenet'; var payload = scriptSig.chunks; if (scriptSig.chunks.length === 2) return Address.fromPubkeyHashScriptSig(scriptSig, network); // TODO: support other scriptSig types return null; }; Address.getScriptPubKeyFor = function(s) { return new Address(s).getScriptPubKey(); }; Address.validate = function(s) { return new Address(s).isValid(); }; module.exports = Address; }).call(this,require("buffer").Buffer) },{"../networks":"ULNIu2","../util":191,"../util/EncodedData":"eLfUFE","../util/VersionedData":"QLzNQg","./Script":"hQ0t76","buffer":95,"util":128}],"./lib/Address":[function(require,module,exports){ module.exports=require('G+CcXD'); },{}],"./lib/Armory":[function(require,module,exports){ module.exports=require('YL/05i'); },{}],"YL/05i":[function(require,module,exports){ (function (Buffer){ var Point = require('./Point'), Key = require('./Key'), sha256 = require('../util').sha256, twoSha256 = require('../util').twoSha256; /** * For now, this class can only supports derivation from public key * It doesn't support private key derivation (TODO). * * @example examples/Armory.js */ function Armory(chaincode, pubkey) { this.chaincode = new Buffer(chaincode, 'hex'); this.pubkey = new Buffer(pubkey, 'hex'); } Armory.prototype.generatePubKey = function() { var pubKey = this.pubkey; var chainCode = this.chaincode; var chainXor = twoSha256(pubKey); for (var i = 0; i < 32; i++) chainXor[i] ^= chainCode[i]; var pt = Point.fromUncompressedPubKey(pubKey); pt = Point.multiply(pt, chainXor); var new_pubkey = pt.toUncompressedPubKey(); return new_pubkey; }; Armory.prototype.next = function() { var next_pubkey = this.generatePubKey(); return new Armory(this.chaincode, next_pubkey); }; /** * PS: MPK here represents the pubkey concatenated * with the chain code. It is an unofficial standard. * * Armory will soon release an officially supported * format: * * https://github.com/etotheipi/BitcoinArmory/issues/204#issuecomment-42217801 */ Armory.fromMasterPublicKey = function(mpk) { var pubkey = mpk.substr(0, 130); var chaincode = mpk.substr(130, mpk.length); return new Armory(chaincode, pubkey); }; function decode(str) { var from = '0123456789abcdef'; var to = 'asdfghjkwertuion'; var res = ''; for (var i = 0; i < str.length; i++) res += from.charAt(to.indexOf(str.charAt(i))); return res; } Armory.decodeSeed = function(seed) { var keys = seed.trim().split('\n'); var lines = []; for (var i = 0; i < keys.length; i++) { var k = keys[i].replace(' ', ''); var raw = new Buffer(decode(k), 'hex'); var data = raw.slice(0, 16); lines.push(data); } var privKey = Buffer.concat([lines[0], lines[1]]); var chainCode = (lines.length == 4) ? Buffer.concat([lines[2], lines[3]]) : Armory.deriveChaincode(privKey); return { privKey: privKey, chainCode: chainCode }; }; // Derive chain code from root key Armory.fromSeed = function(seed) { var res = Armory.decodeSeed(seed); // generate first public key var key = new Key(); key.private = res.privKey; key.compressed = false; key.regenerateSync(); return new Armory(res.chainCode, key.public); }; Armory.deriveChaincode = function(root) { var msg = 'Derive Chaincode from Root Key'; var hash = twoSha256(root); var okey = []; var ikey = []; for (var i = 0; i < hash.length; i++) { okey.push(0x5c ^ hash[i]); ikey.push(0x36 ^ hash[i]); } okey = new Buffer(okey); ikey = new Buffer(ikey); var m = new Buffer(msg, 'utf8'); var a = sha256(Buffer.concat([ikey, m])); var b = sha256(Buffer.concat([okey, a])); return b; }; module.exports = Armory; }).call(this,require("buffer").Buffer) },{"../util":191,"./Key":"ALJ4PS","./Point":"6tXgqr","buffer":95}],"cBnJMk":[function(require,module,exports){ (function (Buffer){ 'use strict'; var Message = require('./Message'); var ECIES = require('./ECIES'); var preconditions = require('preconditions').singleton(); var Key = require('./Key'); var majorVersion = 1; var minorVersion = 0; /* Encrypted, authenticated messages to be shared between copayers */ var AuthMessage = function() {}; AuthMessage.setVersion = function(major, minor) { majorVersion = major; minorVersion = minor; }; AuthMessage.encode = function(topubkey, fromkey, payload, opts) { preconditions.checkArgument(fromkey instanceof Key, 'fromkey'); if (typeof topubkey === 'string') { topubkey = new Buffer(topubkey, 'hex'); } if (!(payload instanceof Buffer)) { payload = new Buffer(JSON.stringify(payload)); } //peers should reject messges containing bigger major version //i.e., increment to prevent communications with old clients var version1 = new Buffer([majorVersion]); //peers should not reject messages containing not-understood minorversion //i.e., increment to allow communication with old clients, but signal new clients var version2 = new Buffer([minorVersion]); if (opts && opts.nonce && Buffer.isBuffer(opts.nonce) && opts.nonce.length == 8) { var nonce = opts.nonce; } else { var nonce = new Buffer(8); nonce.fill(0); //nonce is a big endian 8 byte number } var toencrypt = Buffer.concat([version1, version2, nonce, payload]); var toencrypthexbuf = new Buffer(toencrypt.toString('hex')); //due to bug in sjcl/bitcore, must use hex string var encrypted = AuthMessage._encrypt(topubkey, toencrypthexbuf); var sig = AuthMessage._sign(fromkey, encrypted); var encoded = { pubkey: fromkey.public.toString('hex'), sig: sig.toString('hex'), encrypted: encrypted.toString('hex'), to: topubkey.toString('hex') }; return encoded; }; AuthMessage.decode = function(key, encoded, opts) { if (opts && opts.prevnonce && Buffer.isBuffer(opts.prevnonce) && opts.prevnonce.length == 8) { var prevnonce = opts.prevnonce; } else { var prevnonce = new Buffer(8); prevnonce.fill(0); //nonce is a big endian 8 byte number } try { var frompubkey = new Buffer(encoded.pubkey, 'hex'); } catch (e) { throw new Error('Error decoding public key: ' + e); } try { var sig = new Buffer(encoded.sig, 'hex'); var encrypted = new Buffer(encoded.encrypted, 'hex'); } catch (e) { throw new Error('Error decoding data: ' + e); } try { var v = AuthMessage._verify(frompubkey, sig, encrypted); } catch (e) { throw new Error('Error verifying signature: ' + e); } if (!v) { throw new Error('Invalid signature'); } try { var decryptedhexbuf = AuthMessage._decrypt(key.private, encrypted); var decrypted = new Buffer(decryptedhexbuf.toString(), 'hex'); //workaround for bug in bitcore/sjcl } catch (e) { throw new Error('Cannot decrypt data: ' + e); } try { var version1 = decrypted[0]; var version2 = decrypted[1]; var nonce = decrypted.slice(2, 10); var payload = decrypted.slice(10); } catch (e) { throw new Error('Cannot parse decrypted data: ' + e); } if (payload.length === 0) { throw new Error('No data present'); } if (version1 !== majorVersion) { throw new Error('Invalid version number'); } if (version2 !== minorVersion) { //put special version2 handling code here, if ever needed } if (!AuthMessage._noncegt(nonce, prevnonce) && prevnonce.toString('hex') !== '0000000000000000') { throw new Error('Nonce not equal to zero and not greater than the previous nonce'); } try { payload = JSON.parse(payload); } catch (e) { if (e instanceof SyntaxError) { // if we can't parse a JSON, just return what we found } else { throw e; } } var decoded = { version1: version1, version2: version2, nonce: nonce, payload: payload }; return decoded; }; //return true if nonce > prevnonce; false otherwise AuthMessage._noncegt = function(nonce, prevnonce) { var noncep1 = nonce.slice(0, 4).readUInt32BE(0); var prevnoncep1 = prevnonce.slice(0, 4).readUInt32BE(0); if (noncep1 > prevnoncep1) return true; if (noncep1 < prevnoncep1) return false; var noncep2 = nonce.slice(4, 8).readUInt32BE(0); var prevnoncep2 = prevnonce.slice(4, 8).readUInt32BE(0); if (noncep2 > prevnoncep2) return true; return false; }; AuthMessage._encrypt = function(topubkey, payload, r, iv) { var encrypted = ECIES.encrypt(topubkey, payload, r, iv); return encrypted; }; AuthMessage._decrypt = function(privkey, encrypted) { var decrypted = ECIES.decrypt(privkey, encrypted); return decrypted; }; AuthMessage._sign = function(key, payload) { var sig = Message.sign(payload, key); return sig; }; AuthMessage._verify = function(pubkey, signature, payload) { var v = Message.verifyWithPubKey(pubkey, payload, signature); return v; }; module.exports = AuthMessage; }).call(this,require("buffer").Buffer) },{"./ECIES":"0Qraa1","./Key":"ALJ4PS","./Message":"CBDCgz","buffer":95,"preconditions":163}],"./lib/AuthMessage":[function(require,module,exports){ module.exports=require('cBnJMk'); },{}],"./lib/BIP39":[function(require,module,exports){ module.exports=require('82LilS'); },{}],"82LilS":[function(require,module,exports){ (function (Buffer){ var coinUtil = require('../util'); var sjcl = require('./sjcl'); var SecureRandom = require('./SecureRandom'); var hmacSHA512 = function(key) { var hasher = new sjcl.misc.hmac(key, sjcl.hash.sha512); this.encrypt = function() { return hasher.encrypt.apply(hasher, arguments); }; }; var pbkdf2Sync_sha512 = function(password, salt, iterations, keylen) { var derivedKey = sjcl.misc.pbkdf2(password, salt, iterations, 512, hmacSHA512); return sjcl.codec.hex.fromBits(derivedKey) }; var BIP39 = function() {}; BIP39.mnemonic = function(wordlist, bits) { if (!bits) bits = 128; if (bits % 32 != 0) throw new Error("bits must be multiple of 32"); var buf = SecureRandom.getRandomBuffer(bits / 8); return BIP39.entropy2mnemonic(wordlist, buf); } BIP39.entropy2mnemonic = function(wordlist, buf) { var hash = coinUtil.sha256(buf); var bin = ""; var bits = buf.length * 8; for (var i = 0; i < buf.length; i++) { bin = bin + ("00000000" + buf[i].toString(2)).slice(-8); } var hashbits = hash[0].toString(2); hashbits = ("00000000" + hashbits).slice(-8).slice(0, bits / 32); bin = bin + hashbits; if (bin.length % 11 != 0) throw new Error("internal error - entropy not an even multiple of 11 bits - " + bin.length); var mnemonic = ""; for (var i = 0; i < bin.length / 11; i++) { if (mnemonic != "") mnemonic = mnemonic + " "; var wi = parseInt(bin.slice(i * 11, (i + 1) * 11), 2); mnemonic = mnemonic + wordlist[wi]; } return mnemonic; } BIP39.check = function(wordlist, mnemonic) { var words = mnemonic.split(' '); var bin = ""; for (var i = 0; i < words.length; i++) { var ind = wordlist.indexOf(words[i]); if (ind < 0) return false; bin = bin + ("00000000000" + ind.toString(2)).slice(-11); } if (bin.length % 11 != 0) { throw new Error("internal error - entropy not an even multiple of 11 bits - " + bin.length); } var cs = bin.length / 33; var hash_bits = bin.slice(-cs); var nonhash_bits = bin.slice(0, bin.length - cs); var buf = new Buffer(nonhash_bits.length / 8); for (var i = 0; i < nonhash_bits.length / 8; i++) { buf.writeUInt8(parseInt(bin.slice(i * 8, (i + 1) * 8), 2), i); } var hash = coinUtil.sha256(buf); var expected_hash_bits = hash[0].toString(2); expected_hash_bits = ("00000000" + expected_hash_bits).slice(-8).slice(0, cs); return expected_hash_bits == hash_bits; } BIP39.mnemonic2seed = function(mnemonic, passphrase) { if (!passphrase) passphrase = ""; var hex = pbkdf2Sync_sha512(mnemonic, "mnemonic" + passphrase, 2048, 64); var buf = new Buffer(hex, 'hex'); return buf; } module.exports = BIP39; }).call(this,require("buffer").Buffer) },{"../util":191,"./SecureRandom":"p4SiC2","./sjcl":"oLMOpG","buffer":95}],"./lib/BIP39WordlistEn":[function(require,module,exports){ module.exports=require('sp4vFZ'); },{}],"sp4vFZ":[function(require,module,exports){ var BIP39WordlistEn = ["abandon", "ability", "able", "about", "above", "absent", "absorb", "abstract", "absurd", "abuse", "access", "accident", "account", "accuse", "achieve", "acid", "acoustic", "acquire", "across", "act", "action", "actor", "actress", "actual", "adapt", "add", "addict", "address", "adjust", "admit", "adult", "advance", "advice", "aerobic", "affair", "afford", "afraid", "again", "age", "agent", "agree", "ahead", "aim", "air", "airport", "aisle", "alarm", "album", "alcohol", "alert", "alien", "all", "alley", "allow", "almost", "alone", "alpha", "already", "also", "alter", "always", "amateur", "amazing", "among", "amount", "amused", "analyst", "anchor", "ancient", "anger", "angle", "angry", "animal", "ankle", "announce", "annual", "another", "answer", "antenna", "antique", "anxiety", "any", "apart", "apology", "appear", "apple", "approve", "april", "arch", "arctic", "area", "arena", "argue", "arm", "armed", "armor", "army", "around", "arrange", "arrest", "arrive", "arrow", "art", "artefact", "artist", "artwork", "ask", "aspect", "assault", "asset", "assist", "assume", "asthma", "athlete", "atom", "attack", "attend", "attitude", "attract", "auction", "audit", "august", "aunt", "author", "auto", "autumn", "average", "avocado", "avoid", "awake", "aware", "away", "awesome", "awful", "awkward", "axis", "baby", "bachelor", "bacon", "badge", "bag", "balance", "balcony", "ball", "bamboo", "banana", "banner", "bar", "barely", "bargain", "barrel", "base", "basic", "basket", "battle", "beach", "bean", "beauty", "because", "become", "beef", "before", "begin", "behave", "behind", "believe", "below", "belt", "bench", "benefit", "best", "betray", "better", "between", "beyond", "bicycle", "bid", "bike", "bind", "biology", "bird", "birth", "bitter", "black", "blade", "blame", "blanket", "blast", "bleak", "bless", "blind", "blood", "blossom", "blouse", "blue", "blur", "blush", "board", "boat", "body", "boil", "bomb", "bone", "bonus", "book", "boost", "border", "boring", "borrow", "boss", "bottom", "bounce", "box", "boy", "bracket", "brain", "brand", "brass", "brave", "bread", "breeze", "brick", "bridge", "brief", "bright", "bring", "brisk", "broccoli", "broken", "bronze", "broom", "brother", "brown", "brush", "bubble", "buddy", "budget", "buffalo", "build", "bulb", "bulk", "bullet", "bundle", "bunker", "burden", "burger", "burst", "bus", "business", "busy", "butter", "buyer", "buzz", "cabbage", "cabin", "cable", "cactus", "cage", "cake", "call", "calm", "camera", "camp", "can", "canal", "cancel", "candy", "cannon", "canoe", "canvas", "canyon", "capable", "capital", "captain", "car", "carbon", "card", "cargo", "carpet", "carry", "cart", "case", "cash", "casino", "castle", "casual", "cat", "catalog", "catch", "category", "cattle", "caught", "cause", "caution", "cave", "ceiling", "celery", "cement", "census", "century", "cereal", "certain", "chair", "chalk", "champion", "change", "chaos", "chapter", "charge", "chase", "chat", "cheap", "check", "cheese", "chef", "cherry", "chest", "chicken", "chief", "child", "chimney", "choice", "choose", "chronic", "chuckle", "chunk", "churn", "cigar", "cinnamon", "circle", "citizen", "city", "civil", "claim", "clap", "clarify", "claw", "clay", "clean", "clerk", "clever", "click", "client", "cliff", "climb", "clinic", "clip", "clock", "clog", "close", "cloth", "cloud", "clown", "club", "clump", "cluster", "clutch", "coach", "coast", "coconut", "code", "coffee", "coil", "coin", "collect", "color", "column", "combine", "come", "comfort", "comic", "common", "company", "concert", "conduct", "confirm", "congress", "connect", "consider", "control", "convince", "cook", "cool", "copper", "copy", "coral", "core", "corn", "correct", "cost", "cotton", "couch", "country", "couple", "course", "cousin", "cover", "coyote", "crack", "cradle", "craft", "cram", "crane", "crash", "crater", "crawl", "crazy", "cream", "credit", "creek", "crew", "cricket", "crime", "crisp", "critic", "crop", "cross", "crouch", "crowd", "crucial", "cruel", "cruise", "crumble", "crunch", "crush", "cry", "crystal", "cube", "culture", "cup", "cupboard", "curious", "current", "curtain", "curve", "cushion", "custom", "cute", "cycle", "dad", "damage", "damp", "dance", "danger", "daring", "dash", "daughter", "dawn", "day", "deal", "debate", "debris", "decade", "december", "decide", "decline", "decorate", "decrease", "deer", "defense", "define", "defy", "degree", "delay", "deliver", "demand", "demise", "denial", "dentist", "deny", "depart", "depend", "deposit", "depth", "deputy", "derive", "describe", "desert", "design", "desk", "despair", "destroy", "detail", "detect", "develop", "device", "devote", "diagram", "dial", "diamond", "diary", "dice", "diesel", "diet", "differ", "digital", "dignity", "dilemma", "dinner", "dinosaur", "direct", "dirt", "disagree", "discover", "disease", "dish", "dismiss", "disorder", "display", "distance", "divert", "divide", "divorce", "dizzy", "doctor", "document", "dog", "doll", "dolphin", "domain", "donate", "donkey", "donor", "door", "dose", "double", "dove", "draft", "dragon", "drama", "drastic", "draw", "dream", "dress", "drift", "drill", "drink", "drip", "drive", "drop", "drum", "dry", "duck", "dumb", "dune", "during", "dust", "dutch", "duty", "dwarf", "dynamic", "eager", "eagle", "early", "earn", "earth", "easily", "east", "easy", "echo", "ecology", "economy", "edge", "edit", "educate", "effort", "egg", "eight", "either", "elbow", "elder", "electric", "elegant", "element", "elephant", "elevator", "elite", "else", "embark", "embody", "embrace", "emerge", "emotion", "employ", "empower", "empty", "enable", "enact", "end", "endless", "endorse", "enemy", "energy", "enforce", "engage", "engine", "enhance", "enjoy", "enlist", "enough", "enrich", "enroll", "ensure", "enter", "entire", "entry", "envelope", "episode", "equal", "equip", "era", "erase", "erode", "erosion", "error", "erupt", "escape", "essay", "essence", "estate", "eternal", "ethics", "evidence", "evil", "evoke", "evolve", "exact", "example", "excess", "exchange", "excite", "exclude", "excuse", "execute", "exercise", "exhaust", "exhibit", "exile", "exist", "exit", "exotic", "expand", "expect", "expire", "explain", "expose", "express", "extend", "extra", "eye", "eyebrow", "fabric", "face", "faculty", "fade", "faint", "faith", "fall", "false", "fame", "family", "famous", "fan", "fancy", "fantasy", "farm", "fashion", "fat", "fatal", "father", "fatigue", "fault", "favorite", "feature", "february", "federal", "fee", "feed", "feel", "female", "fence", "festival", "fetch", "fever", "few", "fiber", "fiction", "field", "figure", "file", "film", "filter", "final", "find", "fine", "finger", "finish", "fire", "firm", "first", "fiscal", "fish", "fit", "fitness", "fix", "flag", "flame", "flash", "flat", "flavor", "flee", "flight", "flip", "float", "flock", "floor", "flower", "fluid", "flush", "fly", "foam", "focus", "fog", "foil", "fold", "follow", "food", "foot", "force", "forest", "forget", "fork", "fortune", "forum", "forward", "fossil", "foster", "found", "fox", "fragile", "frame", "frequent", "fresh", "friend", "fringe", "frog", "front", "frost", "frown", "frozen", "fruit", "fuel", "fun", "funny", "furnace", "fury", "future", "gadget", "gain", "galaxy", "gallery", "game", "gap", "garage", "garbage", "garden", "garlic", "garment", "gas", "gasp", "gate", "gather", "gauge", "gaze", "general", "genius", "genre", "gentle", "genuine", "gesture", "ghost", "giant", "gift", "giggle", "ginger", "giraffe", "girl", "give", "glad", "glance", "glare", "glass", "glide", "glimpse", "globe", "gloom", "glory", "glove", "glow", "glue", "goat", "goddess", "gold", "good", "goose", "gorilla", "gospel", "gossip", "govern", "gown", "grab", "grace", "grain", "grant", "grape", "grass", "gravity", "great", "green", "grid", "grief", "grit", "grocery", "group", "grow", "grunt", "guard", "guess", "guide", "guilt", "guitar", "gun", "gym", "habit", "hair", "half", "hammer", "hamster", "hand", "happy", "harbor", "hard", "harsh", "harvest", "hat", "have", "hawk", "hazard", "head", "health", "heart", "heavy", "hedgehog", "height", "hello", "helmet", "help", "hen", "hero", "hidden", "high", "hill", "hint", "hip", "hire", "history", "hobby", "hockey", "hold", "hole", "holiday", "hollow", "home", "honey", "hood", "hope", "horn", "horror", "horse", "hospital", "host", "hotel", "hour", "hover", "hub", "huge", "human", "humble", "humor", "hundred", "hungry", "hunt", "hurdle", "hurry", "hurt", "husband", "hybrid", "ice", "icon", "idea", "identify", "idle", "ignore", "ill", "illegal", "illness", "image", "imitate", "immense", "immune", "impact", "impose", "improve", "impulse", "inch", "include", "income", "increase", "index", "indicate", "indoor", "industry", "infant", "inflict", "inform", "inhale", "inherit", "initial", "inject", "injury", "inmate", "inner", "innocent", "input", "inquiry", "insane", "insect", "inside", "inspire", "install", "intact", "interest", "into", "invest", "invite", "involve", "iron", "island", "isolate", "issue", "item", "ivory", "jacket", "jaguar", "jar", "jazz", "jealous", "jeans", "jelly", "jewel", "job", "join", "joke", "journey", "joy", "judge", "juice", "jump", "jungle", "junior", "junk", "just", "kangaroo", "keen", "keep", "ketchup", "key", "kick", "kid", "kidney", "kind", "kingdom", "kiss", "kit", "kitchen", "kite", "kitten", "kiwi", "knee", "knife", "knock", "know", "lab", "label", "labor", "ladder", "lady", "lake", "lamp", "language", "laptop", "large", "later", "latin", "laugh", "laundry", "lava", "law", "lawn", "lawsuit", "layer", "lazy", "leader", "leaf", "learn", "leave", "lecture", "left", "leg", "legal", "legend", "leisure", "lemon", "lend", "length", "lens", "leopard", "lesson", "letter", "level", "liar", "liberty", "library", "license", "life", "lift", "light", "like", "limb", "limit", "link", "lion", "liquid", "list", "little", "live", "lizard", "load", "loan", "lobster", "local", "lock", "logic", "lonely", "long", "loop", "lottery", "loud", "lounge", "love", "loyal", "lucky", "luggage", "lumber", "lunar", "lunch", "luxury", "lyrics", "machine", "mad", "magic", "magnet", "maid", "mail", "main", "major", "make", "mammal", "man", "manage", "mandate", "mango", "mansion", "manual", "maple", "marble", "march", "margin", "marine", "market", "marriage", "mask", "mass", "master", "match", "material", "math", "matrix", "matter", "maximum", "maze", "meadow", "mean", "measure", "meat", "mechanic", "medal", "media", "melody", "melt", "member", "memory", "mention", "menu", "mercy", "merge", "merit", "merry", "mesh", "message", "metal", "method", "middle", "midnight", "milk", "million", "mimic", "mind", "minimum", "minor", "minute", "miracle", "mirror", "misery", "miss", "mistake", "mix", "mixed", "mixture", "mobile", "model", "modify", "mom", "moment", "monitor", "monkey", "monster", "month", "moon", "moral", "more", "morning", "mosquito", "mother", "motion", "motor", "mountain", "mouse", "move", "movie", "much", "muffin", "mule", "multiply", "muscle", "museum", "mushroom", "music", "must", "mutual", "myself", "mystery", "myth", "naive", "name", "napkin", "narrow", "nasty", "nation", "nature", "near", "neck", "need", "negative", "neglect", "neither", "nephew", "nerve", "nest", "net", "network", "neutral", "never", "news", "next", "nice", "night", "noble", "noise", "nominee", "noodle", "normal", "north", "nose", "notable", "note", "nothing", "notice", "novel", "now", "nuclear", "number", "nurse", "nut", "oak", "obey", "object", "oblige", "obscure", "observe", "obtain", "obvious", "occur", "ocean", "october", "odor", "off", "offer", "office", "often", "oil", "okay", "old", "olive", "olympic", "omit", "once", "one", "onion", "online", "only", "open", "opera", "opinion", "oppose", "option", "orange", "orbit", "orchard", "order", "ordinary", "organ", "orient", "original", "orphan", "ostrich", "other", "outdoor", "outer", "output", "outside", "oval", "oven", "over", "own", "owner", "oxygen", "oyster", "ozone", "pact", "paddle", "page", "pair", "palace", "palm", "panda", "panel", "panic", "panther", "paper", "parade", "parent", "park", "parrot", "party", "pass", "patch", "path", "patient", "patrol", "pattern", "pause", "pave", "payment", "peace", "peanut", "pear", "peasant", "pelican", "pen", "penalty", "pencil", "people", "pepper", "perfect", "permit", "person", "pet", "phone", "photo", "phrase", "physical", "piano", "picnic", "picture", "piece", "pig", "pigeon", "pill", "pilot", "pink", "pioneer", "pipe", "pistol", "pitch", "pizza", "place", "planet", "plastic", "plate", "play", "please", "pledge", "pluck", "plug", "plunge", "poem", "poet", "point", "polar", "pole", "police", "pond", "pony", "pool", "popular", "portion", "position", "possible", "post", "potato", "pottery", "poverty", "powder", "power", "practice", "praise", "predict", "prefer", "prepare", "present", "pretty", "prevent", "price", "pride", "primary", "print", "priority", "prison", "private", "prize", "problem", "process", "produce", "profit", "program", "project", "promote", "proof", "property", "prosper", "protect", "proud", "provide", "public", "pudding", "pull", "pulp", "pulse", "pumpkin", "punch", "pupil", "puppy", "purchase", "purity", "purpose", "purse", "push", "put", "puzzle", "pyramid", "quality", "quantum", "quarter", "question", "quick", "quit", "quiz", "quote", "rabbit", "raccoon", "race", "rack", "radar", "radio", "rail", "rain", "raise", "rally", "ramp", "ranch", "random", "range", "rapid", "rare", "rate", "rather", "raven", "raw", "razor", "ready", "real", "reason", "rebel", "rebuild", "recall", "receive", "recipe", "record", "recycle", "reduce", "reflect", "reform", "refuse", "region", "regret", "regular", "reject", "relax", "release", "relief", "rely", "remain", "remember", "remind", "remove", "render", "renew", "rent", "reopen", "repair", "repeat", "replace", "report", "require", "rescue", "resemble", "resist", "resource", "response", "result", "retire", "retreat", "return", "reunion", "reveal", "review", "reward", "rhythm", "rib", "ribbon", "rice", "rich", "ride", "ridge", "rifle", "right", "rigid", "ring", "riot", "ripple", "risk", "ritual", "rival", "river", "road", "roast", "robot", "robust", "rocket", "romance", "roof", "rookie", "room", "rose", "rotate", "rough", "round", "route", "royal", "rubber", "rude", "rug", "rule", "run", "runway", "rural", "sad", "saddle", "sadness", "safe", "sail", "salad", "salmon", "salon", "salt", "salute", "same", "sample", "sand", "satisfy", "satoshi", "sauce", "sausage", "save", "say", "scale", "scan", "scare", "scatter", "scene", "scheme", "school", "science", "scissors", "scorpion", "scout", "scrap", "screen", "script", "scrub", "sea", "search", "season", "seat", "second", "secret", "section", "security", "seed", "seek", "segment", "select", "sell", "seminar", "senior", "sense", "sentence", "series", "service", "session", "settle", "setup", "seven", "shadow", "shaft", "shallow", "share", "shed", "shell", "sheriff", "shield", "shift", "shine", "ship", "shiver", "shock", "shoe", "shoot", "shop", "short", "shoulder", "shove", "shrimp", "shrug", "shuffle", "shy", "sibling", "sick", "side", "siege", "sight", "sign", "silent", "silk", "silly", "silver", "similar", "simple", "since", "sing", "siren", "sister", "situate", "six", "size", "skate", "sketch", "ski", "skill", "skin", "skirt", "skull", "slab", "slam", "sleep", "slender", "slice", "slide", "slight", "slim", "slogan", "slot", "slow", "slush", "small", "smart", "smile", "smoke", "smooth", "snack", "snake", "snap", "sniff", "snow", "soap", "soccer", "social", "sock", "soda", "soft", "solar", "soldier", "solid", "solution", "solve", "someone", "song", "soon", "sorry", "sort", "soul", "sound", "soup", "source", "south", "space", "spare", "spatial", "spawn", "speak", "special", "speed", "spell", "spend", "sphere", "spice", "spider", "spike", "spin", "spirit", "split", "spoil", "sponsor", "spoon", "sport", "spot", "spray", "spread", "spring", "spy", "square", "squeeze", "squirrel", "stable", "stadium", "staff", "stage", "stairs", "stamp", "stand", "start", "state", "stay", "steak", "steel", "stem", "step", "stereo", "stick", "still", "sting", "stock", "stomach", "stone", "stool", "story", "stove", "strategy", "street", "strike", "strong", "struggle", "student", "stuff", "stumble", "style", "subject", "submit", "subway", "success", "such", "sudden", "suffer", "sugar", "suggest", "suit", "summer", "sun", "sunny", "sunset", "super", "supply", "supreme", "sure", "surface", "surge", "surprise", "surround", "survey", "suspect", "sustain", "swallow", "swamp", "swap", "swarm", "swear", "sweet", "swift", "swim", "swing", "switch", "sword", "symbol", "symptom", "syrup", "system", "table", "tackle", "tag", "tail", "talent", "talk", "tank", "tape", "target", "task", "taste", "tattoo", "taxi", "teach", "team", "tell", "ten", "tenant", "tennis", "tent", "term", "test", "text", "thank", "that", "theme", "then", "theory", "there", "they", "thing", "this", "thought", "three", "thrive", "throw", "thumb", "thunder", "ticket", "tide", "tiger", "tilt", "timber", "time", "tiny", "tip", "tired", "tissue", "title", "toast", "tobacco", "today", "toddler", "toe", "together", "toilet", "token", "tomato", "tomorrow", "tone", "tongue", "tonight", "tool", "tooth", "top", "topic", "topple", "torch", "tornado", "tortoise", "toss", "total", "tourist", "toward", "tower", "town", "toy", "track", "trade", "traffic", "tragic", "train", "transfer", "trap", "trash", "travel", "tray", "treat", "tree", "trend", "trial", "tribe", "trick", "trigger", "trim", "trip", "trophy", "trouble", "truck", "true", "truly", "trumpet", "trust", "truth", "try", "tube", "tuition", "tumble", "tuna", "tunnel", "turkey", "turn", "turtle", "twelve", "twenty", "twice", "twin", "twist", "two", "type", "typical", "ugly", "umbrella", "unable", "unaware", "uncle", "uncover", "under", "undo", "unfair", "unfold", "unhappy", "uniform", "unique", "unit", "universe", "unknown", "unlock", "until", "unusual", "unveil", "update", "upgrade", "uphold", "upon", "upper", "upset", "urban", "urge", "usage", "use", "used", "useful", "useless", "usual", "utility", "vacant", "vacuum", "vague", "valid", "valley", "valve", "van", "vanish", "vapor", "various", "vast", "vault", "vehicle", "velvet", "vendor", "venture", "venue", "verb", "verify", "version", "very", "vessel", "veteran", "viable", "vibrant", "vicious", "victory", "video", "view", "village", "vintage", "violin", "virtual", "virus", "visa", "visit", "visual", "vital", "vivid", "vocal", "voice", "void", "volcano", "volume", "vote", "voyage", "wage", "wagon", "wait", "walk", "wall", "walnut", "want", "warfare", "warm", "warrior", "wash", "wasp", "waste", "water", "wave", "way", "wealth", "weapon", "wear", "weasel", "weather", "web", "wedding", "weekend", "weird", "welcome", "west", "wet", "whale", "what", "wheat", "wheel", "when", "where", "whip", "whisper", "wide", "width", "wife", "wild", "will", "win", "window", "wine", "wing", "wink", "winner", "winter", "wire", "wisdom", "wise", "wish", "witness", "wolf", "woman", "wonder", "wood", "wool", "word", "work", "world", "worry", "worth", "wrap", "wreck", "wrestle", "wrist", "write", "wrong", "yard", "year", "yellow", "you", "young", "youth", "zebra", "zero", "zone", "zoo"]; module.exports = BIP39WordlistEn; },{}],"./lib/Base58":[function(require,module,exports){ module.exports=require('6VqyzY'); },{}],"6VqyzY":[function(require,module,exports){ (function (Buffer){ var crypto = require('crypto'); var bignum = require('bignum'); var globalBuffer = new Buffer(1024); var zerobuf = new Buffer(0); var ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; var ALPHABET_ZERO = ALPHABET[0]; var ALPHABET_BUF = new Buffer(ALPHABET, 'ascii'); var ALPHABET_INV = {}; for (var i = 0; i < ALPHABET.length; i++) { ALPHABET_INV[ALPHABET[i]] = i; }; // Vanilla Base58 Encoding var base58 = { encode: function(buf) { var str; var x = bignum.fromBuffer(buf); var r; if (buf.length < 512) { str = globalBuffer; } else { str = new Buffer(buf.length << 1); } var i = str.length - 1; while (x.gt(0)) { r = x.mod(58); x = x.div(58); str[i] = ALPHABET_BUF[r.toNumber()]; i--; } // deal with leading zeros var j = 0; while (buf[j] == 0) { str[i] = ALPHABET_BUF[0]; j++; i--; } return str.slice(i + 1, str.length).toString('ascii'); }, decode: function(str) { if (str.length == 0) return zerobuf; var answer = bignum(0); for (var i = 0; i < str.length; i++) { answer = answer.mul(58); answer = answer.add(ALPHABET_INV[str[i]]); }; var i = 0; while (i < str.length && str[i] == ALPHABET_ZERO) { i++; } if (i > 0) { var zb = new Buffer(i); zb.fill(0); if (i == str.length) return zb; answer = answer.toBuffer(); return Buffer.concat([zb, answer], i + answer.length); } else { return answer.toBuffer(); } }, }; // Base58Check Encoding function sha256(data) { return new Buffer(crypto.createHash('sha256').update(data).digest('binary'), 'binary'); }; function doubleSHA256(data) { return sha256(sha256(data)); }; var base58Check = { encode: function(buf) { var checkedBuf = new Buffer(buf.length + 4); var hash = doubleSHA256(buf); buf.copy(checkedBuf); hash.copy(checkedBuf, buf.length); return base58.encode(checkedBuf); }, decode: function(s) { var buf = base58.decode(s); if (buf.length < 4) { throw new Error("invalid input: too short"); } var data = buf.slice(0, -4); var csum = buf.slice(-4); var hash = doubleSHA256(data); var hash4 = hash.slice(0, 4); if (csum.toString('hex') !== hash4.toString('hex')) { throw new Error("checksum mismatch"); } return data; }, }; // if you frequently do base58 encodings with data larger // than 512 bytes, you can use this method to expand the // size of the reusable buffer exports.setBuffer = function(buf) { globalBuffer = buf; }; exports.base58 = base58; exports.base58Check = base58Check; exports.encode = base58.encode; exports.decode = base58.decode; }).call(this,require("buffer").Buffer) },{"bignum":61,"buffer":95,"crypto":99}],"./lib/Block":[function(require,module,exports){ module.exports=require('pJEQEB'); },{}],"pJEQEB":[function(require,module,exports){ (function (Buffer){ var util = require('../util'); var Script = require('./Script'); var Bignum = require('bignum'); var Binary = require('binary'); var Step = require('step'); var buffertools = require('buffertools'); var Transaction = require('./Transaction'); var TransactionIn = Transaction.In; var TransactionOut = Transaction.Out; var COINBASE_OP = Transaction.COINBASE_OP; var VerificationError = require('../util/error').VerificationError; var BlockRules = { maxTimeOffset: 2 * 60 * 60, // How far block timestamps can be into the future //largestHash: (new Bignum(2)).pow(256) //largestHash: new Bignum('115792089237316195423570985008687907853269984665640564039457584007913129639936') // = 2^256 largestHash: new Bignum('10000000000000000000000000000000000000000000000000000000000000000', 16) }; function Block(data) { if ("object" !== typeof data) { data = {}; } this.hash = data.hash || null; this.prev_hash = data.prev_hash || util.NULL_HASH; this.merkle_root = data.merkle_root || util.NULL_HASH; this.timestamp = data.timestamp || 0; this.bits = data.bits || 0; this.nonce = data.nonce || 0; this.version = data.version || 0; this.height = data.height || 0; this.size = data.size || 0; this.active = data.active || false; this.chainWork = data.chainWork || util.EMPTY_BUFFER; this.txs = data.txs || []; } Block.prototype.getHeader = function getHeader() { var buf = new Buffer(80); var ofs = 0; buf.writeUInt32LE(this.version, ofs); ofs += 4; this.prev_hash.copy(buf, ofs); ofs += 32; this.merkle_root.copy(buf, ofs); ofs += 32; buf.writeUInt32LE(this.timestamp, ofs); ofs += 4; buf.writeUInt32LE(this.bits, ofs); ofs += 4; buf.writeUInt32LE(this.nonce, ofs); ofs += 4; return buf; }; Block.prototype.parse = function parse(parser, headerOnly) { this.version = parser.word32le(); this.prev_hash = parser.buffer(32); this.merkle_root = parser.buffer(32); this.timestamp = parser.word32le(); this.bits = parser.word32le(); this.nonce = parser.word32le(); this.txs = []; this.size = 0; if (headerOnly) return; var txCount = parser.varInt(); for (var i = 0; i < txCount; i++) { var tx = new Transaction(); tx.parse(parser); this.txs.push(tx); } }; Block.prototype.calcHash = function calcHash() { var header = this.getHeader(); return util.twoSha256(header); }; Block.prototype.checkHash = function checkHash() { if (!this.hash || !this.hash.length) return false; return buffertools.compare(this.calcHash(), this.hash) == 0; }; Block.prototype.getHash = function getHash() { if (!this.hash || !this.hash.length) this.hash = this.calcHash(); return this.hash; }; Block.prototype.checkProofOfWork = function checkProofOfWork() { var target = util.decodeDiffBits(this.bits); // TODO: Create a compare method in node-buffertools that uses the correct // endian so we don't have to reverse both buffers before comparing. var reverseHash = buffertools.reverse(this.hash); if (buffertools.compare(reverseHash, target) > 0) { throw new VerificationError('Difficulty target not met'); } return true; }; /** * Returns the amount of work that went into this block. * * Work is defined as the average number of tries required to meet this * block's difficulty target. For example a target that is greater than 5% * of all possible hashes would mean that 20 "work" is required to meet it. */ Block.prototype.getWork = function getWork() { var target = util.decodeDiffBits(this.bits, true); return BlockRules.largestHash.div(target.add(1)); }; Block.prototype.checkTimestamp = function checkTimestamp() { var currentTime = new Date().getTime() / 1000; if (this.timestamp > currentTime + BlockRules.maxTimeOffset) { throw new VerificationError('Timestamp too far into the future'); } return true; }; Block.prototype.checkTransactions = function checkTransactions(txs) { if (!Array.isArray(txs) || txs.length <= 0) { throw new VerificationError('No transactions'); } if (!txs[0].isCoinBase()) { throw new VerificationError('First tx must be coinbase'); } for (var i = 1; i < txs.length; i++) { if (txs[i].isCoinBase()) { throw new VerificationError('Tx index ' + i + ' must not be coinbase'); } } return true; }; /** * Build merkle tree. * * Ported from Java. Original code: BitcoinJ by Mike Hearn * Copyright (c) 2011 Google Inc. */ Block.prototype.getMerkleTree = function getMerkleTree(txs) { // The merkle hash is based on a tree of hashes calculated from the transactions: // // merkleHash // /\ // / \ // A B // / \ / \ // tx1 tx2 tx3 tx4 // // Basically transactions are hashed, then the hashes of the transactions