|
|
@ -59,12 +59,11 @@ Block._from = function _from(arg) { |
|
|
|
* @type {BlockHeader} |
|
|
|
*/ |
|
|
|
header: arg.header, |
|
|
|
txsvi: arg.txsvi, |
|
|
|
/** |
|
|
|
* @name Block#txs |
|
|
|
* @name Block#transactions |
|
|
|
* @type {Transaction[]} |
|
|
|
*/ |
|
|
|
txs: arg.txs |
|
|
|
transactions: arg.transactions |
|
|
|
}; |
|
|
|
} else { |
|
|
|
throw new TypeError('Unrecognized argument for Block'); |
|
|
@ -81,16 +80,15 @@ Block._fromJSON = function _fromJSON(data) { |
|
|
|
if (JSUtil.isValidJSON(data)) { |
|
|
|
data = JSON.parse(data); |
|
|
|
} |
|
|
|
var txs = []; |
|
|
|
data.txs.forEach(function(tx) { |
|
|
|
txs.push(Transaction().fromJSON(tx)); |
|
|
|
var transactions = []; |
|
|
|
data.transactions.forEach(function(data) { |
|
|
|
transactions.push(Transaction().fromJSON(data)); |
|
|
|
}); |
|
|
|
var info = { |
|
|
|
magicnum: data.magicnum, |
|
|
|
size: data.size, |
|
|
|
header: BlockHeader.fromJSON(data.header), |
|
|
|
txsvi: Varint().fromString(data.txsvi), |
|
|
|
txs: txs |
|
|
|
transactions: transactions |
|
|
|
}; |
|
|
|
return info; |
|
|
|
}; |
|
|
@ -109,16 +107,22 @@ Block.fromJSON = function fromJSON(json) { |
|
|
|
* @returns {Object} - An object representing the block data |
|
|
|
* @private |
|
|
|
*/ |
|
|
|
Block._fromBufferReader = function _fromBufferReader(br) { |
|
|
|
Block._fromBufferReader = function _fromBufferReader(br, options) { |
|
|
|
options = options || {}; |
|
|
|
var info = {}; |
|
|
|
info.magicnum = br.readUInt32LE(); |
|
|
|
info.size = br.readUInt32LE(); |
|
|
|
if (!options.skipMagic) { |
|
|
|
info.magicnum = br.readUInt32LE(); |
|
|
|
info.size = br.readUInt32LE(); |
|
|
|
} |
|
|
|
info.header = BlockHeader.fromBufferReader(br); |
|
|
|
info.txsvi = Varint(br.readVarintBuf()); |
|
|
|
var txslen = info.txsvi.toNumber(); |
|
|
|
info.txs = []; |
|
|
|
for (var i = 0; i < txslen; i++) { |
|
|
|
info.txs.push(Transaction().fromBufferReader(br)); |
|
|
|
if (options.skipMagic) { |
|
|
|
info.magicnum = 0; |
|
|
|
info.size = info.header.bits; |
|
|
|
} |
|
|
|
var transactions = br.readVarintNum(); |
|
|
|
info.transactions = []; |
|
|
|
for (var i = 0; i < transactions; i++) { |
|
|
|
info.transactions.push(Transaction().fromBufferReader(br)); |
|
|
|
} |
|
|
|
return info; |
|
|
|
}; |
|
|
@ -127,8 +131,8 @@ Block._fromBufferReader = function _fromBufferReader(br) { |
|
|
|
* @param {BufferReader} - A buffer reader of the block |
|
|
|
* @returns {Block} - An instance of block |
|
|
|
*/ |
|
|
|
Block.fromBufferReader = function fromBufferReader(br) { |
|
|
|
var info = Block._fromBufferReader(br); |
|
|
|
Block.fromBufferReader = function fromBufferReader(br, opts) { |
|
|
|
var info = Block._fromBufferReader(br, opts); |
|
|
|
return new Block(info); |
|
|
|
}; |
|
|
|
|
|
|
@ -136,8 +140,8 @@ Block.fromBufferReader = function fromBufferReader(br) { |
|
|
|
* @param {Buffer} - A buffer of the block |
|
|
|
* @returns {Block} - An instance of block |
|
|
|
*/ |
|
|
|
Block.fromBuffer = function fromBuffer(buf) { |
|
|
|
return Block.fromBufferReader(BufferReader(buf)); |
|
|
|
Block.fromBuffer = function fromBuffer(buf, opts) { |
|
|
|
return Block.fromBufferReader(BufferReader(buf), opts); |
|
|
|
}; |
|
|
|
|
|
|
|
/** |
|
|
@ -166,16 +170,15 @@ Block.fromRawBlock = function fromRawBlock(data) { |
|
|
|
* @returns {Object} - A plain object with the block properties |
|
|
|
*/ |
|
|
|
Block.prototype.toObject = function toObject() { |
|
|
|
var txs = []; |
|
|
|
this.txs.forEach(function(tx) { |
|
|
|
txs.push(tx.toObject()); |
|
|
|
var transactions = []; |
|
|
|
this.transactions.forEach(function(tx) { |
|
|
|
transactions.push(tx.toObject()); |
|
|
|
}); |
|
|
|
return { |
|
|
|
magicnum: this.magicnum, |
|
|
|
size: this.size, |
|
|
|
header: this.header.toObject(), |
|
|
|
txsvi: this.txsvi.toString(), |
|
|
|
txs: txs |
|
|
|
transactions: transactions |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
@ -211,10 +214,9 @@ Block.prototype.toBufferWriter = function toBufferWriter(bw) { |
|
|
|
bw.writeUInt32LE(this.magicnum); |
|
|
|
bw.writeUInt32LE(this.size); |
|
|
|
bw.write(this.header.toBuffer()); |
|
|
|
bw.write(this.txsvi.buf); |
|
|
|
var txslen = this.txsvi.toNumber(); |
|
|
|
for (var i = 0; i < txslen; i++) { |
|
|
|
this.txs[i].toBufferWriter(bw); |
|
|
|
bw.writeVarintNum(this.transactions.length); |
|
|
|
for (var i = 0; i < this.transactions.length; i++) { |
|
|
|
this.transactions[i].toBufferWriter(bw); |
|
|
|
} |
|
|
|
return bw; |
|
|
|
}; |
|
|
@ -225,11 +227,11 @@ Block.prototype.toBufferWriter = function toBufferWriter(bw) { |
|
|
|
*/ |
|
|
|
Block.prototype.getTransactionHashes = function getTransactionHashes() { |
|
|
|
var hashes = []; |
|
|
|
if (this.txs.length === 0) { |
|
|
|
if (this.transactions.length === 0) { |
|
|
|
return [Block.Values.NULL_HASH]; |
|
|
|
} |
|
|
|
for (var t = 0; t < this.txs.length; t++) { |
|
|
|
hashes.push(this.txs[t]._getHash()); |
|
|
|
for (var t = 0; t < this.transactions.length; t++) { |
|
|
|
hashes.push(this.transactions[t]._getHash()); |
|
|
|
} |
|
|
|
return hashes; |
|
|
|
}; |
|
|
@ -245,7 +247,7 @@ Block.prototype.getMerkleTree = function getMerkleTree() { |
|
|
|
var tree = this.getTransactionHashes(); |
|
|
|
|
|
|
|
var j = 0; |
|
|
|
for (var size = this.txs.length; size > 1; size = Math.floor((size + 1) / 2)) { |
|
|
|
for (var size = this.transactions.length; size > 1; size = Math.floor((size + 1) / 2)) { |
|
|
|
for (var i = 0; i < size; i += 2) { |
|
|
|
var i2 = Math.min(i + 1, size - 1); |
|
|
|
var buf = Buffer.concat([tree[j + i], tree[j + i2]]); |
|
|
|