commit
3233882c40
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
|
397
lib/script.js
397
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.fromBuffer = function(buffer) {
|
||||
var script = new Script();
|
||||
script.chunks = [];
|
||||
|
||||
Script.prototype.toJSON = function() {
|
||||
return this.toString();
|
||||
};
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
/**
|
||||
* @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;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.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');
|
||||
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.writeOp = function(str) {
|
||||
if (typeof str === 'number')
|
||||
this.chunks.push(str);
|
||||
else
|
||||
this.chunks.push(Opcode(str).toNumber());
|
||||
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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
--recursive
|
|
@ -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);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
|
208
test/script.js
208
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() {
|
||||
|
||||
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('#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);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#writeBuffer', function() {
|
||||
|
||||
it('should write these push data', function() {
|
||||
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('#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);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
@ -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({
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue