Skip to content
This repository was archived by the owner on Apr 3, 2019. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 98 additions & 19 deletions bitcore-lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,10 +197,14 @@ Address._transformBuffer = function(buffer, network, type) {
throw new TypeError('Address buffers must be exactly 21 bytes.');
}

network = Networks.get(network);
var networkObj = Networks.get(network);
var bufferVersion = Address._classifyFromVersion(buffer);

if (!bufferVersion.network || (network && network !== bufferVersion.network)) {
if (network && !networkObj) {
throw new TypeError('Unknown network');
}

if (!bufferVersion.network || (networkObj && networkObj !== bufferVersion.network)) {
throw new TypeError('Address has mismatched network type.');
}

Expand Down Expand Up @@ -1103,6 +1107,7 @@ var BufferWriter = require('../encoding/bufferwriter');
var Hash = require('../crypto/hash');
var JSUtil = require('../util/js');
var Transaction = require('../transaction');
var errors = require('../errors');
var $ = require('../util/preconditions');

/**
Expand Down Expand Up @@ -1158,6 +1163,7 @@ function MerkleBlock(arg) {
_.extend(this,info);
this._flagBitsUsed = 0;
this._hashesUsed = 0;

return this;
}

Expand Down Expand Up @@ -1244,26 +1250,61 @@ MerkleBlock.prototype.validMerkleTree = function validMerkleTree() {
return BufferUtil.equals(root, this.header.merkleRoot);
};

/**
* Return a list of all the txs hash that match the filter
* @returns {Array} - txs hash that match the filter
*/
MerkleBlock.prototype.filterdTxsHash = function filterdTxsHash() {
$.checkState(_.isArray(this.flags), 'MerkleBlock flags is not an array');
$.checkState(_.isArray(this.hashes), 'MerkleBlock hashes is not an array');

// Can't have more hashes than numTransactions
if(this.hashes.length > this.numTransactions) {
throw new errors.MerkleBlock.InvalidMerkleTree();
}

// Can't have more flag bits than num hashes
if(this.flags.length * 8 < this.hashes.length) {
throw new errors.MerkleBlock.InvalidMerkleTree();
}

// If there is only one hash the filter do not match any txs in the block
if(this.hashes.length === 1) {
return [];
};

var height = this._calcTreeHeight();
var opts = { hashesUsed: 0, flagBitsUsed: 0 };
var txs = this._traverseMerkleTree(height, 0, opts, true);
if(opts.hashesUsed !== this.hashes.length) {
throw new errors.MerkleBlock.InvalidMerkleTree();
}
return txs;
};

/**
* Traverse a the tree in this MerkleBlock, validating it along the way
* Modeled after Bitcoin Core merkleblock.cpp TraverseAndExtract()
* @param {Number} - depth - Current height
* @param {Number} - pos - Current position in the tree
* @param {Object} - opts - Object with values that need to be mutated throughout the traversal
* @param {Boolean} - checkForTxs - if true return opts.txs else return the Merkle Hash
* @param {Number} - opts.flagBitsUsed - Number of flag bits used, should start at 0
* @param {Number} - opts.hashesUsed - Number of hashes used, should start at 0
* @param {Array} - opts.txs - Will finish populated by transactions found during traversal
* @param {Array} - opts.txs - Will finish populated by transactions found during traversal that match the filter
* @returns {Buffer|null} - Buffer containing the Merkle Hash for that height
* @returns {Array} - transactions found during traversal that match the filter
* @private
*/
MerkleBlock.prototype._traverseMerkleTree = function traverseMerkleTree(depth, pos, opts) {
MerkleBlock.prototype._traverseMerkleTree = function traverseMerkleTree(depth, pos, opts, checkForTxs) {
/* jshint maxcomplexity: 12*/
/* jshint maxstatements: 20 */

opts = opts || {};
opts.txs = opts.txs || [];
opts.flagBitsUsed = opts.flagBitsUsed || 0;
opts.hashesUsed = opts.hashesUsed || 0;
var checkForTxs = checkForTxs || false;

if(opts.flagBitsUsed > this.flags.length * 8) {
return null;
Expand All @@ -1284,7 +1325,11 @@ MerkleBlock.prototype._traverseMerkleTree = function traverseMerkleTree(depth, p
if(pos*2+1 < this._calcTreeWidth(depth-1)) {
right = this._traverseMerkleTree(depth-1, pos*2+1, opts);
}
return Hash.sha256sha256(new Buffer.concat([left, right]));
if (checkForTxs){
return opts.txs;
} else {
return Hash.sha256sha256(new Buffer.concat([left, right]));
};
}
};

Expand Down Expand Up @@ -1367,7 +1412,7 @@ MerkleBlock.fromObject = function fromObject(obj) {
module.exports = MerkleBlock;

}).call(this,require("buffer").Buffer)
},{"../crypto/hash":8,"../encoding/bufferreader":14,"../encoding/bufferwriter":15,"../transaction":28,"../util/buffer":42,"../util/js":43,"../util/preconditions":44,"./blockheader":3,"buffer":47,"lodash":319}],6:[function(require,module,exports){
},{"../crypto/hash":8,"../encoding/bufferreader":14,"../encoding/bufferwriter":15,"../errors":17,"../transaction":28,"../util/buffer":42,"../util/js":43,"../util/preconditions":44,"./blockheader":3,"buffer":47,"lodash":319}],6:[function(require,module,exports){
(function (Buffer){
'use strict';

Expand Down Expand Up @@ -3210,6 +3255,13 @@ module.exports = [{
'name': 'InvalidRate',
'message': 'Invalid exchange rate: {0}'
}]
}, {
name: 'MerkleBlock',
message: 'Internal Error on MerkleBlock {0}',
errors: [{
'name': 'InvalidMerkleTree',
'message': 'This MerkleBlock contain an invalid Merkle Tree'
}]
}, {
name: 'Transaction',
message: 'Internal Error on Transaction {0}',
Expand Down Expand Up @@ -7130,15 +7182,17 @@ var Script = function Script(from) {
return Script.fromAddress(from);
} else if (from instanceof Script) {
return Script.fromBuffer(from.toBuffer());
} else if (typeof from === 'string') {
} else if (_.isString(from)) {
return Script.fromString(from);
} else if (typeof from !== 'undefined') {
} else if (_.isObject(from) && _.isArray(from.chunks)) {
this.set(from);
}
};

Script.prototype.set = function(obj) {
this.chunks = obj.chunks || this.chunks;
$.checkArgument(_.isObject(obj));
$.checkArgument(_.isArray(obj.chunks));
this.chunks = obj.chunks;
return this;
};

Expand Down Expand Up @@ -7322,7 +7376,21 @@ Script.prototype._chunkToString = function(chunk, type) {
if (!chunk.buf) {
// no data chunk
if (typeof Opcode.reverseMap[opcodenum] !== 'undefined') {
str = str + ' ' + Opcode(opcodenum).toString();
if (asm) {
// A few cases where the opcode name differs from reverseMap
// aside from 1 to 16 data pushes.
if (opcodenum === 0) {
// OP_0 -> 0
str = str + ' 0';
} else if(opcodenum === 79) {
// OP_1NEGATE -> 1
str = str + ' -1';
} else {
str = str + ' ' + Opcode(opcodenum).toString();
}
} else {
str = str + ' ' + Opcode(opcodenum).toString();
}
} else {
var numstr = opcodenum.toString(16);
if (numstr.length % 2 !== 0) {
Expand All @@ -7336,7 +7404,7 @@ Script.prototype._chunkToString = function(chunk, type) {
}
} else {
// data chunk
if (opcodenum === Opcode.OP_PUSHDATA1 ||
if (!asm && opcodenum === Opcode.OP_PUSHDATA1 ||
opcodenum === Opcode.OP_PUSHDATA2 ||
opcodenum === Opcode.OP_PUSHDATA4) {
str = str + ' ' + Opcode(opcodenum).toString();
Expand Down Expand Up @@ -9762,13 +9830,13 @@ Transaction.prototype.fromObject = function fromObject(arg) {

Transaction.prototype._checkConsistency = function(arg) {
if (!_.isUndefined(this._changeIndex)) {
$.checkState(this._changeScript);
$.checkState(this.outputs[this._changeIndex]);
$.checkState(this._changeScript, 'Change script is expected.');
$.checkState(this.outputs[this._changeIndex], 'Change index points to undefined output.');
$.checkState(this.outputs[this._changeIndex].script.toString() ===
this._changeScript.toString());
this._changeScript.toString(), 'Change output has an unexpected script.');
}
if (arg && arg.hash) {
$.checkState(arg.hash === this.hash, 'Hash in object does not match transaction hash');
$.checkState(arg.hash === this.hash, 'Hash in object does not match transaction hash.');
}
};

Expand Down Expand Up @@ -10419,7 +10487,7 @@ Transaction.prototype.removeInput = function(txId, outputIndex) {
* @return {Transaction} this, for chaining
*/
Transaction.prototype.sign = function(privateKey, sigtype) {
$.checkState(this.hasAllUtxoInfo());
$.checkState(this.hasAllUtxoInfo(), 'Not all utxo information is available to sign the transaction.');
var self = this;
if (_.isArray(privateKey)) {
_.each(privateKey, function(privateKey) {
Expand Down Expand Up @@ -53953,7 +54021,7 @@ arguments[4][262][0].apply(exports,arguments)
},{}],320:[function(require,module,exports){
module.exports={
"name": "bitcore-lib",
"version": "5.0.0-beta.1",
"version": "0.15.0",
"description": "A pure and powerful JavaScript Bitcoin library.",
"author": "BitPay <[email protected]>",
"main": "index.js",
Expand Down Expand Up @@ -53988,6 +54056,7 @@ module.exports={
},
"dependencies": {
"bn.js": "=4.11.8",
"bs58": "=4.0.1",
"buffer-compare": "=1.1.1",
"elliptic": "=6.4.0",
"inherits": "=2.0.1",
Expand All @@ -54004,13 +54073,23 @@ module.exports={
}

},{}],"bitcore-lib":[function(require,module,exports){
(function (Buffer){
(function (global,Buffer){
'use strict';

var bitcore = module.exports;

// module information
bitcore.version = 'v' + require('./package.json').version;
bitcore.versionGuard = function(version) {
if (version !== undefined) {
var message = 'More than one instance of bitcore-lib found. ' +
'Please make sure to require bitcore-lib and check that submodules do' +
' not also include their own bitcore-lib dependency.';
throw new Error(message);
}
};
bitcore.versionGuard(global._bitcore);
global._bitcore = bitcore.version;

// crypto
bitcore.crypto = {};
Expand Down Expand Up @@ -54065,5 +54144,5 @@ bitcore.deps._ = require('lodash');
// Internal usage, exposed for testing/advanced tweaking
bitcore.Transaction.sighash = require('./lib/transaction/sighash');

}).call(this,require("buffer").Buffer)
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer)
},{"./lib/address":1,"./lib/block":4,"./lib/block/blockheader":3,"./lib/block/merkleblock":5,"./lib/crypto/bn":6,"./lib/crypto/ecdsa":7,"./lib/crypto/hash":8,"./lib/crypto/point":9,"./lib/crypto/random":10,"./lib/crypto/signature":11,"./lib/encoding/base58":12,"./lib/encoding/base58check":13,"./lib/encoding/bufferreader":14,"./lib/encoding/bufferwriter":15,"./lib/encoding/varint":16,"./lib/errors":17,"./lib/hdprivatekey.js":19,"./lib/hdpublickey.js":20,"./lib/networks":21,"./lib/opcode":22,"./lib/privatekey":23,"./lib/publickey":24,"./lib/script":25,"./lib/transaction":28,"./lib/transaction/sighash":36,"./lib/unit":40,"./lib/uri":41,"./lib/util/buffer":42,"./lib/util/js":43,"./lib/util/preconditions":44,"./package.json":320,"bn.js":280,"bs58":281,"buffer":47,"elliptic":285,"lodash":319}]},{},[]);
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Bitcore v5.0.0-beta.1
# Bitcore v0.15.0

## Principles

Expand Down
10 changes: 10 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@ var bitcore = module.exports;

// module information
bitcore.version = 'v' + require('./package.json').version;
bitcore.versionGuard = function(version) {
if (version !== undefined) {
var message = 'More than one instance of bitcore-lib found. ' +
'Please make sure to require bitcore-lib and check that submodules do' +
' not also include their own bitcore-lib dependency.';
throw new Error(message);
}
};
bitcore.versionGuard(global._bitcore);
global._bitcore = bitcore.version;

// crypto
bitcore.crypto = {};
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bitcore-lib",
"version": "5.0.0-beta.1",
"version": "0.15.0",
"description": "A pure and powerful JavaScript Bitcoin library.",
"author": "BitPay <[email protected]>",
"main": "index.js",
Expand Down
12 changes: 12 additions & 0 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,15 @@

var should = require("chai").should();
var bitcore = require("../");

describe('#versionGuard', function() {
it('global._bitcore should be defined', function() {
should.equal(global._bitcore, bitcore.version);
});

it('throw an error if version is already defined', function() {
(function() {
bitcore.versionGuard('version');
}).should.throw('More than one instance of bitcore');
});
});