diff --git a/lib/script.js b/lib/script.js index 0b19ffc..b8b2ce1 100644 --- a/lib/script.js +++ b/lib/script.js @@ -8,7 +8,11 @@ var Script = function Script(buf) { this.chunks = []; if (Buffer.isBuffer(buf)) { - this.parse(buf); + this.fromBuffer(buf); + } + else if (typeof buf === 'string') { + var str = buf; + this.fromString(str); } else if (typeof buf !== 'undefined') { var obj = buf; @@ -21,4 +25,35 @@ Script.prototype.set = function(obj) { return this; }; +Script.prototype.fromBuffer = function(buf) { + this.chunks = []; + + var br = new BufferReader(buf); + while (!br.eof()) { + var opcode = br.readUInt8(); + + var len, chunk; + if (opcode > 0 && opcode < Opcode.map.OP_PUSHDATA1) { + // Read some bytes of data, opcode value is the length of data + this.chunks.push(br.buffer(opcode)); + } else if (opcode === Opcode.map.OP_PUSHDATA1) { + len = br.readUInt8(); + chunk = br.buffer(len); + this.chunks.push(chunk); + } else if (opcode === Opcode.map.OP_PUSHDATA2) { + len = br.readUInt16LE(); + chunk = br.buffer(len); + this.chunks.push(chunk); + } else if (opcode === Opcode.map.OP_PUSHDATA4) { + len = br.readUInt32LE(); + chunk = br.buffer(len); + this.chunks.push(chunk); + } else { + this.chunks.push(opcode); + } + } + + return this; +}; + module.exports = Script; diff --git a/test/script.js b/test/script.js index 32a0ec9..eef22aa 100644 --- a/test/script.js +++ b/test/script.js @@ -1,6 +1,8 @@ var Script = require('../lib/script'); var should = require('chai').should(); var Opcode = require('../lib/opcode'); +var BufferReader = require('../lib/bufferreader'); +var BufferWriter = require('../lib/bufferwriter'); describe('Script', function() { @@ -8,4 +10,58 @@ describe('Script', function() { var script = new Script(); }); + describe('#fromBuffer', function() { + + it('should parse 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]); + }); + + it('should parse 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]); + }); + + it('should parse 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].toString('hex').should.equal('010203'); + }); + + it('should parse 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].toString('hex').should.equal('010203'); + }); + + it('should parse 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].toString('hex').should.equal('010203'); + }); + + it('should parse 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].toString('hex').should.equal('010203'); + }); + + }); + });