|
|
@ -22,8 +22,7 @@ function spec(b) { |
|
|
|
this.disableUnsafeOpcodes = true; |
|
|
|
}; |
|
|
|
|
|
|
|
ScriptInterpreter.prototype.eval = function eval(script, tx, inIndex, hashType, callback) |
|
|
|
{ |
|
|
|
ScriptInterpreter.prototype.eval = function eval(script, tx, inIndex, hashType, callback) { |
|
|
|
if ("function" !== typeof callback) { |
|
|
|
throw new Error("ScriptInterpreter.eval() requires a callback"); |
|
|
|
} |
|
|
@ -123,8 +122,16 @@ function spec(b) { |
|
|
|
break; |
|
|
|
|
|
|
|
case OP_NOP: |
|
|
|
case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5: |
|
|
|
case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: |
|
|
|
case OP_NOP1: |
|
|
|
case OP_NOP2: |
|
|
|
case OP_NOP3: |
|
|
|
case OP_NOP4: |
|
|
|
case OP_NOP5: |
|
|
|
case OP_NOP6: |
|
|
|
case OP_NOP7: |
|
|
|
case OP_NOP8: |
|
|
|
case OP_NOP9: |
|
|
|
case OP_NOP10: |
|
|
|
break; |
|
|
|
|
|
|
|
case OP_IF: |
|
|
@ -417,14 +424,30 @@ function spec(b) { |
|
|
|
// (in -- out)
|
|
|
|
var num = castBigint(this.stackTop()); |
|
|
|
switch (opcode) { |
|
|
|
case OP_1ADD: num = num.add(bignum(1)); break; |
|
|
|
case OP_1SUB: num = num.sub(bignum(1)); break; |
|
|
|
case OP_2MUL: num = num.mul(bignum(2)); break; |
|
|
|
case OP_2DIV: num = num.div(bignum(2)); break; |
|
|
|
case OP_NEGATE: num = num.neg(); break; |
|
|
|
case OP_ABS: num = num.abs(); break; |
|
|
|
case OP_NOT: num = bignum(num.cmp(0) == 0 ? 1 : 0); break; |
|
|
|
case OP_0NOTEQUAL: num = bignum(num.cmp(0) == 0 ? 0 : 1); break; |
|
|
|
case OP_1ADD: |
|
|
|
num = num.add(bignum(1)); |
|
|
|
break; |
|
|
|
case OP_1SUB: |
|
|
|
num = num.sub(bignum(1)); |
|
|
|
break; |
|
|
|
case OP_2MUL: |
|
|
|
num = num.mul(bignum(2)); |
|
|
|
break; |
|
|
|
case OP_2DIV: |
|
|
|
num = num.div(bignum(2)); |
|
|
|
break; |
|
|
|
case OP_NEGATE: |
|
|
|
num = num.neg(); |
|
|
|
break; |
|
|
|
case OP_ABS: |
|
|
|
num = num.abs(); |
|
|
|
break; |
|
|
|
case OP_NOT: |
|
|
|
num = bignum(num.cmp(0) == 0 ? 1 : 0); |
|
|
|
break; |
|
|
|
case OP_0NOTEQUAL: |
|
|
|
num = bignum(num.cmp(0) == 0 ? 0 : 1); |
|
|
|
break; |
|
|
|
} |
|
|
|
this.stack[this.stack.length - 1] = bigintToBuffer(num); |
|
|
|
break; |
|
|
@ -452,11 +475,21 @@ function spec(b) { |
|
|
|
var v2 = castBigint(this.stackTop(1)); |
|
|
|
var num; |
|
|
|
switch (opcode) { |
|
|
|
case OP_ADD: num = v1.add(v2); break; |
|
|
|
case OP_SUB: num = v1.sub(v2); break; |
|
|
|
case OP_MUL: num = v1.mul(v2); break; |
|
|
|
case OP_DIV: num = v1.div(v2); break; |
|
|
|
case OP_MOD: num = v1.mod(v2); break; |
|
|
|
case OP_ADD: |
|
|
|
num = v1.add(v2); |
|
|
|
break; |
|
|
|
case OP_SUB: |
|
|
|
num = v1.sub(v2); |
|
|
|
break; |
|
|
|
case OP_MUL: |
|
|
|
num = v1.mul(v2); |
|
|
|
break; |
|
|
|
case OP_DIV: |
|
|
|
num = v1.div(v2); |
|
|
|
break; |
|
|
|
case OP_MOD: |
|
|
|
num = v1.mod(v2); |
|
|
|
break; |
|
|
|
|
|
|
|
case OP_LSHIFT: |
|
|
|
if (v2.cmp(0) < 0 || v2.cmp(2048) > 0) { |
|
|
@ -485,7 +518,8 @@ function spec(b) { |
|
|
|
num = bignum(v1.cmp(v2) == 0 ? 1 : 0); |
|
|
|
break; |
|
|
|
|
|
|
|
case OP_NUMNOTEQUAL:; |
|
|
|
case OP_NUMNOTEQUAL: |
|
|
|
; |
|
|
|
num = bignum(v1.cmp(v2) != 0 ? 1 : 0); |
|
|
|
break; |
|
|
|
|
|
|
@ -505,8 +539,12 @@ function spec(b) { |
|
|
|
num = bignum(v1.lt(v2) ? 0 : 1); |
|
|
|
break; |
|
|
|
|
|
|
|
case OP_MIN: num = (v1.lt(v2) ? v1 : v2); break; |
|
|
|
case OP_MAX: num = (v1.gt(v2) ? v1 : v2); break; |
|
|
|
case OP_MIN: |
|
|
|
num = (v1.lt(v2) ? v1 : v2); |
|
|
|
break; |
|
|
|
case OP_MAX: |
|
|
|
num = (v1.gt(v2) ? v1 : v2); |
|
|
|
break; |
|
|
|
} |
|
|
|
this.stackPop(); |
|
|
|
this.stackPop(); |
|
|
@ -651,7 +689,9 @@ function spec(b) { |
|
|
|
scriptCode.findAndDelete(sig); |
|
|
|
}); |
|
|
|
|
|
|
|
var success = true, isig = 0, ikey = 0; |
|
|
|
var success = true, |
|
|
|
isig = 0, |
|
|
|
ikey = 0; |
|
|
|
checkMultiSigStep.call(this); |
|
|
|
|
|
|
|
function checkMultiSigStep() { |
|
|
@ -704,6 +744,7 @@ function spec(b) { |
|
|
|
return; |
|
|
|
|
|
|
|
default: |
|
|
|
console.log('opcode '+opcode); |
|
|
|
throw new Error("Unknown opcode encountered"); |
|
|
|
} |
|
|
|
|
|
|
@ -729,8 +770,7 @@ function spec(b) { |
|
|
|
}; |
|
|
|
|
|
|
|
ScriptInterpreter.prototype.evalTwo = |
|
|
|
function evalTwo(scriptSig, scriptPubkey, tx, n, hashType, callback) |
|
|
|
{ |
|
|
|
function evalTwo(scriptSig, scriptPubkey, tx, n, hashType, callback) { |
|
|
|
var self = this; |
|
|
|
|
|
|
|
self.eval(scriptSig, tx, n, hashType, function(e) { |
|
|
@ -760,8 +800,7 @@ function spec(b) { |
|
|
|
return this.stack[this.stack.length - offset]; |
|
|
|
}; |
|
|
|
|
|
|
|
ScriptInterpreter.prototype.stackBack = function stackBack() |
|
|
|
{ |
|
|
|
ScriptInterpreter.prototype.stackBack = function stackBack() { |
|
|
|
return this.stack[-1]; |
|
|
|
}; |
|
|
|
|
|
|
@ -888,8 +927,7 @@ function spec(b) { |
|
|
|
}; |
|
|
|
|
|
|
|
ScriptInterpreter.verify = |
|
|
|
function verify(scriptSig, scriptPubKey, txTo, n, hashType, callback) |
|
|
|
{ |
|
|
|
function verify(scriptSig, scriptPubKey, txTo, n, hashType, callback) { |
|
|
|
if ("function" !== typeof callback) { |
|
|
|
throw new Error("ScriptInterpreter.verify() requires a callback"); |
|
|
|
} |
|
|
@ -919,8 +957,7 @@ function spec(b) { |
|
|
|
}; |
|
|
|
|
|
|
|
function verifyStep4(scriptSig, scriptPubKey, txTo, nIn, |
|
|
|
hashType, opts, callback, si, siCopy) |
|
|
|
{ |
|
|
|
hashType, opts, callback, si, siCopy) { |
|
|
|
if (siCopy.stack.length == 0) { |
|
|
|
callback(null, false); |
|
|
|
return; |
|
|
@ -930,8 +967,7 @@ function spec(b) { |
|
|
|
} |
|
|
|
|
|
|
|
function verifyStep3(scriptSig, scriptPubKey, txTo, nIn, |
|
|
|
hashType, opts, callback, si, siCopy) |
|
|
|
{ |
|
|
|
hashType, opts, callback, si, siCopy) { |
|
|
|
if (si.stack.length == 0) { |
|
|
|
callback(null, false); |
|
|
|
return; |
|
|
@ -967,8 +1003,7 @@ function spec(b) { |
|
|
|
} |
|
|
|
|
|
|
|
function verifyStep2(scriptSig, scriptPubKey, txTo, nIn, |
|
|
|
hashType, opts, callback, si, siCopy) |
|
|
|
{ |
|
|
|
hashType, opts, callback, si, siCopy) { |
|
|
|
if (opts.verifyP2SH) { |
|
|
|
si.stack.forEach(function(item) { |
|
|
|
siCopy.stack.push(item); |
|
|
@ -986,8 +1021,7 @@ function spec(b) { |
|
|
|
|
|
|
|
ScriptInterpreter.verifyFull = |
|
|
|
function verifyFull(scriptSig, scriptPubKey, txTo, nIn, hashType, |
|
|
|
opts, callback) |
|
|
|
{ |
|
|
|
opts, callback) { |
|
|
|
var si = new ScriptInterpreter(); |
|
|
|
var siCopy = new ScriptInterpreter(); |
|
|
|
|
|
|
|