diff --git a/lib/address.js b/lib/address.js index 295f277..d3159e2 100644 --- a/lib/address.js +++ b/lib/address.js @@ -227,7 +227,7 @@ Address._transformString = function(data, network, type){ * * Instantiate an address from a PublicKey instance * - * @param {String} data - An instance of PublicKey + * @param {PublicKey} data - An instance of PublicKey * @param {String} network - The network: 'livenet' or 'testnet' * @returns {Address} A new valid and frozen instance of an Address */ diff --git a/lib/opcode.js b/lib/opcode.js index 323c154..ccd6535 100644 --- a/lib/opcode.js +++ b/lib/opcode.js @@ -1,8 +1,9 @@ 'use strict'; function Opcode(num) { - if (!(this instanceof Opcode)) + if (!(this instanceof Opcode)) { return new Opcode(num); + } if (typeof num === 'number') { this.num = num; @@ -39,8 +40,9 @@ Opcode.prototype.fromString = function(str) { Opcode.prototype.toString = function() { var str = Opcode.reverseMap[this.num]; - if (typeof str === 'undefined') + if (typeof str === 'undefined') { throw new Error('Opcode does not have a string representation'); + } return str; }; @@ -191,4 +193,15 @@ for (var k in Opcode.map) { } } +/** + * @returns true if opcode is one of OP_0, OP_1, ..., OP_16 + */ +Opcode.isSmallIntOp = function(opcode) { + if (opcode instanceof Opcode) { + opcode = opcode.toNumber(); + } + return ((opcode === Opcode.map.OP_0) || + ((opcode >= Opcode.map.OP_1) && (opcode <= Opcode.map.OP_16))); +}; + module.exports = Opcode; diff --git a/lib/script.js b/lib/script.js index a33a999..2474a5b 100644 --- a/lib/script.js +++ b/lib/script.js @@ -4,22 +4,19 @@ var BufferReader = require('./encoding/bufferreader'); var BufferWriter = require('./encoding/bufferwriter'); var Opcode = require('./opcode'); -var Script = function Script(buf) { - if (!(this instanceof Script)) - return new Script(buf); - +var Script = function Script(from) { + if (!(this instanceof Script)) { + return new Script(from); + } + this.chunks = []; - if (Buffer.isBuffer(buf)) { - this.fromBuffer(buf); - } - else if (typeof buf === 'string') { - var str = buf; - this.fromString(str); - } - else if (typeof buf !== 'undefined') { - var obj = buf; - this.set(obj); + if (Buffer.isBuffer(from)) { + return Script.fromBuffer(from); + } else if (typeof from === 'string') { + return Script.fromString(from); + } else if (typeof from !== 'undefined') { + this.set(from); } }; @@ -28,33 +25,26 @@ Script.prototype.set = function(obj) { return this; }; -Script.prototype.fromJSON = function(json) { - return this.fromString(json); -}; - -Script.prototype.toJSON = function() { - return this.toString(); -}; +Script.fromBuffer = function(buffer) { + var script = new Script(); + script.chunks = []; -Script.prototype.fromBuffer = function(buf) { - this.chunks = []; - - var br = new BufferReader(buf); + var br = new BufferReader(buffer); while (!br.eof()) { var opcodenum = br.readUInt8(); var len, buf; if (opcodenum > 0 && opcodenum < Opcode.map.OP_PUSHDATA1) { len = opcodenum; - this.chunks.push({ + script.chunks.push({ buf: br.read(len), len: len, opcodenum: opcodenum }); } else if (opcodenum === Opcode.map.OP_PUSHDATA1) { len = br.readUInt8(); - var buf = br.read(len); - this.chunks.push({ + buf = br.read(len); + script.chunks.push({ buf: buf, len: len, opcodenum: opcodenum @@ -62,7 +52,7 @@ Script.prototype.fromBuffer = function(buf) { } else if (opcodenum === Opcode.map.OP_PUSHDATA2) { len = br.readUInt16LE(); buf = br.read(len); - this.chunks.push({ + script.chunks.push({ buf: buf, len: len, opcodenum: opcodenum @@ -70,17 +60,17 @@ Script.prototype.fromBuffer = function(buf) { } else if (opcodenum === Opcode.map.OP_PUSHDATA4) { len = br.readUInt32LE(); buf = br.read(len); - this.chunks.push({ + script.chunks.push({ buf: buf, len: len, opcodenum: opcodenum }); } else { - this.chunks.push(opcodenum); + script.chunks.push(opcodenum); } } - return this; + return script; }; Script.prototype.toBuffer = function() { @@ -88,24 +78,22 @@ Script.prototype.toBuffer = function() { for (var i = 0; i < this.chunks.length; i++) { var chunk = this.chunks[i]; + var opcodenum; if (typeof chunk === 'number') { - var opcodenum = chunk; + opcodenum = chunk; bw.writeUInt8(opcodenum); } else { - var opcodenum = chunk.opcodenum; + opcodenum = chunk.opcodenum; bw.writeUInt8(chunk.opcodenum); if (opcodenum < Opcode.map.OP_PUSHDATA1) { bw.write(chunk.buf); - } - else if (opcodenum === Opcode.map.OP_PUSHDATA1) { + } else if (opcodenum === Opcode.map.OP_PUSHDATA1) { bw.writeUInt8(chunk.len); bw.write(chunk.buf); - } - else if (opcodenum === Opcode.map.OP_PUSHDATA2) { + } else if (opcodenum === Opcode.map.OP_PUSHDATA2) { bw.writeUInt16LE(chunk.len); bw.write(chunk.buf); - } - else if (opcodenum === Opcode.map.OP_PUSHDATA4) { + } else if (opcodenum === Opcode.map.OP_PUSHDATA4) { bw.writeUInt32LE(chunk.len); bw.write(chunk.buf); } @@ -115,8 +103,9 @@ Script.prototype.toBuffer = function() { return bw.concat(); }; -Script.prototype.fromString = function(str) { - this.chunks = []; +Script.fromString = function(str) { + var script = new Script(); + script.chunks = []; var tokens = str.split(' '); var i = 0; @@ -128,137 +117,289 @@ Script.prototype.fromString = function(str) { if (typeof opcodenum === 'undefined') { opcodenum = parseInt(token); if (opcodenum > 0 && opcodenum < Opcode.map.OP_PUSHDATA1) { - this.chunks.push({ + script.chunks.push({ buf: new Buffer(tokens[i + 1].slice(2), 'hex'), len: opcodenum, opcodenum: opcodenum }); i = i + 2; + } else { + throw new Error('Invalid script: ' + JSON.stringify(str)); } - else { - throw new Error('Invalid script'); - } - } else if (opcodenum === Opcode.map.OP_PUSHDATA1 || opcodenum === Opcode.map.OP_PUSHDATA2 || opcodenum === Opcode.map.OP_PUSHDATA4) { - if (tokens[i + 2].slice(0, 2) != '0x') + } else if (opcodenum === Opcode.map.OP_PUSHDATA1 || + opcodenum === Opcode.map.OP_PUSHDATA2 || + opcodenum === Opcode.map.OP_PUSHDATA4) { + if (tokens[i + 2].slice(0, 2) !== '0x') { throw new Error('Pushdata data must start with 0x'); - this.chunks.push({ + } + script.chunks.push({ buf: new Buffer(tokens[i + 2].slice(2), 'hex'), len: parseInt(tokens[i + 1]), opcodenum: opcodenum }); i = i + 3; } else { - this.chunks.push(opcodenum); + script.chunks.push(opcodenum); i = i + 1; } } - return this; + return script; }; Script.prototype.toString = function() { - var str = ""; + var str = ''; for (var i = 0; i < this.chunks.length; i++) { var chunk = this.chunks[i]; + var opcodenum; if (typeof chunk === 'number') { - var opcodenum = chunk; - str = str + Opcode(opcodenum).toString() + " "; + opcodenum = chunk; + str = str + Opcode(opcodenum).toString() + ' '; } else { - var opcodenum = chunk.opcodenum; - if (opcodenum === Opcode.map.OP_PUSHDATA1 || opcodenum === Opcode.map.OP_PUSHDATA2 || opcodenum === Opcode.map.OP_PUSHDATA4) - str = str + Opcode(opcodenum).toString() + " " ; - str = str + chunk.len + " " ; - str = str + "0x" + chunk.buf.toString('hex') + " "; + opcodenum = chunk.opcodenum; + if (opcodenum === Opcode.map.OP_PUSHDATA1 || + opcodenum === Opcode.map.OP_PUSHDATA2 || + opcodenum === Opcode.map.OP_PUSHDATA4) { + str = str + Opcode(opcodenum).toString() + ' '; + } + str = str + chunk.len + ' '; + str = str + '0x' + chunk.buf.toString('hex') + ' '; } } return str.substr(0, str.length - 1); }; -Script.prototype.isOpReturn = function() { - if (this.chunks[0] === Opcode('OP_RETURN').toNumber() - && - (this.chunks.length === 1 - || - (this.chunks.length === 2 - && this.chunks[1].buf - && this.chunks[1].buf.length <= 40 - && this.chunks[1].length === this.chunks.len))) { - return true; - } else { - return false; - } -}; + +// script classification methods + +/** + * @returns true if this is a pay to pubkey hash output script + */ Script.prototype.isPublicKeyHashOut = function() { - if (this.chunks[0] === Opcode('OP_DUP').toNumber() - && this.chunks[1] === Opcode('OP_HASH160').toNumber() - && this.chunks[2].buf - && this.chunks[3] === Opcode('OP_EQUALVERIFY').toNumber() - && this.chunks[4] === Opcode('OP_CHECKSIG').toNumber()) { - return true; - } else { - return false; - } + return this.chunks[0] === Opcode('OP_DUP').toNumber() && + this.chunks[1] === Opcode('OP_HASH160').toNumber() && + this.chunks[2].buf && + this.chunks[3] === Opcode('OP_EQUALVERIFY').toNumber() && + this.chunks[4] === Opcode('OP_CHECKSIG').toNumber(); }; +/** + * @returns true if this is a pay to public key hash input script + */ Script.prototype.isPublicKeyHashIn = function() { - if (this.chunks.length === 2 - && this.chunks[0].buf - && this.chunks[1].buf) { - return true; - } else { - return false; - } + return !!(this.chunks.length === 2 && + this.chunks[0].buf && + this.chunks[0].buf.length >= 0x47 && + this.chunks[0].buf.length <= 0x49 && + this.chunks[1].buf && + ( + // compressed public key + (this.chunks[1].buf[0] === 0x03 && this.chunks[1].buf.length === 0x21) || + // uncompressed public key + (this.chunks[1].buf[0] === 0x04 && this.chunks[1].buf.length === 0x41)) + ); +}; + +/** + * @returns true if this is a public key output script + */ +Script.prototype.isPublicKeyOut = function() { + return this.chunks.length === 2 && + Buffer.isBuffer(this.chunks[0].buf) && + this.chunks[0].buf.length === 0x41 && + this.chunks[1] === Opcode('OP_CHECKSIG').toNumber(); +}; + +/** + * @returns true if this is a pay to public key input script + */ +Script.prototype.isPublicKeyIn = function() { + return this.chunks.length === 1 && + Buffer.isBuffer(this.chunks[0].buf) && + this.chunks[0].buf.length === 0x47; }; + +/** + * @returns true if this is a p2sh output script + */ Script.prototype.isScriptHashOut = function() { - if (this.chunks.length === 3 - && this.chunks[0] === Opcode('OP_HASH160').toNumber() - && this.chunks[1].buf - && this.chunks[1].buf.length === 20 - && this.chunks[2] === Opcode('OP_EQUAL').toNumber()) { - return true; - } else { - return false; - } + return this.chunks.length === 3 && + this.chunks[0] === Opcode('OP_HASH160').toNumber() && + this.chunks[1].buf && + this.chunks[1].buf.length === 20 && + this.chunks[2] === Opcode('OP_EQUAL').toNumber(); }; -//note that these are frequently indistinguishable from pubkeyhashin +/** + * @returns true if this is a p2sh input script + * Note that these are frequently indistinguishable from pubkeyhashin + */ Script.prototype.isScriptHashIn = function() { - var allpush = this.chunks.every(function(chunk) { - return Buffer.isBuffer(chunk.buf); - }); - if (allpush) { - return true; - } else { + if (this.chunks.length === 0) { + return false; + } + var chunk = this.chunks[this.chunks.length - 1]; + if (!chunk) { + return false; + } + var scriptBuf = chunk.buf; + if (!scriptBuf) { return false; } + var redeemScript = new Script(scriptBuf); + var type = redeemScript.classify(); + return type !== Script.types.UNKNOWN; }; -Script.prototype.write = function(obj) { - if (typeof obj === 'string') - this.writeOp(obj); - else if (typeof obj === 'number') - this.writeOp(obj); - else if (Buffer.isBuffer(obj)) - this.writeBuffer(obj); - else if (typeof obj === 'object') - this.chunks.push(obj); - else - throw new Error('Invalid script chunk'); +/** + * @returns true if this is a mutlsig output script + */ +Script.prototype.isMultisigOut = function() { + return (this.chunks.length > 3 && + Opcode.isSmallIntOp(this.chunks[0]) && + this.chunks.slice(1, this.chunks.length - 2).every(function(obj) { + return obj.buf && Buffer.isBuffer(obj.buf); + }) && + Opcode.isSmallIntOp(this.chunks[this.chunks.length - 2]) && + this.chunks[this.chunks.length - 1] === Opcode.map.OP_CHECKMULTISIG); +}; + + +/** + * @returns true if this is a mutlsig input script + */ +Script.prototype.isMultisigIn = function() { + return this.chunks[0] === 0 && + this.chunks.slice(1, this.chunks.length).every(function(obj) { + return obj.buf && + Buffer.isBuffer(obj.buf) && + obj.buf.length === 0x47; + }); +}; + +/** + * @returns true if this is an OP_RETURN data script + */ +Script.prototype.isOpReturn = function() { + return (this.chunks[0] === Opcode('OP_RETURN').toNumber() && + (this.chunks.length === 1 || + (this.chunks.length === 2 && + this.chunks[1].buf && + this.chunks[1].buf.length <= 40 && + this.chunks[1].length === this.chunks.len))); +}; + + +Script.types = {}; +Script.types.UNKNOWN = 'Unknown'; +Script.types.PUBKEY_OUT = 'Pay to public key'; +Script.types.PUBKEY_IN = 'Spend from public key'; +Script.types.PUBKEYHASH_OUT = 'Pay to public key hash'; +Script.types.PUBKEYHASH_IN = 'Spend from public key hash'; +Script.types.SCRIPTHASH_OUT = 'Pay to script hash'; +Script.types.SCRIPTHASH_IN = 'Spend from script hash'; +Script.types.MULTISIG_OUT = 'Pay to multisig'; +Script.types.MULTISIG_IN = 'Spend from multisig'; +Script.types.OP_RETURN = 'Data push'; + +Script.identifiers = {}; +Script.identifiers.PUBKEY_OUT = Script.prototype.isPublicKeyOut; +Script.identifiers.PUBKEY_IN = Script.prototype.isPublicKeyIn; +Script.identifiers.PUBKEYHASH_OUT = Script.prototype.isPublicKeyHashOut; +Script.identifiers.PUBKEYHASH_IN = Script.prototype.isPublicKeyHashIn; +Script.identifiers.MULTISIG_OUT = Script.prototype.isMultisigOut; +Script.identifiers.MULTISIG_IN = Script.prototype.isMultisigIn; +Script.identifiers.OP_RETURN = Script.prototype.isOpReturn; +Script.identifiers.SCRIPTHASH_OUT = Script.prototype.isScriptHashOut; +Script.identifiers.SCRIPTHASH_IN = Script.prototype.isScriptHashIn; + +/** + * @returns {object} The Script type if it is a known form, + * or Script.UNKNOWN if it isn't + */ +Script.prototype.classify = function() { + for (var type in Script.identifiers) { + if (Script.identifiers[type].bind(this)()) { + return Script.types[type]; + } + } + return Script.types.UNKNOWN; +}; + + +/** + * @returns true if script is one of the known types + */ +Script.prototype.isStandard = function() { + return this.classify() !== Script.types.UNKNOWN; +}; + + +// Script construction methods + +/** + * Adds a script element at the start of the script. + * @param {*} obj a string, number, Opcode, Bufer, or object to add + * @returns {Script} this script instance + */ +Script.prototype.prepend = function(obj) { + this._addByType(obj, true); return this; }; -Script.prototype.writeOp = function(str) { - if (typeof str === 'number') - this.chunks.push(str); - else - this.chunks.push(Opcode(str).toNumber()); +/** + * Adds a script element to the end of the script. + * + * @param {*} obj a string, number, Opcode, Bufer, or object to add + * @returns {Script} this script instance + * + */ +Script.prototype.add = function(obj) { + this._addByType(obj, false); + return this; +}; + +Script.prototype._addByType = function(obj, prepend) { + if (typeof obj === 'string') { + this._addOpcode(obj, prepend); + } else if (typeof obj === 'number') { + this._addOpcode(obj, prepend); + } else if (obj.constructor && obj.constructor.name && obj.constructor.name === 'Opcode') { + this._addOpcode(obj, prepend); + } else if (Buffer.isBuffer(obj)) { + this._addBuffer(obj, prepend); + } else if (typeof obj === 'object') { + this._insertAtPosition(obj, prepend); + } else { + throw new Error('Invalid script chunk'); + } +}; + +Script.prototype._insertAtPosition = function(op, prepend) { + if (prepend) { + this.chunks.unshift(op); + } else { + this.chunks.push(op); + } +}; + +Script.prototype._addOpcode = function(opcode, prepend) { + var op; + if (typeof opcode === 'number') { + op = opcode; + } else if (opcode.constructor && opcode.constructor.name && opcode.constructor.name === 'Opcode') { + op = opcode.toNumber(); + } else { + op = Opcode(opcode).toNumber(); + } + this._insertAtPosition(op, prepend); return this; }; -Script.prototype.writeBuffer = function(buf) { +Script.prototype._addBuffer = function(buf, prepend) { var opcodenum; var len = buf.length; if (buf.length > 0 && buf.length < Opcode.map.OP_PUSHDATA1) { @@ -270,13 +411,13 @@ Script.prototype.writeBuffer = function(buf) { } else if (buf.length < Math.pow(2, 32)) { opcodenum = Opcode.map.OP_PUSHDATA4; } else { - throw new Error("You can't push that much data"); + throw new Error('You can\'t push that much data'); } - this.chunks.push({ + this._insertAtPosition({ buf: buf, len: len, opcodenum: opcodenum - }); + }, prepend); return this; }; diff --git a/lib/txin.js b/lib/txin.js index 75d2a05..dbe62e1 100644 --- a/lib/txin.js +++ b/lib/txin.js @@ -36,7 +36,7 @@ Txin.prototype.fromJSON = function(json) { txidbuf: new Buffer(json.txidbuf, 'hex'), txoutnum: json.txoutnum, scriptvi: Varint().fromJSON(json.scriptvi), - script: Script().fromJSON(json.script), + script: Script.fromString(json.script), seqnum: json.seqnum }); return this; @@ -47,7 +47,7 @@ Txin.prototype.toJSON = function() { txidbuf: this.txidbuf.toString('hex'), txoutnum: this.txoutnum, scriptvi: this.scriptvi.toJSON(), - script: this.script.toJSON(), + script: this.script.toString(), seqnum: this.seqnum }; }; @@ -60,7 +60,7 @@ Txin.prototype.fromBufferReader = function(br) { this.txidbuf = br.read(32); this.txoutnum = br.readUInt32LE(); this.scriptvi = Varint(br.readVarintBuf()); - this.script = Script().fromBuffer(br.read(this.scriptvi.toNumber())); + this.script = Script.fromBuffer(br.read(this.scriptvi.toNumber())); this.seqnum = br.readUInt32LE(); return this; }; diff --git a/lib/txout.js b/lib/txout.js index 22a688d..1f40b77 100644 --- a/lib/txout.js +++ b/lib/txout.js @@ -32,7 +32,7 @@ Txout.prototype.fromJSON = function(json) { this.set({ valuebn: BN().fromJSON(json.valuebn), scriptvi: Varint().fromJSON(json.scriptvi), - script: Script().fromJSON(json.script) + script: Script.fromString(json.script) }); return this; }; @@ -41,7 +41,7 @@ Txout.prototype.toJSON = function() { return { valuebn: this.valuebn.toJSON(), scriptvi: this.scriptvi.toJSON(), - script: this.script.toJSON() + script: this.script.toString() }; }; @@ -52,7 +52,7 @@ Txout.prototype.fromBuffer = function(buf) { Txout.prototype.fromBufferReader = function(br) { this.valuebn = br.readUInt64LEBN(); this.scriptvi = Varint(br.readVarintNum()); - this.script = Script().fromBuffer(br.read(this.scriptvi.toNumber())); + this.script = Script.fromBuffer(br.read(this.scriptvi.toNumber())); return this; }; diff --git a/package.json b/package.json index 6567381..5ae6407 100644 --- a/package.json +++ b/package.json @@ -96,8 +96,11 @@ "mocha": "~2.0.1", "run-sequence": "^1.0.2", "karma": "^0.12.28", + "karma-firefox-launcher": "^0.1.3", "karma-mocha": "^0.1.9", - "karma-firefox-launcher": "^0.1.3" + "lodash": "^2.4.1", + "mocha": "~2.0.1", + "run-sequence": "^1.0.2" }, "license": "MIT" } diff --git a/test/address.js b/test/address.js index 3c29c3b..ce798eb 100644 --- a/test/address.js +++ b/test/address.js @@ -294,7 +294,7 @@ describe('Address', function() { }); it('should make this address from a script', function() { - var s = Script().fromString("OP_CHECKMULTISIG"); + var s = Script.fromString("OP_CHECKMULTISIG"); var buf = s.toBuffer(); var a = Address.fromScript(s); a.toString().should.equal('3BYmEwgV2vANrmfRymr1mFnHXgLjD6gAWm'); @@ -305,7 +305,7 @@ describe('Address', function() { }); it('should make this address from other script', function() { - var s = Script().fromString("OP_CHECKSIG OP_HASH160"); + var s = Script.fromString("OP_CHECKSIG OP_HASH160"); var a = Address.fromScript(s); a.toString().should.equal('347iRqVwks5r493N1rsLN4k9J7Ljg488W7'); var b = new Address(s); diff --git a/test/mocha.opts b/test/mocha.opts new file mode 100644 index 0000000..4a52320 --- /dev/null +++ b/test/mocha.opts @@ -0,0 +1 @@ +--recursive diff --git a/test/opcode.js b/test/opcode.js index a01ecfd..c9d8307 100644 --- a/test/opcode.js +++ b/test/opcode.js @@ -11,13 +11,13 @@ describe('Opcode', function() { var opcode = new Opcode(5); should.exist(opcode); }); - + it('should convert to a string with this handy syntax', function() { Opcode(0).toString().should.equal('OP_0'); Opcode(96).toString().should.equal('OP_16'); Opcode(97).toString().should.equal('OP_NOP'); }); - + it('should convert to a number with this handy syntax', function() { Opcode('OP_0').toNumber().should.equal(0); Opcode('OP_16').toNumber().should.equal(96); @@ -25,37 +25,37 @@ describe('Opcode', function() { }); describe('#fromNumber', function() { - + it('should work for 0', function() { Opcode().fromNumber(0).num.should.equal(0); }); }); - + describe('#toNumber', function() { - + it('should work for 0', function() { Opcode().fromNumber(0).toNumber().should.equal(0); }); }); - + describe('#fromString', function() { - + it('should work for OP_0', function() { Opcode().fromString('OP_0').num.should.equal(0); }); }); - + describe('#toString', function() { - + it('should work for OP_0', function() { Opcode().fromString('OP_0').toString().should.equal('OP_0'); }); }); - + describe('@map', function() { it('should have a map containing 116 elements', function() { @@ -65,12 +65,50 @@ describe('Opcode', function() { }); describe('@reverseMap', function() { - + it('should exist and have op 185', function() { should.exist(Opcode.reverseMap); Opcode.reverseMap[185].should.equal('OP_NOP10'); }); }); + var smallints = [ + Opcode('OP_0'), + Opcode('OP_1'), + Opcode('OP_2'), + Opcode('OP_3'), + Opcode('OP_4'), + Opcode('OP_5'), + Opcode('OP_6'), + Opcode('OP_7'), + Opcode('OP_8'), + Opcode('OP_9'), + Opcode('OP_10'), + Opcode('OP_11'), + Opcode('OP_12'), + Opcode('OP_13'), + Opcode('OP_14'), + Opcode('OP_15'), + Opcode('OP_16') + ]; + + describe('@isSmallIntOp', function() { + var testSmallInt = function() { + Opcode.isSmallIntOp(this).should.equal(true); + }; + for (var i = 0; i < smallints.length; i++) { + var op = smallints[i]; + it('should work for small int ' + op, testSmallInt.bind(op)); + } + + it('should work for non-small ints', function() { + Opcode.isSmallIntOp(Opcode('OP_RETURN')).should.equal(false); + Opcode.isSmallIntOp(Opcode('OP_CHECKSIG')).should.equal(false); + Opcode.isSmallIntOp(Opcode('OP_IF')).should.equal(false); + Opcode.isSmallIntOp(Opcode('OP_NOP')).should.equal(false); + }); + + }); + }); diff --git a/test/script.js b/test/script.js index 721586f..ce0d896 100644 --- a/test/script.js +++ b/test/script.js @@ -6,18 +6,18 @@ var Script = bitcore.Script; var Opcode = bitcore.Opcode; describe('Script', function() { - + it('should make a new script', function() { var script = new Script(); should.exist(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); + var script = Script.fromBuffer(buf); script.chunks.length.should.equal(1); script.chunks[0].should.equal(buf[0]); }); @@ -25,14 +25,14 @@ describe('Script', function() { 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); + 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); + var script = Script.fromBuffer(buf); script.chunks.length.should.equal(1); script.chunks[0].buf.toString('hex').should.equal('010203'); }); @@ -41,7 +41,7 @@ describe('Script', 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); + var script = Script.fromBuffer(buf); script.chunks.length.should.equal(1); script.chunks[0].buf.toString('hex').should.equal('010203'); }); @@ -50,7 +50,7 @@ describe('Script', 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); + var script = Script.fromBuffer(buf); script.chunks.length.should.equal(1); script.chunks[0].buf.toString('hex').should.equal('010203'); }); @@ -59,7 +59,7 @@ describe('Script', 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); + var script = Script.fromBuffer(buf); script.chunks.length.should.equal(1); script.chunks[0].buf.toString('hex').should.equal('010203'); }); @@ -70,7 +70,7 @@ describe('Script', function() { buf[1] = Opcode('OP_PUSHDATA4').toNumber(); buf.writeUInt16LE(3, 2); buf[buf.length - 1] = Opcode('OP_0').toNumber(); - var script = Script().fromBuffer(buf); + 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'); @@ -80,11 +80,11 @@ 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); + 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')); @@ -93,7 +93,7 @@ describe('Script', function() { 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); + 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')); @@ -101,7 +101,7 @@ describe('Script', function() { it('should output this buffer containing three bytes of data', function() { var buf = new Buffer([3, 1, 2, 3]); - var script = Script().fromBuffer(buf); + 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')); @@ -111,7 +111,7 @@ describe('Script', 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); + 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')); @@ -121,7 +121,7 @@ describe('Script', 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); + 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')); @@ -131,7 +131,7 @@ describe('Script', 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); + 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')); @@ -143,7 +143,7 @@ describe('Script', function() { buf[1] = Opcode('OP_PUSHDATA4').toNumber(); buf.writeUInt16LE(3, 2); buf[buf.length - 1] = Opcode('OP_0').toNumber(); - var script = Script().fromBuffer(buf); + 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'); @@ -156,23 +156,28 @@ describe('Script', function() { describe('#fromString', function() { it('should parse these known scripts', function() { - Script().fromString('OP_0 OP_PUSHDATA4 3 0x010203 OP_0').toString().should.equal('OP_0 OP_PUSHDATA4 3 0x010203 OP_0'); - Script().fromString('OP_0 OP_PUSHDATA2 3 0x010203 OP_0').toString().should.equal('OP_0 OP_PUSHDATA2 3 0x010203 OP_0'); - Script().fromString('OP_0 OP_PUSHDATA1 3 0x010203 OP_0').toString().should.equal('OP_0 OP_PUSHDATA1 3 0x010203 OP_0'); - Script().fromString('OP_0 3 0x010203 OP_0').toString().should.equal('OP_0 3 0x010203 OP_0'); + Script.fromString('OP_0 OP_PUSHDATA4 3 0x010203 OP_0').toString().should.equal('OP_0 OP_PUSHDATA4 3 0x010203 OP_0'); + Script.fromString('OP_0 OP_PUSHDATA2 3 0x010203 OP_0').toString().should.equal('OP_0 OP_PUSHDATA2 3 0x010203 OP_0'); + Script.fromString('OP_0 OP_PUSHDATA1 3 0x010203 OP_0').toString().should.equal('OP_0 OP_PUSHDATA1 3 0x010203 OP_0'); + Script.fromString('OP_0 3 0x010203 OP_0').toString().should.equal('OP_0 3 0x010203 OP_0'); }); }); describe('#toString', function() { + it('should work with an empty script', function() { + var script = new Script(); + script.toString().should.equal(''); + }); + 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); + 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'); @@ -182,24 +187,8 @@ describe('Script', function() { }); - describe('#fromJSON', function() { - - it('should parse this known script', function() { - Script().fromJSON('OP_0 OP_PUSHDATA4 3 0x010203 OP_0').toString().should.equal('OP_0 OP_PUSHDATA4 3 0x010203 OP_0'); - }); - - }); - - describe('#toJSON', function() { - - it('should output this known script', function() { - Script().fromString('OP_0 OP_PUSHDATA4 3 0x010203 OP_0').toJSON().should.equal('OP_0 OP_PUSHDATA4 3 0x010203 OP_0'); - }); - - }); - describe('#isOpReturn', function() { - + it('should know this is a (blank) OP_RETURN script', function() { Script('OP_RETURN').isOpReturn().should.equal(true); }); @@ -219,12 +208,12 @@ describe('Script', function() { }); describe('#isPublicKeyHashIn', function() { - - it('should classify this known pubkeyhashin', function() { + + it('should identify this known pubkeyhashin', function() { Script('73 0x3046022100bb3c194a30e460d81d34be0a230179c043a656f67e3c5c8bf47eceae7c4042ee0221008bf54ca11b2985285be0fd7a212873d243e6e73f5fad57e8eb14c4f39728b8c601 65 0x04e365859b3c78a8b7c202412b949ebca58e147dba297be29eee53cd3e1d300a6419bc780cc9aec0dc94ed194e91c8f6433f1b781ee00eac0ead2aae1e8e0712c6').isPublicKeyHashIn().should.equal(true); }); - it('should classify this known non-pubkeyhashin', function() { + it('should identify this known non-pubkeyhashin', function() { Script('73 0x3046022100bb3c194a30e460d81d34be0a230179c043a656f67e3c5c8bf47eceae7c4042ee0221008bf54ca11b2985285be0fd7a212873d243e6e73f5fad57e8eb14c4f39728b8c601 65 0x04e365859b3c78a8b7c202412b949ebca58e147dba297be29eee53cd3e1d300a6419bc780cc9aec0dc94ed194e91c8f6433f1b781ee00eac0ead2aae1e8e0712c6 OP_CHECKSIG').isPublicKeyHashIn().should.equal(false); }); @@ -232,23 +221,23 @@ describe('Script', function() { describe('#isPublicKeyHashOut', function() { - it('should classify this known pubkeyhashout as pubkeyhashout', function() { + it('should identify this known pubkeyhashout as pubkeyhashout', function() { Script('OP_DUP OP_HASH160 20 0000000000000000000000000000000000000000 OP_EQUALVERIFY OP_CHECKSIG').isPublicKeyHashOut().should.equal(true); }); - it('should classify this known non-pubkeyhashout as not pubkeyhashout', function() { + it('should identify this known non-pubkeyhashout as not pubkeyhashout', function() { Script('OP_DUP OP_HASH160 20 0000000000000000000000000000000000000000').isPublicKeyHashOut().should.equal(false); }); }); describe('#isScripthashIn', function() { - - it('should classify this known scripthashin', function() { - Script('20 0000000000000000000000000000000000000000').isScriptHashIn().should.equal(true); + + it('should identify this known scripthashin', function() { + Script('OP_0 73 0x30460221008ca148504190c10eea7f5f9c283c719a37be58c3ad617928011a1bb9570901d2022100ced371a23e86af6f55ff4ce705c57d2721a09c4d192ca39d82c4239825f75a9801 72 0x30450220357011fd3b3ad2b8f2f2d01e05dc6108b51d2a245b4ef40c112d6004596f0475022100a8208c93a39e0c366b983f9a80bfaf89237fcd64ca543568badd2d18ee2e1d7501 OP_PUSHDATA1 105 0x5221024c02dff2f0b8263a562a69ec875b2c95ffad860f428acf2f9e8c6492bd067d362103546324a1351a6b601c623b463e33b6103ca444707d5b278ece1692f1aa7724a42103b1ad3b328429450069cc3f9fa80d537ee66ba1120e93f3f185a5bf686fb51e0a53ae').isScriptHashIn().should.equal(true); }); - it('should classify this known non-scripthashin', function() { + it('should identify this known non-scripthashin', function() { Script('20 0000000000000000000000000000000000000000 OP_CHECKSIG').isScriptHashIn().should.equal(false); }); @@ -256,55 +245,134 @@ describe('Script', function() { describe('#isScripthashOut', function() { - it('should classify this known pubkeyhashout as pubkeyhashout', function() { + it('should identify this known pubkeyhashout as pubkeyhashout', function() { Script('OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUAL').isScriptHashOut().should.equal(true); }); - it('should classify these known non-pubkeyhashout as not pubkeyhashout', function() { + it('should identify these known non-pubkeyhashout as not pubkeyhashout', function() { Script('OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUAL OP_EQUAL').isScriptHashOut().should.equal(false); Script('OP_HASH160 21 0x000000000000000000000000000000000000000000 OP_EQUAL').isScriptHashOut().should.equal(false); }); }); - describe('#writeOp', function() { + describe('#isMultisigOut', function() { + it('should identify known multisig out 1', function() { + Script('OP_2 21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 OP_2 OP_CHECKMULTISIG').isMultisigOut().should.equal(true); + }); + it('should identify known multisig out 2', function() { + Script('OP_1 21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 OP_2 OP_CHECKMULTISIG').isMultisigOut().should.equal(true); + }); + it('should identify known multisig out 3', function() { + Script('OP_2 21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 OP_3 OP_CHECKMULTISIG').isMultisigOut().should.equal(true); + }); + + it('should identify non-multisig out 1', function() { + Script('OP_2 21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 OP_2 OP_CHECKMULTISIG OP_EQUAL').isMultisigOut().should.equal(false); + }); + it('should identify non-multisig out 2', function() { + Script('OP_2').isMultisigOut().should.equal(false); + }); + }); - it('should write these ops', function() { - Script().writeOp('OP_CHECKMULTISIG').toString().should.equal('OP_CHECKMULTISIG'); - Script().writeOp(Opcode.map.OP_CHECKMULTISIG).toString().should.equal('OP_CHECKMULTISIG'); + describe('#isMultisigIn', function() { + it('should identify multisig in 1', function() { + Script('OP_0 0x47 0x3044022002a27769ee33db258bdf7a3792e7da4143ec4001b551f73e6a190b8d1bde449d02206742c56ccd94a7a2e16ca52fc1ae4a0aa122b0014a867a80de104f9cb18e472c01').isMultisigIn().should.equal(true); + }); + it('should identify multisig in 2', function() { + Script('OP_0 0x47 0x3044022002a27769ee33db258bdf7a3792e7da4143ec4001b551f73e6a190b8d1bde449d02206742c56ccd94a7a2e16ca52fc1ae4a0aa122b0014a867a80de104f9cb18e472c01 0x47 30450220357011fd3b3ad2b8f2f2d01e05dc6108b51d2a245b4ef40c112d6004596f0475022100a8208c93a39e0c366b983f9a80bfaf89237fcd64ca543568badd2d18ee2e1d7501').isMultisigIn().should.equal(true); }); + it('should identify non-multisig in 1', function() { + Script('0x47 0x3044022002a27769ee33db258bdf7a3792e7da4143ec4001b551f73e6a190b8d1bde449d02206742c56ccd94a7a2e16ca52fc1ae4a0aa122b0014a867a80de104f9cb18e472c01').isMultisigIn().should.equal(false); + }); + it('should identify non-multisig in 2', function() { + Script('OP_0 0x47 0x3044022002a27769ee33db258bdf7a3792e7da4143ec4001b551f73e6a190b8d1bde449d02206742c56ccd94a7a2e16ca52fc1ae4a0aa122b0014a867a80de104f9cb18e472c01 OP_0').isMultisigIn().should.equal(false); + }); + }); + describe('#classify', function() { + it('should classify public key hash out', function() { + Script('OP_DUP OP_HASH160 20 0000000000000000000000000000000000000000 OP_EQUALVERIFY OP_CHECKSIG').classify().should.equal(Script.types.PUBKEYHASH_OUT); + }); + it('should classify public key hash in', function() { + Script('47 0x3044022077a8d81e656c4a1c1721e68ce35fa0b27f13c342998e75854858c12396a15ffa02206378a8c6959283c008c87a14a9c0ada5cf3934ac5ee29f1fef9cac6969783e9801 21 0x03993c230da7dabb956292851ae755f971c50532efc095a16bee07f83ab9d262df').classify().should.equal(Script.types.PUBKEYHASH_IN); + }); + it('should classify script hash out', function() { + Script('OP_HASH160 20 0x0000000000000000000000000000000000000000 OP_EQUAL').classify().should.equal(Script.types.SCRIPTHASH_OUT); + }); + it('should classify script hash in', function() { + Script('OP_0 73 0x30460221008ca148504190c10eea7f5f9c283c719a37be58c3ad617928011a1bb9570901d2022100ced371a23e86af6f55ff4ce705c57d2721a09c4d192ca39d82c4239825f75a9801 72 0x30450220357011fd3b3ad2b8f2f2d01e05dc6108b51d2a245b4ef40c112d6004596f0475022100a8208c93a39e0c366b983f9a80bfaf89237fcd64ca543568badd2d18ee2e1d7501 OP_PUSHDATA1 105 0x5221024c02dff2f0b8263a562a69ec875b2c95ffad860f428acf2f9e8c6492bd067d362103546324a1351a6b601c623b463e33b6103ca444707d5b278ece1692f1aa7724a42103b1ad3b328429450069cc3f9fa80d537ee66ba1120e93f3f185a5bf686fb51e0a53ae').classify().should.equal(Script.types.SCRIPTHASH_IN); + }); + it('should classify MULTISIG out', function() { + Script('OP_2 21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 OP_2 OP_CHECKMULTISIG').classify().should.equal(Script.types.MULTISIG_OUT); + }); + it('should classify MULTISIG in', function() { + Script('OP_0 0x47 0x3044022002a27769ee33db258bdf7a3792e7da4143ec4001b551f73e6a190b8d1bde449d02206742c56ccd94a7a2e16ca52fc1ae4a0aa122b0014a867a80de104f9cb18e472c01').classify().should.equal(Script.types.MULTISIG_IN); + }); + it('should classify OP_RETURN', function() { + Script('OP_RETURN 1 0x01').classify().should.equal(Script.types.OP_RETURN); + }); + it('should classify public key out', function() { + Script('41 0x0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 OP_CHECKSIG').classify().should.equal(Script.types.PUBKEY_OUT); + }); + it('should classify public key in', function() { + Script('47 0x3044022007415aa37ce7eaa6146001ac8bdefca0ddcba0e37c5dc08c4ac99392124ebac802207d382307fd53f65778b07b9c63b6e196edeadf0be719130c5db21ff1e700d67501').classify().should.equal(Script.types.PUBKEY_IN); + }); + it('should classify unknown', function() { + Script('OP_TRUE OP_FALSE').classify().should.equal(Script.types.UNKNOWN); + }); }); - describe('#writeBuffer', function() { - - it('should write these push data', function() { + describe('#add and #prepend', function() { + + it('should add these ops', function() { + Script().add('OP_CHECKMULTISIG').toString().should.equal('OP_CHECKMULTISIG'); + Script().add('OP_1').add('OP_2').toString().should.equal('OP_1 OP_2'); + Script().add(new Opcode('OP_CHECKMULTISIG')).toString().should.equal('OP_CHECKMULTISIG'); + Script().add(Opcode.map.OP_CHECKMULTISIG).toString().should.equal('OP_CHECKMULTISIG'); + }); + + it('should prepend these ops', function() { + Script().prepend('OP_CHECKMULTISIG').toString().should.equal('OP_CHECKMULTISIG'); + Script().prepend('OP_1').prepend('OP_2').toString().should.equal('OP_2 OP_1'); + }); + + it('should add and prepend correctly', function() { + Script().add('OP_1').prepend('OP_2').add('OP_3').prepend('OP_4').toString() + .should.equal('OP_4 OP_2 OP_1 OP_3'); + }); + + it('should add these push data', function() { var buf = new Buffer(1); buf.fill(0); - Script().writeBuffer(buf).toString().should.equal('1 0x00'); + Script().add(buf).toString().should.equal('1 0x00'); buf = new Buffer(255); buf.fill(0); - Script().writeBuffer(buf).toString().should.equal('OP_PUSHDATA1 255 0x' + buf.toString('hex')); + Script().add(buf).toString().should.equal('OP_PUSHDATA1 255 0x' + buf.toString('hex')); buf = new Buffer(256); buf.fill(0); - Script().writeBuffer(buf).toString().should.equal('OP_PUSHDATA2 256 0x' + buf.toString('hex')); + Script().add(buf).toString().should.equal('OP_PUSHDATA2 256 0x' + buf.toString('hex')); buf = new Buffer(Math.pow(2, 16)); buf.fill(0); - Script().writeBuffer(buf).toString().should.equal('OP_PUSHDATA4 ' + Math.pow(2, 16) + ' 0x' + buf.toString('hex')); + Script().add(buf).toString().should.equal('OP_PUSHDATA4 ' + Math.pow(2, 16) + ' 0x' + buf.toString('hex')); }); - }); - - describe('#write', function() { - - it('should write both pushdata and non-pushdata chunks', function() { - Script().write('OP_CHECKMULTISIG').toString().should.equal('OP_CHECKMULTISIG'); - Script().write(Opcode.map.OP_CHECKMULTISIG).toString().should.equal('OP_CHECKMULTISIG'); + it('should add both pushdata and non-pushdata chunks', function() { + Script().add('OP_CHECKMULTISIG').toString().should.equal('OP_CHECKMULTISIG'); + Script().add(Opcode.map.OP_CHECKMULTISIG).toString().should.equal('OP_CHECKMULTISIG'); var buf = new Buffer(1); buf.fill(0); - Script().write(buf).toString().should.equal('1 0x00'); + Script().add(buf).toString().should.equal('1 0x00'); }); + }); + describe('#isStandard', function() { + it('should classify correctly standard script', function() { + Script('OP_RETURN 1 0x00').isStandard().should.equal(true); + }); + it('should classify correctly non standard script', function() { + Script('OP_TRUE OP_FALSE').isStandard().should.equal(false); + }); }); }); diff --git a/test/txin.js b/test/txin.js index 5147df8..88dae01 100644 --- a/test/txin.js +++ b/test/txin.js @@ -12,7 +12,7 @@ describe('Txin', function() { var txidbuf = new Buffer(32); txidbuf.fill(0); var txoutnum = 0; - var script = Script().fromString('OP_CHECKMULTISIG'); + var script = Script.fromString('OP_CHECKMULTISIG'); var scriptvi = Varint(script.toBuffer().length); var seqnum = 0; var txin = Txin().set({ diff --git a/test/txout.js b/test/txout.js index 0d1f13b..8d13cba 100644 --- a/test/txout.js +++ b/test/txout.js @@ -11,7 +11,7 @@ var Script = bitcore.Script; describe('Txout', function() { var valuebn = BN(5); - var script = Script().fromString('OP_CHECKMULTISIG'); + var script = Script.fromString('OP_CHECKMULTISIG'); var scriptvi = Varint(script.toBuffer().length); it('should make a new txout', function() { @@ -43,7 +43,7 @@ describe('Txout', function() { var txout = Txout().fromJSON({ valuebn: valuebn.toJSON(), scriptvi: scriptvi.toJSON(), - script: script.toJSON() + script: script.toString() }); should.exist(txout.valuebn); should.exist(txout.scriptvi); @@ -58,7 +58,7 @@ describe('Txout', function() { var txout = Txout().fromJSON({ valuebn: valuebn.toJSON(), scriptvi: scriptvi.toJSON(), - script: script.toJSON() + script: script.toString() }); var json = txout.toJSON(); should.exist(json.valuebn);