diff --git a/lib/script/script.js b/lib/script/script.js index 641a724..ed7428a 100644 --- a/lib/script/script.js +++ b/lib/script/script.js @@ -182,32 +182,40 @@ Script.fromString = function(str) { return script; }; -Script.prototype.toString = function() { +Script.prototype._chunkToString = function(chunk) { + var opcodenum = chunk.opcodenum; var str = ''; - for (var i = 0; i < this.chunks.length; i++) { - var chunk = this.chunks[i]; - var opcodenum = chunk.opcodenum; - if (!chunk.buf) { - if (typeof Opcode.reverseMap[opcodenum] !== 'undefined') { - str = str + ' ' + Opcode(opcodenum).toString(); - } else { - var numstr = opcodenum.toString(16); - if (numstr.length % 2 !== 0) { - numstr = '0' + numstr; - } - str = str + ' ' + '0x' + numstr; - } + if (!chunk.buf) { + // no data chunk + if (typeof Opcode.reverseMap[opcodenum] !== 'undefined') { + str = str + ' ' + Opcode(opcodenum).toString(); } else { - if (opcodenum === Opcode.OP_PUSHDATA1 || - opcodenum === Opcode.OP_PUSHDATA2 || - opcodenum === Opcode.OP_PUSHDATA4) { - str = str + ' ' + Opcode(opcodenum).toString(); - } - str = str + ' ' + chunk.len; - if (chunk.len > 0) { - str = str + ' ' + '0x' + chunk.buf.toString('hex'); + var numstr = opcodenum.toString(16); + if (numstr.length % 2 !== 0) { + numstr = '0' + numstr; } + str = str + ' ' + '0x' + numstr; + } + } else { + // data chunk + if (opcodenum === Opcode.OP_PUSHDATA1 || + opcodenum === Opcode.OP_PUSHDATA2 || + opcodenum === Opcode.OP_PUSHDATA4) { + str = str + ' ' + Opcode(opcodenum).toString(); } + str = str + ' ' + chunk.len; + if (chunk.len > 0) { + str = str + ' ' + '0x' + chunk.buf.toString('hex'); + } + } + return str; +}; + +Script.prototype.toString = function() { + var str = ''; + for (var i = 0; i < this.chunks.length; i++) { + var chunk = this.chunks[i]; + str += this._chunkToString(chunk); } return str.substr(1); @@ -480,10 +488,10 @@ Script.prototype._addByType = function(obj, prepend) { this._addOpcode(obj, prepend); } else if (BufferUtil.isBuffer(obj)) { this._addBuffer(obj, prepend); - } else if (typeof obj === 'object') { - this._insertAtPosition(obj, prepend); } else if (obj instanceof Script) { this.chunks = this.chunks.concat(obj.chunks); + } else if (typeof obj === 'object') { + this._insertAtPosition(obj, prepend); } else { throw new Error('Invalid script chunk'); } @@ -583,7 +591,7 @@ Script.buildMultisigOut = function(publicKeys, threshold, opts) { * * @param {PublicKey[]} pubkeys list of all public keys controlling the output * @param {number} threshold amount of required signatures to spend the output - * @param {Array} signatures signatures to append to the script + * @param {Array} signatures and array of signature buffers to append to the script * @param {Object=} opts * @param {boolean=} opts.noSorting don't sort the given public keys before creating the script (false by default) * @param {Script=} opts.cachedMultisig don't recalculate the redeemScript @@ -598,6 +606,8 @@ Script.buildP2SHMultisigIn = function(pubkeys, threshold, signatures, opts) { var s = new Script(); s.add(Opcode.OP_0); _.each(signatures, function(signature) { + $.checkArgument(BufferUtil.isBuffer(signature), 'Signatures must be an array of Buffers'); + // TODO: allow signatures to be an array of Signature objects s.add(signature); }); s.add((opts.cachedMultisig || Script.buildMultisigOut(pubkeys, threshold, opts)).toBuffer()); diff --git a/test/script/script.js b/test/script/script.js index 71cd7df..54a3d6b 100644 --- a/test/script/script.js +++ b/test/script/script.js @@ -430,6 +430,24 @@ 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'); }); + it('works with objects', function() { + Script().add({ + opcodenum: 106 + }).toString().should.equal('OP_RETURN'); + }); + it('works with another script', function() { + var someScript = Script('OP_2 21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 ' + + '21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 OP_2 OP_CHECKMULTISIG'); + var s = new Script().add(someScript); + s.toString() + .should.equal(someScript.toString()); + }); + it('fails with wrong type', function() { + var fails = function() { + return new Script().add(true); + }; + fails.should.throw('Invalid script chunk'); + }); }); describe('#isStandard', function() {