|
|
@ -73,8 +73,7 @@ function spec(b) { |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.isPushOnly = function () |
|
|
|
{ |
|
|
|
Script.prototype.isPushOnly = function() { |
|
|
|
for (var i = 0; i < this.chunks.length; i++) |
|
|
|
if (!Buffer.isBuffer(this.chunks[i])) |
|
|
|
return false; |
|
|
@ -82,8 +81,7 @@ function spec(b) { |
|
|
|
return true; |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.isP2SH = function () |
|
|
|
{ |
|
|
|
Script.prototype.isP2SH = function() { |
|
|
|
return (this.chunks.length == 3 && |
|
|
|
this.chunks[0] == OP_HASH160 && |
|
|
|
Buffer.isBuffer(this.chunks[1]) && |
|
|
@ -91,15 +89,13 @@ function spec(b) { |
|
|
|
this.chunks[2] == OP_EQUAL); |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.isPubkey = function () |
|
|
|
{ |
|
|
|
Script.prototype.isPubkey = function() { |
|
|
|
return (this.chunks.length == 2 && |
|
|
|
Buffer.isBuffer(this.chunks[0]) && |
|
|
|
this.chunks[1] == OP_CHECKSIG); |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.isPubkeyHash = function () |
|
|
|
{ |
|
|
|
Script.prototype.isPubkeyHash = function() { |
|
|
|
return (this.chunks.length == 5 && |
|
|
|
this.chunks[0] == OP_DUP && |
|
|
|
this.chunks[1] == OP_HASH160 && |
|
|
@ -109,22 +105,19 @@ function spec(b) { |
|
|
|
this.chunks[4] == OP_CHECKSIG); |
|
|
|
}; |
|
|
|
|
|
|
|
function isSmallIntOp(opcode) |
|
|
|
{ |
|
|
|
function isSmallIntOp(opcode) { |
|
|
|
return ((opcode == OP_0) || |
|
|
|
((opcode >= OP_1) && (opcode <= OP_16))); |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.isMultiSig = function () |
|
|
|
{ |
|
|
|
Script.prototype.isMultiSig = function() { |
|
|
|
return (this.chunks.length > 3 && |
|
|
|
isSmallIntOp(this.chunks[0]) && |
|
|
|
isSmallIntOp(this.chunks[this.chunks.length - 2]) && |
|
|
|
this.chunks[this.chunks.length - 1] == OP_CHECKMULTISIG); |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.finishedMultiSig = function() |
|
|
|
{ |
|
|
|
Script.prototype.finishedMultiSig = function() { |
|
|
|
var nsigs = 0; |
|
|
|
for (var i = 0; i < this.chunks.length - 1; i++) |
|
|
|
if (this.chunks[i] !== 0) |
|
|
@ -140,11 +133,9 @@ function spec(b) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
Script.prototype.removePlaceHolders = function() |
|
|
|
{ |
|
|
|
Script.prototype.removePlaceHolders = function() { |
|
|
|
var chunks = []; |
|
|
|
for (var i in this.chunks) |
|
|
|
{ |
|
|
|
for (var i in this.chunks) { |
|
|
|
if (this.chunks.hasOwnProperty(i)) { |
|
|
|
var chunk = this.chunks[i]; |
|
|
|
if (chunk != 0) |
|
|
@ -156,8 +147,7 @@ function spec(b) { |
|
|
|
return this; |
|
|
|
} |
|
|
|
|
|
|
|
Script.prototype.prependOp0 = function() |
|
|
|
{ |
|
|
|
Script.prototype.prependOp0 = function() { |
|
|
|
var chunks = [0]; |
|
|
|
for (i in this.chunks) { |
|
|
|
if (this.chunks.hasOwnProperty(i)) { |
|
|
@ -170,8 +160,7 @@ function spec(b) { |
|
|
|
} |
|
|
|
|
|
|
|
// is this a script form we know?
|
|
|
|
Script.prototype.classify = function () |
|
|
|
{ |
|
|
|
Script.prototype.classify = function() { |
|
|
|
if (this.isPubkeyHash()) |
|
|
|
return TX_PUBKEYHASH; |
|
|
|
if (this.isP2SH()) |
|
|
@ -184,8 +173,7 @@ function spec(b) { |
|
|
|
}; |
|
|
|
|
|
|
|
// extract useful data items from known scripts
|
|
|
|
Script.prototype.capture = function () |
|
|
|
{ |
|
|
|
Script.prototype.capture = function() { |
|
|
|
var txType = this.classify(); |
|
|
|
var res = []; |
|
|
|
switch (txType) { |
|
|
@ -213,19 +201,20 @@ function spec(b) { |
|
|
|
}; |
|
|
|
|
|
|
|
// return first extracted data item from script
|
|
|
|
Script.prototype.captureOne = function () |
|
|
|
{ |
|
|
|
Script.prototype.captureOne = function() { |
|
|
|
var arr = this.capture(); |
|
|
|
return arr[0]; |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.getOutType = function () |
|
|
|
{ |
|
|
|
Script.prototype.getOutType = function() { |
|
|
|
var txType = this.classify(); |
|
|
|
switch (txType) { |
|
|
|
case TX_PUBKEY: return 'Pubkey'; |
|
|
|
case TX_PUBKEYHASH: return 'Address'; |
|
|
|
default: return 'Strange'; |
|
|
|
case TX_PUBKEY: |
|
|
|
return 'Pubkey'; |
|
|
|
case TX_PUBKEYHASH: |
|
|
|
return 'Address'; |
|
|
|
default: |
|
|
|
return 'Strange'; |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
@ -233,8 +222,7 @@ function spec(b) { |
|
|
|
return TX_TYPES[this.classify()]; |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.simpleOutHash = function () |
|
|
|
{ |
|
|
|
Script.prototype.simpleOutHash = function() { |
|
|
|
switch (this.getOutType()) { |
|
|
|
case 'Address': |
|
|
|
return this.chunks[2]; |
|
|
@ -247,8 +235,7 @@ function spec(b) { |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.getInType = function () |
|
|
|
{ |
|
|
|
Script.prototype.getInType = function() { |
|
|
|
if (this.chunks.length == 1) { |
|
|
|
// Direct IP to IP transactions only have the public key in their scriptSig.
|
|
|
|
return 'Pubkey'; |
|
|
@ -261,8 +248,7 @@ function spec(b) { |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.simpleInPubKey = function () |
|
|
|
{ |
|
|
|
Script.prototype.simpleInPubKey = function() { |
|
|
|
switch (this.getInType()) { |
|
|
|
case 'Address': |
|
|
|
return this.chunks[1]; |
|
|
@ -275,42 +261,40 @@ function spec(b) { |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.getBuffer = function () |
|
|
|
{ |
|
|
|
Script.prototype.getBuffer = function() { |
|
|
|
return this.buffer; |
|
|
|
}; |
|
|
|
|
|
|
|
Script.fromStringContent = function(s) { |
|
|
|
var chunks = []; |
|
|
|
var split = s.split(' '); |
|
|
|
console.log(split); |
|
|
|
for (var i = 0; i < split.length; i++) { |
|
|
|
var word = split[i]; |
|
|
|
if (word.length > 2 && word.substring(0, 2) === '0x') { |
|
|
|
chunks.push(new Buffer(word.substring(2, word.length), 'hex')); |
|
|
|
} else { |
|
|
|
var integer = parseInt(word); |
|
|
|
if (isNaN(integer)) { |
|
|
|
chunks.push(Opcode.map['OP_'+word]); |
|
|
|
var opcode = Opcode.map['OP_' + word]; |
|
|
|
if (opcode) { |
|
|
|
chunks.push(opcode); |
|
|
|
} else { |
|
|
|
var hexi = integer.toString(16); |
|
|
|
if (hexi.length %2 === 1) hexi = '0'+hexi; |
|
|
|
console.log(hexi); |
|
|
|
chunks.push(new Buffer(hexi,'hex')); |
|
|
|
var integer = parseInt(word); |
|
|
|
if (!isNaN(integer)) { |
|
|
|
//console.log(integer+' bits=\t'+integer.toString(2).replace('-','').length);
|
|
|
|
var data = util.intToBuffer(integer); |
|
|
|
chunks.push(data); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
return Script.fromChunks(chunks); |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.getStringContent = function (truncate, maxEl) |
|
|
|
{ |
|
|
|
Script.prototype.getStringContent = function(truncate, maxEl) { |
|
|
|
if (truncate === null) { |
|
|
|
truncate = true; |
|
|
|
} |
|
|
|
|
|
|
|
if ("undefined" === typeof maxEl) { |
|
|
|
if ('undefined' === typeof maxEl) { |
|
|
|
maxEl = 15; |
|
|
|
} |
|
|
|
|
|
|
@ -336,8 +320,7 @@ function spec(b) { |
|
|
|
return s; |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.toString = function (truncate, maxEl) |
|
|
|
{ |
|
|
|
Script.prototype.toString = function(truncate, maxEl) { |
|
|
|
var script = "<Script "; |
|
|
|
script += this.getStringContent(truncate, maxEl); |
|
|
|
script += ">"; |
|
|
@ -345,8 +328,7 @@ function spec(b) { |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
Script.prototype.writeOp = function (opcode) |
|
|
|
{ |
|
|
|
Script.prototype.writeOp = function(opcode) { |
|
|
|
var buf = Buffer(this.buffer.length + 1); |
|
|
|
this.buffer.copy(buf); |
|
|
|
buf.writeUInt8(opcode, this.buffer.length); |
|
|
@ -356,8 +338,7 @@ function spec(b) { |
|
|
|
this.chunks.push(opcode); |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.writeN = function (n) |
|
|
|
{ |
|
|
|
Script.prototype.writeN = function(n) { |
|
|
|
if (n < 0 || n > 16) |
|
|
|
throw new Error("writeN: out of range value " + n); |
|
|
|
|
|
|
@ -367,8 +348,7 @@ function spec(b) { |
|
|
|
this.writeOp(OP_1 + n - 1); |
|
|
|
}; |
|
|
|
|
|
|
|
function prefixSize(data_length) |
|
|
|
{ |
|
|
|
function prefixSize(data_length) { |
|
|
|
if (data_length < OP_PUSHDATA1) { |
|
|
|
return 1; |
|
|
|
} else if (data_length <= 0xff) { |
|
|
@ -385,21 +365,15 @@ function spec(b) { |
|
|
|
if (data_length < OP_PUSHDATA1) { |
|
|
|
buf = new Buffer(1); |
|
|
|
buf.writeUInt8(data_length, 0); |
|
|
|
} |
|
|
|
|
|
|
|
else if (data_length <= 0xff) { |
|
|
|
} else if (data_length <= 0xff) { |
|
|
|
buf = new Buffer(1 + 1); |
|
|
|
buf.writeUInt8(OP_PUSHDATA1, 0); |
|
|
|
buf.writeUInt8(data_length, 1); |
|
|
|
} |
|
|
|
|
|
|
|
else if (data_length <= 0xffff) { |
|
|
|
} else if (data_length <= 0xffff) { |
|
|
|
buf = new Buffer(1 + 2); |
|
|
|
buf.writeUInt8(OP_PUSHDATA2, 0); |
|
|
|
buf.writeUInt16LE(data_length, 1); |
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
} else { |
|
|
|
buf = new Buffer(1 + 4); |
|
|
|
buf.writeUInt8(OP_PUSHDATA4, 0); |
|
|
|
buf.writeUInt32LE(data_length, 1); |
|
|
@ -408,20 +382,17 @@ function spec(b) { |
|
|
|
return buf; |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.writeBytes = function (data) |
|
|
|
{ |
|
|
|
Script.prototype.writeBytes = function(data) { |
|
|
|
var newSize = this.buffer.length + prefixSize(data.length) + data.length; |
|
|
|
this.buffer = Buffer.concat([this.buffer, encodeLen(data.length), data]); |
|
|
|
this.chunks.push(data); |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.updateBuffer = function () |
|
|
|
{ |
|
|
|
Script.prototype.updateBuffer = function() { |
|
|
|
this.buffer = Script.chunksToBuffer(this.chunks); |
|
|
|
}; |
|
|
|
|
|
|
|
Script.prototype.findAndDelete = function (chunk) |
|
|
|
{ |
|
|
|
Script.prototype.findAndDelete = function(chunk) { |
|
|
|
var dirty = false; |
|
|
|
if (Buffer.isBuffer(chunk)) { |
|
|
|
for (var i = 0, l = this.chunks.length; i < l; i++) { |
|
|
@ -544,4 +515,3 @@ function spec(b) { |
|
|
|
return Script; |
|
|
|
}; |
|
|
|
module.defineClass(spec); |
|
|
|
|
|
|
|