|
@ -1,36 +1,33 @@ |
|
|
require('classtool'); |
|
|
var imports = require('soop').imports(); |
|
|
|
|
|
var config = imports.config || require('./config'); |
|
|
function spec(b) { |
|
|
var log = imports.log || require('./util/log'); |
|
|
var config = b.config || require('./config'); |
|
|
var Opcode = imports.Opcode || require('./Opcode'); |
|
|
var log = b.log || require('./util/log'); |
|
|
var buffertools = imports.buffertools || require('buffertools'); |
|
|
|
|
|
|
|
|
var Opcode = b.Opcode || require('./Opcode').class(); |
|
|
// Make opcodes available as pseudo-constants
|
|
|
var buffertools = b.buffertools || require('buffertools'); |
|
|
for (var i in Opcode.map) { |
|
|
|
|
|
eval(i + ' = ' + Opcode.map[i] + ';'); |
|
|
// Make opcodes available as pseudo-constants
|
|
|
} |
|
|
for (var i in Opcode.map) { |
|
|
|
|
|
eval(i + " = " + Opcode.map[i] + ";"); |
|
|
var util = imports.util || require('./util/util'); |
|
|
} |
|
|
var Parser = imports.Parser || require('./util/BinaryParser'); |
|
|
|
|
|
var Put = imports.Put || require('bufferput'); |
|
|
var util = b.util || require('./util/util'); |
|
|
|
|
|
var Parser = b.Parser || require('./util/BinaryParser').class(); |
|
|
var TX_UNKNOWN = 0; |
|
|
var Put = b.Put || require('bufferput'); |
|
|
var TX_PUBKEY = 1; |
|
|
|
|
|
var TX_PUBKEYHASH = 2; |
|
|
var TX_UNKNOWN = 0; |
|
|
var TX_MULTISIG = 3; |
|
|
var TX_PUBKEY = 1; |
|
|
var TX_SCRIPTHASH = 4; |
|
|
var TX_PUBKEYHASH = 2; |
|
|
|
|
|
var TX_MULTISIG = 3; |
|
|
var TX_TYPES = [ |
|
|
var TX_SCRIPTHASH = 4; |
|
|
|
|
|
|
|
|
|
|
|
var TX_TYPES = [ |
|
|
|
|
|
'unknown', |
|
|
'unknown', |
|
|
'pubkey', |
|
|
'pubkey', |
|
|
'pubkeyhash', |
|
|
'pubkeyhash', |
|
|
'multisig', |
|
|
'multisig', |
|
|
'scripthash' |
|
|
'scripthash' |
|
|
]; |
|
|
]; |
|
|
|
|
|
|
|
|
function Script(buffer) { |
|
|
function Script(buffer) { |
|
|
if(buffer) { |
|
|
if(buffer) { |
|
|
this.buffer = buffer; |
|
|
this.buffer = buffer; |
|
|
} else { |
|
|
} else { |
|
@ -38,16 +35,16 @@ function spec(b) { |
|
|
} |
|
|
} |
|
|
this.chunks = []; |
|
|
this.chunks = []; |
|
|
this.parse(); |
|
|
this.parse(); |
|
|
}; |
|
|
}; |
|
|
this.class = Script; |
|
|
this.class = Script; |
|
|
|
|
|
|
|
|
Script.TX_UNKNOWN=TX_UNKNOWN; |
|
|
Script.TX_UNKNOWN=TX_UNKNOWN; |
|
|
Script.TX_PUBKEY=TX_PUBKEY; |
|
|
Script.TX_PUBKEY=TX_PUBKEY; |
|
|
Script.TX_PUBKEYHASH=TX_PUBKEYHASH; |
|
|
Script.TX_PUBKEYHASH=TX_PUBKEYHASH; |
|
|
Script.TX_MULTISIG=TX_MULTISIG; |
|
|
Script.TX_MULTISIG=TX_MULTISIG; |
|
|
Script.TX_SCRIPTHASH=TX_SCRIPTHASH; |
|
|
Script.TX_SCRIPTHASH=TX_SCRIPTHASH; |
|
|
|
|
|
|
|
|
Script.prototype.parse = function () { |
|
|
Script.prototype.parse = function () { |
|
|
this.chunks = []; |
|
|
this.chunks = []; |
|
|
|
|
|
|
|
|
var parser = new Parser(this.buffer); |
|
|
var parser = new Parser(this.buffer); |
|
@ -71,35 +68,35 @@ function spec(b) { |
|
|
this.chunks.push(opcode); |
|
|
this.chunks.push(opcode); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.isPushOnly = function () |
|
|
Script.prototype.isPushOnly = function () |
|
|
{ |
|
|
{ |
|
|
for (var i = 0; i < this.chunks.length; i++) |
|
|
for (var i = 0; i < this.chunks.length; i++) |
|
|
if (!Buffer.isBuffer(this.chunks[i])) |
|
|
if (!Buffer.isBuffer(this.chunks[i])) |
|
|
return false; |
|
|
return false; |
|
|
|
|
|
|
|
|
return true; |
|
|
return true; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.isP2SH = function () |
|
|
Script.prototype.isP2SH = function () |
|
|
{ |
|
|
{ |
|
|
return (this.chunks.length == 3 && |
|
|
return (this.chunks.length == 3 && |
|
|
this.chunks[0] == OP_HASH160 && |
|
|
this.chunks[0] == OP_HASH160 && |
|
|
Buffer.isBuffer(this.chunks[1]) && |
|
|
Buffer.isBuffer(this.chunks[1]) && |
|
|
this.chunks[1].length == 20 && |
|
|
this.chunks[1].length == 20 && |
|
|
this.chunks[2] == OP_EQUAL); |
|
|
this.chunks[2] == OP_EQUAL); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.isPubkey = function () |
|
|
Script.prototype.isPubkey = function () |
|
|
{ |
|
|
{ |
|
|
return (this.chunks.length == 2 && |
|
|
return (this.chunks.length == 2 && |
|
|
Buffer.isBuffer(this.chunks[0]) && |
|
|
Buffer.isBuffer(this.chunks[0]) && |
|
|
this.chunks[1] == OP_CHECKSIG); |
|
|
this.chunks[1] == OP_CHECKSIG); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.isPubkeyHash = function () |
|
|
Script.prototype.isPubkeyHash = function () |
|
|
{ |
|
|
{ |
|
|
return (this.chunks.length == 5 && |
|
|
return (this.chunks.length == 5 && |
|
|
this.chunks[0] == OP_DUP && |
|
|
this.chunks[0] == OP_DUP && |
|
|
this.chunks[1] == OP_HASH160 && |
|
|
this.chunks[1] == OP_HASH160 && |
|
@ -107,24 +104,24 @@ function spec(b) { |
|
|
this.chunks[2].length == 20 && |
|
|
this.chunks[2].length == 20 && |
|
|
this.chunks[3] == OP_EQUALVERIFY && |
|
|
this.chunks[3] == OP_EQUALVERIFY && |
|
|
this.chunks[4] == OP_CHECKSIG); |
|
|
this.chunks[4] == OP_CHECKSIG); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
function isSmallIntOp(opcode) |
|
|
function isSmallIntOp(opcode) |
|
|
{ |
|
|
{ |
|
|
return ((opcode == OP_0) || |
|
|
return ((opcode == OP_0) || |
|
|
((opcode >= OP_1) && (opcode <= OP_16))); |
|
|
((opcode >= OP_1) && (opcode <= OP_16))); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.isMultiSig = function () |
|
|
Script.prototype.isMultiSig = function () |
|
|
{ |
|
|
{ |
|
|
return (this.chunks.length > 3 && |
|
|
return (this.chunks.length > 3 && |
|
|
isSmallIntOp(this.chunks[0]) && |
|
|
isSmallIntOp(this.chunks[0]) && |
|
|
isSmallIntOp(this.chunks[this.chunks.length-2]) && |
|
|
isSmallIntOp(this.chunks[this.chunks.length-2]) && |
|
|
this.chunks[this.chunks.length-1] == OP_CHECKMULTISIG); |
|
|
this.chunks[this.chunks.length-1] == OP_CHECKMULTISIG); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.finishedMultiSig = function() |
|
|
Script.prototype.finishedMultiSig = function() |
|
|
{ |
|
|
{ |
|
|
var nsigs = 0; |
|
|
var nsigs = 0; |
|
|
for (var i = 0; i < this.chunks.length-1; i++) |
|
|
for (var i = 0; i < this.chunks.length-1; i++) |
|
|
if (this.chunks[i] !== 0) |
|
|
if (this.chunks[i] !== 0) |
|
@ -138,10 +135,10 @@ function spec(b) { |
|
|
return true; |
|
|
return true; |
|
|
else |
|
|
else |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Script.prototype.removePlaceHolders = function() |
|
|
Script.prototype.removePlaceHolders = function() |
|
|
{ |
|
|
{ |
|
|
var chunks = []; |
|
|
var chunks = []; |
|
|
for (var i in this.chunks) |
|
|
for (var i in this.chunks) |
|
|
{ |
|
|
{ |
|
@ -154,10 +151,10 @@ function spec(b) { |
|
|
this.chunks = chunks; |
|
|
this.chunks = chunks; |
|
|
this.updateBuffer(); |
|
|
this.updateBuffer(); |
|
|
return this; |
|
|
return this; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
Script.prototype.prependOp0 = function() |
|
|
Script.prototype.prependOp0 = function() |
|
|
{ |
|
|
{ |
|
|
var chunks = [0]; |
|
|
var chunks = [0]; |
|
|
for (i in this.chunks) { |
|
|
for (i in this.chunks) { |
|
|
if (this.chunks.hasOwnProperty(i)) { |
|
|
if (this.chunks.hasOwnProperty(i)) { |
|
@ -167,74 +164,74 @@ function spec(b) { |
|
|
this.chunks = chunks; |
|
|
this.chunks = chunks; |
|
|
this.updateBuffer(); |
|
|
this.updateBuffer(); |
|
|
return this; |
|
|
return this; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// is this a script form we know?
|
|
|
// is this a script form we know?
|
|
|
Script.prototype.classify = function () |
|
|
Script.prototype.classify = function () |
|
|
{ |
|
|
{ |
|
|
if (this.isPubkeyHash()) |
|
|
if (this.isPubkeyHash()) |
|
|
return TX_PUBKEYHASH; |
|
|
return TX_PUBKEYHASH; |
|
|
if (this.isP2SH()) |
|
|
if (this.isP2SH()) |
|
|
return TX_SCRIPTHASH; |
|
|
return TX_SCRIPTHASH; |
|
|
if (this.isMultiSig()) |
|
|
if (this.isMultiSig()) |
|
|
return TX_MULTISIG; |
|
|
return TX_MULTISIG; |
|
|
if (this.isPubkey()) |
|
|
if (this.isPubkey()) |
|
|
return TX_PUBKEY; |
|
|
return TX_PUBKEY; |
|
|
return TX_UNKNOWN; |
|
|
return TX_UNKNOWN; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
// extract useful data items from known scripts
|
|
|
// extract useful data items from known scripts
|
|
|
Script.prototype.capture = function () |
|
|
Script.prototype.capture = function () |
|
|
{ |
|
|
{ |
|
|
var txType = this.classify(); |
|
|
var txType = this.classify(); |
|
|
var res = []; |
|
|
var res = []; |
|
|
switch (txType) { |
|
|
switch (txType) { |
|
|
case TX_PUBKEY: |
|
|
case TX_PUBKEY: |
|
|
res.push(this.chunks[0]); |
|
|
res.push(this.chunks[0]); |
|
|
break; |
|
|
break; |
|
|
case TX_PUBKEYHASH: |
|
|
case TX_PUBKEYHASH: |
|
|
res.push(this.chunks[2]); |
|
|
res.push(this.chunks[2]); |
|
|
break; |
|
|
break; |
|
|
case TX_MULTISIG: |
|
|
case TX_MULTISIG: |
|
|
for (var i = 1; i < (this.chunks.length - 2); i++) |
|
|
for (var i = 1; i < (this.chunks.length - 2); i++) |
|
|
res.push(this.chunks[i]); |
|
|
res.push(this.chunks[i]); |
|
|
break; |
|
|
break; |
|
|
case TX_SCRIPTHASH: |
|
|
case TX_SCRIPTHASH: |
|
|
res.push(this.chunks[1]); |
|
|
res.push(this.chunks[1]); |
|
|
break; |
|
|
break; |
|
|
|
|
|
|
|
|
case TX_UNKNOWN: |
|
|
case TX_UNKNOWN: |
|
|
default: |
|
|
default: |
|
|
// do nothing
|
|
|
// do nothing
|
|
|
break; |
|
|
break; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return res; |
|
|
return res; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
// return first extracted data item from script
|
|
|
// return first extracted data item from script
|
|
|
Script.prototype.captureOne = function () |
|
|
Script.prototype.captureOne = function () |
|
|
{ |
|
|
{ |
|
|
var arr = this.capture(); |
|
|
var arr = this.capture(); |
|
|
return arr[0]; |
|
|
return arr[0]; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.getOutType = function () |
|
|
Script.prototype.getOutType = function () |
|
|
{ |
|
|
{ |
|
|
var txType = this.classify(); |
|
|
var txType = this.classify(); |
|
|
switch (txType) { |
|
|
switch (txType) { |
|
|
case TX_PUBKEY: return 'Pubkey'; |
|
|
case TX_PUBKEY: return 'Pubkey'; |
|
|
case TX_PUBKEYHASH: return 'Address'; |
|
|
case TX_PUBKEYHASH: return 'Address'; |
|
|
default: return 'Strange'; |
|
|
default: return 'Strange'; |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.getRawOutType = function() { |
|
|
Script.prototype.getRawOutType = function() { |
|
|
return TX_TYPES[this.classify()]; |
|
|
return TX_TYPES[this.classify()]; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.simpleOutHash = function () |
|
|
Script.prototype.simpleOutHash = function () |
|
|
{ |
|
|
{ |
|
|
switch (this.getOutType()) { |
|
|
switch (this.getOutType()) { |
|
|
case 'Address': |
|
|
case 'Address': |
|
|
return this.chunks[2]; |
|
|
return this.chunks[2]; |
|
@ -245,10 +242,10 @@ function spec(b) { |
|
|
log.debug("Strange script was: " + this.toString()); |
|
|
log.debug("Strange script was: " + this.toString()); |
|
|
return null; |
|
|
return null; |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.getInType = function () |
|
|
Script.prototype.getInType = function () |
|
|
{ |
|
|
{ |
|
|
if (this.chunks.length == 1) { |
|
|
if (this.chunks.length == 1) { |
|
|
// Direct IP to IP transactions only have the public key in their scriptSig.
|
|
|
// Direct IP to IP transactions only have the public key in their scriptSig.
|
|
|
return 'Pubkey'; |
|
|
return 'Pubkey'; |
|
@ -259,10 +256,10 @@ function spec(b) { |
|
|
} else { |
|
|
} else { |
|
|
return 'Strange'; |
|
|
return 'Strange'; |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.simpleInPubKey = function () |
|
|
Script.prototype.simpleInPubKey = function () |
|
|
{ |
|
|
{ |
|
|
switch (this.getInType()) { |
|
|
switch (this.getInType()) { |
|
|
case 'Address': |
|
|
case 'Address': |
|
|
return this.chunks[1]; |
|
|
return this.chunks[1]; |
|
@ -273,15 +270,15 @@ function spec(b) { |
|
|
log.debug("Strange script was: " + this.toString()); |
|
|
log.debug("Strange script was: " + this.toString()); |
|
|
return null; |
|
|
return null; |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.getBuffer = function () |
|
|
Script.prototype.getBuffer = function () |
|
|
{ |
|
|
{ |
|
|
return this.buffer; |
|
|
return this.buffer; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.getStringContent = function (truncate, maxEl) |
|
|
Script.prototype.getStringContent = function (truncate, maxEl) |
|
|
{ |
|
|
{ |
|
|
if (truncate === null) { |
|
|
if (truncate === null) { |
|
|
truncate = true; |
|
|
truncate = true; |
|
|
} |
|
|
} |
|
@ -310,19 +307,19 @@ function spec(b) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
return script; |
|
|
return script; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.toString = function (truncate, maxEl) |
|
|
Script.prototype.toString = function (truncate, maxEl) |
|
|
{ |
|
|
{ |
|
|
var script = "<Script "; |
|
|
var script = "<Script "; |
|
|
script += this.getStringContent(truncate, maxEl); |
|
|
script += this.getStringContent(truncate, maxEl); |
|
|
script += ">"; |
|
|
script += ">"; |
|
|
return script; |
|
|
return script; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Script.prototype.writeOp = function (opcode) |
|
|
Script.prototype.writeOp = function (opcode) |
|
|
{ |
|
|
{ |
|
|
var buf = Buffer(this.buffer.length + 1); |
|
|
var buf = Buffer(this.buffer.length + 1); |
|
|
this.buffer.copy(buf); |
|
|
this.buffer.copy(buf); |
|
|
buf.writeUInt8(opcode, this.buffer.length); |
|
|
buf.writeUInt8(opcode, this.buffer.length); |
|
@ -330,10 +327,10 @@ function spec(b) { |
|
|
this.buffer = buf; |
|
|
this.buffer = buf; |
|
|
|
|
|
|
|
|
this.chunks.push(opcode); |
|
|
this.chunks.push(opcode); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.writeN = function (n) |
|
|
Script.prototype.writeN = function (n) |
|
|
{ |
|
|
{ |
|
|
if (n < 0 || n > 16) |
|
|
if (n < 0 || n > 16) |
|
|
throw new Error("writeN: out of range value " + n); |
|
|
throw new Error("writeN: out of range value " + n); |
|
|
|
|
|
|
|
@ -341,10 +338,10 @@ function spec(b) { |
|
|
this.writeOp(OP_0); |
|
|
this.writeOp(OP_0); |
|
|
else |
|
|
else |
|
|
this.writeOp(OP_1 + n - 1); |
|
|
this.writeOp(OP_1 + n - 1); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
function prefixSize(data_length) |
|
|
function prefixSize(data_length) |
|
|
{ |
|
|
{ |
|
|
if (data_length < OP_PUSHDATA1) { |
|
|
if (data_length < OP_PUSHDATA1) { |
|
|
return 1; |
|
|
return 1; |
|
|
} else if (data_length <= 0xff) { |
|
|
} else if (data_length <= 0xff) { |
|
@ -354,9 +351,9 @@ function spec(b) { |
|
|
} else { |
|
|
} else { |
|
|
return 1 + 4; |
|
|
return 1 + 4; |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
function encodeLen(data_length) { |
|
|
function encodeLen(data_length) { |
|
|
var buf = undefined; |
|
|
var buf = undefined; |
|
|
if (data_length < OP_PUSHDATA1) { |
|
|
if (data_length < OP_PUSHDATA1) { |
|
|
buf = new Buffer(1); |
|
|
buf = new Buffer(1); |
|
@ -382,22 +379,22 @@ function spec(b) { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return buf; |
|
|
return buf; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.writeBytes = function (data) |
|
|
Script.prototype.writeBytes = function (data) |
|
|
{ |
|
|
{ |
|
|
var newSize = this.buffer.length + prefixSize(data.length) + data.length; |
|
|
var newSize = this.buffer.length + prefixSize(data.length) + data.length; |
|
|
this.buffer = Buffer.concat([this.buffer, encodeLen(data.length), data]); |
|
|
this.buffer = Buffer.concat([this.buffer, encodeLen(data.length), data]); |
|
|
this.chunks.push(data); |
|
|
this.chunks.push(data); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.updateBuffer = function () |
|
|
Script.prototype.updateBuffer = function () |
|
|
{ |
|
|
{ |
|
|
this.buffer = Script.chunksToBuffer(this.chunks); |
|
|
this.buffer = Script.chunksToBuffer(this.chunks); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.prototype.findAndDelete = function (chunk) |
|
|
Script.prototype.findAndDelete = function (chunk) |
|
|
{ |
|
|
{ |
|
|
var dirty = false; |
|
|
var dirty = false; |
|
|
if (Buffer.isBuffer(chunk)) { |
|
|
if (Buffer.isBuffer(chunk)) { |
|
|
for (var i = 0, l = this.chunks.length; i < l; i++) { |
|
|
for (var i = 0, l = this.chunks.length; i < l; i++) { |
|
@ -420,25 +417,25 @@ function spec(b) { |
|
|
if (dirty) { |
|
|
if (dirty) { |
|
|
this.updateBuffer(); |
|
|
this.updateBuffer(); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Creates a simple OP_CHECKSIG with pubkey output script. |
|
|
* Creates a simple OP_CHECKSIG with pubkey output script. |
|
|
* |
|
|
* |
|
|
* These are used for coinbase transactions and at some point were used for |
|
|
* These are used for coinbase transactions and at some point were used for |
|
|
* IP-based transactions as well. |
|
|
* IP-based transactions as well. |
|
|
*/ |
|
|
*/ |
|
|
Script.createPubKeyOut = function (pubkey) { |
|
|
Script.createPubKeyOut = function (pubkey) { |
|
|
var script = new Script(); |
|
|
var script = new Script(); |
|
|
script.writeBytes(pubkey); |
|
|
script.writeBytes(pubkey); |
|
|
script.writeOp(OP_CHECKSIG); |
|
|
script.writeOp(OP_CHECKSIG); |
|
|
return script; |
|
|
return script; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Creates a standard txout script. |
|
|
* Creates a standard txout script. |
|
|
*/ |
|
|
*/ |
|
|
Script.createPubKeyHashOut = function (pubKeyHash) { |
|
|
Script.createPubKeyHashOut = function (pubKeyHash) { |
|
|
var script = new Script(); |
|
|
var script = new Script(); |
|
|
script.writeOp(OP_DUP); |
|
|
script.writeOp(OP_DUP); |
|
|
script.writeOp(OP_HASH160); |
|
|
script.writeOp(OP_HASH160); |
|
@ -446,9 +443,9 @@ function spec(b) { |
|
|
script.writeOp(OP_EQUALVERIFY); |
|
|
script.writeOp(OP_EQUALVERIFY); |
|
|
script.writeOp(OP_CHECKSIG); |
|
|
script.writeOp(OP_CHECKSIG); |
|
|
return script; |
|
|
return script; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.createMultisig = function(n_required, keys) { |
|
|
Script.createMultisig = function(n_required, keys) { |
|
|
var script = new Script(); |
|
|
var script = new Script(); |
|
|
script.writeN(n_required); |
|
|
script.writeN(n_required); |
|
|
keys.forEach(function(key) { |
|
|
keys.forEach(function(key) { |
|
@ -457,17 +454,17 @@ function spec(b) { |
|
|
script.writeN(keys.length); |
|
|
script.writeN(keys.length); |
|
|
script.writeOp(OP_CHECKMULTISIG); |
|
|
script.writeOp(OP_CHECKMULTISIG); |
|
|
return script; |
|
|
return script; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.createP2SH = function(scriptHash) { |
|
|
Script.createP2SH = function(scriptHash) { |
|
|
var script = new Script(); |
|
|
var script = new Script(); |
|
|
script.writeOp(OP_HASH160); |
|
|
script.writeOp(OP_HASH160); |
|
|
script.writeBytes(scriptHash); |
|
|
script.writeBytes(scriptHash); |
|
|
script.writeOp(OP_EQUAL); |
|
|
script.writeOp(OP_EQUAL); |
|
|
return script; |
|
|
return script; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.fromTestData = function (testData) { |
|
|
Script.fromTestData = function (testData) { |
|
|
testData = testData.map(function (chunk) { |
|
|
testData = testData.map(function (chunk) { |
|
|
if ("string" === typeof chunk) { |
|
|
if ("string" === typeof chunk) { |
|
|
return new Buffer(chunk, 'hex'); |
|
|
return new Buffer(chunk, 'hex'); |
|
@ -480,16 +477,16 @@ function spec(b) { |
|
|
script.chunks = testData; |
|
|
script.chunks = testData; |
|
|
script.updateBuffer(); |
|
|
script.updateBuffer(); |
|
|
return script; |
|
|
return script; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.fromChunks = function (chunks) { |
|
|
Script.fromChunks = function (chunks) { |
|
|
var script = new Script(); |
|
|
var script = new Script(); |
|
|
script.chunks = chunks; |
|
|
script.chunks = chunks; |
|
|
script.updateBuffer(); |
|
|
script.updateBuffer(); |
|
|
return script; |
|
|
return script; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
Script.chunksToBuffer = function (chunks) { |
|
|
Script.chunksToBuffer = function (chunks) { |
|
|
var buf = new Put(); |
|
|
var buf = new Put(); |
|
|
|
|
|
|
|
|
for (var i = 0, l = chunks.length; i < l; i++) { |
|
|
for (var i = 0, l = chunks.length; i < l; i++) { |
|
@ -515,9 +512,6 @@ function spec(b) { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
return buf.buffer(); |
|
|
return buf.buffer(); |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
return Script; |
|
|
|
|
|
}; |
|
|
}; |
|
|
module.defineClass(spec); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
module.exports = require('soop')(Script); |
|
|