|
|
@ -32,25 +32,26 @@ var Interpreter = function Interpreter(obj) { |
|
|
|
}; |
|
|
|
|
|
|
|
Interpreter.prototype.verifyWitnessProgram = function(version, program, witness, satoshis, flags) { |
|
|
|
var scriptPubKey = new Script; |
|
|
|
var scriptPubKey = new Script(); |
|
|
|
var stack = []; |
|
|
|
|
|
|
|
if (version == 0) { |
|
|
|
if (version === 0) { |
|
|
|
if (program.length == 32) { |
|
|
|
if (witness.length == 0) { |
|
|
|
this.errstr = 'v0 scripthash program empty'; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
scriptPubKey = witness[witness.length - 1]; |
|
|
|
var hash = Hash.sha256(scriptPubKey); |
|
|
|
if (hash !== program.script) { |
|
|
|
var scriptPubKeyBuffer = witness[witness.length - 1]; |
|
|
|
scriptPubKey = new Script(scriptPubKeyBuffer); |
|
|
|
var hash = Hash.sha256(scriptPubKeyBuffer); |
|
|
|
if (hash.toString('hex') !== program.toString('hex')) { |
|
|
|
this.errstr = 'witness program mismatch'; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
stack = witness.slice(0, -1); |
|
|
|
} else if (program.script.length == 20) { |
|
|
|
} else if (program.length == 20) { |
|
|
|
if (witness.length != 2) { |
|
|
|
this.errstr = 'witness program mismatch'; |
|
|
|
return false; |
|
|
@ -69,6 +70,7 @@ Interpreter.prototype.verifyWitnessProgram = function(version, program, witness, |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
this.initialize(); |
|
|
|
this.set({ |
|
|
|
script: scriptPubKey, |
|
|
|
stack: stack, |
|
|
@ -110,7 +112,7 @@ Interpreter.prototype.verifyWitnessProgram = function(version, program, witness, |
|
|
|
* |
|
|
|
* Translated from bitcoind's VerifyScript |
|
|
|
*/ |
|
|
|
Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, witness, satoshis) { |
|
|
|
Interpreter.prototype.verify = function(scriptSig, scriptPubkey, tx, nin, flags, witness, satoshis) { |
|
|
|
|
|
|
|
var Transaction = require('../transaction'); |
|
|
|
if (_.isUndefined(tx)) { |
|
|
@ -183,15 +185,14 @@ Interpreter.prototype.verifyWitnessProgram = function(version, program, witness, |
|
|
|
var version, program; |
|
|
|
|
|
|
|
if ((flags & Interpreter.SCRIPT_VERIFY_WITNESS)) { |
|
|
|
if (scriptPubkey.isWitnessProgram()) { |
|
|
|
version = scriptPubkey[0]; |
|
|
|
program = s.toProgram(); |
|
|
|
var witnessValues = {}; |
|
|
|
if (scriptPubkey.isWitnessProgram(witnessValues)) { |
|
|
|
hadWitness = true; |
|
|
|
if (scriptSig.toBuffer().length != 0) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
if (!this.verifyWitnessProgram(version, program, witness, satoshis, flags)) { |
|
|
|
if (!this.verifyWitnessProgram(witnessValues.version, witnessValues.program, witness, satoshis, flags)) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
@ -239,17 +240,18 @@ Interpreter.prototype.verifyWitnessProgram = function(version, program, witness, |
|
|
|
this.errstr = 'SCRIPT_ERR_EVAL_FALSE_IN_P2SH_STACK'; |
|
|
|
return false; |
|
|
|
} |
|
|
|
if ((flags & this.SCRIPT_VERIFY_WITNESS)) { |
|
|
|
if (redeemScript.isWitnessOut()) { |
|
|
|
version = redeemScript[0]; |
|
|
|
program = redeemScript.toProgram(); |
|
|
|
if ((flags & Interpreter.SCRIPT_VERIFY_WITNESS)) { |
|
|
|
var witnessValues = {}; |
|
|
|
if (redeemScript.isWitnessProgram(witnessValues)) { |
|
|
|
hadWitness = true; |
|
|
|
if (scriptSig !== redeemScript) { |
|
|
|
var redeemScriptPush = new Script(); |
|
|
|
redeemScriptPush.add(redeemScript.toBuffer()); |
|
|
|
if (scriptSig.toHex() !== redeemScriptPush.toHex()) { |
|
|
|
this.errstr = 'Malleated scriptSig'; |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
if (!this.verifyWitnessProgram(version, program, witness, satoshis, flags)) { |
|
|
|
if (!this.verifyWitnessProgram(witnessValues.version, witnessValues.program, witness, satoshis, flags)) { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
@ -257,7 +259,7 @@ Interpreter.prototype.verifyWitnessProgram = function(version, program, witness, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if ((flags & this.SCRIPT_VERIFY_WITNESS)) { |
|
|
|
if ((flags & Interpreter.SCRIPT_VERIFY_WITNESS)) { |
|
|
|
if (!hadWitness && witness.length > 0) { |
|
|
|
this.errstr = 'Witness unexpected'; |
|
|
|
return false; |
|
|
|