From ca67786a77d5431d91c1c5369e15bda459bc25de Mon Sep 17 00:00:00 2001 From: "Ryan X. Charles" Date: Mon, 23 Jun 2014 10:57:02 -0700 Subject: [PATCH] ran js-beautify on all bitcore source js-beautify -s 2 -r *.js ...did not run on bundles, only on source. --- bitcore.js | 47 +- browser/build.js | 2 +- const.js | 20 +- examples/Armory.js | 1 - examples/ConnectionTor.js | 11 +- examples/CreateAndSignTx-Multisig.js | 47 +- examples/CreateAndSignTx-PayToPubkeyHash.js | 59 +- examples/CreateAndSignTx-PayToScriptHash.js | 63 +- examples/CreateKey.js | 24 +- examples/CreateScript.js | 40 +- examples/ECIES.js | 8 +- examples/HierarchicalKey.js | 2 +- examples/PeerDiscovery.js | 6 +- examples/SendTx.js | 2 +- examples/SimpleP2Pmonitor.js | 28 +- examples/VanityAddress.js | 6 +- lib/Address.js | 17 +- lib/Armory.js | 28 +- lib/BIP39.js | 15 +- lib/BIP39WordlistEn.js | 2 +- lib/Base58.js | 27 +- lib/Block.js | 169 +- lib/Bloom.js | 25 +- lib/Connection.js | 476 ++-- lib/Curve.js | 15 +- lib/Deserialize.js | 5 +- lib/Electrum.js | 26 +- lib/HierarchicalKey.js | 106 +- lib/Message.js | 3 +- lib/Opcode.js | 238 +- lib/Peer.js | 18 +- lib/PeerManager.js | 81 +- lib/Point.js | 16 +- lib/PrivateKey.js | 43 +- lib/RpcClient.js | 72 +- lib/SIN.js | 24 +- lib/SINKey.js | 6 +- lib/Script.js | 60 +- lib/ScriptInterpreter.js | 2 +- lib/Sign.js | 127 +- lib/Transaction.js | 16 +- lib/TransactionBuilder.js | 397 +-- lib/Wallet.js | 39 +- lib/WalletKey.js | 2 +- lib/browser/Bignum.js | 2670 +++++++++---------- lib/browser/ECIES.js | 22 +- lib/browser/Key.js | 26 +- lib/browser/Point.js | 58 +- lib/common/ECIES.js | 15 +- lib/common/SecureRandom.js | 3 +- networks.js | 4 +- util/BinaryParser.js | 73 +- util/EncFile.js | 14 +- util/EncodedData.js | 25 +- util/VersionedData.js | 20 +- util/error.js | 9 +- util/index.js | 2 +- util/log.js | 23 +- util/time.js | 5 +- util/util.js | 8 +- 60 files changed, 2756 insertions(+), 2642 deletions(-) diff --git a/bitcore.js b/bitcore.js index 282a9c8..d0c12ac 100644 --- a/bitcore.js +++ b/bitcore.js @@ -7,19 +7,27 @@ 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)}}); + 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'); -}}); +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'); -}}); +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'); @@ -38,10 +46,12 @@ requireWhenAccessed('VersionedData', './util/VersionedData'); requireWhenAccessed('BinaryParser', './util/BinaryParser'); requireWhenAccessed('Address', './lib/Address'); requireWhenAccessed('HierarchicalKey', './lib/HierarchicalKey'); -Object.defineProperty(module.exports, 'BIP32', {get: function() { - console.log('BIP32 is deprecated. Use bitcore.HierarchicalKey instead.'); - return require('./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'); @@ -55,10 +65,12 @@ 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'); -}}); +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'); @@ -70,4 +82,3 @@ requireWhenAccessed('Message', './lib/Message'); requireWhenAccessed('Electrum', './lib/Electrum'); requireWhenAccessed('Armory', './lib/Armory'); module.exports.Buffer = Buffer; - diff --git a/browser/build.js b/browser/build.js index 92268f6..1d21e43 100644 --- a/browser/build.js +++ b/browser/build.js @@ -11,7 +11,7 @@ var puts = function(error, stdout, stderr) { //sys.puts(stderr); }; -var pack = function (params) { +var pack = function(params) { var file = require.resolve('soop'); var dir = file.substr(0, file.length - String('soop.js').length); var preludePath = dir + 'example/custom_prelude.js'; diff --git a/const.js b/const.js index 7e4d7ed..4e46549 100644 --- a/const.js +++ b/const.js @@ -1,18 +1,20 @@ - MSG = { - TX: 1, - BLOCK: 2, + 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'; + 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; - diff --git a/examples/Armory.js b/examples/Armory.js index 713cd8b..c077c9e 100644 --- a/examples/Armory.js +++ b/examples/Armory.js @@ -63,4 +63,3 @@ for (var i = 0; i < 5; i++) { console.log(Address.fromPubKey(b.pubkey).as('base58')); b = b.next(); } - diff --git a/examples/ConnectionTor.js b/examples/ConnectionTor.js index c96040f..a622178 100644 --- a/examples/ConnectionTor.js +++ b/examples/ConnectionTor.js @@ -1,6 +1,6 @@ -var Peer = require('../lib/Peer'); +var Peer = require('../lib/Peer'); var Connection = require('../lib/Connection'); -var dns = require('dns'); +var dns = require('dns'); // get a peer from dns seed dns.resolve('dnsseed.bluematt.me', function(err, seeds) { @@ -9,12 +9,15 @@ dns.resolve('dnsseed.bluematt.me', function(err, seeds) { //Custom peer: //var peer = new Peer('180.153.139.246', '8888'); - + // create a connection without an existing socket // but specify a socks5 proxy to create a socket // that's bound to that proxy in it's place var connection = new Connection(null, peer, { - proxy: { host: '127.0.0.1', port: 9050 } + proxy: { + host: '127.0.0.1', + port: 9050 + } }); connection.open(); diff --git a/examples/CreateAndSignTx-Multisig.js b/examples/CreateAndSignTx-Multisig.js index 4fdbfbe..1f9a739 100644 --- a/examples/CreateAndSignTx-Multisig.js +++ b/examples/CreateAndSignTx-Multisig.js @@ -1,10 +1,11 @@ - var run = function() { - bitcore = typeof (bitcore) === 'undefined' ? require('../bitcore') : bitcore; + bitcore = typeof(bitcore) === 'undefined' ? require('../bitcore') : bitcore; var networks = require('../networks'); var WalletKey = bitcore.WalletKey; var Builder = bitcore.TransactionBuilder; - var opts = {network: networks.testnet}; + var opts = { + network: networks.testnet + }; console.log('## Network: ' + opts.network.name); @@ -13,8 +14,7 @@ var run = function() { input.priv = "cS62Ej4SobZnpFQYN1PEEBr2KWf5sgRYYnELtumcG6WVCfxno39V"; // Complete with the corresponding UTXO you want to use - var utxos = [ - { + var utxos = [{ address: input.addr, txid: "39c71ebda371f75f4b854a720eaf9898b237facf3c2b101b58cd4383a44a6adc", vout: 1, @@ -22,10 +22,9 @@ var run = function() { scriptPubKey: "76a914e867aad8bd361f57c50adc37a0c018692b5b0c9a88ac", amount: 0.4296, confirmations: 2 - } - ]; + }]; - var privs = [ + var privs = [ "cP6JBHuQf7yqeqtdKRd22ibF3VehDv7G6BdzxSNABgrv3jFJUGoN", "cQfRwF7XLSM5xGUpF8PZvob2MZyULvZPA2j5cat2RKDJrja7FtCZ", "cUkYub4jtFVYymHh38yMMW36nJB4pXG5Pzd5QjResq79kAndkJcg", @@ -36,18 +35,24 @@ var run = function() { var pubkeys = [] privs.forEach(function(p) { var wk = new WalletKey(opts); - wk.fromObj({priv: p}); + wk.fromObj({ + priv: p + }); pubkeys.push(bitcore.buffertools.toHex(wk.privKey.public)); }); - var outs = [{nreq:3, pubkeys:pubkeys, amount:0.05}]; + var outs = [{ + nreq: 3, + pubkeys: pubkeys, + amount: 0.05 + }]; var tx = new Builder(opts) .setUnspent(utxos) .setOutputs(outs) .sign([input.priv]) .build(); - var txHex = tx.serialize().toString('hex'); + var txHex = tx.serialize().toString('hex'); console.log('1) SEND TO MULSISIG TX: ', txHex); console.log('[this example originally generated TXID: e4bc22d8c519d3cf848d710619f8480be56176a4a6548dfbe865ab3886b578b5 on testnet]\n\n\thttp://test.bitcore.io/tx/e4bc22d8c519d3cf848d710619f8480be56176a4a6548dfbe865ab3886b578b5\n\n'); @@ -59,31 +64,32 @@ var run = function() { * * REDDEEM TX */ - var utxos2 = [ - { + var utxos2 = [{ address: input.addr, txid: "e4bc22d8c519d3cf848d710619f8480be56176a4a6548dfbe865ab3886b578b5", vout: 0, ts: 1396288753, - scriptPubKey: scriptPubKey, + scriptPubKey: scriptPubKey, amount: 0.05, confirmations: 2 - } - ]; + }]; - outs = [{address:input.addr, amount:0.04}]; + outs = [{ + address: input.addr, + amount: 0.04 + }]; var b = new Builder(opts) .setUnspent(utxos2) .setOutputs(outs) .sign(privs); - tx= b.build(); + tx = b.build(); - var txHex = tx.serialize().toString('hex'); + var txHex = tx.serialize().toString('hex'); console.log('2) REDEEM SCRIPT: ', txHex); -console.log('=> Is signed status:', b.isFullySigned(), tx.countInputMissingSignatures(0) ); + console.log('=> Is signed status:', b.isFullySigned(), tx.countInputMissingSignatures(0)); console.log('[this example originally generated TXID: 1eb388977b2de99562eb0fbcc661a100eaffed99c53bfcfebe5a087002039b83 on testnet]\n\n\thttp://test.bitcore.io/tx/1eb388977b2de99562eb0fbcc661a100eaffed99c53bfcfebe5a087002039b83'); @@ -100,4 +106,3 @@ if (typeof module !== 'undefined') { } //// - diff --git a/examples/CreateAndSignTx-PayToPubkeyHash.js b/examples/CreateAndSignTx-PayToPubkeyHash.js index 4d703ce..c719cd6 100644 --- a/examples/CreateAndSignTx-PayToPubkeyHash.js +++ b/examples/CreateAndSignTx-PayToPubkeyHash.js @@ -1,11 +1,8 @@ - - - var run = function() { - bitcore = typeof (bitcore) === 'undefined' ? require('../bitcore') : bitcore; + bitcore = typeof(bitcore) === 'undefined' ? require('../bitcore') : bitcore; - var priv = 'cTgGUrcro89yUtKeG6gHBAS14r3qp25KwTTxG9d4kEzcFxecuZDm'; - var amt = '0.005'; + var priv = 'cTgGUrcro89yUtKeG6gHBAS14r3qp25KwTTxG9d4kEzcFxecuZDm'; + var amt = '0.005'; var toAddress = 'myuAQcCc1REUgXGsCTiYhZvPPc3XxZ36G1'; var changeAddressString = 'moDz3jEo9q7CxjBDjmb13sL4SKkgo2AACE'; @@ -19,13 +16,20 @@ var run = function() { confirmations: 2 }]; - console.log('TX Data: BTC:' + amt + ' => '+ toAddress + ', change To:' + changeAddressString ) ; + console.log('TX Data: BTC:' + amt + ' => ' + toAddress + ', change To:' + changeAddressString); console.log('Unspends Outputs:', utxos); - var outs = [{address:toAddress, amount:amt}]; + var outs = [{ + address: toAddress, + amount: amt + }]; var keys = [priv]; - var opts = {remainderOut: {address: changeAddressString}}; + var opts = { + remainderOut: { + address: changeAddressString + } + }; var Builder = bitcore.TransactionBuilder; var tx = new Builder(opts) @@ -34,25 +38,25 @@ var run = function() { .sign(keys) .build(); - /* create and signing can be done in multiple steps using: - * - * var builder = new bitcore.TransactionBuilder(opts) - * .setUnspent(utxos) - * .setOutputs(outs); - * - * builder.sign(key1); - * builder.sign(key2); - * ... - * if (builder.isFullySigned()){ - * var tx = builder.build(); - * } - * - * The selected Unspent Outputs for the transaction can be retrieved with: - * - * var selectedUnspent = build.getSelectedUnspent(); - */ + /* create and signing can be done in multiple steps using: + * + * var builder = new bitcore.TransactionBuilder(opts) + * .setUnspent(utxos) + * .setOutputs(outs); + * + * builder.sign(key1); + * builder.sign(key2); + * ... + * if (builder.isFullySigned()){ + * var tx = builder.build(); + * } + * + * The selected Unspent Outputs for the transaction can be retrieved with: + * + * var selectedUnspent = build.getSelectedUnspent(); + */ - var txHex = tx.serialize().toString('hex'); + var txHex = tx.serialize().toString('hex'); console.log('TX HEX IS: ', txHex); }; @@ -67,4 +71,3 @@ if (typeof module !== 'undefined') { } //// - diff --git a/examples/CreateAndSignTx-PayToScriptHash.js b/examples/CreateAndSignTx-PayToScriptHash.js index f80593c..c234149 100644 --- a/examples/CreateAndSignTx-PayToScriptHash.js +++ b/examples/CreateAndSignTx-PayToScriptHash.js @@ -1,10 +1,12 @@ var run = function() { - bitcore = typeof (bitcore) === 'undefined' ? require('../bitcore') : bitcore; + bitcore = typeof(bitcore) === 'undefined' ? require('../bitcore') : bitcore; var networks = require('../networks'); var WalletKey = bitcore.WalletKey; var Script = bitcore.Script; var Builder = bitcore.TransactionBuilder; - var opts = {network: networks.testnet}; + var opts = { + network: networks.testnet + }; console.log('## Network: ' + opts.network.name); @@ -13,19 +15,17 @@ var run = function() { input.priv = "cS62Ej4SobZnpFQYN1PEEBr2KWf5sgRYYnELtumcG6WVCfxno39V"; // Complete with the corresponding UTXO you want to use - var utxos = [ - { + var utxos = [{ address: "n2hoFVbPrYQf7RJwiRy1tkbuPPqyhAEfbp", txid: "e4bc22d8c519d3cf848d710619f8480be56176a4a6548dfbe865ab3886b578b5", vout: 1, ts: 1396290442, scriptPubKey: "76a914e867aad8bd361f57c50adc37a0c018692b5b0c9a88ac", - amount: 0.3795, + amount: 0.3795, confirmations: 7 - } - ]; + }]; - var privs = [ + var privs = [ "cMpKwGr5oxEacN95WFKNEq6tTcvi11regFwS3muHvGYVxMPJX8JA", "cVf32m9MR4vxcPwKNJuPepUe8XrHD2z63eCk76d6njRGyCkXpkSM", "cQ2sVRFX4jQYMLhWyzz6jTQ2xju51P36968ecXnPhRLKLH677eKR", @@ -36,29 +36,37 @@ var run = function() { var pubkeys = [] privs.forEach(function(p) { var wk = new WalletKey(opts); - wk.fromObj({priv: p}); + wk.fromObj({ + priv: p + }); pubkeys.push(bitcore.buffertools.toHex(wk.privKey.public)); }); // multisig p2sh - var opts = {nreq:3, pubkeys:pubkeys}; + var opts = { + nreq: 3, + pubkeys: pubkeys + }; // p2scriphash p2sh //var opts = [{address: an_address}]; - + var info = Builder.infoForP2sh(opts, 'testnet'); var p2shScript = info.scriptBufHex; var p2shAddress = info.address; - var outs = [{address:p2shAddress, amount:0.05}]; + var outs = [{ + address: p2shAddress, + amount: 0.05 + }]; var tx = new Builder(opts) .setUnspent(utxos) .setOutputs(outs) .sign([input.priv]) .build(); - var txHex = tx.serialize().toString('hex'); + var txHex = tx.serialize().toString('hex'); console.log('## p2sh address: ' + p2shAddress); //TODO @@ -72,8 +80,7 @@ var run = function() { * * REDDEEM TX */ - var utxos2 = [ - { + var utxos2 = [{ address: p2shAddress, txid: "c2e50d1c8c581d8c4408378b751633f7eb86687fc5f0502be7b467173f275ae7", vout: 0, @@ -81,13 +88,15 @@ var run = function() { scriptPubKey: scriptPubKey, amount: 0.05, confirmations: 1 - } - ]; + }]; - outs = [{address:input.addr, amount:0.04}]; + outs = [{ + address: input.addr, + amount: 0.04 + }]; var hashMap = {}; - hashMap[p2shAddress]=p2shScript; + hashMap[p2shAddress] = p2shScript; var b = new Builder(opts) .setUnspent(utxos2) @@ -95,21 +104,21 @@ var run = function() { .setOutputs(outs) .sign(privs); - tx= b.build(); + tx = b.build(); -console.log('Builder:'); -console.log('\tSignatures:' + tx.countInputMissingSignatures(0) ); -console.log('\t#isFullySigned:' + b.isFullySigned() ); + console.log('Builder:'); + console.log('\tSignatures:' + tx.countInputMissingSignatures(0)); + console.log('\t#isFullySigned:' + b.isFullySigned()); -console.log('TX:'); -console.log('\t #isComplete:' + tx.isComplete() ); + console.log('TX:'); + console.log('\t #isComplete:' + tx.isComplete()); - var txHex = tx.serialize().toString('hex'); + var txHex = tx.serialize().toString('hex'); console.log('2) REDEEM SCRIPT: ', txHex); console.log('[this example originally generated TXID: 8284aa3b6f9c71c35ecb1d61d05ae78c8ca1f36940eaa615b50584dfc3d95cb7 on testnet]\n\n\thttp://test.bitcore.io/tx/8284aa3b6f9c71c35ecb1d61d05ae78c8ca1f36940eaa615b50584dfc3d95cb7\n\n'); -/* + /* // To send TX with RPC: var RpcClient = bitcore.RpcClient; var config = { diff --git a/examples/CreateKey.js b/examples/CreateKey.js index 7f2f8a1..eb7661a 100644 --- a/examples/CreateKey.js +++ b/examples/CreateKey.js @@ -8,21 +8,23 @@ var run = function() { var networks = require('../networks'); var WalletKey = bitcore.WalletKey; - var opts = {network: networks.testnet}; + var opts = { + network: networks.testnet + }; function print(wk) { console.log('\n## Network: ' + wk.network.name); - console.log ('\t * Hex Representation'); - console.log ('\tPrivate: ' + bitcore.buffertools.toHex(wk.privKey.private)); - console.log ('\tPublic : ' + bitcore.buffertools.toHex(wk.privKey.public)); - console.log ('\tPublic Compressed : ' + (wk.privKey.compressed?'Yes':'No')); + console.log('\t * Hex Representation'); + console.log('\tPrivate: ' + bitcore.buffertools.toHex(wk.privKey.private)); + console.log('\tPublic : ' + bitcore.buffertools.toHex(wk.privKey.public)); + console.log('\tPublic Compressed : ' + (wk.privKey.compressed ? 'Yes' : 'No')); var wkObj = wk.storeObj(); - console.log ('\n\t * WalletKey Store Object'); - console.log ('\tPrivate: ' + wkObj.priv); - console.log ('\tPublic : ' + wkObj.pub); - console.log ('\tAddr : ' + wkObj.addr); + console.log('\n\t * WalletKey Store Object'); + console.log('\tPrivate: ' + wkObj.priv); + console.log('\tPublic : ' + wkObj.pub); + console.log('\tAddr : ' + wkObj.addr); }; //Generate a new one (compressed public key, compressed WIF flag) @@ -32,7 +34,9 @@ var run = function() { //Generate from private Key WIF. Compressed status taken from WIF. var wk2 = new WalletKey(opts); - wk2.fromObj({priv:'cMpKwGr5oxEacN95WFKNEq6tTcvi11regFwS3muHvGYVxMPJX8JA'}); + wk2.fromObj({ + priv: 'cMpKwGr5oxEacN95WFKNEq6tTcvi11regFwS3muHvGYVxMPJX8JA' + }); print(wk2); diff --git a/examples/CreateScript.js b/examples/CreateScript.js index cbcbca5..d4595c4 100644 --- a/examples/CreateScript.js +++ b/examples/CreateScript.js @@ -9,7 +9,9 @@ var run = function() { var buffertools = bitcore.buffertools; var Address = bitcore.Address; var util = bitcore.util; - var opts = {network: networks.testnet}; + var opts = { + network: networks.testnet + }; var p = console.log; @@ -22,38 +24,38 @@ var run = function() { p('\tHex : ' + buffertools.toHex(s.buffer)); p('\tHuman : ' + s.toHumanReadable()); p('\tKey -------------------------------'); - console.log ('\tPrivate: ' + wkObj.priv); - console.log ('\tPublic : ' + wkObj.pub); - console.log ('\tAddr : ' + wkObj.addr); + console.log('\tPrivate: ' + wkObj.priv); + console.log('\tPublic : ' + wkObj.pub); + console.log('\tAddr : ' + wkObj.addr); s = Script.createPubKeyHashOut(wk.privKey.public); p('\nScript PubKeyHash:'); p('\tHex : ' + buffertools.toHex(s.buffer)); p('\tHuman : ' + s.toHumanReadable()); p('\tKey -------------------------------'); - console.log ('\tPrivate: ' + wkObj.priv); - console.log ('\tPublic : ' + wkObj.pub); - console.log ('\tAddr : ' + wkObj.addr); + console.log('\tPrivate: ' + wkObj.priv); + console.log('\tPublic : ' + wkObj.pub); + console.log('\tAddr : ' + wkObj.addr); - var wks=[]; + var wks = []; var pubs = []; - for (var i =0; i<5; i++) { + for (var i = 0; i < 5; i++) { wks[i] = new WalletKey(opts); wks[i].generate(); pubs.push(wks[i].privKey.public); } - s = Script.createMultisig(3,pubs); + s = Script.createMultisig(3, pubs); p('\nScript MultiSig (3 out of 5 required signatures):'); p('\tHex : ' + buffertools.toHex(s.buffer)); p('\tHuman : ' + s.toHumanReadable()); - for (i =0; i<5; i++) { + for (i = 0; i < 5; i++) { wkObj = wks[i].storeObj(); - p('\tKey ['+i+'] -------------------------------'); - console.log ('\tPrivate: ' + wkObj.priv); - console.log ('\tPublic : ' + wkObj.pub); - console.log ('\tAddr : ' + wkObj.addr); + p('\tKey [' + i + '] -------------------------------'); + console.log('\tPrivate: ' + wkObj.priv); + console.log('\tPublic : ' + wkObj.pub); + console.log('\tAddr : ' + wkObj.addr); } var hash = util.sha256ripe160(s.buffer); @@ -62,10 +64,10 @@ var run = function() { p('\nScript P2SH:'); p('\tHex : ' + buffertools.toHex(s.buffer)); p('\tHuman : ' + s.toHumanReadable()); - p('\tScript Hash: ' + buffertools.toHex(hash)); - var a = new Address(networks.livenet.P2SHVersion,hash); - p('\tp2sh Addr: ' + a.toString()); - + p('\tScript Hash: ' + buffertools.toHex(hash)); + var a = new Address(networks.livenet.P2SHVersion, hash); + p('\tp2sh Addr: ' + a.toString()); + }; module.exports.run = run; diff --git a/examples/ECIES.js b/examples/ECIES.js index 9e00b9b..ea38b68 100644 --- a/examples/ECIES.js +++ b/examples/ECIES.js @@ -1,16 +1,16 @@ var run = function() { - bitcore = typeof (bitcore) === 'undefined' ? require('../bitcore') : bitcore; + bitcore = typeof(bitcore) === 'undefined' ? require('../bitcore') : bitcore; console.log('ECIES: Elliptic Curve Integrated Encryption Scheme'); console.log('A way of encrypting with a public key and decrypting with a private key.'); - + var key = bitcore.Key.generateSync(); console.log('Private key: ' + key.private.toString('hex')); console.log('Public key: ' + key.public.toString('hex')); - + var message = new Buffer('This is a message to be encrypted'); console.log('Message: "' + message.toString() + '"'); - + var encrypted = bitcore.ECIES.encrypt(key.public, message); console.log('Encrypted (with public key): ' + encrypted.toString('hex')); diff --git a/examples/HierarchicalKey.js b/examples/HierarchicalKey.js index 62ae508..0a485fc 100644 --- a/examples/HierarchicalKey.js +++ b/examples/HierarchicalKey.js @@ -1,5 +1,5 @@ var run = function() { - bitcore = typeof (bitcore) === 'undefined' ? require('../bitcore') : bitcore; + bitcore = typeof(bitcore) === 'undefined' ? require('../bitcore') : bitcore; var HierarchicalKey = bitcore.HierarchicalKey; var Address = bitcore.Address; var networks = bitcore.networks; diff --git a/examples/PeerDiscovery.js b/examples/PeerDiscovery.js index b070c29..576364f 100644 --- a/examples/PeerDiscovery.js +++ b/examples/PeerDiscovery.js @@ -1,4 +1,6 @@ var PeerManager = require('../lib/PeerManager'); -var peerman = new PeerManager(); +var peerman = new PeerManager(); -peerman.discover({ limit: 12 }).start(); +peerman.discover({ + limit: 12 +}).start(); diff --git a/examples/SendTx.js b/examples/SendTx.js index f34ee4e..a7454b5 100644 --- a/examples/SendTx.js +++ b/examples/SendTx.js @@ -81,7 +81,7 @@ var run = function() { */ var txid = tx.getHash().toString('hex'); - console.log('Created transaction with txid '+txid); + console.log('Created transaction with txid ' + txid); var raw_tx = tx.serialize().toString('hex'); console.log('Transaction raw hex dump:'); console.log('-------------------------------------'); diff --git a/examples/SimpleP2Pmonitor.js b/examples/SimpleP2Pmonitor.js index 838e578..a2e2674 100644 --- a/examples/SimpleP2Pmonitor.js +++ b/examples/SimpleP2Pmonitor.js @@ -18,16 +18,17 @@ var socket = peer.createConnection(); var con = new Connection(socket, peer); -con.on('error', function (msg) { - var peer = msg.peer, err = msg.err; +con.on('error', function(msg) { + var peer = msg.peer, + err = msg.err; console.error('Error connecting to peer', peer.host + ':' + peer.port, '(' + err.message + ')'); }); -con.on('disconnect', function (msg) { +con.on('disconnect', function(msg) { console.log('disconnect: ', msg); }); -con.on('connect', function (msg) { +con.on('connect', function(msg) { console.log('Connected to %s', msg.peer.host + ':' + msg.peer.port); }); @@ -36,37 +37,36 @@ con.on('connect', function (msg) { // Make a log function available to all listeners // The log function is just like console.log except it prefixes // messages with [host:port] -function listen (event_name, fn) { - con.on(event_name, function (event) { - fn(event, function () { +function listen(event_name, fn) { + con.on(event_name, function(event) { + fn(event, function() { var args = Array.prototype.slice.call(arguments); var str = args.shift(); str = '[%s:%s] ' + str; - args = [ str, event.peer.host, event.peer.port ].concat(args); + args = [str, event.peer.host, event.peer.port].concat(args); console.log.apply(console, args); }); }); } -listen('getaddr', function (event, log) { +listen('getaddr', function(event, log) { log('Received message getaddr'); log(event); }); -listen('verack', function (event, log) { +listen('verack', function(event, log) { log('Received message verack'); }); -listen('version', function (event, log) { +listen('version', function(event, log) { log('Received message version (%s)', event.message.version); }); -listen('addr', function (event, log) { +listen('addr', function(event, log) { log('Received message addr (%s addresses)', event.message.addrs.length); }); -listen('inv', function (event, log) { +listen('inv', function(event, log) { log('Received message inv (%s invs)', event.message.count); console.log(event.message.invs); }); - diff --git a/examples/VanityAddress.js b/examples/VanityAddress.js index d14f9ad..1e9d004 100644 --- a/examples/VanityAddress.js +++ b/examples/VanityAddress.js @@ -10,15 +10,15 @@ var run = function() { // config your regular expression var re = /[0-9]{6}$/; // ends in 6 digits - var a,k,m; + var a, k, m; while (true) { k = Key.generateSync(); a = Address.fromKey(k); m = a.toString().match(re); if (m) break; } - console.log('Address: '+a.toString()); - console.log('Private Key: '+k.private.toString('hex')); + console.log('Address: ' + a.toString()); + console.log('Private Key: ' + k.private.toString('hex')); }; diff --git a/lib/Address.js b/lib/Address.js index ac2fecc..1337807 100644 --- a/lib/Address.js +++ b/lib/Address.js @@ -85,7 +85,7 @@ Address.fromScript = function(script, network) { network = 'livenet'; if (typeof script === 'string') { - script = new Script(new Buffer(script,'hex')); + script = new Script(new Buffer(script, 'hex')); } var version = networks[network].P2SHVersion; @@ -99,16 +99,17 @@ Address.fromScript = function(script, network) { Address.fromScriptPubKey = function(scriptPubKey, network) { if (typeof scriptPubKey === 'string') { - scriptPubKey = new Script(new Buffer(scriptPubKey,'hex')); + scriptPubKey = new Script(new Buffer(scriptPubKey, 'hex')); } if (!network) network = 'livenet'; - var ret=[], version; + var ret = [], + version; var payload = scriptPubKey.capture(); - if (payload) { + if (payload) { var txType = scriptPubKey.classify(); switch (txType) { case Script.TX_PUBKEY: @@ -120,15 +121,15 @@ Address.fromScriptPubKey = function(scriptPubKey, network) { break; case Script.TX_MULTISIG: version = networks[network].addressVersion; - for(var i in payload) + 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])); + for (var i in payload) + ret.push(new Address(version, payload[i])); } return ret; }; @@ -137,7 +138,7 @@ Address.fromScriptPubKey = function(scriptPubKey, network) { Address.prototype.validate = function() { this.doAsBinary(function() { Address.super(this, 'validate', arguments); - if(this.data.length !== 21) throw new Error('invalid data length'); + if (this.data.length !== 21) throw new Error('invalid data length'); }); if (typeof this.network() === 'undefined') throw new Error('invalid network'); }; diff --git a/lib/Armory.js b/lib/Armory.js index 94be0e5..e0c4c39 100644 --- a/lib/Armory.js +++ b/lib/Armory.js @@ -9,12 +9,12 @@ var Point = require('./Point'), * * @example examples/Armory.js */ -function Armory (chaincode, pubkey) { +function Armory(chaincode, pubkey) { this.chaincode = new Buffer(chaincode, 'hex'); this.pubkey = new Buffer(pubkey, 'hex'); } -Armory.prototype.generatePubKey = function () { +Armory.prototype.generatePubKey = function() { var pubKey = this.pubkey; var chainCode = this.chaincode; var chainXor = twoSha256(pubKey); @@ -30,7 +30,7 @@ Armory.prototype.generatePubKey = function () { return new_pubkey; }; -Armory.prototype.next = function () { +Armory.prototype.next = function() { var next_pubkey = this.generatePubKey(); return new Armory(this.chaincode, next_pubkey); }; @@ -44,13 +44,13 @@ Armory.prototype.next = function () { * * https://github.com/etotheipi/BitcoinArmory/issues/204#issuecomment-42217801 */ -Armory.fromMasterPublicKey = function (mpk) { +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) { +function decode(str) { var from = '0123456789abcdef'; var to = 'asdfghjkwertuion'; var res = ''; @@ -59,20 +59,20 @@ function decode (str) { return res; } -Armory.decodeSeed = function (seed) { +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 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); + 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, @@ -81,7 +81,7 @@ Armory.decodeSeed = function (seed) { }; // Derive chain code from root key -Armory.fromSeed = function (seed) { +Armory.fromSeed = function(seed) { var res = Armory.decodeSeed(seed); // generate first public key var key = new Key(); @@ -92,7 +92,7 @@ Armory.fromSeed = function (seed) { return new Armory(res.chainCode, key.public); }; -Armory.deriveChaincode = function (root) { +Armory.deriveChaincode = function(root) { var msg = 'Derive Chaincode from Root Key'; var hash = twoSha256(root); @@ -107,8 +107,8 @@ Armory.deriveChaincode = function (root) { ikey = new Buffer(ikey); var m = new Buffer(msg, 'utf8'); - var a = sha256(Buffer.concat([ ikey, m ])); - var b = sha256(Buffer.concat([ okey, a ])); + var a = sha256(Buffer.concat([ikey, m])); + var b = sha256(Buffer.concat([okey, a])); return b; }; diff --git a/lib/BIP39.js b/lib/BIP39.js index 05e36cd..c74fa11 100644 --- a/lib/BIP39.js +++ b/lib/BIP39.js @@ -3,10 +3,10 @@ var coinUtil = imports.coinUtil || require('../util'); var sjcl = imports.sjcl || require('./sjcl'); var SecureRandom = require('./SecureRandom'); -var hmacSHA512 = function (key) { +var hmacSHA512 = function(key) { var hasher = new sjcl.misc.hmac(key, sjcl.hash.sha512); - this.encrypt = function () { - return hasher.encrypt.apply(hasher, arguments); + this.encrypt = function() { + return hasher.encrypt.apply(hasher, arguments); }; }; @@ -15,8 +15,7 @@ var pbkdf2Sync_sha512 = function(password, salt, iterations, keylen) { return sjcl.codec.hex.fromBits(derivedKey) }; -var BIP39 = function() { -}; +var BIP39 = function() {}; BIP39.mnemonic = function(wordlist, bits) { if (!bits) @@ -31,11 +30,11 @@ 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++) { + 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); + 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); @@ -43,7 +42,7 @@ BIP39.entropy2mnemonic = function(wordlist, buf) { for (var i = 0; i < bin.length / 11; i++) { if (mnemonic != "") mnemonic = mnemonic + " "; - var wi = parseInt(bin.slice(i*11, (i+1)*11), 2); + var wi = parseInt(bin.slice(i * 11, (i + 1) * 11), 2); mnemonic = mnemonic + wordlist[wi]; } return mnemonic; diff --git a/lib/BIP39WordlistEn.js b/lib/BIP39WordlistEn.js index a3bc35f..d669261 100644 --- a/lib/BIP39WordlistEn.js +++ b/lib/BIP39WordlistEn.js @@ -1,2 +1,2 @@ -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"]; +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 = require('soop')(BIP39WordlistEn); diff --git a/lib/Base58.js b/lib/Base58.js index 1bcdff8..54cd8d1 100644 --- a/lib/Base58.js +++ b/lib/Base58.js @@ -7,7 +7,7 @@ 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++) { +for (var i = 0; i < ALPHABET.length; i++) { ALPHABET_INV[ALPHABET[i]] = i; }; @@ -18,13 +18,13 @@ var base58 = { var x = bignum.fromBuffer(buf); var r; - if(buf.length < 512) { + if (buf.length < 512) { str = globalBuffer; } else { str = new Buffer(buf.length << 1); } var i = str.length - 1; - while(x.gt(0)) { + while (x.gt(0)) { r = x.mod(58); x = x.div(58); str[i] = ALPHABET_BUF[r.toNumber()]; @@ -32,32 +32,33 @@ var base58 = { } // deal with leading zeros - var j=0; - while(buf[j] == 0) { + var j = 0; + while (buf[j] == 0) { str[i] = ALPHABET_BUF[0]; - j++; i--; + j++; + i--; } - return str.slice(i+1,str.length).toString('ascii'); + return str.slice(i + 1, str.length).toString('ascii'); }, decode: function(str) { - if(str.length == 0) return zerobuf; + if (str.length == 0) return zerobuf; var answer = bignum(0); - for(var i=0; i 0) { + if (i > 0) { var zb = new Buffer(i); zb.fill(0); - if(i == str.length) return zb; + if (i == str.length) return zb; answer = answer.toBuffer(); - return Buffer.concat([zb, answer], i+answer.length); + return Buffer.concat([zb, answer], i + answer.length); } else { return answer.toBuffer(); } diff --git a/lib/Block.js b/lib/Block.js index 57c6d48..bd36e87 100644 --- a/lib/Block.js +++ b/lib/Block.js @@ -1,24 +1,23 @@ -var imports = require('soop').imports(); +var imports = require('soop').imports(); -var util = imports.util || require('../util'); -var Debug1 = imports.Debug1 || function() {}; -var Script = imports.Script || require('./Script'); -var Bignum = imports.Bignum || require('bignum'); -var Binary = imports.Binary || require('binary'); -var Step = imports.Step || require('step'); -var buffertools = imports.buffertools || require('buffertools'); -var Transaction = imports.Transaction || require('./Transaction'); -var TransactionIn = Transaction.In; -var TransactionOut = Transaction.Out; -var COINBASE_OP = Transaction.COINBASE_OP; +var util = imports.util || require('../util'); +var Debug1 = imports.Debug1 || function() {}; +var Script = imports.Script || require('./Script'); +var Bignum = imports.Bignum || require('bignum'); +var Binary = imports.Binary || require('binary'); +var Step = imports.Step || require('step'); +var buffertools = imports.buffertools || require('buffertools'); +var Transaction = imports.Transaction || require('./Transaction'); +var TransactionIn = Transaction.In; +var TransactionOut = Transaction.Out; +var COINBASE_OP = Transaction.COINBASE_OP; var VerificationError = imports.VerificationError || require('../util/error').VerificationError; var BlockRules = { - maxTimeOffset: 2 * 60 * 60, // How far block timestamps can be into the future + maxTimeOffset: 2 * 60 * 60, // How far block timestamps can be into the future largestHash: Bignum(2).pow(256) }; -function Block(data) -{ +function Block(data) { if ("object" !== typeof data) { data = {}; } @@ -39,12 +38,18 @@ function Block(data) 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; + 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; }; @@ -102,12 +107,12 @@ Block.prototype.checkProofOfWork = function checkProofOfWork() { }; /** - * 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. - */ + * 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)); @@ -131,7 +136,7 @@ Block.prototype.checkTransactions = function checkTransactions(txs) { } for (var i = 1; i < txs.length; i++) { if (txs[i].isCoinBase()) { - throw new VerificationError('Tx index '+i+' must not be coinbase'); + throw new VerificationError('Tx index ' + i + ' must not be coinbase'); } } @@ -139,11 +144,11 @@ Block.prototype.checkTransactions = function checkTransactions(txs) { }; /** - * Build merkle tree. - * - * Ported from Java. Original code: BitcoinJ by Mike Hearn - * Copyright (c) 2011 Google Inc. - */ + * 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: // @@ -165,7 +170,7 @@ Block.prototype.getMerkleTree = function getMerkleTree(txs) { } // Start by adding all the hashes of the transactions as leaves of the tree. - var tree = txs.map(function (tx) { + var tree = txs.map(function(tx) { return tx instanceof Transaction ? tx.getHash() : tx; }); @@ -177,7 +182,7 @@ Block.prototype.getMerkleTree = function getMerkleTree(txs) { var i2 = Math.min(i + 1, size - 1); var a = tree[j + i]; var b = tree[j + i2]; - tree.push(util.twoSha256(Buffer.concat([a,b]))); + tree.push(util.twoSha256(Buffer.concat([a, b]))); } j += size; } @@ -229,24 +234,23 @@ Block.prototype.getBlockValue = function getBlockValue() { }; Block.prototype.toString = function toString() { - return ""; + return ""; }; Block.prototype.createCoinbaseTx = -function createCoinbaseTx(beneficiary) -{ - var tx = new Transaction(); - tx.ins.push(new TransactionIn({ - s: util.EMPTY_BUFFER, - q: 0xffffffff, - o: COINBASE_OP - })); - tx.outs.push(new TransactionOut({ - v: util.bigIntToValue(this.getBlockValue()), - s: Script.createPubKeyOut(beneficiary).getBuffer() - })); - return tx; + function createCoinbaseTx(beneficiary) { + var tx = new Transaction(); + tx.ins.push(new TransactionIn({ + s: util.EMPTY_BUFFER, + q: 0xffffffff, + o: COINBASE_OP + })); + tx.outs.push(new TransactionOut({ + v: util.bigIntToValue(this.getBlockValue()), + s: Script.createPubKeyOut(beneficiary).getBuffer() + })); + return tx; }; Block.prototype.solve = function solve(miner, callback) { @@ -256,45 +260,44 @@ Block.prototype.solve = function solve(miner, callback) { }; /** - * Returns an object with the same field names as jgarzik's getblock patch. - */ + * Returns an object with the same field names as jgarzik's getblock patch. + */ Block.prototype.getStandardizedObject = -function getStandardizedObject(txs) -{ - var block = { - hash: util.formatHashFull(this.getHash()), - version: this.version, - prev_block: util.formatHashFull(this.prev_hash), - mrkl_root: util.formatHashFull(this.merkle_root), - time: this.timestamp, - bits: this.bits, - nonce: this.nonce, - height: this.height - }; + function getStandardizedObject(txs) { + var block = { + hash: util.formatHashFull(this.getHash()), + version: this.version, + prev_block: util.formatHashFull(this.prev_hash), + mrkl_root: util.formatHashFull(this.merkle_root), + time: this.timestamp, + bits: this.bits, + nonce: this.nonce, + height: this.height + }; - if (txs) { - var mrkl_tree = this.getMerkleTree(txs).map(function (buffer) { - return util.formatHashFull(buffer); - }); - block.mrkl_root = mrkl_tree[mrkl_tree.length - 1]; + if (txs) { + var mrkl_tree = this.getMerkleTree(txs).map(function(buffer) { + return util.formatHashFull(buffer); + }); + block.mrkl_root = mrkl_tree[mrkl_tree.length - 1]; - block.n_tx = txs.length; - var totalSize = 80; // Block header - totalSize += util.getVarIntSize(txs.length); // txn_count - txs = txs.map(function (tx) { - tx = tx.getStandardizedObject(); - totalSize += tx.size; - return tx; - }); - block.size = totalSize; - block.tx = txs; + block.n_tx = txs.length; + var totalSize = 80; // Block header + totalSize += util.getVarIntSize(txs.length); // txn_count + txs = txs.map(function(tx) { + tx = tx.getStandardizedObject(); + totalSize += tx.size; + return tx; + }); + block.size = totalSize; + block.tx = txs; - block.mrkl_tree = mrkl_tree; - } else { - block.size = this.size; - } - return block; + block.mrkl_tree = mrkl_tree; + } else { + block.size = this.size; + } + return block; }; module.exports = require('soop')(Block); diff --git a/lib/Bloom.js b/lib/Bloom.js index 0bb166b..f291467 100644 --- a/lib/Bloom.js +++ b/lib/Bloom.js @@ -1,4 +1,4 @@ -var MAX_BLOOM_FILTER_SIZE = 36000; // bytes +var MAX_BLOOM_FILTER_SIZE = 36000; // bytes var MAX_HASH_FUNCS = 50; var LN2SQUARED = 0.4804530139182014246671025263266649717305529515945455; var LN2 = 0.6931471805599453094172321214581765680755001343602552; @@ -47,13 +47,16 @@ Bloom.prototype.hash = function(hashNum, data) { var k1 = 0; switch (data.length & 3) { - case 3: k1 ^= tail[2] << 16; - case 2: k1 ^= tail[1] << 8; - case 1: k1 ^= tail[0]; - k1 *= c1; - k1 = ROTL32(k1, 15); - k1 *= c2; - h1 ^= k1; + case 3: + k1 ^= tail[2] << 16; + case 2: + k1 ^= tail[1] << 8; + case 1: + k1 ^= tail[0]; + k1 *= c1; + k1 = ROTL32(k1, 15); + k1 *= c2; + h1 ^= k1; } // finalize @@ -90,7 +93,7 @@ Bloom.prototype.sizeOk = function() { }; function toInt(v) { - return ~~v; + return~~ v; } function min(a, b) { @@ -101,10 +104,10 @@ function min(a, b) { Bloom.prototype.init = function(elements, FPRate) { var filterSize = min(toInt(-1.0 / LN2SQUARED * elements * Math.log(FPRate)), - MAX_BLOOM_FILTER_SIZE * 8) / 8; + MAX_BLOOM_FILTER_SIZE * 8) / 8; this.data[filterSize] = 0; this.hashFuncs = min(toInt(this.data.length * 8 / elements * LN2), - MAX_HASH_FUNCS); + MAX_HASH_FUNCS); }; diff --git a/lib/Connection.js b/lib/Connection.js index 1377545..7622c63 100644 --- a/lib/Connection.js +++ b/lib/Connection.js @@ -1,32 +1,32 @@ -var imports = require('soop').imports(); +var imports = require('soop').imports(); -var log = imports.log || require('../util/log'); +var log = imports.log || require('../util/log'); var MAX_RECEIVE_BUFFER = 10000000; -var PROTOCOL_VERSION = 70000; +var PROTOCOL_VERSION = 70000; -var Put = imports.Put || require('bufferput'); -var Buffers = imports.Buffers || require('buffers'); +var Put = imports.Put || require('bufferput'); +var Buffers = imports.Buffers || require('buffers'); require('../patches/Buffers.monkey').patch(Buffers); var bitcoreDefaults = imports.config || require('../config'); -var networks = imports.networks || require('../networks'); -var Block = imports.Block || require('./Block'); -var Transaction = imports.Transaction || require('./Transaction'); -var util = imports.util || require('../util'); -var Parser = imports.Parser || require('../util/BinaryParser'); -var buffertools = imports.buffertools || require('buffertools'); -var doubleSha256 = imports.doubleSha256 || util.twoSha256; -var SecureRandom = imports.SecureRandom || require('./SecureRandom'); -var nonce = SecureRandom.getPseudoRandomBuffer(8); +var networks = imports.networks || require('../networks'); +var Block = imports.Block || require('./Block'); +var Transaction = imports.Transaction || require('./Transaction'); +var util = imports.util || require('../util'); +var Parser = imports.Parser || require('../util/BinaryParser'); +var buffertools = imports.buffertools || require('buffertools'); +var doubleSha256 = imports.doubleSha256 || util.twoSha256; +var SecureRandom = imports.SecureRandom || require('./SecureRandom'); +var nonce = SecureRandom.getPseudoRandomBuffer(8); var BIP0031_VERSION = 60000; function Connection(socket, peer, opts) { Connection.super(this, arguments); - + this.config = opts || bitcoreDefaults; - + this.network = networks[this.config.network] || networks.livenet; this.socket = socket; this.peer = peer; @@ -70,22 +70,22 @@ Connection.prototype.open = function(callback) { return this; }; -Connection.prototype.setupHandlers = function () { +Connection.prototype.setupHandlers = function() { this.socket.addListener('connect', this.handleConnect.bind(this)); this.socket.addListener('error', this.handleError.bind(this)); this.socket.addListener('end', this.handleDisconnect.bind(this)); - this.socket.addListener('data', (function (data) { + this.socket.addListener('data', (function(data) { var dumpLen = 35; - log.debug('['+this.peer+'] '+ - 'Recieved '+data.length+' bytes of data:'); - log.debug('... '+ buffertools.toHex(data.slice(0, dumpLen > data.length ? - data.length : dumpLen)) + - (data.length > dumpLen ? '...' : '')); + log.debug('[' + this.peer + '] ' + + 'Recieved ' + data.length + ' bytes of data:'); + log.debug('... ' + buffertools.toHex(data.slice(0, dumpLen > data.length ? + data.length : dumpLen)) + + (data.length > dumpLen ? '...' : '')); }).bind(this)); this.socket.addListener('data', this.handleData.bind(this)); }; -Connection.prototype.handleConnect = function () { +Connection.prototype.handleConnect = function() { if (!this.inbound) { this.sendVersion(); } @@ -98,11 +98,11 @@ Connection.prototype.handleConnect = function () { Connection.prototype.handleError = function(err) { if (err.errno == 110 || err.errno == 'ETIMEDOUT') { - log.info('connection timed out for '+this.peer); + log.info('connection timed out for ' + this.peer); } else if (err.errno == 111 || err.errno == 'ECONNREFUSED') { - log.info('connection refused for '+this.peer); + log.info('connection refused for ' + this.peer); } else { - log.warn('connection with '+this.peer+' '+err.toString()); + log.warn('connection with ' + this.peer + ' ' + err.toString()); } this.emit('error', { conn: this, @@ -112,7 +112,7 @@ Connection.prototype.handleError = function(err) { }); }; -Connection.prototype.handleDisconnect = function () { +Connection.prototype.handleDisconnect = function() { this.emit('disconnect', { conn: this, socket: this.socket, @@ -128,48 +128,48 @@ Connection.prototype.handleMessage = function(message) { try { switch (message.command) { - case 'version': - // Did we connect to ourself? - if (buffertools.compare(nonce, message.nonce) === 0) { - this.socket.end(); - return; - } + case 'version': + // Did we connect to ourself? + if (buffertools.compare(nonce, message.nonce) === 0) { + this.socket.end(); + return; + } - if (this.inbound) { - this.sendVersion(); - } + if (this.inbound) { + this.sendVersion(); + } - if (message.version >= 209) { - this.sendMessage('verack', new Buffer([])); - } - this.sendVer = Math.min(message.version, PROTOCOL_VERSION); - if (message.version < 209) { + if (message.version >= 209) { + this.sendMessage('verack', new Buffer([])); + } + this.sendVer = Math.min(message.version, PROTOCOL_VERSION); + if (message.version < 209) { + this.recvVer = Math.min(message.version, PROTOCOL_VERSION); + } else { + // We won't start expecting a checksum until after we've received + // the 'verack' message. + this.once('verack', (function() { + this.recvVer = message.version; + }).bind(this)); + } + this.bestHeight = message.start_height; + break; + + case 'verack': this.recvVer = Math.min(message.version, PROTOCOL_VERSION); - } else { - // We won't start expecting a checksum until after we've received - // the 'verack' message. - this.once('verack', (function () { - this.recvVer = message.version; - }).bind(this)); - } - this.bestHeight = message.start_height; - break; + this.active = true; + break; - case 'verack': - this.recvVer = Math.min(message.version, PROTOCOL_VERSION); - this.active = true; - break; - - case 'ping': - if ('object' === typeof message.nonce) { - this.sendPong(message.nonce); - } - break; + case 'ping': + if ('object' === typeof message.nonce) { + this.sendPong(message.nonce); + } + break; } } catch (e) { - log.err('Error while handling "'+message.command+'" message from ' + - this.peer + ':\n' + - (e.stack ? e.stack : e.toString())); + log.err('Error while handling "' + message.command + '" message from ' + + this.peer + ':\n' + + (e.stack ? e.stack : e.toString())); return; } this.emit(message.command, { @@ -180,17 +180,17 @@ Connection.prototype.handleMessage = function(message) { }); }; -Connection.prototype.sendPong = function (nonce) { +Connection.prototype.sendPong = function(nonce) { this.sendMessage('pong', nonce); }; -Connection.prototype.sendVersion = function () { +Connection.prototype.sendVersion = function() { var subversion = '/BitcoinX:0.1/'; var put = new Put(); put.word32le(PROTOCOL_VERSION); // version put.word64le(1); // services - put.word64le(Math.round(new Date().getTime()/1000)); // timestamp + put.word64le(Math.round(new Date().getTime() / 1000)); // timestamp put.pad(26); // addr_me put.pad(26); // addr_you put.put(nonce); @@ -201,7 +201,7 @@ Connection.prototype.sendVersion = function () { this.sendMessage('version', put.buffer()); }; -Connection.prototype.sendGetBlocks = function (starts, stop, wantHeaders) { +Connection.prototype.sendGetBlocks = function(starts, stop, wantHeaders) { // Default value for stop is 0 to get as many blocks as possible (500) stop = stop || util.NULL_HASH; @@ -236,7 +236,7 @@ Connection.prototype.sendGetHeaders = function(starts, stop) { this.sendGetBlocks(starts, stop, true); }; -Connection.prototype.sendGetData = function (invs) { +Connection.prototype.sendGetData = function(invs) { var put = new Put(); put.varint(invs.length); for (var i = 0; i < invs.length; i++) { @@ -246,16 +246,16 @@ Connection.prototype.sendGetData = function (invs) { this.sendMessage('getdata', put.buffer()); }; -Connection.prototype.sendGetAddr = function (invs) { +Connection.prototype.sendGetAddr = function(invs) { var put = new Put(); this.sendMessage('getaddr', put.buffer()); }; Connection.prototype.sendInv = function(data) { - if(!Array.isArray(data)) data = [data]; + if (!Array.isArray(data)) data = [data]; var put = new Put(); put.varint(data.length); - data.forEach(function (value) { + data.forEach(function(value) { if (value instanceof Block) { // Block put.word32le(2); // MSG_BLOCK @@ -268,10 +268,10 @@ Connection.prototype.sendInv = function(data) { this.sendMessage('inv', put.buffer()); }; -Connection.prototype.sendHeaders = function (headers) { +Connection.prototype.sendHeaders = function(headers) { var put = new Put(); put.varint(headers.length); - headers.forEach(function (header) { + headers.forEach(function(header) { put.put(header); // Indicate 0 transactions @@ -280,11 +280,11 @@ Connection.prototype.sendHeaders = function (headers) { this.sendMessage('headers', put.buffer()); }; -Connection.prototype.sendTx = function (tx) { +Connection.prototype.sendTx = function(tx) { this.sendMessage('tx', tx.serialize()); }; -Connection.prototype.sendBlock = function (block, txs) { +Connection.prototype.sendBlock = function(block, txs) { var put = new Put(); // Block header @@ -292,14 +292,14 @@ Connection.prototype.sendBlock = function (block, txs) { // List of transactions put.varint(txs.length); - txs.forEach(function (tx) { + txs.forEach(function(tx) { put.put(tx.serialize()); }); this.sendMessage('block', put.buffer()); }; -Connection.prototype.sendMessage = function (command, payload) { +Connection.prototype.sendMessage = function(command, payload) { try { var magic = this.network.magic; var commandBuf = new Buffer(command, 'ascii'); @@ -312,35 +312,35 @@ Connection.prototype.sendMessage = function (command, payload) { checksum = new Buffer([]); } - var message = new Put(); // -- HEADER -- - message.put(magic); // magic bytes - message.put(commandBuf); // command name - message.pad(12 - commandBuf.length); // zero-padded - message.word32le(payload.length); // payload length - message.put(checksum); // checksum + var message = new Put(); // -- HEADER -- + message.put(magic); // magic bytes + message.put(commandBuf); // command name + message.pad(12 - commandBuf.length); // zero-padded + message.word32le(payload.length); // payload length + message.put(checksum); // checksum // -- BODY -- - message.put(payload); // payload data + message.put(payload); // payload data var buffer = message.buffer(); - log.debug('['+this.peer+'] '+ - 'Sending message '+command+' ('+payload.length+' bytes)'); + log.debug('[' + this.peer + '] ' + + 'Sending message ' + command + ' (' + payload.length + ' bytes)'); this.socket.write(buffer); } catch (err) { // TODO: We should catch this error one level higher in order to better // determine how to react to it. For now though, ignoring it will do. - log.err('Error while sending message to peer '+this.peer+': '+ - (err.stack ? err.stack : err.toString())); + log.err('Error while sending message to peer ' + this.peer + ': ' + + (err.stack ? err.stack : err.toString())); } }; -Connection.prototype.handleData = function (data) { +Connection.prototype.handleData = function(data) { this.buffers.push(data); if (this.buffers.length > MAX_RECEIVE_BUFFER) { - log.err('Peer '+this.peer+' exceeded maxreceivebuffer, disconnecting.'+ - (err.stack ? err.stack : err.toString())); + log.err('Peer ' + this.peer + ' exceeded maxreceivebuffer, disconnecting.' + + (err.stack ? err.stack : err.toString())); this.socket.destroy(); return; } @@ -348,22 +348,22 @@ Connection.prototype.handleData = function (data) { this.processData(); }; -Connection.prototype.processData = function () { +Connection.prototype.processData = function() { // If there are less than 20 bytes there can't be a message yet. if (this.buffers.length < 20) return; var magic = this.network.magic; var i = 0; for (;;) { - if (this.buffers.get(i ) === magic[0] && - this.buffers.get(i+1) === magic[1] && - this.buffers.get(i+2) === magic[2] && - this.buffers.get(i+3) === magic[3]) { + if (this.buffers.get(i) === magic[0] && + this.buffers.get(i + 1) === magic[1] && + this.buffers.get(i + 2) === magic[2] && + this.buffers.get(i + 3) === magic[3]) { if (i !== 0) { - log.debug('['+this.peer+'] '+ - 'Received '+i+ - ' bytes of inter-message garbage: '); - log.debug('... '+this.buffers.slice(0,i)); + log.debug('[' + this.peer + '] ' + + 'Received ' + i + + ' bytes of inter-message garbage: '); + log.debug('... ' + this.buffers.slice(0, i)); this.buffers.skip(i); } @@ -377,32 +377,33 @@ Connection.prototype.processData = function () { i++; } - var payloadLen = (this.buffers.get(16) ) + - (this.buffers.get(17) << 8) + - (this.buffers.get(18) << 16) + - (this.buffers.get(19) << 24); + var payloadLen = (this.buffers.get(16)) + + (this.buffers.get(17) << 8) + + (this.buffers.get(18) << 16) + + (this.buffers.get(19) << 24); var startPos = (this.recvVer >= 209) ? 24 : 20; var endPos = startPos + payloadLen; if (this.buffers.length < endPos) return; - var command = this.buffers.slice(4, 16).toString('ascii').replace(/\0+$/,''); + var command = this.buffers.slice(4, 16).toString('ascii').replace(/\0+$/, ''); var payload = this.buffers.slice(startPos, endPos); var checksum = (this.recvVer >= 209) ? this.buffers.slice(20, 24) : null; - log.debug('['+this.peer+'] ' + - 'Received message ' + command + - ' (' + payloadLen + ' bytes)'); + log.debug('[' + this.peer + '] ' + + 'Received message ' + command + + ' (' + payloadLen + ' bytes)'); if (checksum !== null) { var checksumConfirm = doubleSha256(payload).slice(0, 4); if (buffertools.compare(checksumConfirm, checksum) !== 0) { - log.err('['+this.peer+'] '+ - 'Checksum failed', - { cmd: command, - expected: checksumConfirm.toString('hex'), - actual: checksum.toString('hex') }); + log.err('[' + this.peer + '] ' + + 'Checksum failed', { + cmd: command, + expected: checksumConfirm.toString('hex'), + actual: checksum.toString('hex') + }); return; } } @@ -411,9 +412,9 @@ Connection.prototype.processData = function () { try { message = this.parseMessage(command, payload); } catch (e) { - log.err('Error while parsing message '+command+' from ' + - this.peer + ':\n' + - (e.stack ? e.stack : e.toString())); + log.err('Error while parsing message ' + command + ' from ' + + this.peer + ':\n' + + (e.stack ? e.stack : e.toString())); } if (message) { @@ -424,7 +425,7 @@ Connection.prototype.processData = function () { this.processData(); }; -Connection.prototype.parseMessage = function (command, payload) { +Connection.prototype.parseMessage = function(command, payload) { var parser = new Parser(payload); var data = { @@ -434,129 +435,130 @@ Connection.prototype.parseMessage = function (command, payload) { var i; switch (command) { - case 'version': // https://en.bitcoin.it/wiki/Protocol_specification#version - data.version = parser.word32le(); - data.services = parser.word64le(); - data.timestamp = parser.word64le(); - data.addr_me = parser.buffer(26); - data.addr_you = parser.buffer(26); - data.nonce = parser.buffer(8); - data.subversion = parser.varStr(); - data.start_height = parser.word32le(); - break; - - case 'inv': - case 'getdata': - data.count = parser.varInt(); - - data.invs = []; - for (i = 0; i < data.count; i++) { - data.invs.push({ - type: parser.word32le(), - hash: parser.buffer(32) - }); - } - break; - - case 'headers': - data.count = parser.varInt(); - - data.headers = []; - for (i = 0; i < data.count; i++) { - var header = new Block(); - header.parse(parser); - data.headers.push(header); - } - break; - - case 'block': - var block = new Block(); - block.parse(parser); - - data.block = block; - data.version = block.version; - data.prev_hash = block.prev_hash; - data.merkle_root = block.merkle_root; - data.timestamp = block.timestamp; - data.bits = block.bits; - data.nonce = block.nonce; - - data.txs = block.txs; - - data.size = payload.length; - break; - - case 'tx': - var tx = new Transaction(); - tx.parse(parser); - return { - command: command, - version: tx.version, - lock_time: tx.lock_time, - ins: tx.ins, - outs: tx.outs, - tx: tx, - }; - - case 'getblocks': - case 'getheaders': - // parse out the version - data.version = parser.word32le(); - - // TODO: Limit block locator size? - // reference implementation limits to 500 results - var startCount = parser.varInt(); - - data.starts = []; - for (i = 0; i < startCount; i++) { - data.starts.push(parser.buffer(32)); - } - data.stop = parser.buffer(32); - break; - - case 'addr': - var addrCount = parser.varInt(); - - // Enforce a maximum number of addresses per message - if (addrCount > 1000) { - addrCount = 1000; - } - - data.addrs = []; - for (i = 0; i < addrCount; i++) { - // TODO: Time actually depends on the version of the other peer (>=31402) - data.addrs.push({ - time: parser.word32le(), - services: parser.word64le(), - ip: parser.buffer(16), - port: parser.word16be() - }); - } - break; - - case 'alert': - data.payload = parser.varStr(); - data.signature = parser.varStr(); - break; - - case 'ping': - if (this.recvVer > BIP0031_VERSION) { + case 'version': // https://en.bitcoin.it/wiki/Protocol_specification#version + data.version = parser.word32le(); + data.services = parser.word64le(); + data.timestamp = parser.word64le(); + data.addr_me = parser.buffer(26); + data.addr_you = parser.buffer(26); data.nonce = parser.buffer(8); - } - break; + data.subversion = parser.varStr(); + data.start_height = parser.word32le(); + break; - case 'getaddr': - case 'verack': - case 'reject': - // Empty message, nothing to parse - break; + case 'inv': + case 'getdata': + data.count = parser.varInt(); - default: - log.err('Connection.parseMessage(): Command not implemented', - {cmd: command}); + data.invs = []; + for (i = 0; i < data.count; i++) { + data.invs.push({ + type: parser.word32le(), + hash: parser.buffer(32) + }); + } + break; - // This tells the calling function not to issue an event - return null; + case 'headers': + data.count = parser.varInt(); + + data.headers = []; + for (i = 0; i < data.count; i++) { + var header = new Block(); + header.parse(parser); + data.headers.push(header); + } + break; + + case 'block': + var block = new Block(); + block.parse(parser); + + data.block = block; + data.version = block.version; + data.prev_hash = block.prev_hash; + data.merkle_root = block.merkle_root; + data.timestamp = block.timestamp; + data.bits = block.bits; + data.nonce = block.nonce; + + data.txs = block.txs; + + data.size = payload.length; + break; + + case 'tx': + var tx = new Transaction(); + tx.parse(parser); + return { + command: command, + version: tx.version, + lock_time: tx.lock_time, + ins: tx.ins, + outs: tx.outs, + tx: tx, + }; + + case 'getblocks': + case 'getheaders': + // parse out the version + data.version = parser.word32le(); + + // TODO: Limit block locator size? + // reference implementation limits to 500 results + var startCount = parser.varInt(); + + data.starts = []; + for (i = 0; i < startCount; i++) { + data.starts.push(parser.buffer(32)); + } + data.stop = parser.buffer(32); + break; + + case 'addr': + var addrCount = parser.varInt(); + + // Enforce a maximum number of addresses per message + if (addrCount > 1000) { + addrCount = 1000; + } + + data.addrs = []; + for (i = 0; i < addrCount; i++) { + // TODO: Time actually depends on the version of the other peer (>=31402) + data.addrs.push({ + time: parser.word32le(), + services: parser.word64le(), + ip: parser.buffer(16), + port: parser.word16be() + }); + } + break; + + case 'alert': + data.payload = parser.varStr(); + data.signature = parser.varStr(); + break; + + case 'ping': + if (this.recvVer > BIP0031_VERSION) { + data.nonce = parser.buffer(8); + } + break; + + case 'getaddr': + case 'verack': + case 'reject': + // Empty message, nothing to parse + break; + + default: + log.err('Connection.parseMessage(): Command not implemented', { + cmd: command + }); + + // This tells the calling function not to issue an event + return null; } return data; diff --git a/lib/Curve.js b/lib/Curve.js index dfdef52..da2a134 100644 --- a/lib/Curve.js +++ b/lib/Curve.js @@ -3,11 +3,12 @@ var imports = require('soop'); var bignum = imports.bignum || require('bignum'); var Point = imports.Point || require('./Point'); -var n = bignum.fromBuffer(new Buffer("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 'hex'), {size: 32}); +var n = bignum.fromBuffer(new Buffer("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 'hex'), { + size: 32 +}); -var Curve = function() { -}; +var Curve = function() {}; /* secp256k1 curve */ var G; @@ -16,8 +17,12 @@ Curve.getG = function() { // when Point is not loaded yet // use cached version if available - G = G || new Point(bignum.fromBuffer(new Buffer("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 'hex'), {size: 32}), - bignum.fromBuffer(new Buffer("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 'hex'), {size: 32})); + G = G || new Point(bignum.fromBuffer(new Buffer("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 'hex'), { + size: 32 + }), + bignum.fromBuffer(new Buffer("483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", 'hex'), { + size: 32 + })); return G; }; diff --git a/lib/Deserialize.js b/lib/Deserialize.js index 48befd6..12bd2b8 100644 --- a/lib/Deserialize.js +++ b/lib/Deserialize.js @@ -1,8 +1,5 @@ - -exports.intFromCompact = function(c) -{ +exports.intFromCompact = function(c) { var bytes = ((c >>> 24) & 0xff) >>> 0; var v = ((c & 0xffffff) << (8 * (bytes - 3))) >>> 0; return v; } - diff --git a/lib/Electrum.js b/lib/Electrum.js index 0245779..a4d4771 100644 --- a/lib/Electrum.js +++ b/lib/Electrum.js @@ -12,19 +12,23 @@ var Key = require('./Key'), * * @example examples/ElectrumMPK.js */ -function Electrum (master_public_key) { +function Electrum(master_public_key) { this.mpk = new Buffer(master_public_key, 'hex'); } -Electrum.prototype.getSequence = function (for_change, n) { +Electrum.prototype.getSequence = function(for_change, n) { var mode = for_change ? 1 : 0; - var buf = Buffer.concat([ new Buffer(n + ':' + mode + ':', 'utf8'), this.mpk ]); + var buf = Buffer.concat([new Buffer(n + ':' + mode + ':', 'utf8'), this.mpk]); return bignum.fromBuffer(twoSha256(buf)); }; -Electrum.prototype.generatePubKey = function (n, for_change) { - var x = bignum.fromBuffer(this.mpk.slice(0, 32), { size: 32 }); - var y = bignum.fromBuffer(this.mpk.slice(32, 64), { size: 32 }); +Electrum.prototype.generatePubKey = function(n, for_change) { + var x = bignum.fromBuffer(this.mpk.slice(0, 32), { + size: 32 + }); + var y = bignum.fromBuffer(this.mpk.slice(32, 64), { + size: 32 + }); var mpk_pt = new Point(x, y); var sequence = this.getSequence(for_change, n); @@ -37,8 +41,12 @@ Electrum.prototype.generatePubKey = function (n, for_change) { pt = Point.add(mpk_pt, sequence_pt); - var xbuf = pt.x.toBuffer({ size: 32 }); - var ybuf = pt.y.toBuffer({ size: 32 }); + var xbuf = pt.x.toBuffer({ + size: 32 + }); + var ybuf = pt.y.toBuffer({ + size: 32 + }); var prefix = new Buffer([0x04]); var key = new Key(); @@ -48,7 +56,7 @@ Electrum.prototype.generatePubKey = function (n, for_change) { return key.public; }; -Electrum.prototype.generateChangePubKey = function (sequence) { +Electrum.prototype.generateChangePubKey = function(sequence) { return this.generatePubKey(sequence, true); }; diff --git a/lib/HierarchicalKey.js b/lib/HierarchicalKey.js index 4f45afb..7e2bf1f 100644 --- a/lib/HierarchicalKey.js +++ b/lib/HierarchicalKey.js @@ -19,8 +19,7 @@ var HierarchicalKey = function(bytes) { if (typeof bytes == 'undefined' || bytes == 'mainnet' || bytes == 'livenet') { bytes = 'livenet'; this.version = networks['livenet'].hkeyPrivateVersion; - } - else if (bytes == 'testnet') { + } else if (bytes == 'testnet') { this.version = networks['testnet'].hkeyPrivateVersion; } if (bytes == 'livenet' || bytes == 'testnet') { @@ -35,12 +34,12 @@ var HierarchicalKey = function(bytes) { this.buildExtendedPrivateKey(); return; } - + // decode base58 if (typeof bytes === 'string') { var decoded = base58.decode(bytes); if (decoded.length != 82) - throw new Error('Not enough data, expected 82 and received '+decoded.length); + throw new Error('Not enough data, expected 82 and received ' + decoded.length); var checksum = decoded.slice(78, 82); bytes = decoded.slice(0, 78); @@ -51,7 +50,7 @@ var HierarchicalKey = function(bytes) { } } - if (bytes !== undefined && bytes !== null) + if (bytes !== undefined && bytes !== null) this.initFromBytes(bytes); } @@ -61,9 +60,9 @@ HierarchicalKey.seed = function(bytes, network) { if (!Buffer.isBuffer(bytes)) bytes = new Buffer(bytes, 'hex'); //if not buffer, assume hex - if (bytes.length < 128/8) + if (bytes.length < 128 / 8) return false; //need more entropy - if (bytes.length > 512/8) + if (bytes.length > 512 / 8) return false; var hash = coinUtil.sha512hmac(bytes, new Buffer('Bitcoin seed')); @@ -87,23 +86,23 @@ HierarchicalKey.seed = function(bytes, network) { HierarchicalKey.prototype.initFromBytes = function(bytes) { // Both pub and private extended keys are 78 bytes - if(bytes.length != 78) throw new Error('not enough data'); + if (bytes.length != 78) throw new Error('not enough data'); - this.version = u32(bytes.slice(0, 4)); - this.depth = u8(bytes.slice(4, 5)); + this.version = u32(bytes.slice(0, 4)); + this.depth = u8(bytes.slice(4, 5)); this.parentFingerprint = bytes.slice(5, 9); - this.childIndex = u32(bytes.slice(9, 13)); - this.chainCode = bytes.slice(13, 45); - + this.childIndex = u32(bytes.slice(9, 13)); + this.chainCode = bytes.slice(13, 45); + var keyBytes = bytes.slice(45, 78); - var isPrivate = - (this.version == networks['livenet'].hkeyPrivateVersion || - this.version == networks['testnet'].hkeyPrivateVersion ); + var isPrivate = + (this.version == networks['livenet'].hkeyPrivateVersion || + this.version == networks['testnet'].hkeyPrivateVersion); - var isPublic = - (this.version == networks['livenet'].hkeyPublicVersion || - this.version == networks['testnet'].hkeyPublicVersion ); + var isPublic = + (this.version == networks['livenet'].hkeyPublicVersion || + this.version == networks['testnet'].hkeyPublicVersion); if (isPrivate && keyBytes[0] == 0) { this.eckey = new Key(); @@ -129,17 +128,17 @@ HierarchicalKey.prototype.buildExtendedPublicKey = function() { this.extendedPublicKey = new Buffer([]); var v = null; - switch(this.version) { - case networks['livenet'].hkeyPublicVersion: - case networks['livenet'].hkeyPrivateVersion: - v = networks['livenet'].hkeyPublicVersion; - break; - case networks['testnet'].hkeyPublicVersion: - case networks['testnet'].hkeyPrivateVersion: - v = networks['testnet'].hkeyPublicVersion; - break; - default: - throw new Error('Unknown version'); + switch (this.version) { + case networks['livenet'].hkeyPublicVersion: + case networks['livenet'].hkeyPrivateVersion: + v = networks['livenet'].hkeyPublicVersion; + break; + case networks['testnet'].hkeyPublicVersion: + case networks['testnet'].hkeyPrivateVersion: + v = networks['testnet'].hkeyPublicVersion; + break; + default: + throw new Error('Unknown version'); } // Version @@ -220,12 +219,12 @@ HierarchicalKey.prototype.derive = function(path) { for (var i in e) { var c = e[i]; - if (i == 0 ) { + if (i == 0) { if (c != 'm') throw new Error('invalid path'); continue; } - var usePrivate = (c.length > 1) && (c[c.length-1] == '\''); + var usePrivate = (c.length > 1) && (c[c.length - 1] == '\''); var childIndex = parseInt(usePrivate ? c.slice(0, c.length - 1) : c) & 0x7fffffff; if (usePrivate) @@ -241,15 +240,15 @@ HierarchicalKey.prototype.deriveChild = function(i) { var ib = []; ib.push((i >> 24) & 0xff); ib.push((i >> 16) & 0xff); - ib.push((i >> 8) & 0xff); + ib.push((i >> 8) & 0xff); ib.push(i & 0xff); ib = new Buffer(ib); var usePrivate = (i & 0x80000000) != 0; - var isPrivate = - (this.version == networks['livenet'].hkeyPrivateVersion || - this.version == networks['testnet'].hkeyPrivateVersion ); + var isPrivate = + (this.version == networks['livenet'].hkeyPrivateVersion || + this.version == networks['testnet'].hkeyPrivateVersion); if (usePrivate && (!this.hasPrivateKey || !isPrivate)) throw new Error('Cannot do private key derivation without private key'); @@ -265,18 +264,24 @@ HierarchicalKey.prototype.deriveChild = function(i) { } var hash = coinUtil.sha512hmac(data, this.chainCode); - var il = bignum.fromBuffer(hash.slice(0, 32), {size: 32}); + var il = bignum.fromBuffer(hash.slice(0, 32), { + size: 32 + }); var ir = hash.slice(32, 64); // ki = IL + kpar (mod n). - var priv = bignum.fromBuffer(this.eckey.private, {size: 32}); + var priv = bignum.fromBuffer(this.eckey.private, { + size: 32 + }); var k = il.add(priv).mod(secp256k1_n); ret = new HierarchicalKey(null); ret.chainCode = ir; ret.eckey = new Key(); - ret.eckey.private = k.toBuffer({size: 32}); + ret.eckey.private = k.toBuffer({ + size: 32 + }); ret.eckey.regenerateSync(); ret.hasPrivateKey = true; @@ -302,14 +307,14 @@ HierarchicalKey.prototype.deriveChild = function(i) { ret.chainCode = new Buffer(ir); var eckey = new Key(); - eckey.public = newpub; + eckey.public = newpub; eckey.compressed = true; ret.eckey = eckey; ret.hasPrivateKey = false; } ret.childIndex = i; - ret.parentFingerprint = this.pubKeyHash.slice(0,4); + ret.parentFingerprint = this.pubKeyHash.slice(0, 4); ret.version = this.version; ret.depth = this.depth + 1; @@ -334,9 +339,20 @@ function uint(f, size) { return n; } -function u8(f) {return uint(f,1);} -function u16(f) {return uint(f,2);} -function u32(f) {return uint(f,4);} -function u64(f) {return uint(f,8);} +function u8(f) { + return uint(f, 1); +} + +function u16(f) { + return uint(f, 2); +} + +function u32(f) { + return uint(f, 4); +} + +function u64(f) { + return uint(f, 8); +} module.exports = require('soop')(HierarchicalKey); diff --git a/lib/Message.js b/lib/Message.js index 018090c..d1c8a7a 100644 --- a/lib/Message.js +++ b/lib/Message.js @@ -3,8 +3,7 @@ var imports = require('soop').imports(); var coinUtil = imports.coinUtil || require('../util'); var Key = imports.Key || require('./Key'); -var Message = function() { -}; +var Message = function() {}; Message.sign = function(str, key) { var hash = Message.magicHash(str); diff --git a/lib/Opcode.js b/lib/Opcode.js index 44f693f..4111e32 100644 --- a/lib/Opcode.js +++ b/lib/Opcode.js @@ -1,156 +1,156 @@ -var imports = require('soop').imports(); +var imports = require('soop').imports(); function Opcode(num) { this.code = num; }; -Opcode.prototype.toString = function () { +Opcode.prototype.toString = function() { return Opcode.reverseMap[this.code]; }; Opcode.map = { // push value - OP_FALSE : 0, - OP_0 : 0, - OP_PUSHDATA1 : 76, - OP_PUSHDATA2 : 77, - OP_PUSHDATA4 : 78, - OP_1NEGATE : 79, - OP_RESERVED : 80, - OP_TRUE : 81, - OP_1 : 81, - OP_2 : 82, - OP_3 : 83, - OP_4 : 84, - OP_5 : 85, - OP_6 : 86, - OP_7 : 87, - OP_8 : 88, - OP_9 : 89, - OP_10 : 90, - OP_11 : 91, - OP_12 : 92, - OP_13 : 93, - OP_14 : 94, - OP_15 : 95, - OP_16 : 96, + OP_FALSE: 0, + OP_0: 0, + OP_PUSHDATA1: 76, + OP_PUSHDATA2: 77, + OP_PUSHDATA4: 78, + OP_1NEGATE: 79, + OP_RESERVED: 80, + OP_TRUE: 81, + OP_1: 81, + OP_2: 82, + OP_3: 83, + OP_4: 84, + OP_5: 85, + OP_6: 86, + OP_7: 87, + OP_8: 88, + OP_9: 89, + OP_10: 90, + OP_11: 91, + OP_12: 92, + OP_13: 93, + OP_14: 94, + OP_15: 95, + OP_16: 96, // control - OP_NOP : 97, - OP_VER : 98, - OP_IF : 99, - OP_NOTIF : 100, - OP_VERIF : 101, - OP_VERNOTIF : 102, - OP_ELSE : 103, - OP_ENDIF : 104, - OP_VERIFY : 105, - OP_RETURN : 106, + OP_NOP: 97, + OP_VER: 98, + OP_IF: 99, + OP_NOTIF: 100, + OP_VERIF: 101, + OP_VERNOTIF: 102, + OP_ELSE: 103, + OP_ENDIF: 104, + OP_VERIFY: 105, + OP_RETURN: 106, // stack ops - OP_TOALTSTACK : 107, - OP_FROMALTSTACK : 108, - OP_2DROP : 109, - OP_2DUP : 110, - OP_3DUP : 111, - OP_2OVER : 112, - OP_2ROT : 113, - OP_2SWAP : 114, - OP_IFDUP : 115, - OP_DEPTH : 116, - OP_DROP : 117, - OP_DUP : 118, - OP_NIP : 119, - OP_OVER : 120, - OP_PICK : 121, - OP_ROLL : 122, - OP_ROT : 123, - OP_SWAP : 124, - OP_TUCK : 125, + OP_TOALTSTACK: 107, + OP_FROMALTSTACK: 108, + OP_2DROP: 109, + OP_2DUP: 110, + OP_3DUP: 111, + OP_2OVER: 112, + OP_2ROT: 113, + OP_2SWAP: 114, + OP_IFDUP: 115, + OP_DEPTH: 116, + OP_DROP: 117, + OP_DUP: 118, + OP_NIP: 119, + OP_OVER: 120, + OP_PICK: 121, + OP_ROLL: 122, + OP_ROT: 123, + OP_SWAP: 124, + OP_TUCK: 125, // splice ops - OP_CAT : 126, - OP_SUBSTR : 127, - OP_LEFT : 128, - OP_RIGHT : 129, - OP_SIZE : 130, + OP_CAT: 126, + OP_SUBSTR: 127, + OP_LEFT: 128, + OP_RIGHT: 129, + OP_SIZE: 130, // bit logic - OP_INVERT : 131, - OP_AND : 132, - OP_OR : 133, - OP_XOR : 134, - OP_EQUAL : 135, - OP_EQUALVERIFY : 136, - OP_RESERVED1 : 137, - OP_RESERVED2 : 138, + OP_INVERT: 131, + OP_AND: 132, + OP_OR: 133, + OP_XOR: 134, + OP_EQUAL: 135, + OP_EQUALVERIFY: 136, + OP_RESERVED1: 137, + OP_RESERVED2: 138, // numeric - OP_1ADD : 139, - OP_1SUB : 140, - OP_2MUL : 141, - OP_2DIV : 142, - OP_NEGATE : 143, - OP_ABS : 144, - OP_NOT : 145, - OP_0NOTEQUAL : 146, + OP_1ADD: 139, + OP_1SUB: 140, + OP_2MUL: 141, + OP_2DIV: 142, + OP_NEGATE: 143, + OP_ABS: 144, + OP_NOT: 145, + OP_0NOTEQUAL: 146, - OP_ADD : 147, - OP_SUB : 148, - OP_MUL : 149, - OP_DIV : 150, - OP_MOD : 151, - OP_LSHIFT : 152, - OP_RSHIFT : 153, + OP_ADD: 147, + OP_SUB: 148, + OP_MUL: 149, + OP_DIV: 150, + OP_MOD: 151, + OP_LSHIFT: 152, + OP_RSHIFT: 153, - OP_BOOLAND : 154, - OP_BOOLOR : 155, - OP_NUMEQUAL : 156, - OP_NUMEQUALVERIFY : 157, - OP_NUMNOTEQUAL : 158, - OP_LESSTHAN : 159, - OP_GREATERTHAN : 160, - OP_LESSTHANOREQUAL : 161, - OP_GREATERTHANOREQUAL : 162, - OP_MIN : 163, - OP_MAX : 164, + OP_BOOLAND: 154, + OP_BOOLOR: 155, + OP_NUMEQUAL: 156, + OP_NUMEQUALVERIFY: 157, + OP_NUMNOTEQUAL: 158, + OP_LESSTHAN: 159, + OP_GREATERTHAN: 160, + OP_LESSTHANOREQUAL: 161, + OP_GREATERTHANOREQUAL: 162, + OP_MIN: 163, + OP_MAX: 164, - OP_WITHIN : 165, + OP_WITHIN: 165, // crypto - OP_RIPEMD160 : 166, - OP_SHA1 : 167, - OP_SHA256 : 168, - OP_HASH160 : 169, - OP_HASH256 : 170, - OP_CODESEPARATOR : 171, - OP_CHECKSIG : 172, - OP_CHECKSIGVERIFY : 173, - OP_CHECKMULTISIG : 174, - OP_CHECKMULTISIGVERIFY : 175, + OP_RIPEMD160: 166, + OP_SHA1: 167, + OP_SHA256: 168, + OP_HASH160: 169, + OP_HASH256: 170, + OP_CODESEPARATOR: 171, + OP_CHECKSIG: 172, + OP_CHECKSIGVERIFY: 173, + OP_CHECKMULTISIG: 174, + OP_CHECKMULTISIGVERIFY: 175, // expansion - OP_NOP1 : 176, - OP_NOP2 : 177, - OP_NOP3 : 178, - OP_NOP4 : 179, - OP_NOP5 : 180, - OP_NOP6 : 181, - OP_NOP7 : 182, - OP_NOP8 : 183, - OP_NOP9 : 184, - OP_NOP10 : 185, + OP_NOP1: 176, + OP_NOP2: 177, + OP_NOP3: 178, + OP_NOP4: 179, + OP_NOP5: 180, + OP_NOP6: 181, + OP_NOP7: 182, + OP_NOP8: 183, + OP_NOP9: 184, + OP_NOP10: 185, // template matching params - OP_PUBKEYHASH : 253, - OP_PUBKEY : 254, - OP_INVALIDOPCODE : 255 + OP_PUBKEYHASH: 253, + OP_PUBKEY: 254, + OP_INVALIDOPCODE: 255 }; Opcode.reverseMap = []; for (var k in Opcode.map) { - if(Opcode.map.hasOwnProperty(k)) { + if (Opcode.map.hasOwnProperty(k)) { Opcode.reverseMap[Opcode.map[k]] = k.substr(3); } } diff --git a/lib/Peer.js b/lib/Peer.js index a73d66e..123ec65 100644 --- a/lib/Peer.js +++ b/lib/Peer.js @@ -1,7 +1,7 @@ -var imports = require('soop').imports(); +var imports = require('soop').imports(); -var Net = imports.Net || require('net'); -var Binary = imports.Binary || require('binary'); +var Net = imports.Net || require('net'); +var Binary = imports.Binary || require('binary'); var buffertools = imports.buffertools || require('buffertools'); function Peer(host, port, services) { @@ -24,29 +24,29 @@ function Peer(host, port, services) { this.port = +port || 8333; } else { throw new Error('Could not instantiate peer, invalid parameter type: ' + - typeof host); + typeof host); } this.services = (services) ? services : null; this.lastSeen = 0; }; -Peer.IPV6_IPV4_PADDING = new Buffer([0,0,0,0,0,0,0,0,0,0,255,255]); +Peer.IPV6_IPV4_PADDING = new Buffer([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255]); -Peer.prototype.createConnection = function () { +Peer.prototype.createConnection = function() { this.connection = Net.createConnection(this.port, this.host); return this.connection; }; -Peer.prototype.getHostAsBuffer = function () { +Peer.prototype.getHostAsBuffer = function() { return new Buffer(this.host.split('.')); }; -Peer.prototype.toString = function () { +Peer.prototype.toString = function() { return this.host + ":" + this.port; }; -Peer.prototype.toBuffer = function () { +Peer.prototype.toBuffer = function() { var put = Binary.put(); put.word32le(this.lastSeen); put.word64le(this.services); diff --git a/lib/PeerManager.js b/lib/PeerManager.js index df7029b..4c95ffc 100644 --- a/lib/PeerManager.js +++ b/lib/PeerManager.js @@ -1,10 +1,10 @@ -var imports = require('soop').imports(); -var log = imports.log || require('../util/log'); +var imports = require('soop').imports(); +var log = imports.log || require('../util/log'); var bitcoreDefaults = imports.config || require('../config'); -var Connection = imports.Connection || require ('./Connection'); -var Peer = imports.Peer || require('./Peer'); +var Connection = imports.Connection || require('./Connection'); +var Peer = imports.Peer || require('./Peer'); -GetAdjustedTime = imports.GetAdjustedTime || function () { +GetAdjustedTime = imports.GetAdjustedTime || function() { // TODO: Implement actual adjustment return Math.floor(new Date().getTime() / 1000); }; @@ -42,36 +42,37 @@ PeerManager.Connection = Connection; PeerManager.prototype.start = function() { this.active = true; - if(!this.timer) { + if (!this.timer) { this.timer = setInterval(this.checkStatus.bind(this), this.interval); } }; PeerManager.prototype.stop = function() { this.active = false; - if(this.timer) { + if (this.timer) { clearInterval(this.timer); this.timer = null; } - for(var i=0; i= 31402 || this.peers.length < 1000)) { + if (this.peerDiscovery && + (e.message.version >= 31402 || this.peers.length < 1000)) { e.conn.sendGetAddr(); e.conn.getaddr = true; } }; -PeerManager.prototype.handleReady = function (e) { - log.info('connected to '+e.conn.peer.host+':'+e.conn.peer.port); +PeerManager.prototype.handleReady = function(e) { + log.info('connected to ' + e.conn.peer.host + ':' + e.conn.peer.port); this.emit('connect', { pm: this, conn: e.conn, @@ -155,17 +156,17 @@ PeerManager.prototype.handleReady = function (e) { peer: e.peer }); - if(this.isConnected == false) { + if (this.isConnected == false) { this.emit('netConnected', e); this.isConnected = true; } }; -PeerManager.prototype.handleAddr = function (e) { - if(!this.peerDiscovery) return; +PeerManager.prototype.handleAddr = function(e) { + if (!this.peerDiscovery) return; var now = GetAdjustedTime(); - e.message.addrs.forEach(function (addr) { + e.message.addrs.forEach(function(addr) { try { // In case of an invalid time, assume "5 days ago" if (addr.time <= 100000000 || addr.time > (now + 10 * 60)) { @@ -178,11 +179,11 @@ PeerManager.prototype.handleAddr = function (e) { this.peers.push(peer); // TODO: Handle addr relay - } catch(e) { - log.warn("Invalid addr received: "+e.message); + } catch (e) { + log.warn("Invalid addr received: " + e.message); } }.bind(this)); - if (e.message.addrs.length < 1000 ) { + if (e.message.addrs.length < 1000) { e.conn.getaddr = false; } }; @@ -192,14 +193,14 @@ PeerManager.prototype.handleGetAddr = function(e) { }; PeerManager.prototype.handleError = function(e) { - log.err('unkown error with peer '+e.peer+' (disconnecting): '+e.err); + log.err('unkown error with peer ' + e.peer + ' (disconnecting): ' + e.err); this.handleDisconnect.apply(this, [].slice.call(arguments)); }; PeerManager.prototype.handleDisconnect = function(e) { log.info('disconnected from peer ' + e.peer); var i = this.connections.indexOf(e.conn); - if(i != -1) this.connections.splice(i, 1); + if (i != -1) this.connections.splice(i, 1); this.removePeer(e.peer); if (this.pool.length) { @@ -207,19 +208,19 @@ PeerManager.prototype.handleDisconnect = function(e) { this.addPeer(this.pool.pop()); } - if(!this.connections.length) { + if (!this.connections.length) { this.emit('netDisconnected'); this.isConnected = false; } }; -PeerManager.prototype.getActiveConnection = function () { - var activeConnections = this.connections.filter(function (conn) { +PeerManager.prototype.getActiveConnection = function() { + var activeConnections = this.connections.filter(function(conn) { return conn.active; }); if (activeConnections.length) { - var randomIndex = Math.floor(Math.random()*activeConnections.length); + var randomIndex = Math.floor(Math.random() * activeConnections.length); var candidate = activeConnections[randomIndex]; if (candidate.socket.writable) { return candidate; @@ -237,16 +238,16 @@ PeerManager.prototype.getActiveConnection = function () { } }; -PeerManager.prototype.getActiveConnections = function () { +PeerManager.prototype.getActiveConnections = function() { return this.connections.slice(0); }; PeerManager.prototype.discover = function(options, callback) { - var self = this; - var async = imports.async || require('async'); - var dns = imports.dns || require('dns'); + var self = this; + var async = imports.async || require('async'); + var dns = imports.dns || require('dns'); var networks = imports.networks || require('../networks'); - var seeds = networks[self.config.network].dnsSeeds; + var seeds = networks[self.config.network].dnsSeeds; self.limit = options.limit || 12; @@ -264,16 +265,16 @@ PeerManager.prototype.discover = function(options, callback) { return done(null, []); } - log.info('resolving dns seed '+ seed); + log.info('resolving dns seed ' + seed); dns.resolve(seed, function(err, peers) { if (err) { - log.err('failed to resolve dns seed '+ seed, err); + log.err('failed to resolve dns seed ' + seed, err); self.seeds.failed.push(seed); return done(null, []); } - log.info('found '+ peers.length + ' peers from ' + seed); + log.info('found ' + peers.length + ' peers from ' + seed); self.seeds.resolved.push(seed); // transform that list into a list of Peer instances diff --git a/lib/Point.js b/lib/Point.js index 3864b80..e3e57eb 100644 --- a/lib/Point.js +++ b/lib/Point.js @@ -28,15 +28,23 @@ Point.multiply = function(p1, x) { //convert the public key of a Key into a Point Point.fromUncompressedPubKey = function(pubkey) { var point = new Point(); - point.x = bignum.fromBuffer(pubkey.slice(1, 33), {size: 32}); - point.y = bignum.fromBuffer(pubkey.slice(33, 65), {size: 32}); + point.x = bignum.fromBuffer(pubkey.slice(1, 33), { + size: 32 + }); + point.y = bignum.fromBuffer(pubkey.slice(33, 65), { + size: 32 + }); return point; }; //convert the Point into the Key containing a compressed public key Point.prototype.toUncompressedPubKey = function() { - var xbuf = this.x.toBuffer({size: 32}); - var ybuf = this.y.toBuffer({size: 32}); + var xbuf = this.x.toBuffer({ + size: 32 + }); + var ybuf = this.y.toBuffer({ + size: 32 + }); var prefix = new Buffer([0x04]); var pubkey = Buffer.concat([prefix, xbuf, ybuf]); return pubkey; diff --git a/lib/PrivateKey.js b/lib/PrivateKey.js index 62929fc..ddddca4 100644 --- a/lib/PrivateKey.js +++ b/lib/PrivateKey.js @@ -1,7 +1,7 @@ -var imports = require('soop').imports(); +var imports = require('soop').imports(); var parent = imports.parent || require('../util/VersionedData'); -var networks= imports.networks || require('../networks'); +var networks = imports.networks || require('../networks'); //compressed is true if public key is compressed; false otherwise function PrivateKey(version, buf, compressed) { @@ -16,7 +16,7 @@ parent.applyEncodingsTo(PrivateKey); PrivateKey.prototype.validate = function() { this.doAsBinary(function() { PrivateKey.super(this, 'validate', arguments); - if (this.data.length < 32 || (this.data.length > 1+32 && !this.compressed()) || (this.data.length==1+32+1 && this.data[1+32+1-1]!=1) || this.data.length>1+32+1) + if (this.data.length < 32 || (this.data.length > 1 + 32 && !this.compressed()) || (this.data.length == 1 + 32 + 1 && this.data[1 + 32 + 1 - 1] != 1) || this.data.length > 1 + 32 + 1) throw new Error('invalid data length'); }); if (typeof this.network() === 'undefined') throw new Error('invalid network'); @@ -25,38 +25,39 @@ PrivateKey.prototype.validate = function() { // get or set the payload data (as a Buffer object) // overloaded from VersionedData PrivateKey.prototype.payload = function(data) { - if(data) { - this.doAsBinary(function() {data.copy(this.data,1);}); + if (data) { + this.doAsBinary(function() { + data.copy(this.data, 1); + }); return data; } - var buf=this.as('binary'); - if (buf.length==1+32+1) - return buf.slice(1,1+32); - else if (buf.length==1+32) + var buf = this.as('binary'); + if (buf.length == 1 + 32 + 1) + return buf.slice(1, 1 + 32); + else if (buf.length == 1 + 32) return buf.slice(1); }; // get or set whether the corresponding public key is compressed PrivateKey.prototype.compressed = function(compressed) { if (compressed !== undefined) { - this.doAsBinary(function(){ - var len=1+32+1; + this.doAsBinary(function() { + var len = 1 + 32 + 1; if (compressed) { - var data=new Buffer(len); + var data = new Buffer(len); this.data.copy(data); - this.data=data; - this.data[len-1]=1; + this.data = data; + this.data[len - 1] = 1; } else { - this.data=this.data.slice(0,len-1); + this.data = this.data.slice(0, len - 1); } }); - } - else { - var len=1+32+1; - var data=this.as('binary'); - if (data.length==len && data[len-1]==1) + } else { + var len = 1 + 32 + 1; + var data = this.as('binary'); + if (data.length == len && data[len - 1] == 1) return true; - else if (data.length==len-1) + else if (data.length == len - 1) return false; else throw new Error('invalid private key'); diff --git a/lib/RpcClient.js b/lib/RpcClient.js index 68cc16f..62b9ce0 100644 --- a/lib/RpcClient.js +++ b/lib/RpcClient.js @@ -3,9 +3,9 @@ // Copyright 2013 BitPay, Inc. // var imports = require('soop').imports(); -var http = imports.http || require('http'); -var https = imports.https || require('https'); -var log = imports.log || require('../util/log'); +var http = imports.http || require('http'); +var https = imports.https || require('https'); +var log = imports.log || require('../util/log'); function RpcClient(opts) { opts = opts || {}; @@ -15,9 +15,9 @@ function RpcClient(opts) { this.pass = opts.pass || 'pass'; this.protocol = (opts.protocol == 'http') ? http : https; this.batchedCalls = null; - this.disableAgent = opts.disableAgent || false; + this.disableAgent = opts.disableAgent || false; } - + RpcClient.prototype.batch = function(batchCallback, resultCallback) { this.batchedCalls = []; batchCallback(); @@ -77,7 +77,7 @@ var callspec = { lockUnspent: '', move: 'str str float int str', sendFrom: 'str str float int str str', - sendMany: 'str str int str', //not sure this is will work + sendMany: 'str str int str', //not sure this is will work sendRawTransaction: '', sendToAddress: 'str float str str', setAccount: '', @@ -102,30 +102,45 @@ function generateRPCMethods(constructor, apiCalls, rpc) { function createRPCMethod(methodName, argMap) { return function() { var limit = arguments.length - 1; - if(this.batchedCalls) var limit = arguments.length; - for (var i=0; i 3 && isSmallIntOp(this.chunks[0]) && - this.chunks.slice(1,this.chunks.length-2).every(function(i){return Buffer.isBuffer(i);}) && + this.chunks.slice(1, this.chunks.length - 2).every(function(i) { + return Buffer.isBuffer(i); + }) && isSmallIntOp(this.chunks[this.chunks.length - 2]) && this.chunks[this.chunks.length - 1] == Opcode.map.OP_CHECKMULTISIG); }; Script.prototype.isP2shScriptSig = function() { - if( !isSmallIntOp(this.chunks[0]) || this.chunks[0] !==0 ) + if (!isSmallIntOp(this.chunks[0]) || this.chunks[0] !== 0) return false; - var redeemScript = new Script(this.chunks[this.chunks.length-1]); - var type=redeemScript.classify(); + var redeemScript = new Script(this.chunks[this.chunks.length - 1]); + var type = redeemScript.classify(); return type !== TX_UNKNOWN; }; Script.prototype.isMultiSigScriptSig = function() { - if( !isSmallIntOp(this.chunks[0]) || this.chunks[0] !==0 ) + if (!isSmallIntOp(this.chunks[0]) || this.chunks[0] !== 0) return false; return !this.isP2shScriptSig(); }; Script.prototype.countSignatures = function() { var ret = 0; - var l =this.chunks.length; + var l = this.chunks.length; // Multisig? - if (this.isMultiSigScriptSig()){ + if (this.isMultiSigScriptSig()) { ret = l - 1; - } - else if (this.isP2shScriptSig()) { + } else if (this.isP2shScriptSig()) { ret = l - 2; } // p2pubkey or p2pubkeyhash else { - ret = buffertools.compare(this.getBuffer(), util.EMPTY_BUFFER)===0?0:1; + ret = buffertools.compare(this.getBuffer(), util.EMPTY_BUFFER) === 0 ? 0 : 1; } return ret; }; @@ -155,14 +156,13 @@ Script.prototype.countMissingSignatures = function() { } var ret = 0; - var l =this.chunks.length; + var l = this.chunks.length; // P2SH? - if (isSmallIntOp(this.chunks[0]) && this.chunks[0] ===0) { - var redeemScript = new Script(this.chunks[l-1]); + if (isSmallIntOp(this.chunks[0]) && this.chunks[0] === 0) { + var redeemScript = new Script(this.chunks[l - 1]); if (!isSmallIntOp(redeemScript.chunks[0])) { log.debug("Unrecognized script type"); - } - else { + } else { var nreq = redeemScript.chunks[0] - 80; //see OP_2-OP_16 ret = nreq - (l - 2); // 2-> marked 0 + redeemScript } @@ -201,9 +201,9 @@ Script.prototype.getMultiSigInfo = function() { } return { - nsigs : nsigs, - npubkeys : npubkeys, - pubkeys : pubkeys + nsigs: nsigs, + npubkeys: npubkeys, + pubkeys: pubkeys } }; @@ -567,7 +567,7 @@ Script.prototype.toHumanReadable = function() { } else { var opcode = Opcode.reverseMap[chunk]; if (typeof opcode === 'undefined') { - opcode = '0x'+chunk.toString(16); + opcode = '0x' + chunk.toString(16); } s += opcode; } @@ -598,17 +598,17 @@ Script.stringToBuffer = function(s) { //console.log('integer'); var data = util.intToBufferSM(integer); buf.put(Script.chunksToBuffer([data])); - } else if (word[0] === '\'' && word[word.length-1] === '\'') { + } else if (word[0] === '\'' && word[word.length - 1] === '\'') { // string //console.log('string'); - word = word.substring(1,word.length-1); + word = word.substring(1, word.length - 1); var hexString = ''; - for(var c=0;c 0) - return; + case TX_PUBKEY: + // already signed + if (scriptSig.chunks.length > 0) + return; - var pubkeyhash = util.sha256ripe160(scriptData[0]); - var addr = new Address(network.addressVersion, pubkeyhash); - var addrStr = addr.toString(); - if (!(addrStr in keys)) - throw new Error("unknown pubkey"); - - var signature = signOne(hash, addrStr, keys); - scriptSig.writeBytes(signature); - break; - - case TX_PUBKEYHASH: - // already signed - if (scriptSig.chunks.length > 0) - return; - - var addr = new Address(network.addressVersion, scriptData[0]); - var addrStr = addr.toString(); - if (!(addrStr in keys)) - throw new Error("unknown pubkey hash address"); - - var signature = signOne(hash, addrStr, keys); - scriptSig.writeBytes(signature); - scriptSig.writeBytes(key.public); - break; - - case TX_SCRIPTHASH: - // already signed - if (scriptSig.chunks.length > 0) - return; - - var addr = new Address(network.addressVersion, subData[0]); - var addrStr = addr.toString(); - if (!(addrStr in keys)) - throw new Error("unknown script(pubkey hash) address"); - - var signature = signOne(hash, addrStr, keys); - scriptSig.writeBytes(signature); - scriptSig.writeBytes(key.public); - break; - - case TX_MULTISIG: - while (scriptSig.chunks.length < scriptData.length) { - scriptSig.writeBytes(util.EMPTY_BUFFER); - } - for (var i = 0; i < scriptData.length; i++) { - // skip already signed - if (scriptSig.chunks[i].length > 0) - continue; - - var pubkeyhash = util.sha256ripe160(scriptSig.chunks[i]); + var pubkeyhash = util.sha256ripe160(scriptData[0]); var addr = new Address(network.addressVersion, pubkeyhash); var addrStr = addr.toString(); if (!(addrStr in keys)) - continue; + throw new Error("unknown pubkey"); var signature = signOne(hash, addrStr, keys); - scriptSig.chunks[i] = signature; - } - break; + scriptSig.writeBytes(signature); + break; + + case TX_PUBKEYHASH: + // already signed + if (scriptSig.chunks.length > 0) + return; + + var addr = new Address(network.addressVersion, scriptData[0]); + var addrStr = addr.toString(); + if (!(addrStr in keys)) + throw new Error("unknown pubkey hash address"); + + var signature = signOne(hash, addrStr, keys); + scriptSig.writeBytes(signature); + scriptSig.writeBytes(key.public); + break; + + case TX_SCRIPTHASH: + // already signed + if (scriptSig.chunks.length > 0) + return; + + var addr = new Address(network.addressVersion, subData[0]); + var addrStr = addr.toString(); + if (!(addrStr in keys)) + throw new Error("unknown script(pubkey hash) address"); + + var signature = signOne(hash, addrStr, keys); + scriptSig.writeBytes(signature); + scriptSig.writeBytes(key.public); + break; + + case TX_MULTISIG: + while (scriptSig.chunks.length < scriptData.length) { + scriptSig.writeBytes(util.EMPTY_BUFFER); + } + for (var i = 0; i < scriptData.length; i++) { + // skip already signed + if (scriptSig.chunks[i].length > 0) + continue; + + var pubkeyhash = util.sha256ripe160(scriptSig.chunks[i]); + var addr = new Address(network.addressVersion, pubkeyhash); + var addrStr = addr.toString(); + if (!(addrStr in keys)) + continue; + + var signature = signOne(hash, addrStr, keys); + scriptSig.chunks[i] = signature; + } + break; } if (txtype == TX_SCRIPTHASH) scriptSig.writeBytes(subscriptRaw); } -exports.Transaction = function Transaction(tx, txInputs, network, keys, scripts) -{ +exports.Transaction = function Transaction(tx, txInputs, network, keys, scripts) { for (var i = 0; i < tx.ins.length; i++) signTxIn(i, tx, txInputs, network, keys, scripts); }; - diff --git a/lib/Transaction.js b/lib/Transaction.js index d79b627..c39a2d3 100644 --- a/lib/Transaction.js +++ b/lib/Transaction.js @@ -199,13 +199,13 @@ Transaction.prototype.getHash = function getHash() { }; -Transaction.prototype.calcNormalizedHash = function () { - this.normalizedHash = this.hashForSignature(new Script(),0, SIGHASH_ALL); +Transaction.prototype.calcNormalizedHash = function() { + this.normalizedHash = this.hashForSignature(new Script(), 0, SIGHASH_ALL); return this.normalizedHash; }; -Transaction.prototype.getNormalizedHash = function () { +Transaction.prototype.getNormalizedHash = function() { if (!this.normalizedHash || !this.normalizedHash.length) { this.normalizedHash = this.calcNormalizedHash(); } @@ -403,7 +403,7 @@ var oneBuffer = function() { // see https://bitcointalk.org/index.php?topic=260595 var ret = new Buffer(32); ret.writeUInt8(1, 0); - for (var i=1; i<32; i++) ret.writeUInt8(0, i); + for (var i = 1; i < 32; i++) ret.writeUInt8(0, i); return ret; // return 1 bug }; @@ -586,7 +586,7 @@ Transaction.prototype.calcSize = function() { return totalSize; }; -Transaction.prototype.getSize = function () { +Transaction.prototype.getSize = function() { if (!this.size) { this.size = this.calcSize(); } @@ -609,17 +609,17 @@ Transaction.prototype.countInputMissingSignatures = function(index) { // Works on p2pubkey, p2pubkeyhash & p2sh (no normal multisig) Transaction.prototype.isInputComplete = function(index) { var m = this.countInputMissingSignatures(index); - if (m===null) return null; + if (m === null) return null; return m === 0; }; // Works on p2pubkey, p2pubkeyhash & p2sh (no normal multisig) Transaction.prototype.isComplete = function() { var ret = true; - var l = this.ins.length; + var l = this.ins.length; for (var i = 0; i < l; i++) { - if (!this.isInputComplete(i)){ + if (!this.isInputComplete(i)) { ret = false; break; } diff --git a/lib/TransactionBuilder.js b/lib/TransactionBuilder.js index b3c5111..a16a330 100644 --- a/lib/TransactionBuilder.js +++ b/lib/TransactionBuilder.js @@ -97,8 +97,8 @@ var FEE_PER_1000B_SAT = parseInt(0.0001 * util.COIN); // ``` function TransactionBuilder(opts) { - opts = opts || {}; - this.lockTime = opts.lockTime || 0; + opts = opts || {}; + this.lockTime = opts.lockTime || 0; this.spendUnconfirmed = opts.spendUnconfirmed || false; if (opts.fee || opts.feeSat) { @@ -107,9 +107,9 @@ function TransactionBuilder(opts) { this.remainderOut = opts.remainderOut; this.signhash = opts.signhash || Transaction.SIGHASH_ALL; - this.tx = {}; - this.inputsSigned= 0; - this.signaturesAdded= 0; + this.tx = {}; + this.inputsSigned = 0; + this.signaturesAdded = 0; return this; } @@ -119,10 +119,10 @@ TransactionBuilder.FEE_PER_1000B_SAT = FEE_PER_1000B_SAT; TransactionBuilder._scriptForPubkeys = function(out) { var l = out.pubkeys.length; - var pubKeyBuf=[]; + var pubKeyBuf = []; - for (var i=0; i (maxSizeK + 1) * 1000); return this; @@ -383,13 +384,13 @@ TransactionBuilder.prototype._setFeeAndRemainder = function(txobj) { TransactionBuilder.prototype.setOutputs = function(outs) { var valueOutSat = bignum(0); - var txobj = {}; - txobj.version = 1; - txobj.lock_time = this.lockTime || 0; - txobj.ins = []; + var txobj = {}; + txobj.version = 1; + txobj.lock_time = this.lockTime || 0; + txobj.ins = []; txobj.outs = []; - var l =outs.length; + var l = outs.length; for (var i = 0; i < l; i++) { var amountSat = outs[i].amountSat || util.parseValue(outs[i].amount); var value = util.bigIntToValue(amountSat); @@ -422,13 +423,15 @@ TransactionBuilder._mapKeys = function(keys) { if (typeof k === 'string') { var pk = new PrivateKey(k); - wk = new WalletKey({ network: pk.network() }); - wk.fromObj({ priv: k }); - } - else if (k instanceof WalletKey) { + wk = new WalletKey({ + network: pk.network() + }); + wk.fromObj({ + priv: k + }); + } else if (k instanceof WalletKey) { wk = k; - } - else { + } else { throw new Error('argument must be an array of strings (WIF format) or WalletKey objects'); } walletKeyMap[wk.storeObj().addr] = wk; @@ -437,30 +440,31 @@ TransactionBuilder._mapKeys = function(keys) { }; TransactionBuilder._signHashAndVerify = function(wk, txSigHash) { - var triesLeft = 10, sigRaw; + var triesLeft = 10, + sigRaw; do { sigRaw = wk.privKey.signSync(txSigHash); } while (wk.privKey.verifySignatureSync(txSigHash, sigRaw) === false && - triesLeft--); + triesLeft--); - if (triesLeft<0) + if (triesLeft < 0) throw new Error('could not sign input: verification failed'); return sigRaw; }; TransactionBuilder.prototype._checkTx = function() { - if (! this.tx || !this.tx.ins.length || !this.tx.outs.length) + if (!this.tx || !this.tx.ins.length || !this.tx.outs.length) throw new Error('tx is not defined'); }; -TransactionBuilder.prototype._multiFindKey = function(walletKeyMap,pubKeyHash) { +TransactionBuilder.prototype._multiFindKey = function(walletKeyMap, pubKeyHash) { var wk; - [ networks.livenet, networks.testnet].forEach(function(n) { - [ n.addressVersion, n.P2SHVersion].forEach(function(v) { - var a = new Address(v,pubKeyHash); + [networks.livenet, networks.testnet].forEach(function(n) { + [n.addressVersion, n.P2SHVersion].forEach(function(v) { + var a = new Address(v, pubKeyHash); if (!wk && walletKeyMap[a]) { wk = walletKeyMap[a]; } @@ -474,14 +478,12 @@ TransactionBuilder.prototype._findWalletKey = function(walletKeyMap, input) { var wk; if (input.address) { - wk = walletKeyMap[input.address]; - } - else if (input.pubKeyHash) { - wk = this._multiFindKey(walletKeyMap, input.pubKeyHash); - } - else if (input.pubKeyBuf) { + wk = walletKeyMap[input.address]; + } else if (input.pubKeyHash) { + wk = this._multiFindKey(walletKeyMap, input.pubKeyHash); + } else if (input.pubKeyBuf) { var pubKeyHash = util.sha256ripe160(input.pubKeyBuf); - wk = this._multiFindKey(walletKeyMap, pubKeyHash); + wk = this._multiFindKey(walletKeyMap, pubKeyHash); } else { throw new Error('no infomation at input to find keys'); } @@ -491,37 +493,45 @@ TransactionBuilder.prototype._findWalletKey = function(walletKeyMap, input) { TransactionBuilder.prototype._signPubKey = function(walletKeyMap, input, txSigHash) { if (this.tx.ins[input.i].s.length > 0) return {}; - var wk = this._findWalletKey(walletKeyMap, input); + var wk = this._findWalletKey(walletKeyMap, input); if (!wk) return; - var sigRaw = TransactionBuilder._signHashAndVerify(wk, txSigHash); - var sigType = new Buffer(1); - sigType[0] = this.signhash; - var sig = Buffer.concat([sigRaw, sigType]); + var sigRaw = TransactionBuilder._signHashAndVerify(wk, txSigHash); + var sigType = new Buffer(1); + sigType[0] = this.signhash; + var sig = Buffer.concat([sigRaw, sigType]); var scriptSig = new Script(); scriptSig.chunks.push(sig); scriptSig.updateBuffer(); - return {inputFullySigned: true, signaturesAdded: 1, script: scriptSig.getBuffer()}; + return { + inputFullySigned: true, + signaturesAdded: 1, + script: scriptSig.getBuffer() + }; }; TransactionBuilder.prototype._signPubKeyHash = function(walletKeyMap, input, txSigHash) { if (this.tx.ins[input.i].s.length > 0) return {}; - var wk = this._findWalletKey(walletKeyMap, input); + var wk = this._findWalletKey(walletKeyMap, input); if (!wk) return; - var sigRaw = TransactionBuilder._signHashAndVerify(wk, txSigHash); - var sigType = new Buffer(1); - sigType[0] = this.signhash; - var sig = Buffer.concat([sigRaw, sigType]); + var sigRaw = TransactionBuilder._signHashAndVerify(wk, txSigHash); + var sigType = new Buffer(1); + sigType[0] = this.signhash; + var sig = Buffer.concat([sigRaw, sigType]); var scriptSig = new Script(); scriptSig.chunks.push(sig); scriptSig.chunks.push(wk.privKey.public); scriptSig.updateBuffer(); - return {inputFullySigned: true, signaturesAdded: 1, script: scriptSig.getBuffer()}; + return { + inputFullySigned: true, + signaturesAdded: 1, + script: scriptSig.getBuffer() + }; }; /* FOR TESTING @@ -537,13 +547,13 @@ var _dumpChunks = function (scriptSig, label) { TransactionBuilder.prototype._chunkSignedWithKey = function(scriptSig, txSigHash, publicKey) { var ret; var k = new Key(); - k.public =publicKey; + k.public = publicKey; - for(var i=1; i<= scriptSig.countSignatures(); i++) { + for (var i = 1; i <= scriptSig.countSignatures(); i++) { var chunk = scriptSig.chunks[i]; - var sigRaw = new Buffer(chunk.slice(0,chunk.length-1)); - if (k.verifySignatureSync(txSigHash, sigRaw) ) { - ret=chunk; + var sigRaw = new Buffer(chunk.slice(0, chunk.length - 1)); + if (k.verifySignatureSync(txSigHash, sigRaw)) { + ret = chunk; } } return ret; @@ -551,10 +561,10 @@ TransactionBuilder.prototype._chunkSignedWithKey = function(scriptSig, txSigHash TransactionBuilder.prototype._getSignatureOrder = function(sigPrio, sigRaw, txSigHash, pubkeys) { - var l=pubkeys.length; - for(var j=0; j2) || (l1<2 && l0>2 ))) + if (l0 && l1 && ((l0 < 2 && l1 > 2) || (l1 < 2 && l0 > 2))) throw new Error('TX sig types mismatch in merge'); - if ((!l0 && !l1) || ( l0 && !l1) || (!l0 && l1)) + if ((!l0 && !l1) || (l0 && !l1) || (!l0 && l1)) return s1buf; // Get the pubkeys var input = this.inputMap[index]; - var type = input.scriptPubKey.classify(); + var type = input.scriptPubKey.classify(); //p2pubkey or p2pubkeyhash if (type === Script.TX_PUBKEYHASH || type === Script.TX_PUBKEY) { log.debug('Merging two signed inputs type:' + input.scriptPubKey.getRawOutType() + '. Signatures differs. Using the first version.'); return s0buf; - } - else if (type!== Script.TX_SCRIPTHASH) { + } else if (type !== Script.TX_SCRIPTHASH) { // No support for normal multisig or strange txs. - throw new Error('Script type:'+input.scriptPubKey.getRawOutType()+'not supported at #merge'); + throw new Error('Script type:' + input.scriptPubKey.getRawOutType() + 'not supported at #merge'); } - return this._mergeInputSigP2sh(input,s0, s1); + return this._mergeInputSigP2sh(input, s0, s1); }; // TODO this could be on Transaction class TransactionBuilder.prototype._mergeTx = function(tx) { - var v0 = this.tx; - var v1 = tx; + var v0 = this.tx; + var v1 = tx; - var l = v0.ins.length; - if (l !== v1.ins.length) - throw new Error('TX in length mismatch in merge'); + var l = v0.ins.length; + if (l !== v1.ins.length) + throw new Error('TX in length mismatch in merge'); - this.inputsSigned =0; - for(var i=0; i= 2 && b < 65 ) ) ) { - - digits = '[' + DIGITS.slice( 0, b = b | 0 ) + ']+'; - - // Before non-decimal number validity test and base conversion - // remove the `.` from e.g. '1.', and replace e.g. '.1' with '0.1'. - n = n.replace( /\.$/, '' ).replace( /^\./, '0.' ); - - // Any number in exponential form will fail due to the e+/-. - if ( valid = new RegExp( - '^' + digits + '(?:\\.' + digits + ')?$', b < 37 ? 'i' : '' ).test(n) ) { - - if ( isNum ) { - - if ( n.replace( /^0\.0*|\./, '' ).length > 15 ) { - - // 'new BigNumber() number type has more than 15 significant digits: {n}' - ifExceptionsThrow( orig, 0 ); - } - - // Prevent later check for length on converted number. - isNum = !isNum; - } - n = convert( n, 10, b, x['s'] ); - - } else if ( n != 'Infinity' && n != 'NaN' ) { - - // 'new BigNumber() not a base {b} number: {n}' - ifExceptionsThrow( orig, 1, b ); - n = 'NaN'; - } - } else { - - // 'new BigNumber() base not an integer: {b}' - // 'new BigNumber() base out of range: {b}' - ifExceptionsThrow( b, 2 ); - - // Ignore base. - valid = isValid.test(n); - } - } else { - valid = isValid.test(n); - } - - if ( !valid ) { - - // Infinity/NaN - x['c'] = x['e'] = null; - - // NaN - if ( n != 'Infinity' ) { - - // No exception on NaN. - if ( n != 'NaN' ) { - - // 'new BigNumber() not a number: {n}' - ifExceptionsThrow( orig, 3 ); - } - x['s'] = null; - } - id = 0; - - return; - } - } - - // Decimal point? - if ( ( e = n.indexOf('.') ) > -1 ) { - n = n.replace( '.', '' ); - } - - // Exponential form? - if ( ( i = n.search( /e/i ) ) > 0 ) { - - // Determine exponent. - if ( e < 0 ) { - e = i; - } - e += +n.slice( i + 1 ); - n = n.substring( 0, i ); - - } else if ( e < 0 ) { - - // Integer. - e = n.length; - } - - // Determine leading zeros. - for ( i = 0; n.charAt(i) == '0'; i++ ) { - } - - b = n.length; - - // Disallow numbers with over 15 significant digits if number type. - if ( isNum && b > 15 && n.slice(i).length > 15 ) { - - // 'new BigNumber() number type has more than 15 significant digits: {n}' - ifExceptionsThrow( orig, 0 ); - } + // Duplicate. + if (n instanceof BigNumber) { id = 0; - // Overflow? - if ( ( e -= i + 1 ) > MAX_EXP ) { + // e is undefined. + if (b !== e) { + n += '' + } else { + x['s'] = n['s']; + x['e'] = n['e']; + x['c'] = (n = n['c']) ? n.slice() : n; + return; + } + } - // Infinity. - x['c'] = x['e'] = null; + // Accept empty string as zero + if (n === '') n = 0; + + // If number, check if minus zero. + if (typeof n != 'string') { + n = (isNum = typeof n == 'number' || + Object.prototype.toString.call(n) == '[object Number]') && + n === 0 && 1 / n < 0 ? '-0' : n + ''; + } + + orig = n; + + if (b === e && isValid.test(n)) { + + // Determine sign. + x['s'] = n.charAt(0) == '-' ? (n = n.slice(1), -1) : 1; + + // Either n is not a valid BigNumber or a base has been specified. + } else { + + // Enable exponential notation to be used with base 10 argument. + // Ensure return value is rounded to DECIMAL_PLACES as with other bases. + if (b == 10) { + + return setMode(n, DECIMAL_PLACES, ROUNDING_MODE); + } + + n = trim.call(n).replace(/^\+(?!-)/, ''); + + x['s'] = n.charAt(0) == '-' ? (n = n.replace(/^-(?!-)/, ''), -1) : 1; + + if (b != null) { + + if ((b == (b | 0) || !ERRORS) && + !(outOfRange = !(b >= 2 && b < 65))) { + + digits = '[' + DIGITS.slice(0, b = b | 0) + ']+'; + + // Before non-decimal number validity test and base conversion + // remove the `.` from e.g. '1.', and replace e.g. '.1' with '0.1'. + n = n.replace(/\.$/, '').replace(/^\./, '0.'); + + // Any number in exponential form will fail due to the e+/-. + if (valid = new RegExp( + '^' + digits + '(?:\\.' + digits + ')?$', b < 37 ? 'i' : '').test(n)) { + + if (isNum) { + + if (n.replace(/^0\.0*|\./, '').length > 15) { + + // 'new BigNumber() number type has more than 15 significant digits: {n}' + ifExceptionsThrow(orig, 0); + } + + // Prevent later check for length on converted number. + isNum = !isNum; + } + n = convert(n, 10, b, x['s']); + + } else if (n != 'Infinity' && n != 'NaN') { + + // 'new BigNumber() not a base {b} number: {n}' + ifExceptionsThrow(orig, 1, b); + n = 'NaN'; + } + } else { + + // 'new BigNumber() base not an integer: {b}' + // 'new BigNumber() base out of range: {b}' + ifExceptionsThrow(b, 2); + + // Ignore base. + valid = isValid.test(n); + } + } else { + valid = isValid.test(n); + } + + if (!valid) { + + // Infinity/NaN + x['c'] = x['e'] = null; + + // NaN + if (n != 'Infinity') { + + // No exception on NaN. + if (n != 'NaN') { + + // 'new BigNumber() not a number: {n}' + ifExceptionsThrow(orig, 3); + } + x['s'] = null; + } + id = 0; + + return; + } + } + + // Decimal point? + if ((e = n.indexOf('.')) > -1) { + n = n.replace('.', ''); + } + + // Exponential form? + if ((i = n.search(/e/i)) > 0) { + + // Determine exponent. + if (e < 0) { + e = i; + } + e += +n.slice(i + 1); + n = n.substring(0, i); + + } else if (e < 0) { + + // Integer. + e = n.length; + } + + // Determine leading zeros. + for (i = 0; n.charAt(i) == '0'; i++) {} + + b = n.length; + + // Disallow numbers with over 15 significant digits if number type. + if (isNum && b > 15 && n.slice(i).length > 15) { + + // 'new BigNumber() number type has more than 15 significant digits: {n}' + ifExceptionsThrow(orig, 0); + } + id = 0; + + // Overflow? + if ((e -= i + 1) > MAX_EXP) { + + // Infinity. + x['c'] = x['e'] = null; // Zero or underflow? - } else if ( i == b || e < MIN_EXP ) { + } else if (i == b || e < MIN_EXP) { - // Zero. - x['c'] = [ x['e'] = 0 ]; - } else { + // Zero. + x['c'] = [x['e'] = 0]; + } else { - // Determine trailing zeros. - for ( ; n.charAt(--b) == '0'; ) { - } + // Determine trailing zeros. + for (; n.charAt(--b) == '0';) {} - x['e'] = e; - x['c'] = []; + x['e'] = e; + x['c'] = []; - // Convert string to array of digits (without leading and trailing zeros). - for ( e = 0; i <= b; x['c'][e++] = +n.charAt(i++) ) { - } - } + // Convert string to array of digits (without leading and trailing zeros). + for (e = 0; i <= b; x['c'][e++] = +n.charAt(i++)) {} + } } @@ -294,40 +293,39 @@ BigNumber['ROUND_HALF_FLOOR'] = 8; /* * Create an instance from a Buffer */ -BigNumber['fromBuffer'] = function (buf, opts) { +BigNumber['fromBuffer'] = function(buf, opts) { - if (!opts) opts = {}; + if (!opts) opts = {}; - var endian = { 1 : 'big', '-1' : 'little' }[opts.endian] - || opts.endian || 'big' - ; + var endian = { + 1: 'big', + '-1': 'little' + }[opts.endian] || opts.endian || 'big'; - var size = opts.size === 'auto' ? Math.ceil(buf.length) : (opts.size || 1); + var size = opts.size === 'auto' ? Math.ceil(buf.length) : (opts.size || 1); - if (buf.length % size !== 0) { - throw new RangeError('Buffer length (' + buf.length + ')' - + ' must be a multiple of size (' + size + ')' - ); + if (buf.length % size !== 0) { + throw new RangeError('Buffer length (' + buf.length + ')' + ' must be a multiple of size (' + size + ')'); + } + + var hex = []; + for (var i = 0; i < buf.length; i += size) { + var chunk = []; + for (var j = 0; j < size; j++) { + chunk.push(buf[ + i + (endian === 'big' ? j : (size - j - 1)) + ]); } - var hex = []; - for (var i = 0; i < buf.length; i += size) { - var chunk = []; - for (var j = 0; j < size; j++) { - chunk.push(buf[ - i + (endian === 'big' ? j : (size - j - 1)) - ]); - } + hex.push(chunk + .map(function(c) { + return (c < 16 ? '0' : '') + c.toString(16); + }) + .join('') + ); + } - hex.push(chunk - .map(function (c) { - return (c < 16 ? '0' : '') + c.toString(16); - }) - .join('') - ); - } - - return BigNumber(hex.join(''), 16); + return BigNumber(hex.join(''), 16); }; @@ -345,106 +343,106 @@ BigNumber['fromBuffer'] = function (buf, opts) { * * Return an object with the properties current values. */ -BigNumber['config'] = function () { - var v, p, - i = 0, - r = {}, - a = arguments, - o = a[0], - c = 'config', - inRange = function ( n, lo, hi ) { - return !( ( outOfRange = n < lo || n > hi ) || - parse(n) != n && n !== 0 ); - }, - has = o && typeof o == 'object' - ? function () {if ( o.hasOwnProperty(p) ) return ( v = o[p] ) != null} - : function () {if ( a.length > i ) return ( v = a[i++] ) != null}; +BigNumber['config'] = function() { + var v, p, + i = 0, + r = {}, + a = arguments, + o = a[0], + c = 'config', + inRange = function(n, lo, hi) { + return !((outOfRange = n < lo || n > hi) || + parse(n) != n && n !== 0); + }, + has = o && typeof o == 'object' ? function() { + if (o.hasOwnProperty(p)) return (v = o[p]) != null + } : function() { + if (a.length > i) return (v = a[i++]) != null + }; - // [DECIMAL_PLACES] {number} Integer, 0 to MAX inclusive. - if ( has( p = 'DECIMAL_PLACES' ) ) { + // [DECIMAL_PLACES] {number} Integer, 0 to MAX inclusive. + if (has(p = 'DECIMAL_PLACES')) { - if ( inRange( v, 0, MAX ) ) { - DECIMAL_PLACES = v | 0; - } else { + if (inRange(v, 0, MAX)) { + DECIMAL_PLACES = v | 0; + } else { - // 'config() DECIMAL_PLACES not an integer: {v}' - // 'config() DECIMAL_PLACES out of range: {v}' - ifExceptionsThrow( v, p, c ); - } + // 'config() DECIMAL_PLACES not an integer: {v}' + // 'config() DECIMAL_PLACES out of range: {v}' + ifExceptionsThrow(v, p, c); } - r[p] = DECIMAL_PLACES; + } + r[p] = DECIMAL_PLACES; - // [ROUNDING_MODE] {number} Integer, 0 to 8 inclusive. - if ( has( p = 'ROUNDING_MODE' ) ) { + // [ROUNDING_MODE] {number} Integer, 0 to 8 inclusive. + if (has(p = 'ROUNDING_MODE')) { - if ( inRange( v, 0, 8 ) ) { - ROUNDING_MODE = v | 0; - } else { + if (inRange(v, 0, 8)) { + ROUNDING_MODE = v | 0; + } else { - // 'config() ROUNDING_MODE not an integer: {v}' - // 'config() ROUNDING_MODE out of range: {v}' - ifExceptionsThrow( v, p, c ); - } + // 'config() ROUNDING_MODE not an integer: {v}' + // 'config() ROUNDING_MODE out of range: {v}' + ifExceptionsThrow(v, p, c); } - r[p] = ROUNDING_MODE; + } + r[p] = ROUNDING_MODE; - /* - * [EXPONENTIAL_AT] {number|number[]} Integer, -MAX to MAX inclusive or - * [ integer -MAX to 0 inclusive, 0 to MAX inclusive ]. - */ - if ( has( p = 'EXPONENTIAL_AT' ) ) { + /* + * [EXPONENTIAL_AT] {number|number[]} Integer, -MAX to MAX inclusive or + * [ integer -MAX to 0 inclusive, 0 to MAX inclusive ]. + */ + if (has(p = 'EXPONENTIAL_AT')) { - if ( inRange( v, -MAX, MAX ) ) { - TO_EXP_NEG = -( TO_EXP_POS = ~~( v < 0 ? -v : +v ) ); - } else if ( !outOfRange && v && inRange( v[0], -MAX, 0 ) && - inRange( v[1], 0, MAX ) ) { - TO_EXP_NEG = ~~v[0]; - TO_EXP_POS = ~~v[1]; - } else { + if (inRange(v, -MAX, MAX)) { + TO_EXP_NEG = -(TO_EXP_POS = ~~ (v < 0 ? -v : +v)); + } else if (!outOfRange && v && inRange(v[0], -MAX, 0) && + inRange(v[1], 0, MAX)) { + TO_EXP_NEG = ~~v[0]; + TO_EXP_POS = ~~v[1]; + } else { - // 'config() EXPONENTIAL_AT not an integer or not [integer, integer]: {v}' - // 'config() EXPONENTIAL_AT out of range or not [negative, positive: {v}' - ifExceptionsThrow( v, p, c, 1 ); - } + // 'config() EXPONENTIAL_AT not an integer or not [integer, integer]: {v}' + // 'config() EXPONENTIAL_AT out of range or not [negative, positive: {v}' + ifExceptionsThrow(v, p, c, 1); } - r[p] = [ TO_EXP_NEG, TO_EXP_POS ]; + } + r[p] = [TO_EXP_NEG, TO_EXP_POS]; - /* - * [RANGE][ {number|number[]} Non-zero integer, -MAX to MAX inclusive or - * [ integer -MAX to -1 inclusive, integer 1 to MAX inclusive ]. - */ - if ( has( p = 'RANGE' ) ) { + /* + * [RANGE][ {number|number[]} Non-zero integer, -MAX to MAX inclusive or + * [ integer -MAX to -1 inclusive, integer 1 to MAX inclusive ]. + */ + if (has(p = 'RANGE')) { - if ( inRange( v, -MAX, MAX ) && ~~v ) { - MIN_EXP = -( MAX_EXP = ~~( v < 0 ? -v : +v ) ); - } else if ( !outOfRange && v && inRange( v[0], -MAX, -1 ) && - inRange( v[1], 1, MAX ) ) { - MIN_EXP = ~~v[0], MAX_EXP = ~~v[1]; - } else { + if (inRange(v, -MAX, MAX) && ~~v) { + MIN_EXP = -(MAX_EXP = ~~ (v < 0 ? -v : +v)); + } else if (!outOfRange && v && inRange(v[0], -MAX, -1) && + inRange(v[1], 1, MAX)) { + MIN_EXP = ~~v[0], MAX_EXP = ~~v[1]; + } else { - // 'config() RANGE not a non-zero integer or not [integer, integer]: {v}' - // 'config() RANGE out of range or not [negative, positive: {v}' - ifExceptionsThrow( v, p, c, 1, 1 ); - } + // 'config() RANGE not a non-zero integer or not [integer, integer]: {v}' + // 'config() RANGE out of range or not [negative, positive: {v}' + ifExceptionsThrow(v, p, c, 1, 1); } - r[p] = [ MIN_EXP, MAX_EXP ]; + } + r[p] = [MIN_EXP, MAX_EXP]; - // [ERRORS] {boolean|number} true, false, 1 or 0. - if ( has( p = 'ERRORS' ) ) { + // [ERRORS] {boolean|number} true, false, 1 or 0. + if (has(p = 'ERRORS')) { - if ( v === !!v || v === 1 || v === 0 ) { - parse = ( outOfRange = id = 0, ERRORS = !!v ) - ? parseInt - : parseFloat; - } else { + if (v === !!v || v === 1 || v === 0) { + parse = (outOfRange = id = 0, ERRORS = !!v) ? parseInt : parseFloat; + } else { - // 'config() ERRORS not a boolean or binary digit: {v}' - ifExceptionsThrow( v, p, c, 0, 0, 1 ); - } + // 'config() ERRORS not a boolean or binary digit: {v}' + ifExceptionsThrow(v, p, c, 0, 0, 1); } - r[p] = ERRORS; + } + r[p] = ERRORS; - return r; + return r; }; @@ -452,265 +450,248 @@ BigNumber['config'] = function () { // Assemble error messages. Throw BigNumber Errors. -function ifExceptionsThrow( arg, i, j, isArray, isRange, isErrors) { +function ifExceptionsThrow(arg, i, j, isArray, isRange, isErrors) { - if ( ERRORS ) { - var error, - method = ['new BigNumber', 'cmp', 'div', 'eq', 'gt', 'gte', 'lt', - 'lte', 'minus', 'mod', 'plus', 'times', 'toFr' - ][ id ? id < 0 ? -id : id : 1 / id < 0 ? 1 : 0 ] + '()', - message = outOfRange ? ' out of range' : ' not a' + - ( isRange ? ' non-zero' : 'n' ) + ' integer'; + if (ERRORS) { + var error, + method = ['new BigNumber', 'cmp', 'div', 'eq', 'gt', 'gte', 'lt', + 'lte', 'minus', 'mod', 'plus', 'times', 'toFr' + ][id ? id < 0 ? -id : id : 1 / id < 0 ? 1 : 0] + '()', + message = outOfRange ? ' out of range' : ' not a' + + (isRange ? ' non-zero' : 'n') + ' integer'; - message = ( [ - method + ' number type has more than 15 significant digits', - method + ' not a base ' + j + ' number', - method + ' base' + message, - method + ' not a number' ][i] || - j + '() ' + i + ( isErrors - ? ' not a boolean or binary digit' - : message + ( isArray - ? ' or not [' + ( outOfRange - ? ' negative, positive' - : ' integer, integer' ) + ' ]' - : '' ) ) ) + ': ' + arg; + message = ([ + method + ' number type has more than 15 significant digits', + method + ' not a base ' + j + ' number', + method + ' base' + message, + method + ' not a number' + ][i] || + j + '() ' + i + (isErrors ? ' not a boolean or binary digit' : message + (isArray ? ' or not [' + (outOfRange ? ' negative, positive' : ' integer, integer') + ' ]' : ''))) + ': ' + arg; - outOfRange = id = 0; - error = new Error(message); - error['name'] = 'BigNumber Error'; + outOfRange = id = 0; + error = new Error(message); + error['name'] = 'BigNumber Error'; - throw error; - } + throw error; + } } /* * Convert a numeric string of baseIn to a numeric string of baseOut. */ -function convert( nStr, baseOut, baseIn, sign ) { - var e, dvs, dvd, nArr, fracArr, fracBN; +function convert(nStr, baseOut, baseIn, sign) { + var e, dvs, dvd, nArr, fracArr, fracBN; - // Convert string of base bIn to an array of numbers of baseOut. - // Eg. strToArr('255', 10) where baseOut is 16, returns [15, 15]. - // Eg. strToArr('ff', 16) where baseOut is 10, returns [2, 5, 5]. - function strToArr( str, bIn ) { - var j, - i = 0, - strL = str.length, - arrL, - arr = [0]; + // Convert string of base bIn to an array of numbers of baseOut. + // Eg. strToArr('255', 10) where baseOut is 16, returns [15, 15]. + // Eg. strToArr('ff', 16) where baseOut is 10, returns [2, 5, 5]. + function strToArr(str, bIn) { + var j, + i = 0, + strL = str.length, + arrL, + arr = [0]; - for ( bIn = bIn || baseIn; i < strL; i++ ) { + for (bIn = bIn || baseIn; i < strL; i++) { - for ( arrL = arr.length, j = 0; j < arrL; arr[j] *= bIn, j++ ) { - } + for (arrL = arr.length, j = 0; j < arrL; arr[j] *= bIn, j++) {} - for ( arr[0] += DIGITS.indexOf( str.charAt(i) ), j = 0; - j < arr.length; - j++ ) { + for (arr[0] += DIGITS.indexOf(str.charAt(i)), j = 0; j < arr.length; j++) { - if ( arr[j] > baseOut - 1 ) { + if (arr[j] > baseOut - 1) { - if ( arr[j + 1] == null ) { - arr[j + 1] = 0; - } - arr[j + 1] += arr[j] / baseOut ^ 0; - arr[j] %= baseOut; - } - } + if (arr[j + 1] == null) { + arr[j + 1] = 0; + } + arr[j + 1] += arr[j] / baseOut ^ 0; + arr[j] %= baseOut; } - - return arr.reverse(); + } } - // Convert array to string. - // E.g. arrToStr( [9, 10, 11] ) becomes '9ab' (in bases above 11). - function arrToStr( arr ) { - var i = 0, - arrL = arr.length, - str = ''; + return arr.reverse(); + } - for ( ; i < arrL; str += DIGITS.charAt( arr[i++] ) ) { - } + // Convert array to string. + // E.g. arrToStr( [9, 10, 11] ) becomes '9ab' (in bases above 11). + function arrToStr(arr) { + var i = 0, + arrL = arr.length, + str = ''; - return str; - } + for (; i < arrL; str += DIGITS.charAt(arr[i++])) {} - if ( baseIn < 37 ) { - nStr = nStr.toLowerCase(); - } + return str; + } + + if (baseIn < 37) { + nStr = nStr.toLowerCase(); + } + + /* + * If non-integer convert integer part and fraction part separately. + * Convert the fraction part as if it is an integer than use division to + * reduce it down again to a value less than one. + */ + if ((e = nStr.indexOf('.')) > -1) { /* - * If non-integer convert integer part and fraction part separately. - * Convert the fraction part as if it is an integer than use division to - * reduce it down again to a value less than one. + * Calculate the power to which to raise the base to get the number + * to divide the fraction part by after it has been converted as an + * integer to the required base. */ - if ( ( e = nStr.indexOf( '.' ) ) > -1 ) { + e = nStr.length - e - 1; - /* - * Calculate the power to which to raise the base to get the number - * to divide the fraction part by after it has been converted as an - * integer to the required base. - */ - e = nStr.length - e - 1; + // Use toFixed to avoid possible exponential notation. + dvs = strToArr(new BigNumber(baseIn)['pow'](e)['toF'](), 10); - // Use toFixed to avoid possible exponential notation. - dvs = strToArr( new BigNumber(baseIn)['pow'](e)['toF'](), 10 ); + nArr = nStr.split('.'); - nArr = nStr.split('.'); + // Convert the base of the fraction part (as integer). + dvd = strToArr(nArr[1]); - // Convert the base of the fraction part (as integer). - dvd = strToArr( nArr[1] ); + // Convert the base of the integer part. + nArr = strToArr(nArr[0]); - // Convert the base of the integer part. - nArr = strToArr( nArr[0] ); + // Result will be a BigNumber with a value less than 1. + fracBN = divide(dvd, dvs, dvd.length - dvs.length, sign, baseOut, + // Is least significant digit of integer part an odd number? + nArr[nArr.length - 1] & 1); - // Result will be a BigNumber with a value less than 1. - fracBN = divide( dvd, dvs, dvd.length - dvs.length, sign, baseOut, - // Is least significant digit of integer part an odd number? - nArr[nArr.length - 1] & 1 ); + fracArr = fracBN['c']; - fracArr = fracBN['c']; + // e can be <= 0 ( if e == 0, fracArr is [0] or [1] ). + if (e = fracBN['e']) { - // e can be <= 0 ( if e == 0, fracArr is [0] or [1] ). - if ( e = fracBN['e'] ) { + // Append zeros according to the exponent of the result. + for (; ++e; fracArr.unshift(0)) {} - // Append zeros according to the exponent of the result. - for ( ; ++e; fracArr.unshift(0) ) { - } + // Append the fraction part to the converted integer part. + nStr = arrToStr(nArr) + '.' + arrToStr(fracArr); - // Append the fraction part to the converted integer part. - nStr = arrToStr(nArr) + '.' + arrToStr(fracArr); + // fracArr is [1]. + // Fraction digits rounded up, so increment last digit of integer part. + } else if (fracArr[0]) { - // fracArr is [1]. - // Fraction digits rounded up, so increment last digit of integer part. - } else if ( fracArr[0] ) { + if (nArr[e = nArr.length - 1] < baseOut - 1) { + ++nArr[e]; + nStr = arrToStr(nArr); + } else { + nStr = new BigNumber(arrToStr(nArr), + baseOut)['plus'](ONE)['toS'](baseOut); + } - if ( nArr[ e = nArr.length - 1 ] < baseOut - 1 ) { - ++nArr[e]; - nStr = arrToStr(nArr); - } else { - nStr = new BigNumber( arrToStr(nArr), - baseOut )['plus'](ONE)['toS'](baseOut); - } - - // fracArr is [0]. No fraction digits. - } else { - nStr = arrToStr(nArr); - } + // fracArr is [0]. No fraction digits. } else { - - // Simple integer. Convert base. - nStr = arrToStr( strToArr(nStr) ); + nStr = arrToStr(nArr); } + } else { - return nStr; + // Simple integer. Convert base. + nStr = arrToStr(strToArr(nStr)); + } + + return nStr; } // Perform division in the specified base. Called by div and convert. -function divide( dvd, dvs, exp, s, base, isOdd ) { - var dvsL, dvsT, next, cmp, remI, - dvsZ = dvs.slice(), - dvdI = dvsL = dvs.length, - dvdL = dvd.length, - rem = dvd.slice( 0, dvsL ), - remL = rem.length, - quo = new BigNumber(ONE), - qc = quo['c'] = [], - qi = 0, - dig = DECIMAL_PLACES + ( quo['e'] = exp ) + 1; +function divide(dvd, dvs, exp, s, base, isOdd) { + var dvsL, dvsT, next, cmp, remI, + dvsZ = dvs.slice(), + dvdI = dvsL = dvs.length, + dvdL = dvd.length, + rem = dvd.slice(0, dvsL), + remL = rem.length, + quo = new BigNumber(ONE), + qc = quo['c'] = [], + qi = 0, + dig = DECIMAL_PLACES + (quo['e'] = exp) + 1; - quo['s'] = s; - s = dig < 0 ? 0 : dig; + quo['s'] = s; + s = dig < 0 ? 0 : dig; - // Add zeros to make remainder as long as divisor. - for ( ; remL++ < dvsL; rem.push(0) ) { - } + // Add zeros to make remainder as long as divisor. + for (; remL++ < dvsL; rem.push(0)) {} - // Create version of divisor with leading zero. - dvsZ.unshift(0); + // Create version of divisor with leading zero. + dvsZ.unshift(0); - do { + do { - // 'next' is how many times the divisor goes into the current remainder. - for ( next = 0; next < base; next++ ) { + // 'next' is how many times the divisor goes into the current remainder. + for (next = 0; next < base; next++) { - // Compare divisor and remainder. - if ( dvsL != ( remL = rem.length ) ) { - cmp = dvsL > remL ? 1 : -1; - } else { - for ( remI = -1, cmp = 0; ++remI < dvsL; ) { + // Compare divisor and remainder. + if (dvsL != (remL = rem.length)) { + cmp = dvsL > remL ? 1 : -1; + } else { + for (remI = -1, cmp = 0; ++remI < dvsL;) { - if ( dvs[remI] != rem[remI] ) { - cmp = dvs[remI] > rem[remI] ? 1 : -1; - break; - } - } - } - - // Subtract divisor from remainder (if divisor < remainder). - if ( cmp < 0 ) { - - // Remainder cannot be more than one digit longer than divisor. - // Equalise lengths using divisor with extra leading zero? - for ( dvsT = remL == dvsL ? dvs : dvsZ; remL; ) { - - if ( rem[--remL] < dvsT[remL] ) { - - for ( remI = remL; - remI && !rem[--remI]; - rem[remI] = base - 1 ) { - } - --rem[remI]; - rem[remL] += base; - } - rem[remL] -= dvsT[remL]; - } - for ( ; !rem[0]; rem.shift() ) { - } - } else { - break; - } + if (dvs[remI] != rem[remI]) { + cmp = dvs[remI] > rem[remI] ? 1 : -1; + break; + } } + } - // Add the 'next' digit to the result array. - qc[qi++] = cmp ? next : ++next; + // Subtract divisor from remainder (if divisor < remainder). + if (cmp < 0) { - // Update the remainder. - rem[0] && cmp - ? ( rem[remL] = dvd[dvdI] || 0 ) - : ( rem = [ dvd[dvdI] ] ); + // Remainder cannot be more than one digit longer than divisor. + // Equalise lengths using divisor with extra leading zero? + for (dvsT = remL == dvsL ? dvs : dvsZ; remL;) { - } while ( ( dvdI++ < dvdL || rem[0] != null ) && s-- ); + if (rem[--remL] < dvsT[remL]) { - // Leading zero? Do not remove if result is simply zero (qi == 1). - if ( !qc[0] && qi != 1 ) { - - // There can't be more than one zero. - --quo['e']; - qc.shift(); + for (remI = remL; remI && !rem[--remI]; rem[remI] = base - 1) {} + --rem[remI]; + rem[remL] += base; + } + rem[remL] -= dvsT[remL]; + } + for (; !rem[0]; rem.shift()) {} + } else { + break; + } } - // Round? - if ( qi > dig ) { - rnd( quo, DECIMAL_PLACES, base, isOdd, rem[0] != null ); - } + // Add the 'next' digit to the result array. + qc[qi++] = cmp ? next : ++next; - // Overflow? - if ( quo['e'] > MAX_EXP ) { + // Update the remainder. + rem[0] && cmp ? (rem[remL] = dvd[dvdI] || 0) : (rem = [dvd[dvdI]]); - // Infinity. - quo['c'] = quo['e'] = null; + } while ((dvdI++ < dvdL || rem[0] != null) && s--); + + // Leading zero? Do not remove if result is simply zero (qi == 1). + if (!qc[0] && qi != 1) { + + // There can't be more than one zero. + --quo['e']; + qc.shift(); + } + + // Round? + if (qi > dig) { + rnd(quo, DECIMAL_PLACES, base, isOdd, rem[0] != null); + } + + // Overflow? + if (quo['e'] > MAX_EXP) { + + // Infinity. + quo['c'] = quo['e'] = null; // Underflow? - } else if ( quo['e'] < MIN_EXP ) { + } else if (quo['e'] < MIN_EXP) { - // Zero. - quo['c'] = [quo['e'] = 0]; - } + // Zero. + quo['c'] = [quo['e'] = 0]; + } - return quo; + return quo; } @@ -722,139 +703,133 @@ function divide( dvd, dvs, exp, s, base, isOdd ) { * d is the index (with the value in normal notation) of the digit that may be * rounded up. */ -function format( n, d, exp ) { +function format(n, d, exp) { - // Initially, i is the number of decimal places required. - var i = d - (n = new BigNumber(n))['e'], - c = n['c']; + // Initially, i is the number of decimal places required. + var i = d - (n = new BigNumber(n))['e'], + c = n['c']; - // +-Infinity or NaN? - if ( !c ) { - return n['toS'](); - } + // +-Infinity or NaN? + if (!c) { + return n['toS'](); + } - // Round? - if ( c.length > ++d ) { - rnd( n, i, 10 ); - } + // Round? + if (c.length > ++d) { + rnd(n, i, 10); + } - // Recalculate d if toFixed as n['e'] may have changed if value rounded up. - i = c[0] == 0 ? i + 1 : exp ? d : n['e'] + i + 1; + // Recalculate d if toFixed as n['e'] may have changed if value rounded up. + i = c[0] == 0 ? i + 1 : exp ? d : n['e'] + i + 1; - // Append zeros? - for ( ; c.length < i; c.push(0) ) { - } - i = n['e']; + // Append zeros? + for (; c.length < i; c.push(0)) {} + i = n['e']; - /* - * toPrecision returns exponential notation if the number of significant - * digits specified is less than the number of digits necessary to - * represent the integer part of the value in normal notation. - */ - return exp == 1 || exp == 2 && ( --d < i || i <= TO_EXP_NEG ) + /* + * toPrecision returns exponential notation if the number of significant + * digits specified is less than the number of digits necessary to + * represent the integer part of the value in normal notation. + */ + return exp == 1 || exp == 2 && (--d < i || i <= TO_EXP_NEG) - // Exponential notation. - ? ( n['s'] < 0 && c[0] ? '-' : '' ) + ( c.length > 1 - ? ( c.splice( 1, 0, '.' ), c.join('') ) - : c[0] ) + ( i < 0 ? 'e' : 'e+' ) + i + // Exponential notation. + ? (n['s'] < 0 && c[0] ? '-' : '') + (c.length > 1 ? (c.splice(1, 0, '.'), c.join('')) : c[0]) + (i < 0 ? 'e' : 'e+') + i - // Normal notation. - : n['toS'](); + // Normal notation. + : n['toS'](); } // Round if necessary. // Called by divide, format, setMode and sqrt. -function rnd( x, dp, base, isOdd, r ) { - var xc = x['c'], - isNeg = x['s'] < 0, - half = base / 2, - i = x['e'] + dp + 1, +function rnd(x, dp, base, isOdd, r) { + var xc = x['c'], + isNeg = x['s'] < 0, + half = base / 2, + i = x['e'] + dp + 1, - // 'next' is the digit after the digit that may be rounded up. - next = xc[i], + // 'next' is the digit after the digit that may be rounded up. + next = xc[i], - /* - * 'more' is whether there are digits after 'next'. - * E.g. - * 0.005 (e = -3) to be rounded to 0 decimal places (dp = 0) gives i = -2 - * The 'next' digit is zero, and there ARE 'more' digits after it. - * 0.5 (e = -1) dp = 0 gives i = 0 - * The 'next' digit is 5 and there are no 'more' digits after it. - */ - more = r || i < 0 || xc[i + 1] != null; + /* + * 'more' is whether there are digits after 'next'. + * E.g. + * 0.005 (e = -3) to be rounded to 0 decimal places (dp = 0) gives i = -2 + * The 'next' digit is zero, and there ARE 'more' digits after it. + * 0.5 (e = -1) dp = 0 gives i = 0 + * The 'next' digit is 5 and there are no 'more' digits after it. + */ + more = r || i < 0 || xc[i + 1] != null; - r = ROUNDING_MODE < 4 - ? ( next != null || more ) && - ( ROUNDING_MODE == 0 || - ROUNDING_MODE == 2 && !isNeg || - ROUNDING_MODE == 3 && isNeg ) - : next > half || next == half && - ( ROUNDING_MODE == 4 || more || + r = ROUNDING_MODE < 4 ? (next != null || more) && + (ROUNDING_MODE == 0 || + ROUNDING_MODE == 2 && !isNeg || + ROUNDING_MODE == 3 && isNeg) : next > half || next == half && + (ROUNDING_MODE == 4 || more || - /* - * isOdd is used in base conversion and refers to the least significant - * digit of the integer part of the value to be converted. The fraction - * part is rounded by this method separately from the integer part. - */ - ROUNDING_MODE == 6 && ( xc[i - 1] & 1 || !dp && isOdd ) || - ROUNDING_MODE == 7 && !isNeg || - ROUNDING_MODE == 8 && isNeg ); + /* + * isOdd is used in base conversion and refers to the least significant + * digit of the integer part of the value to be converted. The fraction + * part is rounded by this method separately from the integer part. + */ + ROUNDING_MODE == 6 && (xc[i - 1] & 1 || !dp && isOdd) || + ROUNDING_MODE == 7 && !isNeg || + ROUNDING_MODE == 8 && isNeg); - if ( i < 1 || !xc[0] ) { - xc.length = 0; - xc.push(0); + if (i < 1 || !xc[0]) { + xc.length = 0; + xc.push(0); - if ( r ) { + if (r) { - // 1, 0.1, 0.01, 0.001, 0.0001 etc. - xc[0] = 1; - x['e'] = -dp; - } else { + // 1, 0.1, 0.01, 0.001, 0.0001 etc. + xc[0] = 1; + x['e'] = -dp; + } else { - // Zero. - x['e'] = 0; - } - - return x; - } - - // Remove any digits after the required decimal places. - xc.length = i--; - - // Round up? - if ( r ) { - - // Rounding up may mean the previous digit has to be rounded up and so on. - for ( --base; ++xc[i] > base; ) { - xc[i] = 0; - - if ( !i-- ) { - ++x['e']; - xc.unshift(1); - } - } - } - - // Remove trailing zeros. - for ( i = xc.length; !xc[--i]; xc.pop() ) { + // Zero. + x['e'] = 0; } return x; + } + + // Remove any digits after the required decimal places. + xc.length = i--; + + // Round up? + if (r) { + + // Rounding up may mean the previous digit has to be rounded up and so on. + for (--base; ++xc[i] > base;) { + xc[i] = 0; + + if (!i--) { + ++x['e']; + xc.unshift(1); + } + } + } + + // Remove trailing zeros. + for (i = xc.length; !xc[--i]; xc.pop()) {} + + return x; } // Round after setting the appropriate rounding mode. // Handles ceil, floor and round. -function setMode( x, dp, rm ) { - var r = ROUNDING_MODE; +function setMode(x, dp, rm) { + var r = ROUNDING_MODE; - ROUNDING_MODE = rm; - x = new BigNumber(x); - x['c'] && rnd( x, dp, 10 ); - ROUNDING_MODE = r; + ROUNDING_MODE = rm; + x = new BigNumber(x); + x['c'] && rnd(x, dp, 10); + ROUNDING_MODE = r; - return x; + return x; } @@ -864,21 +839,21 @@ function setMode( x, dp, rm ) { /* * Return a new BigNumber whose value is the absolute value of this BigNumber. */ -P['abs'] = P['absoluteValue'] = function () { - var x = new BigNumber(this); +P['abs'] = P['absoluteValue'] = function() { + var x = new BigNumber(this); - if ( x['s'] < 0 ) { - x['s'] = 1; - } + if (x['s'] < 0) { + x['s'] = 1; + } - return x; + return x; }; /* * Return the bit length of the number. */ -P['bitLength'] = function () { - return this.toString(2).length; +P['bitLength'] = function() { + return this.toString(2).length; }; @@ -886,8 +861,8 @@ P['bitLength'] = function () { * Return a new BigNumber whose value is the value of this BigNumber * rounded to a whole number in the direction of Infinity. */ -P['ceil'] = function () { - return setMode( this, 0, 2 ); +P['ceil'] = function() { + return setMode(this, 0, 2); }; @@ -898,54 +873,54 @@ P['ceil'] = function () { * 0 if they have the same value, * or null if the value of either is NaN. */ -P['comparedTo'] = P['cmp'] = function ( y, b ) { - var a, - x = this, - xc = x['c'], - yc = ( id = -id, y = new BigNumber( y, b ) )['c'], - i = x['s'], - j = y['s'], - k = x['e'], - l = y['e']; +P['comparedTo'] = P['cmp'] = function(y, b) { + var a, + x = this, + xc = x['c'], + yc = (id = -id, y = new BigNumber(y, b))['c'], + i = x['s'], + j = y['s'], + k = x['e'], + l = y['e']; - // Either NaN? - if ( !i || !j ) { - return null; + // Either NaN? + if (!i || !j) { + return null; + } + + a = xc && !xc[0], b = yc && !yc[0]; + + // Either zero? + if (a || b) { + return a ? b ? 0 : -j : i; + } + + // Signs differ? + if (i != j) { + return i; + } + + // Either Infinity? + if (a = i < 0, b = k == l, !xc || !yc) { + return b ? 0 : !xc ^ a ? 1 : -1; + } + + // Compare exponents. + if (!b) { + return k > l ^ a ? 1 : -1; + } + + // Compare digit by digit. + for (i = -1, + j = (k = xc.length) < (l = yc.length) ? k : l; + ++i < j;) { + + if (xc[i] != yc[i]) { + return xc[i] > yc[i] ^ a ? 1 : -1; } - - a = xc && !xc[0], b = yc && !yc[0]; - - // Either zero? - if ( a || b ) { - return a ? b ? 0 : -j : i; - } - - // Signs differ? - if ( i != j ) { - return i; - } - - // Either Infinity? - if ( a = i < 0, b = k == l, !xc || !yc ) { - return b ? 0 : !xc ^ a ? 1 : -1; - } - - // Compare exponents. - if ( !b ) { - return k > l ^ a ? 1 : -1; - } - - // Compare digit by digit. - for ( i = -1, - j = ( k = xc.length ) < ( l = yc.length ) ? k : l; - ++i < j; ) { - - if ( xc[i] != yc[i] ) { - return xc[i] > yc[i] ^ a ? 1 : -1; - } - } - // Compare lengths. - return k == l ? 0 : k > l ^ a ? 1 : -1; + } + // Compare lengths. + return k == l ? 0 : k > l ^ a ? 1 : -1; }; @@ -970,37 +945,37 @@ P['comparedTo'] = P['cmp'] = function ( y, b ) { * divided by the value of BigNumber(y, b), rounded according to * DECIMAL_PLACES and ROUNDING_MODE. */ -P['dividedBy'] = P['div'] = function ( y, b ) { - var xc = this['c'], - xe = this['e'], - xs = this['s'], - yc = ( id = 2, y = new BigNumber( y, b ) )['c'], - ye = y['e'], - ys = y['s'], - s = xs == ys ? 1 : -1; +P['dividedBy'] = P['div'] = function(y, b) { + var xc = this['c'], + xe = this['e'], + xs = this['s'], + yc = (id = 2, y = new BigNumber(y, b))['c'], + ye = y['e'], + ys = y['s'], + s = xs == ys ? 1 : -1; - // Either NaN/Infinity/0? - return !xe && ( !xc || !xc[0] ) || !ye && ( !yc || !yc[0] ) + // Either NaN/Infinity/0? + return !xe && (!xc || !xc[0]) || !ye && (!yc || !yc[0]) - // Either NaN? - ? new BigNumber( !xs || !ys || + // Either NaN? + ? new BigNumber(!xs || !ys || - // Both 0 or both Infinity? - ( xc ? yc && xc[0] == yc[0] : !yc ) + // Both 0 or both Infinity? + (xc ? yc && xc[0] == yc[0] : !yc) - // Return NaN. - ? NaN + // Return NaN. + ? NaN - // x is 0 or y is Infinity? - : xc && xc[0] == 0 || !yc + // x is 0 or y is Infinity? + : xc && xc[0] == 0 || !yc - // Return +-0. - ? s * 0 + // Return +-0. + ? s * 0 - // y is 0. Return +-Infinity. - : s / 0 ) + // y is 0. Return +-Infinity. + : s / 0) - : divide( xc, yc, xe - ye, s, 10 ); + : divide(xc, yc, xe - ye, s, 10); }; @@ -1008,9 +983,9 @@ P['dividedBy'] = P['div'] = function ( y, b ) { * Return true if the value of this BigNumber is equal to the value of * BigNumber(n, b), otherwise returns false. */ -P['equals'] = P['eq'] = function ( n, b ) { - id = 3; - return this['cmp']( n, b ) === 0; +P['equals'] = P['eq'] = function(n, b) { + id = 3; + return this['cmp'](n, b) === 0; }; @@ -1018,8 +993,8 @@ P['equals'] = P['eq'] = function ( n, b ) { * Return a new BigNumber whose value is the value of this BigNumber * rounded to a whole number in the direction of -Infinity. */ -P['floor'] = function () { - return setMode( this, 0, 3 ); +P['floor'] = function() { + return setMode(this, 0, 3); }; @@ -1027,9 +1002,9 @@ P['floor'] = function () { * Return true if the value of this BigNumber is greater than the value of * BigNumber(n, b), otherwise returns false. */ -P['greaterThan'] = P['gt'] = function ( n, b ) { - id = 4; - return this['cmp']( n, b ) > 0; +P['greaterThan'] = P['gt'] = function(n, b) { + id = 4; + return this['cmp'](n, b) > 0; }; @@ -1037,9 +1012,9 @@ P['greaterThan'] = P['gt'] = function ( n, b ) { * Return true if the value of this BigNumber is greater than or equal to * the value of BigNumber(n, b), otherwise returns false. */ -P['greaterThanOrEqualTo'] = P['gte'] = function ( n, b ) { - id = 5; - return ( b = this['cmp']( n, b ) ) == 1 || b === 0; +P['greaterThanOrEqualTo'] = P['gte'] = function(n, b) { + id = 5; + return (b = this['cmp'](n, b)) == 1 || b === 0; }; @@ -1047,8 +1022,8 @@ P['greaterThanOrEqualTo'] = P['gte'] = function ( n, b ) { * Return true if the value of this BigNumber is a finite number, otherwise * returns false. */ -P['isFinite'] = P['isF'] = function () { - return !!this['c']; +P['isFinite'] = P['isF'] = function() { + return !!this['c']; }; @@ -1056,8 +1031,8 @@ P['isFinite'] = P['isF'] = function () { * Return true if the value of this BigNumber is NaN, otherwise returns * false. */ -P['isNaN'] = function () { - return !this['s']; +P['isNaN'] = function() { + return !this['s']; }; @@ -1065,8 +1040,8 @@ P['isNaN'] = function () { * Return true if the value of this BigNumber is negative, otherwise * returns false. */ -P['isNegative'] = P['isNeg'] = function () { - return this['s'] < 0; +P['isNegative'] = P['isNeg'] = function() { + return this['s'] < 0; }; @@ -1074,8 +1049,8 @@ P['isNegative'] = P['isNeg'] = function () { * Return true if the value of this BigNumber is 0 or -0, otherwise returns * false. */ -P['isZero'] = P['isZ'] = function () { - return !!this['c'] && this['c'][0] == 0; +P['isZero'] = P['isZ'] = function() { + return !!this['c'] && this['c'][0] == 0; }; @@ -1083,9 +1058,9 @@ P['isZero'] = P['isZ'] = function () { * Return true if the value of this BigNumber is less than the value of * BigNumber(n, b), otherwise returns false. */ -P['lessThan'] = P['lt'] = function ( n, b ) { - id = 6; - return this['cmp']( n, b ) < 0; +P['lessThan'] = P['lt'] = function(n, b) { + id = 6; + return this['cmp'](n, b) < 0; }; @@ -1093,9 +1068,9 @@ P['lessThan'] = P['lt'] = function ( n, b ) { * Return true if the value of this BigNumber is less than or equal to the * value of BigNumber(n, b), otherwise returns false. */ -P['lessThanOrEqualTo'] = P['lte'] = P['le'] = function ( n, b ) { - id = 7; - return ( b = this['cmp']( n, b ) ) == -1 || b === 0; +P['lessThanOrEqualTo'] = P['lte'] = P['le'] = function(n, b) { + id = 7; + return (b = this['cmp'](n, b)) == -1 || b === 0; }; @@ -1119,132 +1094,125 @@ P['lessThanOrEqualTo'] = P['lte'] = P['le'] = function ( n, b ) { * Return a new BigNumber whose value is the value of this BigNumber minus * the value of BigNumber(y, b). */ -P['minus'] = P['sub'] = function ( y, b ) { - var d, i, j, xLTy, - x = this, - a = x['s']; +P['minus'] = P['sub'] = function(y, b) { + var d, i, j, xLTy, + x = this, + a = x['s']; - b = ( id = 8, y = new BigNumber( y, b ) )['s']; + b = (id = 8, y = new BigNumber(y, b))['s']; - // Either NaN? - if ( !a || !b ) { - return new BigNumber(NaN); + // Either NaN? + if (!a || !b) { + return new BigNumber(NaN); + } + + // Signs differ? + if (a != b) { + return y['s'] = -b, x['plus'](y); + } + + var xc = x['c'], + xe = x['e'], + yc = y['c'], + ye = y['e']; + + if (!xe || !ye) { + + // Either Infinity? + if (!xc || !yc) { + return xc ? (y['s'] = -b, y) : new BigNumber(yc ? x : NaN); } - // Signs differ? - if ( a != b ) { - return y['s'] = -b, x['plus'](y); + // Either zero? + if (!xc[0] || !yc[0]) { + + // y is non-zero? + return yc[0] ? (y['s'] = -b, y) + + // x is non-zero? + : new BigNumber(xc[0] ? x + + // Both are zero. + // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity + : ROUNDING_MODE == 3 ? -0 : 0); } + } - var xc = x['c'], - xe = x['e'], - yc = y['c'], - ye = y['e']; + // Determine which is the bigger number. + // Prepend zeros to equalise exponents. + if (xc = xc.slice(), a = xe - ye) { + d = (xLTy = a < 0) ? (a = -a, xc) : (ye = xe, yc); - if ( !xe || !ye ) { + for (d.reverse(), b = a; b--; d.push(0)) {} + d.reverse(); + } else { - // Either Infinity? - if ( !xc || !yc ) { - return xc ? ( y['s'] = -b, y ) : new BigNumber( yc ? x : NaN ); - } + // Exponents equal. Check digit by digit. + j = ((xLTy = xc.length < yc.length) ? xc : yc).length; - // Either zero? - if ( !xc[0] || !yc[0] ) { + for (a = b = 0; b < j; b++) { - // y is non-zero? - return yc[0] - ? ( y['s'] = -b, y ) - - // x is non-zero? - : new BigNumber( xc[0] - ? x - - // Both are zero. - // IEEE 754 (2008) 6.3: n - n = -0 when rounding to -Infinity - : ROUNDING_MODE == 3 ? -0 : 0 ); - } + if (xc[b] != yc[b]) { + xLTy = xc[b] < yc[b]; + break; + } } + } - // Determine which is the bigger number. - // Prepend zeros to equalise exponents. - if ( xc = xc.slice(), a = xe - ye ) { - d = ( xLTy = a < 0 ) ? ( a = -a, xc ) : ( ye = xe, yc ); + // x < y? Point xc to the array of the bigger number. + if (xLTy) { + d = xc, xc = yc, yc = d; + y['s'] = -y['s']; + } - for ( d.reverse(), b = a; b--; d.push(0) ) { - } - d.reverse(); - } else { + /* + * Append zeros to xc if shorter. No need to add zeros to yc if shorter + * as subtraction only needs to start at yc.length. + */ + if ((b = -((j = xc.length) - yc.length)) > 0) { - // Exponents equal. Check digit by digit. - j = ( ( xLTy = xc.length < yc.length ) ? xc : yc ).length; + for (; b--; xc[j++] = 0) {} + } - for ( a = b = 0; b < j; b++ ) { + // Subtract yc from xc. + for (b = yc.length; b > a;) { - if ( xc[b] != yc[b] ) { - xLTy = xc[b] < yc[b]; - break; - } - } + if (xc[--b] < yc[b]) { + + for (i = b; i && !xc[--i]; xc[i] = 9) {} + --xc[i]; + xc[b] += 10; } + xc[b] -= yc[b]; + } - // x < y? Point xc to the array of the bigger number. - if ( xLTy ) { - d = xc, xc = yc, yc = d; - y['s'] = -y['s']; - } + // Remove trailing zeros. + for (; xc[--j] == 0; xc.pop()) {} + + // Remove leading zeros and adjust exponent accordingly. + for (; xc[0] == 0; xc.shift(), --ye) {} + + /* + * No need to check for Infinity as +x - +y != Infinity && -x - -y != Infinity + * when neither x or y are Infinity. + */ + + // Underflow? + if (ye < MIN_EXP || !xc[0]) { /* - * Append zeros to xc if shorter. No need to add zeros to yc if shorter - * as subtraction only needs to start at yc.length. + * Following IEEE 754 (2008) 6.3, + * n - n = +0 but n - n = -0 when rounding towards -Infinity. */ - if ( ( b = -( ( j = xc.length ) - yc.length ) ) > 0 ) { - - for ( ; b--; xc[j++] = 0 ) { - } + if (!xc[0]) { + y['s'] = ROUNDING_MODE == 3 ? -1 : 1; } - // Subtract yc from xc. - for ( b = yc.length; b > a; ){ + // Result is zero. + xc = [ye = 0]; + } - if ( xc[--b] < yc[b] ) { - - for ( i = b; i && !xc[--i]; xc[i] = 9 ) { - } - --xc[i]; - xc[b] += 10; - } - xc[b] -= yc[b]; - } - - // Remove trailing zeros. - for ( ; xc[--j] == 0; xc.pop() ) { - } - - // Remove leading zeros and adjust exponent accordingly. - for ( ; xc[0] == 0; xc.shift(), --ye ) { - } - - /* - * No need to check for Infinity as +x - +y != Infinity && -x - -y != Infinity - * when neither x or y are Infinity. - */ - - // Underflow? - if ( ye < MIN_EXP || !xc[0] ) { - - /* - * Following IEEE 754 (2008) 6.3, - * n - n = +0 but n - n = -0 when rounding towards -Infinity. - */ - if ( !xc[0] ) { - y['s'] = ROUNDING_MODE == 3 ? -1 : 1; - } - - // Result is zero. - xc = [ye = 0]; - } - - return y['c'] = xc, y['e'] = ye, y; + return y['c'] = xc, y['e'] = ye, y; }; @@ -1262,31 +1230,29 @@ P['minus'] = P['sub'] = function ( y, b ) { * Return a new BigNumber whose value is the value of this BigNumber modulo * the value of BigNumber(y, b). */ -P['modulo'] = P['mod'] = function ( y, b ) { - var x = this, - xc = x['c'], - yc = ( id = 9, y = new BigNumber( y, b ) )['c'], - i = x['s'], - j = y['s']; +P['modulo'] = P['mod'] = function(y, b) { + var x = this, + xc = x['c'], + yc = (id = 9, y = new BigNumber(y, b))['c'], + i = x['s'], + j = y['s']; - // Is x or y NaN, or y zero? - b = !i || !j || yc && !yc[0]; + // Is x or y NaN, or y zero? + b = !i || !j || yc && !yc[0]; - if ( b || xc && !xc[0] ) { - return new BigNumber( b ? NaN : x ); - } + if (b || xc && !xc[0]) { + return new BigNumber(b ? NaN : x); + } - x['s'] = y['s'] = 1; - b = y['cmp'](x) == 1; - x['s'] = i, y['s'] = j; + x['s'] = y['s'] = 1; + b = y['cmp'](x) == 1; + x['s'] = i, y['s'] = j; - return b - ? new BigNumber(x) - : ( i = DECIMAL_PLACES, j = ROUNDING_MODE, - DECIMAL_PLACES = 0, ROUNDING_MODE = 1, - x = x['div'](y), - DECIMAL_PLACES = i, ROUNDING_MODE = j, - this['minus']( x['times'](y) ) ); + return b ? new BigNumber(x) : (i = DECIMAL_PLACES, j = ROUNDING_MODE, + DECIMAL_PLACES = 0, ROUNDING_MODE = 1, + x = x['div'](y), + DECIMAL_PLACES = i, ROUNDING_MODE = j, + this['minus'](x['times'](y))); }; @@ -1294,10 +1260,10 @@ P['modulo'] = P['mod'] = function ( y, b ) { * Return a new BigNumber whose value is the value of this BigNumber * negated, i.e. multiplied by -1. */ -P['negated'] = P['neg'] = function () { - var x = new BigNumber(this); +P['negated'] = P['neg'] = function() { + var x = new BigNumber(this); - return x['s'] = -x['s'] || null, x; + return x['s'] = -x['s'] || null, x; }; @@ -1321,94 +1287,88 @@ P['negated'] = P['neg'] = function () { * Return a new BigNumber whose value is the value of this BigNumber plus * the value of BigNumber(y, b). */ -P['plus'] = P['add'] = function ( y, b ) { - var d, - x = this, - a = x['s']; +P['plus'] = P['add'] = function(y, b) { + var d, + x = this, + a = x['s']; - b = ( id = 10, y = new BigNumber( y, b ) )['s']; + b = (id = 10, y = new BigNumber(y, b))['s']; - // Either NaN? - if ( !a || !b ) { - return new BigNumber(NaN); + // Either NaN? + if (!a || !b) { + return new BigNumber(NaN); + } + + // Signs differ? + if (a != b) { + return y['s'] = -b, x['minus'](y); + } + + var xe = x['e'], + xc = x['c'], + ye = y['e'], + yc = y['c']; + + if (!xe || !ye) { + + // Either Infinity? + if (!xc || !yc) { + + // Return +-Infinity. + return new BigNumber(a / 0); } - // Signs differ? - if ( a != b ) { - return y['s'] = -b, x['minus'](y); + // Either zero? + if (!xc[0] || !yc[0]) { + + // y is non-zero? + return yc[0] ? y + + // x is non-zero? + : new BigNumber(xc[0] ? x + + // Both are zero. Return zero. + : a * 0); } + } - var xe = x['e'], - xc = x['c'], - ye = y['e'], - yc = y['c']; + // Prepend zeros to equalise exponents. + // Note: Faster to use reverse then do unshifts. + if (xc = xc.slice(), a = xe - ye) { + d = a > 0 ? (ye = xe, yc) : (a = -a, xc); - if ( !xe || !ye ) { + for (d.reverse(); a--; d.push(0)) {} + d.reverse(); + } - // Either Infinity? - if ( !xc || !yc ) { + // Point xc to the longer array. + if (xc.length - yc.length < 0) { + d = yc, yc = xc, xc = d; + } - // Return +-Infinity. - return new BigNumber( a / 0 ); - } + /* + * Only start adding at yc.length - 1 as the + * further digits of xc can be left as they are. + */ + for (a = yc.length, b = 0; a; b = (xc[--a] = xc[a] + yc[a] + b) / 10 ^ 0, xc[a] %= 10) {} - // Either zero? - if ( !xc[0] || !yc[0] ) { + // No need to check for zero, as +x + +y != 0 && -x + -y != 0 - // y is non-zero? - return yc[0] - ? y + if (b) { + xc.unshift(b); - // x is non-zero? - : new BigNumber( xc[0] - ? x + // Overflow? (MAX_EXP + 1 possible) + if (++ye > MAX_EXP) { - // Both are zero. Return zero. - : a * 0 ); - } + // Infinity. + xc = ye = null; } + } - // Prepend zeros to equalise exponents. - // Note: Faster to use reverse then do unshifts. - if ( xc = xc.slice(), a = xe - ye ) { - d = a > 0 ? ( ye = xe, yc ) : ( a = -a, xc ); + // Remove trailing zeros. + for (a = xc.length; xc[--a] == 0; xc.pop()) {} - for ( d.reverse(); a--; d.push(0) ) { - } - d.reverse(); - } - - // Point xc to the longer array. - if ( xc.length - yc.length < 0 ) { - d = yc, yc = xc, xc = d; - } - - /* - * Only start adding at yc.length - 1 as the - * further digits of xc can be left as they are. - */ - for ( a = yc.length, b = 0; a; - b = ( xc[--a] = xc[a] + yc[a] + b ) / 10 ^ 0, xc[a] %= 10 ) { - } - - // No need to check for zero, as +x + +y != 0 && -x + -y != 0 - - if ( b ) { - xc.unshift(b); - - // Overflow? (MAX_EXP + 1 possible) - if ( ++ye > MAX_EXP ) { - - // Infinity. - xc = ye = null; - } - } - - // Remove trailing zeros. - for ( a = xc.length; xc[--a] == 0; xc.pop() ) { - } - - return y['c'] = xc, y['e'] = ye, y; + return y['c'] = xc, y['e'] = ye, y; }; @@ -1419,51 +1379,51 @@ P['plus'] = P['add'] = function ( y, b ) { * * e {number} Integer, -MAX_POWER to MAX_POWER inclusive. */ -P['toPower'] = P['pow'] = function ( e ) { +P['toPower'] = P['pow'] = function(e) { - // e to integer, avoiding NaN or Infinity becoming 0. - var i = e * 0 == 0 ? e | 0 : e, - x = new BigNumber(this), - y = new BigNumber(ONE); + // e to integer, avoiding NaN or Infinity becoming 0. + var i = e * 0 == 0 ? e | 0 : e, + x = new BigNumber(this), + y = new BigNumber(ONE); - // Use Math.pow? - // Pass +-Infinity for out of range exponents. - if ( ( ( ( outOfRange = e < -MAX_POWER || e > MAX_POWER ) && - (i = e * 1 / 0) ) || + // Use Math.pow? + // Pass +-Infinity for out of range exponents. + if ((((outOfRange = e < -MAX_POWER || e > MAX_POWER) && + (i = e * 1 / 0)) || - /* - * Any exponent that fails the parse becomes NaN. - * - * Include 'e !== 0' because on Opera -0 == parseFloat(-0) is false, - * despite -0 === parseFloat(-0) && -0 == parseFloat('-0') is true. - */ - parse(e) != e && e !== 0 && !(i = NaN) ) && + /* + * Any exponent that fails the parse becomes NaN. + * + * Include 'e !== 0' because on Opera -0 == parseFloat(-0) is false, + * despite -0 === parseFloat(-0) && -0 == parseFloat('-0') is true. + */ + parse(e) != e && e !== 0 && !(i = NaN)) && - // 'pow() exponent not an integer: {e}' - // 'pow() exponent out of range: {e}' - !ifExceptionsThrow( e, 'exponent', 'pow' ) || + // 'pow() exponent not an integer: {e}' + // 'pow() exponent out of range: {e}' + !ifExceptionsThrow(e, 'exponent', 'pow') || - // Pass zero to Math.pow, as any value to the power zero is 1. - !i ) { + // Pass zero to Math.pow, as any value to the power zero is 1. + !i) { - // i is +-Infinity, NaN or 0. - return new BigNumber( Math.pow( x['toS'](), i ) ); + // i is +-Infinity, NaN or 0. + return new BigNumber(Math.pow(x['toS'](), i)); + } + + for (i = i < 0 ? -i : i;;) { + + if (i & 1) { + y = y['times'](x); } + i >>= 1; - for ( i = i < 0 ? -i : i; ; ) { - - if ( i & 1 ) { - y = y['times'](x); - } - i >>= 1; - - if ( !i ) { - break; - } - x = x['times'](x); + if (!i) { + break; } + x = x['times'](x); + } - return e < 0 ? ONE['div'](y) : y; + return e < 0 ? ONE['div'](y) : y; }; @@ -1474,8 +1434,8 @@ P['toPower'] = P['pow'] = function ( e ) { * m {BigNumber} the value to take the power of * n {BigNumber} the value to modulo by */ -P['powm'] = function ( m, n ) { - return this.pow(m).mod(n); +P['powm'] = function(m, n) { + return this.pow(m).mod(n); }; @@ -1487,29 +1447,25 @@ P['powm'] = function ( m, n ) { * [dp] {number} Integer, 0 to MAX inclusive. * [rm] {number} Integer, 0 to 8 inclusive. */ -P['round'] = function ( dp, rm ) { +P['round'] = function(dp, rm) { - dp = dp == null || ( ( ( outOfRange = dp < 0 || dp > MAX ) || - parse(dp) != dp ) && + dp = dp == null || (((outOfRange = dp < 0 || dp > MAX) || + parse(dp) != dp) && - // 'round() decimal places out of range: {dp}' - // 'round() decimal places not an integer: {dp}' - !ifExceptionsThrow( dp, 'decimal places', 'round' ) ) - ? 0 - : dp | 0; + // 'round() decimal places out of range: {dp}' + // 'round() decimal places not an integer: {dp}' + !ifExceptionsThrow(dp, 'decimal places', 'round')) ? 0 : dp | 0; - rm = rm == null || ( ( ( outOfRange = rm < 0 || rm > 8 ) || + rm = rm == null || (((outOfRange = rm < 0 || rm > 8) || // Include '&& rm !== 0' because with Opera -0 == parseFloat(-0) is false. - parse(rm) != rm && rm !== 0 ) && + parse(rm) != rm && rm !== 0) && - // 'round() mode not an integer: {rm}' - // 'round() mode out of range: {rm}' - !ifExceptionsThrow( rm, 'mode', 'round' ) ) - ? ROUNDING_MODE - : rm | 0; + // 'round() mode not an integer: {rm}' + // 'round() mode out of range: {rm}' + !ifExceptionsThrow(rm, 'mode', 'round')) ? ROUNDING_MODE : rm | 0; - return setMode( this, dp, rm ); + return setMode(this, dp, rm); }; @@ -1524,126 +1480,124 @@ P['round'] = function ( dp, rm ) { * Return a new BigNumber whose value is the square root of the value of * this BigNumber, rounded according to DECIMAL_PLACES and ROUNDING_MODE. */ -P['squareRoot'] = P['sqrt'] = function () { - var n, r, re, t, - x = this, - c = x['c'], - s = x['s'], - e = x['e'], - dp = DECIMAL_PLACES, - rm = ROUNDING_MODE, - half = new BigNumber('0.5'); +P['squareRoot'] = P['sqrt'] = function() { + var n, r, re, t, + x = this, + c = x['c'], + s = x['s'], + e = x['e'], + dp = DECIMAL_PLACES, + rm = ROUNDING_MODE, + half = new BigNumber('0.5'); - // Negative/NaN/Infinity/zero? - if ( s !== 1 || !c || !c[0] ) { + // Negative/NaN/Infinity/zero? + if (s !== 1 || !c || !c[0]) { - return new BigNumber( !s || s < 0 && ( !c || c[0] ) - ? NaN - : c ? x : 1 / 0 ); - } + return new BigNumber(!s || s < 0 && (!c || c[0]) ? NaN : c ? x : 1 / 0); + } - // Initial estimate. - s = Math.sqrt( x['toS']() ); - ROUNDING_MODE = 1; + // Initial estimate. + s = Math.sqrt(x['toS']()); + ROUNDING_MODE = 1; - /* + /* Math.sqrt underflow/overflow? Pass x to Math.sqrt as integer, then adjust the exponent of the result. */ - if ( s == 0 || s == 1 / 0 ) { - n = c.join(''); + if (s == 0 || s == 1 / 0) { + n = c.join(''); - if ( !( n.length + e & 1 ) ) { - n += '0'; - } - r = new BigNumber( Math.sqrt(n) + '' ); - - // r may still not be finite. - if ( !r['c'] ) { - r['c'] = [1]; - } - r['e'] = ( ( ( e + 1 ) / 2 ) | 0 ) - ( e < 0 || e & 1 ); - } else { - r = new BigNumber( n = s.toString() ); + if (!(n.length + e & 1)) { + n += '0'; } - re = r['e']; - s = re + ( DECIMAL_PLACES += 4 ); + r = new BigNumber(Math.sqrt(n) + ''); - if ( s < 3 ) { - s = 0; + // r may still not be finite. + if (!r['c']) { + r['c'] = [1]; } - e = s; + r['e'] = (((e + 1) / 2) | 0) - (e < 0 || e & 1); + } else { + r = new BigNumber(n = s.toString()); + } + re = r['e']; + s = re + (DECIMAL_PLACES += 4); - // Newton-Raphson iteration. - for ( ; ; ) { - t = r; - r = half['times']( t['plus']( x['div'](t) ) ); + if (s < 3) { + s = 0; + } + e = s; - if ( t['c'].slice( 0, s ).join('') === r['c'].slice( 0, s ).join('') ) { - c = r['c']; + // Newton-Raphson iteration. + for (;;) { + t = r; + r = half['times'](t['plus'](x['div'](t))); - /* + if (t['c'].slice(0, s).join('') === r['c'].slice(0, s).join('')) { + c = r['c']; + + /* The exponent of r may here be one less than the final result exponent (re), e.g 0.0009999 (e-4) --> 0.001 (e-3), so adjust s so the rounding digits are indexed correctly. */ - s = s - ( n && r['e'] < re ); + s = s - (n && r['e'] < re); - /* + /* The 4th rounding digit may be in error by -1 so if the 4 rounding digits are 9999 or 4999 (i.e. approaching a rounding boundary) continue the iteration. */ - if ( c[s] == 9 && c[s - 1] == 9 && c[s - 2] == 9 && - ( c[s - 3] == 9 || n && c[s - 3] == 4 ) ) { + if (c[s] == 9 && c[s - 1] == 9 && c[s - 2] == 9 && + (c[s - 3] == 9 || n && c[s - 3] == 4)) { - /* + /* If 9999 on first run through, check to see if rounding up gives the exact result as the nines may infinitely repeat. */ - if ( n && c[s - 3] == 9 ) { - t = r['round']( dp, 0 ); + if (n && c[s - 3] == 9) { + t = r['round'](dp, 0); - if ( t['times'](t)['eq'](x) ) { - ROUNDING_MODE = rm; - DECIMAL_PLACES = dp; + if (t['times'](t)['eq'](x)) { + ROUNDING_MODE = rm; + DECIMAL_PLACES = dp; - return t; - } - } - DECIMAL_PLACES += 4; - s += 4; - n = ''; - } else { + return t; + } + } + DECIMAL_PLACES += 4; + s += 4; + n = ''; + } else { - /* + /* If the rounding digits are null, 0000 or 5000, check for an exact result. If not, then there are further digits so increment the 1st rounding digit to ensure correct rounding. */ - if ( !c[e] && !c[e - 1] && !c[e - 2] && - ( !c[e - 3] || c[e - 3] == 5 ) ) { + if (!c[e] && !c[e - 1] && !c[e - 2] && + (!c[e - 3] || c[e - 3] == 5)) { - // Truncate to the first rounding digit. - if ( c.length > e - 2 ) { - c.length = e - 2; - } + // Truncate to the first rounding digit. + if (c.length > e - 2) { + c.length = e - 2; + } - if ( !r['times'](r)['eq'](x) ) { + if (!r['times'](r)['eq'](x)) { - while ( c.length < e - 3 ) { - c.push(0); - } - c[e - 3]++; - } - } - ROUNDING_MODE = rm; - rnd( r, DECIMAL_PLACES = dp, 10 ); - - return r; + while (c.length < e - 3) { + c.push(0); } + c[e - 3]++; + } } + ROUNDING_MODE = rm; + rnd(r, DECIMAL_PLACES = dp, 10); + + return r; + } } + } }; @@ -1667,158 +1621,158 @@ P['squareRoot'] = P['sqrt'] = function () { * Return a new BigNumber whose value is the value of this BigNumber times * the value of BigNumber(y, b). */ -P['times'] = P['mul'] = function ( y, b ) { - var c, - x = this, - xc = x['c'], - yc = ( id = 11, y = new BigNumber( y, b ) )['c'], - i = x['e'], - j = y['e'], - a = x['s']; +P['times'] = P['mul'] = function(y, b) { + var c, + x = this, + xc = x['c'], + yc = (id = 11, y = new BigNumber(y, b))['c'], + i = x['e'], + j = y['e'], + a = x['s']; - y['s'] = a == ( b = y['s'] ) ? 1 : -1; + y['s'] = a == (b = y['s']) ? 1 : -1; - // Either NaN/Infinity/0? - if ( !i && ( !xc || !xc[0] ) || !j && ( !yc || !yc[0] ) ) { + // Either NaN/Infinity/0? + if (!i && (!xc || !xc[0]) || !j && (!yc || !yc[0])) { - // Either NaN? - return new BigNumber( !a || !b || + // Either NaN? + return new BigNumber(!a || !b || - // x is 0 and y is Infinity or y is 0 and x is Infinity? - xc && !xc[0] && !yc || yc && !yc[0] && !xc + // x is 0 and y is Infinity or y is 0 and x is Infinity? + xc && !xc[0] && !yc || yc && !yc[0] && !xc - // Return NaN. - ? NaN + // Return NaN. + ? NaN - // Either Infinity? - : !xc || !yc + // Either Infinity? + : !xc || !yc - // Return +-Infinity. - ? y['s'] / 0 + // Return +-Infinity. + ? y['s'] / 0 - // x or y is 0. Return +-0. - : y['s'] * 0 ); + // x or y is 0. Return +-0. + : y['s'] * 0); + } + y['e'] = i + j; + + if ((a = xc.length) < (b = yc.length)) { + c = xc, xc = yc, yc = c, j = a, a = b, b = j; + } + + for (j = a + b, c = []; j--; c.push(0)) {} + + // Multiply! + for (i = b - 1; i > -1; i--) { + + for (b = 0, j = a + i; j > i; b = c[j] + yc[i] * xc[j - i - 1] + b, + c[j--] = b % 10 | 0, + b = b / 10 | 0) {} + + if (b) { + c[j] = (c[j] + b) % 10; } - y['e'] = i + j; + } - if ( ( a = xc.length ) < ( b = yc.length ) ) { - c = xc, xc = yc, yc = c, j = a, a = b, b = j; - } + b && ++y['e']; - for ( j = a + b, c = []; j--; c.push(0) ) { - } + // Remove any leading zero. + !c[0] && c.shift(); - // Multiply! - for ( i = b - 1; i > -1; i-- ) { + // Remove trailing zeros. + for (j = c.length; !c[--j]; c.pop()) {} - for ( b = 0, j = a + i; - j > i; - b = c[j] + yc[i] * xc[j - i - 1] + b, - c[j--] = b % 10 | 0, - b = b / 10 | 0 ) { - } + // No zero check needed as only x * 0 == 0 etc. - if ( b ) { - c[j] = ( c[j] + b ) % 10; - } - } + // Overflow? + y['c'] = y['e'] > MAX_EXP - b && ++y['e']; + // Infinity. + ? (y['e'] = null) - // Remove any leading zero. - !c[0] && c.shift(); + // Underflow? + : y['e'] < MIN_EXP - // Remove trailing zeros. - for ( j = c.length; !c[--j]; c.pop() ) { - } + // Zero. + ? [y['e'] = 0] - // No zero check needed as only x * 0 == 0 etc. + // Neither. + : c; - // Overflow? - y['c'] = y['e'] > MAX_EXP - - // Infinity. - ? ( y['e'] = null ) - - // Underflow? - : y['e'] < MIN_EXP - - // Zero. - ? [ y['e'] = 0 ] - - // Neither. - : c; - - return y; + return y; }; /* - * Return a buffer containing the + * Return a buffer containing the */ -P['toBuffer'] = function ( opts ) { +P['toBuffer'] = function(opts) { - if (typeof opts === 'string') { - if (opts !== 'mpint') return 'Unsupported Buffer representation'; + if (typeof opts === 'string') { + if (opts !== 'mpint') return 'Unsupported Buffer representation'; - var abs = this.abs(); - var buf = abs.toBuffer({ size : 1, endian : 'big' }); - var len = buf.length === 1 && buf[0] === 0 ? 0 : buf.length; - if (buf[0] & 0x80) len ++; + var abs = this.abs(); + var buf = abs.toBuffer({ + size: 1, + endian: 'big' + }); + var len = buf.length === 1 && buf[0] === 0 ? 0 : buf.length; + if (buf[0] & 0x80) len++; - var ret = new Buffer(4 + len); - if (len > 0) buf.copy(ret, 4 + (buf[0] & 0x80 ? 1 : 0)); - if (buf[0] & 0x80) ret[4] = 0; + var ret = new Buffer(4 + len); + if (len > 0) buf.copy(ret, 4 + (buf[0] & 0x80 ? 1 : 0)); + if (buf[0] & 0x80) ret[4] = 0; - ret[0] = len & (0xff << 24); - ret[1] = len & (0xff << 16); - ret[2] = len & (0xff << 8); - ret[3] = len & (0xff << 0); + ret[0] = len & (0xff << 24); + ret[1] = len & (0xff << 16); + ret[2] = len & (0xff << 8); + ret[3] = len & (0xff << 0); - // two's compliment for negative integers: - var isNeg = this.lt(0); - if (isNeg) { - for (var i = 4; i < ret.length; i++) { - ret[i] = 0xff - ret[i]; - } - } - ret[4] = (ret[4] & 0x7f) | (isNeg ? 0x80 : 0); - if (isNeg) ret[ret.length - 1] ++; - - return ret; + // two's compliment for negative integers: + var isNeg = this.lt(0); + if (isNeg) { + for (var i = 4; i < ret.length; i++) { + ret[i] = 0xff - ret[i]; + } } + ret[4] = (ret[4] & 0x7f) | (isNeg ? 0x80 : 0); + if (isNeg) ret[ret.length - 1]++; - if (!opts) opts = {}; + return ret; + } - var endian = { 1 : 'big', '-1' : 'little' }[opts.endian] - || opts.endian || 'big' - ; + if (!opts) opts = {}; - var hex = this.toString(16); - if (hex.charAt(0) === '-') throw new Error( - 'converting negative numbers to Buffers not supported yet' - ); + var endian = { + 1: 'big', + '-1': 'little' + }[opts.endian] || opts.endian || 'big'; - var size = opts.size === 'auto' ? Math.ceil(hex.length / 2) : (opts.size || 1); + var hex = this.toString(16); + if (hex.charAt(0) === '-') throw new Error( + 'converting negative numbers to Buffers not supported yet' + ); - var len = Math.ceil(hex.length / (2 * size)) * size; - var buf = new Buffer(len); + var size = opts.size === 'auto' ? Math.ceil(hex.length / 2) : (opts.size || 1); - // zero-pad the hex string so the chunks are all `size` long - while (hex.length < 2 * len) hex = '0' + hex; + var len = Math.ceil(hex.length / (2 * size)) * size; + var buf = new Buffer(len); - var hx = hex - .split(new RegExp('(.{' + (2 * size) + '})')) - .filter(function (s) { return s.length > 0 }) - ; + // zero-pad the hex string so the chunks are all `size` long + while (hex.length < 2 * len) hex = '0' + hex; - hx.forEach(function (chunk, i) { - for (var j = 0; j < size; j++) { - var ix = i * size + (endian === 'big' ? j : size - j - 1); - buf[ix] = parseInt(chunk.slice(j*2,j*2+2), 16); - } + var hx = hex + .split(new RegExp('(.{' + (2 * size) + '})')) + .filter(function(s) { + return s.length > 0 }); - return buf; + hx.forEach(function(chunk, i) { + for (var j = 0; j < size; j++) { + var ix = i * size + (endian === 'big' ? j : size - j - 1); + buf[ix] = parseInt(chunk.slice(j * 2, j * 2 + 2), 16); + } + }); + + return buf; }; /* @@ -1828,22 +1782,19 @@ P['toBuffer'] = function ( opts ) { * * [dp] {number} Integer, 0 to MAX inclusive. */ -P['toExponential'] = P['toE'] = function ( dp ) { +P['toExponential'] = P['toE'] = function(dp) { - return format( this, - ( dp == null || ( ( outOfRange = dp < 0 || dp > MAX ) || + return format(this, (dp == null || ((outOfRange = dp < 0 || dp > MAX) || - /* - * Include '&& dp !== 0' because with Opera -0 == parseFloat(-0) is - * false, despite -0 == parseFloat('-0') && 0 == -0 being true. - */ - parse(dp) != dp && dp !== 0 ) && + /* + * Include '&& dp !== 0' because with Opera -0 == parseFloat(-0) is + * false, despite -0 == parseFloat('-0') && 0 == -0 being true. + */ + parse(dp) != dp && dp !== 0) && - // 'toE() decimal places not an integer: {dp}' - // 'toE() decimal places out of range: {dp}' - !ifExceptionsThrow( dp, 'decimal places', 'toE' ) ) && this['c'] - ? this['c'].length - 1 - : dp | 0, 1 ); + // 'toE() decimal places not an integer: {dp}' + // 'toE() decimal places out of range: {dp}' + !ifExceptionsThrow(dp, 'decimal places', 'toE')) && this['c'] ? this['c'].length - 1 : dp | 0, 1); }; @@ -1857,45 +1808,45 @@ P['toExponential'] = P['toE'] = function ( dp ) { * * [dp] {number} Integer, 0 to MAX inclusive. */ -P['toFixed'] = P['toF'] = function ( dp ) { - var n, str, d, - x = this; +P['toFixed'] = P['toF'] = function(dp) { + var n, str, d, + x = this; - if ( !( dp == null || ( ( outOfRange = dp < 0 || dp > MAX ) || - parse(dp) != dp && dp !== 0 ) && + if (!(dp == null || ((outOfRange = dp < 0 || dp > MAX) || + parse(dp) != dp && dp !== 0) && - // 'toF() decimal places not an integer: {dp}' - // 'toF() decimal places out of range: {dp}' - !ifExceptionsThrow( dp, 'decimal places', 'toF' ) ) ) { - d = x['e'] + ( dp | 0 ); + // 'toF() decimal places not an integer: {dp}' + // 'toF() decimal places out of range: {dp}' + !ifExceptionsThrow(dp, 'decimal places', 'toF'))) { + d = x['e'] + (dp | 0); + } + + n = TO_EXP_NEG, dp = TO_EXP_POS; + TO_EXP_NEG = -(TO_EXP_POS = 1 / 0); + + // Note: str is initially undefined. + if (d == str) { + str = x['toS'](); + } else { + str = format(x, d); + + // (-0).toFixed() is '0', but (-0.1).toFixed() is '-0'. + // (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. + if (x['s'] < 0 && x['c']) { + + // As e.g. -0 toFixed(3), will wrongly be returned as -0.000 from toString. + if (!x['c'][0]) { + str = str.replace(/^-/, ''); + + // As e.g. -0.5 if rounded to -0 will cause toString to omit the minus sign. + } else if (str.indexOf('-') < 0) { + str = '-' + str; + } } + } + TO_EXP_NEG = n, TO_EXP_POS = dp; - n = TO_EXP_NEG, dp = TO_EXP_POS; - TO_EXP_NEG = -( TO_EXP_POS = 1 / 0 ); - - // Note: str is initially undefined. - if ( d == str ) { - str = x['toS'](); - } else { - str = format( x, d ); - - // (-0).toFixed() is '0', but (-0.1).toFixed() is '-0'. - // (-0).toFixed(1) is '0.0', but (-0.01).toFixed(1) is '-0.0'. - if ( x['s'] < 0 && x['c'] ) { - - // As e.g. -0 toFixed(3), will wrongly be returned as -0.000 from toString. - if ( !x['c'][0] ) { - str = str.replace(/^-/, ''); - - // As e.g. -0.5 if rounded to -0 will cause toString to omit the minus sign. - } else if ( str.indexOf('-') < 0 ) { - str = '-' + str; - } - } - } - TO_EXP_NEG = n, TO_EXP_POS = dp; - - return str; + return str; }; @@ -1909,83 +1860,81 @@ P['toFixed'] = P['toF'] = function ( dp ) { * * [maxD] {number|string|BigNumber} Integer >= 1 and < Infinity. */ -P['toFraction'] = P['toFr'] = function ( maxD ) { - var q, frac, n0, d0, d2, n, e, - n1 = d0 = new BigNumber(ONE), - d1 = n0 = new BigNumber('0'), - x = this, - xc = x['c'], - exp = MAX_EXP, - dp = DECIMAL_PLACES, - rm = ROUNDING_MODE, - d = new BigNumber(ONE); +P['toFraction'] = P['toFr'] = function(maxD) { + var q, frac, n0, d0, d2, n, e, + n1 = d0 = new BigNumber(ONE), + d1 = n0 = new BigNumber('0'), + x = this, + xc = x['c'], + exp = MAX_EXP, + dp = DECIMAL_PLACES, + rm = ROUNDING_MODE, + d = new BigNumber(ONE); - // NaN, Infinity. - if ( !xc ) { - return x['toS'](); + // NaN, Infinity. + if (!xc) { + return x['toS'](); + } + + e = d['e'] = xc.length - x['e'] - 1; + + // If max denominator is undefined or null... + if (maxD == null || + + // or NaN... + (!(id = 12, n = new BigNumber(maxD))['s'] || + + // or less than 1, or Infinity... + (outOfRange = n['cmp'](n1) < 0 || !n['c']) || + + // or not an integer... + (ERRORS && n['e'] < n['c'].length - 1)) && + + // 'toFr() max denominator not an integer: {maxD}' + // 'toFr() max denominator out of range: {maxD}' + !ifExceptionsThrow(maxD, 'max denominator', 'toFr') || + + // or greater than the maxD needed to specify the value exactly... + (maxD = n)['cmp'](d) > 0) { + + // d is e.g. 10, 100, 1000, 10000... , n1 is 1. + maxD = e > 0 ? d : n1; + } + + MAX_EXP = 1 / 0; + n = new BigNumber(xc.join('')); + + for (DECIMAL_PLACES = 0, ROUNDING_MODE = 1;;) { + q = n['div'](d); + d2 = d0['plus'](q['times'](d1)); + + if (d2['cmp'](maxD) == 1) { + break; } - e = d['e'] = xc.length - x['e'] - 1; + d0 = d1, d1 = d2; - // If max denominator is undefined or null... - if ( maxD == null || + n1 = n0['plus'](q['times'](d2 = n1)); + n0 = d2; - // or NaN... - ( !( id = 12, n = new BigNumber(maxD) )['s'] || + d = n['minus'](q['times'](d2 = d)); + n = d2; + } - // or less than 1, or Infinity... - ( outOfRange = n['cmp'](n1) < 0 || !n['c'] ) || + d2 = maxD['minus'](d0)['div'](d1); + n0 = n0['plus'](d2['times'](n1)); + d0 = d0['plus'](d2['times'](d1)); - // or not an integer... - ( ERRORS && n['e'] < n['c'].length - 1 ) ) && + n0['s'] = n1['s'] = x['s']; - // 'toFr() max denominator not an integer: {maxD}' - // 'toFr() max denominator out of range: {maxD}' - !ifExceptionsThrow( maxD, 'max denominator', 'toFr' ) || + DECIMAL_PLACES = e * 2; + ROUNDING_MODE = rm; - // or greater than the maxD needed to specify the value exactly... - ( maxD = n )['cmp'](d) > 0 ) { + // Determine which fraction is closer to x, n0 / d0 or n1 / d1? + frac = n1['div'](d1)['minus'](x)['abs']()['cmp']( + n0['div'](d0)['minus'](x)['abs']()) < 1 ? [n1['toS'](), d1['toS']()] : [n0['toS'](), d0['toS']()]; - // d is e.g. 10, 100, 1000, 10000... , n1 is 1. - maxD = e > 0 ? d : n1; - } - - MAX_EXP = 1 / 0; - n = new BigNumber( xc.join('') ); - - for ( DECIMAL_PLACES = 0, ROUNDING_MODE = 1; ; ) { - q = n['div'](d); - d2 = d0['plus']( q['times'](d1) ); - - if ( d2['cmp'](maxD) == 1 ) { - break; - } - - d0 = d1, d1 = d2; - - n1 = n0['plus']( q['times']( d2 = n1 ) ); - n0 = d2; - - d = n['minus']( q['times']( d2 = d ) ); - n = d2; - } - - d2 = maxD['minus'](d0)['div'](d1); - n0 = n0['plus']( d2['times'](n1) ); - d0 = d0['plus']( d2['times'](d1) ); - - n0['s'] = n1['s'] = x['s']; - - DECIMAL_PLACES = e * 2; - ROUNDING_MODE = rm; - - // Determine which fraction is closer to x, n0 / d0 or n1 / d1? - frac = n1['div'](d1)['minus'](x)['abs']()['cmp']( - n0['div'](d0)['minus'](x)['abs']() ) < 1 - ? [ n1['toS'](), d1['toS']() ] - : [ n0['toS'](), d0['toS']() ]; - - return MAX_EXP = exp, DECIMAL_PLACES = dp, frac; + return MAX_EXP = exp, DECIMAL_PLACES = dp, frac; }; @@ -1997,21 +1946,19 @@ P['toFraction'] = P['toFr'] = function ( maxD ) { * * sd {number} Integer, 1 to MAX inclusive. */ -P['toPrecision'] = P['toP'] = function ( sd ) { +P['toPrecision'] = P['toP'] = function(sd) { - /* - * ERRORS true: Throw if sd not undefined, null or an integer in range. - * ERRORS false: Ignore sd if not a number or not in range. - * Truncate non-integers. - */ - return sd == null || ( ( ( outOfRange = sd < 1 || sd > MAX ) || - parse(sd) != sd ) && + /* + * ERRORS true: Throw if sd not undefined, null or an integer in range. + * ERRORS false: Ignore sd if not a number or not in range. + * Truncate non-integers. + */ + return sd == null || (((outOfRange = sd < 1 || sd > MAX) || + parse(sd) != sd) && - // 'toP() precision not an integer: {sd}' - // 'toP() precision out of range: {sd}' - !ifExceptionsThrow( sd, 'precision', 'toP' ) ) - ? this['toS']() - : format( this, --sd | 0, 2 ); + // 'toP() precision not an integer: {sd}' + // 'toP() precision out of range: {sd}' + !ifExceptionsThrow(sd, 'precision', 'toP')) ? this['toS']() : format(this, --sd | 0, 2); }; @@ -2025,76 +1972,74 @@ P['toPrecision'] = P['toP'] = function ( sd ) { * * [b] {number} Integer, 2 to 64 inclusive. */ -P['toString'] = P['toS'] = function ( b ) { - var u, str, strL, - x = this, - xe = x['e']; +P['toString'] = P['toS'] = function(b) { + var u, str, strL, + x = this, + xe = x['e']; - // Infinity or NaN? - if ( xe === null ) { - str = x['s'] ? 'Infinity' : 'NaN'; + // Infinity or NaN? + if (xe === null) { + str = x['s'] ? 'Infinity' : 'NaN'; // Exponential format? - } else if ( b === u && ( xe <= TO_EXP_NEG || xe >= TO_EXP_POS ) ) { - return format( x, x['c'].length - 1, 1 ); + } else if (b === u && (xe <= TO_EXP_NEG || xe >= TO_EXP_POS)) { + return format(x, x['c'].length - 1, 1); + } else { + str = x['c'].join(''); + + // Negative exponent? + if (xe < 0) { + + // Prepend zeros. + for (; ++xe; str = '0' + str) {} + str = '0.' + str; + + // Positive exponent? + } else if (strL = str.length, xe > 0) { + + if (++xe > strL) { + + // Append zeros. + for (xe -= strL; xe--; str += '0') {} + } else if (xe < strL) { + str = str.slice(0, xe) + '.' + str.slice(xe); + } + + // Exponent zero. } else { - str = x['c'].join(''); - - // Negative exponent? - if ( xe < 0 ) { - - // Prepend zeros. - for ( ; ++xe; str = '0' + str ) { - } - str = '0.' + str; - - // Positive exponent? - } else if ( strL = str.length, xe > 0 ) { - - if ( ++xe > strL ) { - - // Append zeros. - for ( xe -= strL; xe-- ; str += '0' ) { - } - } else if ( xe < strL ) { - str = str.slice( 0, xe ) + '.' + str.slice(xe); - } - - // Exponent zero. - } else { - if ( u = str.charAt(0), strL > 1 ) { - str = u + '.' + str.slice(1); - - // Avoid '-0' - } else if ( u == '0' ) { - return u; - } - } - - if ( b != null ) { - - if ( !( outOfRange = !( b >= 2 && b < 65 ) ) && - ( b == (b | 0) || !ERRORS ) ) { - str = convert( str, b | 0, 10, x['s'] ); - - // Avoid '-0' - if ( str == '0' ) { - return str; - } - } else { - - // 'toS() base not an integer: {b}' - // 'toS() base out of range: {b}' - ifExceptionsThrow( b, 'base', 'toS' ); - } - } + if (u = str.charAt(0), strL > 1) { + str = u + '.' + str.slice(1); + // Avoid '-0' + } else if (u == '0') { + return u; + } } - return x['s'] < 0 ? '-' + str : str; + if (b != null) { + + if (!(outOfRange = !(b >= 2 && b < 65)) && + (b == (b | 0) || !ERRORS)) { + str = convert(str, b | 0, 10, x['s']); + + // Avoid '-0' + if (str == '0') { + return str; + } + } else { + + // 'toS() base not an integer: {b}' + // 'toS() base out of range: {b}' + ifExceptionsThrow(b, 'base', 'toS'); + } + } + + } + + return x['s'] < 0 ? '-' + str : str; }; -P['toNumber'] = function () { +P['toNumber'] = function() { return parseInt(this['toString'](), 10); }; @@ -2102,8 +2047,8 @@ P['toNumber'] = function () { /* * Return as toString, but do not accept a base argument. */ -P['valueOf'] = function () { - return this['toS'](); +P['valueOf'] = function() { + return this['toS'](); }; @@ -2118,6 +2063,9 @@ P['valueOf'] = function () { // EXPORT -BigNumber.config({EXPONENTIAL_AT: 9999999, DECIMAL_PLACES: 0, ROUNDING_MODE: 1}); +BigNumber.config({ + EXPONENTIAL_AT: 9999999, + DECIMAL_PLACES: 0, + ROUNDING_MODE: 1 +}); module.exports = BigNumber; - diff --git a/lib/browser/ECIES.js b/lib/browser/ECIES.js index 6aeda46..681601e 100644 --- a/lib/browser/ECIES.js +++ b/lib/browser/ECIES.js @@ -9,7 +9,13 @@ ECIES.symmetricEncrypt = function(key, iv, message) { var smessage = sjcl.codec.hex.toBits(message.toString('hex')); sjcl.beware["CBC mode is dangerous because it doesn't protect message integrity."](); - var params = {iv: siv, ks: 256, ts: 128, iter: 1000, mode: 'cbc'}; + var params = { + iv: siv, + ks: 256, + ts: 128, + iter: 1000, + mode: 'cbc' + }; var encrypted = sjcl.encrypt(skey, smessage, params); var enchex = sjcl.codec.hex.fromBits(sjcl.codec.base64.toBits(JSON.parse(encrypted).ct)); @@ -24,12 +30,22 @@ ECIES.symmetricDecrypt = function(key, encrypted) { var skey = sjcl.codec.hex.toBits(key.toString('hex')); var iv = encrypted.slice(0, 16); var todecrypt = encrypted.slice(16, encrypted.length); - + var siv = sjcl.codec.base64.fromBits(sjcl.codec.hex.toBits(iv.toString('hex'))); var sct = sjcl.codec.base64.fromBits(sjcl.codec.hex.toBits(todecrypt.toString('hex'))); sjcl.beware["CBC mode is dangerous because it doesn't protect message integrity."](); - var obj = {iv: siv, v: 1, iter: 1000, ks: 256, ts: 128, mode: 'cbc', adata: '', cipher: 'aes', ct: sct}; + var obj = { + iv: siv, + v: 1, + iter: 1000, + ks: 256, + ts: 128, + mode: 'cbc', + adata: '', + cipher: 'aes', + ct: sct + }; var str = JSON.stringify(obj); var decrypted = sjcl.decrypt(skey, str); diff --git a/lib/browser/Key.js b/lib/browser/Key.js index 0f3e91e..d008d3c 100644 --- a/lib/browser/Key.js +++ b/lib/browser/Key.js @@ -12,7 +12,7 @@ var bufferToArray = Key.bufferToArray = function(buffer) { var ret = []; var l = buffer.length; - for(var i =0; i, <20-byte-hash>) function EncodedData(data, encoding) { this.data = data; - if(!encoding && (typeof data == 'string')) { + if (!encoding && (typeof data == 'string')) { this.__proto__ = this.encodings['base58']; } else { this.__proto__ = this.encodings[encoding || 'binary']; @@ -18,7 +18,7 @@ function EncodedData(data, encoding) { // get or set the encoding used (transforms data) EncodedData.prototype.encoding = function(encoding) { - if(encoding && (encoding != this._encoding)) { + if (encoding && (encoding != this._encoding)) { this.data = this.as(encoding); this.__proto__ = this.encodings[encoding]; } @@ -32,7 +32,7 @@ EncodedData.prototype.withEncoding = function(encoding) { // answer the data in the given encoding EncodedData.prototype.as = function(encoding) { - if(!encodings[encoding]) throw new Error('invalid encoding'); + if (!encodings[encoding]) throw new Error('invalid encoding'); return this.converters[encoding].call(this); }; @@ -46,7 +46,7 @@ EncodedData.prototype.isValid = function() { try { this.validate(); return true; - } catch(e) { + } catch (e) { return false; } }; @@ -61,7 +61,7 @@ EncodedData.prototype.isValid = function() { try { this.validate(); return true; - } catch(e) { + } catch (e) { return false; } }; @@ -129,10 +129,12 @@ var encodings = { }, }; -var no_conversion = function() {return this.data;}; -for(var k in encodings) { - if(encodings.hasOwnProperty(k)){ - if(!encodings[k].converters[k]) +var no_conversion = function() { + return this.data; +}; +for (var k in encodings) { + if (encodings.hasOwnProperty(k)) { + if (!encodings[k].converters[k]) encodings[k].converters[k] = no_conversion; encodings[k]._encoding = k; } @@ -140,10 +142,10 @@ for(var k in encodings) { EncodedData.applyEncodingsTo = function(aClass) { var tmp = {}; - for(var k in encodings) { + for (var k in encodings) { var enc = encodings[k]; var obj = {}; - for(var j in enc) { + for (var j in enc) { obj[j] = enc[j]; } obj.__proto__ = aClass.prototype; @@ -155,4 +157,3 @@ EncodedData.applyEncodingsTo = function(aClass) { EncodedData.applyEncodingsTo(EncodedData); module.exports = require('soop')(EncodedData); - diff --git a/util/VersionedData.js b/util/VersionedData.js index 3ed357d..dcff86c 100644 --- a/util/VersionedData.js +++ b/util/VersionedData.js @@ -1,10 +1,10 @@ -var imports = require('soop').imports(); -var base58 = imports.base58 || require('../lib/Base58').base58Check; -var parent = imports.parent || require('./EncodedData'); +var imports = require('soop').imports(); +var base58 = imports.base58 || require('../lib/Base58').base58Check; +var parent = imports.parent || require('./EncodedData'); function VersionedData(version, payload) { - if(typeof version != 'number') { + if (typeof version != 'number') { VersionedData.super(this, arguments); return; }; @@ -19,8 +19,10 @@ parent.applyEncodingsTo(VersionedData); // get or set the version data (the first byte of the address) VersionedData.prototype.version = function(num) { - if(num || (num === 0)) { - this.doAsBinary(function() {this.data.writeUInt8(num, 0);}); + if (num || (num === 0)) { + this.doAsBinary(function() { + this.data.writeUInt8(num, 0); + }); return num; } return this.as('binary').readUInt8(0); @@ -28,8 +30,10 @@ VersionedData.prototype.version = function(num) { // get or set the payload data (as a Buffer object) VersionedData.prototype.payload = function(data) { - if(data) { - this.doAsBinary(function() {data.copy(this.data,1);}); + if (data) { + this.doAsBinary(function() { + data.copy(this.data, 1); + }); return data; } return this.as('binary').slice(1); diff --git a/util/error.js b/util/error.js index 4e5097f..6b64997 100644 --- a/util/error.js +++ b/util/error.js @@ -1,4 +1,3 @@ - /** * Used during transcation verification when a source txout is missing. * @@ -9,8 +8,8 @@ function MissingSourceError(msg, missingTxHash) { // TODO: Since this happens in normal operation, perhaps we should // avoid generating a whole stack trace. Error.call(this); -// This is not compatible with firefox. -// Error.captureStackTrace(this, arguments.callee); + // This is not compatible with firefox. + // Error.captureStackTrace(this, arguments.callee); this.message = msg; this.missingTxHash = missingTxHash; this.name = 'MissingSourceError'; @@ -32,8 +31,8 @@ function VerificationError(msg, missingTxHash) { // avoid generating a whole stack trace. Error.call(this); -// This is not compatible with firefox. -// Error.captureStackTrace(this, arguments.callee); + // This is not compatible with firefox. + // Error.captureStackTrace(this, arguments.callee); this.message = msg; this.missingTxHash = missingTxHash; this.name = 'VerificationError'; diff --git a/util/index.js b/util/index.js index 2c8b25e..9476cb2 100644 --- a/util/index.js +++ b/util/index.js @@ -1 +1 @@ -module.exports = require('./util'); \ No newline at end of file +module.exports = require('./util'); diff --git a/util/log.js b/util/log.js index 435007f..b34714e 100644 --- a/util/log.js +++ b/util/log.js @@ -6,13 +6,28 @@ var cl = function() { }; var loggers = { - none: {info: noop, warn: noop, err: noop, debug: noop}, - normal: {info: cl, warn: cl, err: cl, debug: noop}, - debug: {info: cl, warn: cl, err: cl, debug: cl}, + none: { + info: noop, + warn: noop, + err: noop, + debug: noop + }, + normal: { + info: cl, + warn: cl, + err: cl, + debug: noop + }, + debug: { + info: cl, + warn: cl, + err: cl, + debug: cl + }, }; var config = require('../config'); -if(config.log) { +if (config.log) { module.exports = config.log; } else { module.exports = loggers[config.logger || 'normal']; diff --git a/util/time.js b/util/time.js index 1582fca..bfd84f9 100644 --- a/util/time.js +++ b/util/time.js @@ -1,7 +1,4 @@ - // current time, in seconds -exports.curtime = function curtime() -{ +exports.curtime = function curtime() { return Math.round(Date.now() / 1000); } - diff --git a/util/util.js b/util/util.js index e486727..588a813 100644 --- a/util/util.js +++ b/util/util.js @@ -26,7 +26,7 @@ var sha512 = exports.sha512 = function(data) { return new Buffer(crypto.createHash('sha512').update(data).digest('binary'), 'binary'); }; -var sha512hmac = exports.sha512hmac = function (data, key) { +var sha512hmac = exports.sha512hmac = function(data, key) { if (inBrowser) { var skey = sjcl.codec.hex.toBits(key.toString('hex')); var sdata = sjcl.codec.hex.toBits(data.toString('hex')); @@ -41,7 +41,7 @@ var sha512hmac = exports.sha512hmac = function (data, key) { return hash; }; -var ripe160 = exports.ripe160 = function (data) { +var ripe160 = exports.ripe160 = function(data) { if (!Buffer.isBuffer(data)) { throw new Error('arg should be a buffer'); } @@ -360,12 +360,12 @@ var decodeDiffBits = exports.decodeDiffBits = function(diffBits, asBigInt) { var target = bignum(diffBits & 0xffffff); /* - * shiftLeft is not implemented on the bignum browser + * shiftLeft is not implemented on the bignum browser * * target = target.shiftLeft(8*((diffBits >>> 24) - 3)); */ - var mov = 8*((diffBits >>> 24) - 3); + var mov = 8 * ((diffBits >>> 24) - 3); while (mov-- > 0) target = target.mul(2);