From e6af57f4faf0c98ddf37418e49b1caea5d762a96 Mon Sep 17 00:00:00 2001 From: "Ryan X. Charles" Date: Mon, 1 Sep 2014 18:01:17 -0700 Subject: [PATCH] script.toBuffer(); --- README.md | 1 + lib/script.js | 30 ++++++++++++++++---- test/script.js | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5711a72..2e0686e 100644 --- a/README.md +++ b/README.md @@ -46,3 +46,4 @@ Features over bitcore: * Better test coverage * Proper message signing and verification * npm-shrinkwrap.json ensures npm install works as intended +* byte-for-byte reading/writing scripts diff --git a/lib/script.js b/lib/script.js index 81a4cba..4b56b37 100644 --- a/lib/script.js +++ b/lib/script.js @@ -1,4 +1,5 @@ var BufferReader = require('./bufferreader'); +var BufferWriter = require('./bufferwriter'); var Opcode = require('./opcode'); var Script = function Script(buf) { @@ -75,14 +76,33 @@ Script.prototype.fromBuffer = function(buf) { Script.prototype.toBuffer = function() { var bw = new BufferWriter(); - for (var key in this.chunks) { - if (this.chunks.hasOwnProperty(key)) { - var chunk = this.chunks[key]; - if (typeof chunk === 'number') { - + for (var i = 0; i < this.chunks.length; i++) { + var chunk = this.chunks[i]; + if (typeof chunk === 'number') { + var opcodenum = chunk; + bw.writeUInt8(opcodenum); + } else { + var opcodenum = chunk.opcodenum; + bw.writeUInt8(chunk.opcodenum); + if (opcodenum < Opcode.map.OP_PUSHDATA1) { + bw.write(chunk.buf); + } + else if (opcodenum === Opcode.map.OP_PUSHDATA1) { + bw.writeUInt8(chunk.len); + bw.write(chunk.buf); + } + else if (opcodenum === Opcode.map.OP_PUSHDATA2) { + bw.writeUInt16LE(chunk.len); + bw.write(chunk.buf); + } + else if (opcodenum === Opcode.map.OP_PUSHDATA4) { + bw.writeUInt32LE(chunk.len); + bw.write(chunk.buf); } } } + + return bw.concat(); }; module.exports = Script; diff --git a/test/script.js b/test/script.js index a034675..6f19ba7 100644 --- a/test/script.js +++ b/test/script.js @@ -77,4 +77,78 @@ describe('Script', function() { }); + describe('#toBuffer', function() { + + it('should output this buffer containing an OP code', function() { + var buf = new Buffer(1); + buf[0] = Opcode('OP_0').toNumber(); + var script = Script().fromBuffer(buf); + script.chunks.length.should.equal(1); + script.chunks[0].should.equal(buf[0]); + script.toBuffer().toString('hex').should.equal(buf.toString('hex')); + }); + + it('should output this buffer containing another OP code', function() { + var buf = new Buffer(1); + buf[0] = Opcode('OP_CHECKMULTISIG').toNumber(); + var script = Script().fromBuffer(buf); + script.chunks.length.should.equal(1); + script.chunks[0].should.equal(buf[0]); + script.toBuffer().toString('hex').should.equal(buf.toString('hex')); + }); + + it('should output this buffer containing three bytes of data', function() { + var buf = new Buffer([3, 1, 2, 3]); + var script = Script().fromBuffer(buf); + script.chunks.length.should.equal(1); + script.chunks[0].buf.toString('hex').should.equal('010203'); + script.toBuffer().toString('hex').should.equal(buf.toString('hex')); + }); + + it('should output this buffer containing OP_PUSHDATA1 and three bytes of data', function() { + var buf = new Buffer([0, 0, 1, 2, 3]); + buf[0] = Opcode('OP_PUSHDATA1').toNumber(); + buf.writeUInt8(3, 1); + var script = Script().fromBuffer(buf); + script.chunks.length.should.equal(1); + script.chunks[0].buf.toString('hex').should.equal('010203'); + script.toBuffer().toString('hex').should.equal(buf.toString('hex')); + }); + + it('should output this buffer containing OP_PUSHDATA2 and three bytes of data', function() { + var buf = new Buffer([0, 0, 0, 1, 2, 3]); + buf[0] = Opcode('OP_PUSHDATA2').toNumber(); + buf.writeUInt16LE(3, 1); + var script = Script().fromBuffer(buf); + script.chunks.length.should.equal(1); + script.chunks[0].buf.toString('hex').should.equal('010203'); + script.toBuffer().toString('hex').should.equal(buf.toString('hex')); + }); + + it('should output this buffer containing OP_PUSHDATA4 and three bytes of data', function() { + var buf = new Buffer([0, 0, 0, 0, 0, 1, 2, 3]); + buf[0] = Opcode('OP_PUSHDATA4').toNumber(); + buf.writeUInt16LE(3, 1); + var script = Script().fromBuffer(buf); + script.chunks.length.should.equal(1); + script.chunks[0].buf.toString('hex').should.equal('010203'); + script.toBuffer().toString('hex').should.equal(buf.toString('hex')); + }); + + it('should output this buffer an OP code, data, and another OP code', function() { + var buf = new Buffer([0, 0, 0, 0, 0, 0, 1, 2, 3, 0]); + buf[0] = Opcode('OP_0').toNumber(); + buf[1] = Opcode('OP_PUSHDATA4').toNumber(); + buf.writeUInt16LE(3, 2); + buf[buf.length - 1] = Opcode('OP_0').toNumber(); + var script = Script().fromBuffer(buf); + script.chunks.length.should.equal(3); + script.chunks[0].should.equal(buf[0]); + script.chunks[1].buf.toString('hex').should.equal('010203'); + script.chunks[2].should.equal(buf[buf.length - 1]); + script.toBuffer().toString('hex').should.equal(buf.toString('hex')); + }); + + }); + });