bip114: mast.

This commit is contained in:
Christopher Jeffrey 2016-06-24 10:15:34 -07:00
parent a70482c0c5
commit 5cce4539d1
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
2 changed files with 54 additions and 0 deletions

View File

@ -662,6 +662,7 @@ exports.flags = {
VERIFY_CHECKSEQUENCEVERIFY: (1 << 10),
VERIFY_WITNESS: (1 << 11),
VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM: (1 << 12),
VERIFY_MAST: (1 << 13),
VERIFY_SEQUENCE: (1 << 0),
MEDIAN_TIME_PAST: (1 << 1)
};

View File

@ -4077,6 +4077,7 @@ Script.verifyProgram = function verifyProgram(witness, output, flags, tx, i) {
var program = output.toProgram();
var stack = witness.toStack();
var witnessScript, redeem, j;
var hash, pathdata, depth, path, posdata, pos, depth, root;
assert(program, 'verifyProgram called on non-witness-program.');
assert((flags & constants.flags.VERIFY_WITNESS) !== 0);
@ -4101,6 +4102,58 @@ Script.verifyProgram = function verifyProgram(witness, output, flags, tx, i) {
// Failure on version=0 (bad program data length)
throw new ScriptError('WITNESS_PROGRAM_WRONG_LENGTH');
}
} else if ((flags & constants.flags.VERIFY_MAST) && program.version === 1) {
if (program.data.length !== 32)
throw new ScriptError('WITNESS_PROGRAM_WRONG_LENGTH');
if (stack.length < 3)
throw new ScriptError('WITNESS_PROGRAM_MISMATCH');
witnessScript = stack.pop();
redeem = new Script(witnessScript);
hash = utils.hash256(witnessScript);
pathdata = stack.pop();
if (pathdata.length & 0x1f)
throw new ScriptError('WITNESS_PROGRAM_MISMATCH');
depth = pathdata.length >>> 5;
if (depth > 32)
throw new ScriptError('WITNESS_PROGRAM_MISMATCH');
path = [];
for (j = 0; j < depth; j++)
path.push(pathdata.slice(j * 32, j * 32 + 32));
posdata = stack.pop();
if (posdata.length > 4)
throw new ScriptError('WITNESS_PROGRAM_MISMATCH');
pos = 0;
if (posdata.length > 0) {
if (posdata[posdata.length - 1] === 0x00)
throw new ScriptError('WITNESS_PROGRAM_MISMATCH');
for (j = 0; j < posdata.length; j++)
pos |= posdata[i] << 8 * j;
if (pos < 0)
pos += 0x100000000;
}
if (depth < 32) {
if (pos >= ((1 << depth) >>> 0))
throw new ScriptError('WITNESS_PROGRAM_MISMATCH');
}
root = utils.checkMerkleBranch(hash, path, pos);
if (!utils.equal(root, program.data))
throw new ScriptError('WITNESS_PROGRAM_MISMATCH');
} else {
// Anyone can spend (we can return true here
// if we want to always relay these transactions).