From 10ee5532c36d15ea854a248ad7740474720980ed Mon Sep 17 00:00:00 2001 From: Daniel Cousens Date: Fri, 2 May 2014 06:25:57 +1000 Subject: [PATCH] Serialize now returns a buffer --- src/script.js | 10 ++++++++-- src/transaction.js | 23 +++++++++++++---------- test/transaction.js | 20 ++++++++++++-------- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/src/script.js b/src/script.js index 793f227..4cd70f5 100644 --- a/src/script.js +++ b/src/script.js @@ -13,8 +13,14 @@ function Script(data) { this.parse() } -Script.fromHex = function(data) { - return new Script(convert.hexToBytes(data)) +Script.fromBuffer = function(buffer) { +// assert(Buffer.isBuffer(buffer)) // FIXME: transitionary + + return new Script(Array.prototype.slice.call(buffer)) +} + +Script.fromHex = function(hex) { + return Script.fromBuffer(new Buffer(hex, 'hex')) } Script.fromPubKey = function(str) { diff --git a/src/transaction.js b/src/transaction.js index 11d6880..f3b1351 100644 --- a/src/transaction.js +++ b/src/transaction.js @@ -118,9 +118,8 @@ Transaction.prototype.addOutput = function (address, value, network) { /** * Serialize this transaction. * - * Returns the transaction as a byte array in the standard Bitcoin binary - * format. This method is byte-perfect, i.e. the resulting byte array can - * be hashed to get the transaction's standard Bitcoin hash. + * Returns the transaction as a binary buffer in + * accordance with the Bitcoin protocol. */ Transaction.prototype.serialize = function () { var buffer = [] @@ -152,11 +151,11 @@ Transaction.prototype.serialize = function () { buffer = buffer.concat(convert.numToBytes(parseInt(this.locktime), 4)) - return buffer + return new Buffer(buffer) } Transaction.prototype.serializeHex = function() { - return convert.bytesToHex(this.serialize()) + return this.serialize().toString('hex') } //var OP_CODESEPARATOR = 171 @@ -213,9 +212,10 @@ Transaction.prototype.hashTransactionForSignature = txTmp.ins = [txTmp.ins[inIndex]] } - var buffer = txTmp.serialize() - buffer = buffer.concat(convert.numToBytes(parseInt(hashType), 4)) + var htB = new Buffer(4) + htB.writeUInt32LE(hashType, 0) + var buffer = Buffer.concat([txTmp.serialize(), htB]) return crypto.hash256(buffer) } @@ -283,12 +283,15 @@ Transaction.deserialize = function(buffer) { var i for (i = 0; i < ins; i++) { + var hash = readBytes(32) + Array.prototype.reverse.call(hash) + obj.ins.push({ outpoint: { - hash: convert.bytesToHex(readBytes(32).reverse()), + hash: convert.bytesToHex(hash), index: readAsInt(4) }, - script: new Script(readVarString()), + script: Script.fromBuffer(readVarString()), sequence: readAsInt(4) }) } @@ -297,7 +300,7 @@ Transaction.deserialize = function(buffer) { for (i = 0; i < outs; i++) { obj.outs.push({ value: convert.bytesToNum(readBytes(8)), - script: new Script(readVarString()) + script: Script.fromBuffer(readVarString()) }) } diff --git a/test/transaction.js b/test/transaction.js index 722ff93..59a0523 100644 --- a/test/transaction.js +++ b/test/transaction.js @@ -81,14 +81,18 @@ describe('Transaction', function() { tx.addInput("0cb859105100ebc3344f749c835c7af7d7103ec0d8cbc3d8ccbd5d28c3c36b57", 0) tx.addOutput("15mMHKL96tWAUtqF3tbVf99Z8arcmnJrr3", 100) - // but we're going to replace the tx.ins.length VarInt with a 32-bit equivalent - // however the same resultant number of inputs (1) - var bytes = tx.serialize() - var mutated = bytes.slice(0, 4).concat([254, 1, 0, 0, 0], bytes.slice(5)) - - // the deserialized-serialized transaction should return to its original state (== tx) - var bytes2 = Transaction.deserialize(mutated).serialize() - assert.deepEqual(bytes, bytes2) + var buffer = tx.serialize() + + // we're going to replace the 8bit VarInt for tx.ins.length with a stretched 32bit equivalent + var mutated = Buffer.concat([ + buffer.slice(0, 4), + new Buffer([254, 1, 0, 0, 0]), + buffer.slice(5) + ]) + + // the deserialized-serialized transaction should return to its non-mutated state (== tx) + var buffer2 = Transaction.deserialize(mutated).serialize() + assert.deepEqual(buffer, buffer2) }) })