From b81a64e8cfce06cffc17499f38aaec43a7d73dac Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Mon, 6 Jul 2015 19:50:10 -0400 Subject: [PATCH 1/2] Added script.toASM method --- lib/script/script.js | 26 ++++++++++++++++++++++---- test/script/script.js | 4 ++-- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/lib/script/script.js b/lib/script/script.js index f93ace2..13d69a7 100644 --- a/lib/script/script.js +++ b/lib/script/script.js @@ -182,8 +182,9 @@ Script.fromString = function(str) { return script; }; -Script.prototype._chunkToString = function(chunk) { +Script.prototype._chunkToString = function(chunk, type) { var opcodenum = chunk.opcodenum; + var asm = (type === 'asm'); var str = ''; if (!chunk.buf) { // no data chunk @@ -194,7 +195,11 @@ Script.prototype._chunkToString = function(chunk) { if (numstr.length % 2 !== 0) { numstr = '0' + numstr; } - str = str + ' ' + '0x' + numstr; + if (asm) { + str = str + ' ' + numstr; + } else { + str = str + ' ' + '0x' + numstr; + } } } else { // data chunk @@ -203,14 +208,27 @@ Script.prototype._chunkToString = function(chunk) { opcodenum === Opcode.OP_PUSHDATA4) { str = str + ' ' + Opcode(opcodenum).toString(); } - str = str + ' ' + chunk.len; if (chunk.len > 0) { - str = str + ' ' + '0x' + chunk.buf.toString('hex'); + if (asm) { + str = str + ' ' + chunk.buf.toString('hex'); + } else { + str = str + ' ' + chunk.len + ' ' + '0x' + chunk.buf.toString('hex'); + } } } return str; }; +Script.prototype.toASM = function() { + var str = ''; + for (var i = 0; i < this.chunks.length; i++) { + var chunk = this.chunks[i]; + str += this._chunkToString(chunk, 'asm'); + } + + return str.substr(1); +}; + Script.prototype.toString = function() { var str = ''; for (var i = 0; i < this.chunks.length; i++) { diff --git a/test/script/script.js b/test/script/script.js index dd138a2..7ecfb20 100644 --- a/test/script/script.js +++ b/test/script/script.js @@ -439,7 +439,7 @@ describe('Script', function() { }); it('should work for no data OP_RETURN', function() { - Script().add(Opcode.OP_RETURN).add(new Buffer('')).toString().should.equal('OP_RETURN 0'); + Script().add(Opcode.OP_RETURN).add(new Buffer('')).toString().should.equal('OP_RETURN'); }); it('works with objects', function() { Script().add({ @@ -558,7 +558,7 @@ describe('Script', function() { var data = new Buffer(''); var s = Script.buildDataOut(data); should.exist(s); - s.toString().should.equal('OP_RETURN 0'); + s.toString().should.equal('OP_RETURN'); s.isDataOut().should.equal(true); }); it('should create script from some data', function() { From 55d8c4156a747c5442da56a68ddbd7e4b381256e Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Mon, 6 Jul 2015 20:24:15 -0400 Subject: [PATCH 2/2] Add tests for script.toASM() and new method script.fromASM() --- lib/script/script.js | 42 ++++++++++++++++++++++++++++++++++++++++++ test/script/script.js | 18 ++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/lib/script/script.js b/lib/script/script.js index 13d69a7..6469255 100644 --- a/lib/script/script.js +++ b/lib/script/script.js @@ -134,6 +134,48 @@ Script.prototype.toBuffer = function() { return bw.concat(); }; +Script.fromASM = function(str) { + var script = new Script(); + script.chunks = []; + + var tokens = str.split(' '); + var i = 0; + while (i < tokens.length) { + var token = tokens[i]; + var opcode = Opcode(token); + var opcodenum = opcode.toNumber(); + + if (_.isUndefined(opcodenum)) { + var buf = new Buffer(tokens[i], 'hex'); + script.chunks.push({ + buf: buf, + len: buf.length, + opcodenum: buf.length + }); + i = i + 1; + } else if (opcodenum === Opcode.OP_PUSHDATA1 || + opcodenum === Opcode.OP_PUSHDATA2 || + opcodenum === Opcode.OP_PUSHDATA4) { + script.chunks.push({ + buf: new Buffer(tokens[i + 2], 'hex'), + len: parseInt(tokens[i + 1]), + opcodenum: opcodenum + }); + i = i + 3; + } else { + script.chunks.push({ + opcodenum: opcodenum + }); + i = i + 1; + } + } + return script; +}; + +Script.fromHex = function(str) { + return new Script(new buffer.Buffer(str, 'hex')); +}; + Script.fromString = function(str) { if (JSUtil.isHexa(str) || str.length === 0) { return new Script(new buffer.Buffer(str, 'hex')); diff --git a/test/script/script.js b/test/script/script.js index 7ecfb20..f786016 100644 --- a/test/script/script.js +++ b/test/script/script.js @@ -159,6 +159,19 @@ describe('Script', function() { }); + describe('#fromASM', function() { + it('should parse this known script in ASM', function() { + var asm = 'OP_DUP OP_HASH160 f4c03610e60ad15100929cc23da2f3a799af1725 OP_EQUALVERIFY OP_CHECKSIG'; + var script = Script.fromASM(asm); + script.chunks[0].opcodenum.should.equal(Opcode.OP_DUP); + script.chunks[1].opcodenum.should.equal(Opcode.OP_HASH160); + script.chunks[2].opcodenum.should.equal(20); + script.chunks[2].buf.toString('hex').should.equal('f4c03610e60ad15100929cc23da2f3a799af1725'); + script.chunks[3].opcodenum.should.equal(Opcode.OP_EQUALVERIFY); + script.chunks[4].opcodenum.should.equal(Opcode.OP_CHECKSIG); + }); + }); + describe('#fromString', function() { it('should parse these known scripts', function() { @@ -191,6 +204,11 @@ describe('Script', function() { script.toString().toString('hex').should.equal('OP_0 OP_PUSHDATA4 3 0x010203 OP_0'); }); + it('should output this known script as ASM', function() { + var script = Script.fromHex('76a914f4c03610e60ad15100929cc23da2f3a799af172588ac'); + script.toASM().should.equal('OP_DUP OP_HASH160 f4c03610e60ad15100929cc23da2f3a799af1725 OP_EQUALVERIFY OP_CHECKSIG'); + }); + }); describe('toHex', function() {