Script, ScriptInterpreter: Verify P2SH scripts and signatures

This commit is contained in:
Jeff Garzik 2013-08-21 08:29:06 -04:00
parent b0fd358d45
commit b6f05a3111
2 changed files with 71 additions and 0 deletions

View File

@ -66,6 +66,15 @@ function spec(b) {
}
};
Script.prototype.isPushOnly = function ()
{
for (var i = 0; i < this.chunks.length; i++)
if (!Buffer.isBuffer(this.chunks[i]))
return false;
return true;
};
Script.prototype.isP2SH = function ()
{
return (this.chunks.length == 3 &&

View File

@ -1,6 +1,7 @@
require('classtool');
function spec(b) {
var assert = require('assert');
var config = b.config || require('./config');
var log = b.log || require('./util/log')(config);
@ -758,6 +759,11 @@ function spec(b) {
return this.stack[this.stack.length-offset];
};
ScriptInterpreter.prototype.stackBack = function stackBack()
{
return this.stack[-1];
};
/**
* Pop the top element off the stack and return it.
*/
@ -911,6 +917,62 @@ function spec(b) {
return si;
};
ScriptInterpreter.verifyFull =
function verifyFull(scriptSig, scriptPubKey, txTo, nIn, hashType, opts)
{
var si = new ScriptInterpreter();
var siCopy = new ScriptInterpreter();
var ok = true;
si.eval(scriptSig, txTo, nIn, hashType, function (err) {
if (err)
ok = false;
});
if (!ok)
return false;
if (opts.verifyP2SH) {
si.stack.forEach(function(item) {
siCopy.stack.push(item);
});
}
ok = true;
si.eval(scriptPubKey, txTo, nIn, hashType, function (err) {
if (err)
ok = false;
});
if (!ok)
return false;
if (si.stack.length == 0)
return false;
if (castBool(si.stackBack()) == false)
return false;
if (opts.verifyP2SH && scriptPubKey.isP2SH()) {
if (!scriptSig.isPushOnly())
return false;
assert.notEqual(siCopy.length, 0);
var subscript = new Script(siCopy.stackPop());
ok = true;
siCopy.eval(subscript, txTo, nIn, hashType, function (err) {
if (err)
ok = false;
});
if (!ok)
return false;
if (siCopy.stack.length == 0)
return false;
return castBool(siCopy.stackBack());
}
return true;
};
var checkSig = ScriptInterpreter.checkSig =
function (sig, pubkey, scriptCode, tx, n, hashType, callback) {
if (!sig.length) {