script: remove mast.
This commit is contained in:
parent
163e89fc29
commit
9b269dd1f0
@ -766,15 +766,6 @@ class Address {
|
||||
return this.version === 0 && this.hash.length === 32;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the address is witness masthash.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
isWitnessMasthash() {
|
||||
return this.version === 1 && this.hash.length === 32;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the address is a witness program.
|
||||
* @returns {Boolean}
|
||||
|
||||
@ -346,8 +346,7 @@ exports.flags = {
|
||||
VERIFY_DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM: 1 << 12,
|
||||
VERIFY_MINIMALIF: 1 << 13,
|
||||
VERIFY_NULLFAIL: 1 << 14,
|
||||
VERIFY_WITNESS_PUBKEYTYPE: 1 << 15,
|
||||
VERIFY_MAST: 1 << 16
|
||||
VERIFY_WITNESS_PUBKEYTYPE: 1 << 15
|
||||
};
|
||||
|
||||
/**
|
||||
@ -448,8 +447,7 @@ exports.types = {
|
||||
NULLDATA: 5,
|
||||
WITNESSMALFORMED: 0x80,
|
||||
WITNESSSCRIPTHASH: 0x81,
|
||||
WITNESSPUBKEYHASH: 0x82,
|
||||
WITNESSMASTHASH: 0x83
|
||||
WITNESSPUBKEYHASH: 0x82
|
||||
};
|
||||
|
||||
/**
|
||||
@ -466,8 +464,7 @@ exports.typesByVal = {
|
||||
5: 'NULLDATA',
|
||||
0x80: 'WITNESSMALFORMED',
|
||||
0x81: 'WITNESSSCRIPTHASH',
|
||||
0x82: 'WITNESSPUBKEYHASH',
|
||||
0x83: 'WITNESSMASTHASH'
|
||||
0x82: 'WITNESSPUBKEYHASH'
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -54,14 +54,6 @@ class Program {
|
||||
return scriptTypes.WITNESSMALFORMED;
|
||||
}
|
||||
|
||||
if (this.version === 1) {
|
||||
if (this.data.length === 32)
|
||||
return scriptTypes.WITNESSMASTHASH;
|
||||
|
||||
// Fail on bad version=1
|
||||
return scriptTypes.WITNESSMALFORMED;
|
||||
}
|
||||
|
||||
// No interpretation of script (anyone can spend)
|
||||
return scriptTypes.NONSTANDARD;
|
||||
}
|
||||
|
||||
@ -1724,9 +1724,6 @@ class Script {
|
||||
if (this.isWitnessScripthash())
|
||||
return scriptTypes.WITNESSSCRIPTHASH;
|
||||
|
||||
if (this.isWitnessMasthash())
|
||||
return scriptTypes.WITNESSMASTHASH;
|
||||
|
||||
if (this.isMultisig())
|
||||
return scriptTypes.MULTISIG;
|
||||
|
||||
@ -2187,30 +2184,6 @@ class Script {
|
||||
return this.getData(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the output script
|
||||
* is a pay-to-mast program.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
isWitnessMasthash() {
|
||||
return this.raw.length === 34
|
||||
&& this.raw[0] === opcodes.OP_1
|
||||
&& this.raw[1] === 0x20;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get P2WMH hash if present.
|
||||
* @returns {Buffer|null}
|
||||
*/
|
||||
|
||||
getWitnessMasthash() {
|
||||
if (!this.isWitnessMasthash())
|
||||
return null;
|
||||
|
||||
return this.getData(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test whether the output script is unspendable.
|
||||
* @returns {Boolean}
|
||||
@ -3256,9 +3229,6 @@ class Script {
|
||||
// Failure on version=0 (bad program data length).
|
||||
throw new ScriptError('WITNESS_PROGRAM_WRONG_LENGTH');
|
||||
}
|
||||
} else if ((flags & Script.flags.VERIFY_MAST) && program.version === 1) {
|
||||
Script.verifyMast(program, stack, output, flags, tx, index);
|
||||
return;
|
||||
} else {
|
||||
// Anyone can spend (we can return true here
|
||||
// if we want to always relay these transactions).
|
||||
@ -3286,138 +3256,6 @@ class Script {
|
||||
throw new ScriptError('EVAL_FALSE');
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify a MAST witness program.
|
||||
* @param {Program} program
|
||||
* @param {Stack} stack
|
||||
* @param {Script} output
|
||||
* @param {VerifyFlags} flags
|
||||
* @param {TX} tx
|
||||
* @param {Number} index
|
||||
* @param {Amount} value
|
||||
* @throws {ScriptError}
|
||||
*/
|
||||
|
||||
static verifyMast(program, stack, output, flags, tx, index, value) {
|
||||
assert(program.version === 1);
|
||||
assert((flags & Script.flags.VERIFY_MAST) !== 0);
|
||||
|
||||
if (stack.length < 4)
|
||||
throw new ScriptError('INVALID_MAST_STACK');
|
||||
|
||||
const metadata = stack.get(-1);
|
||||
if (metadata.length < 1 || metadata.length > 5)
|
||||
throw new ScriptError('INVALID_MAST_STACK');
|
||||
|
||||
const subscripts = metadata[0];
|
||||
if (subscripts === 0 || stack.length < subscripts + 3)
|
||||
throw new ScriptError('INVALID_MAST_STACK');
|
||||
|
||||
let ops = subscripts;
|
||||
let scriptRoot = bio.write();
|
||||
scriptRoot.writeU8(subscripts);
|
||||
|
||||
if (metadata[metadata.length - 1] === 0x00)
|
||||
throw new ScriptError('INVALID_MAST_STACK');
|
||||
|
||||
let version = 0;
|
||||
|
||||
for (let j = 1; j < metadata.length; j++)
|
||||
version |= metadata[j] << 8 * (j - 1);
|
||||
|
||||
if (version < 0)
|
||||
version += 0x100000000;
|
||||
|
||||
if (version > 0) {
|
||||
if (flags & Script.flags.DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM)
|
||||
throw new ScriptError('DISCOURAGE_UPGRADABLE_WITNESS_PROGRAM');
|
||||
}
|
||||
|
||||
let mastRoot = bio.write();
|
||||
mastRoot.writeU32(version);
|
||||
|
||||
const pathdata = stack.get(-2);
|
||||
|
||||
if (pathdata.length & 0x1f)
|
||||
throw new ScriptError('INVALID_MAST_STACK');
|
||||
|
||||
const depth = pathdata.length >>> 5;
|
||||
|
||||
if (depth > 32)
|
||||
throw new ScriptError('INVALID_MAST_STACK');
|
||||
|
||||
ops += depth;
|
||||
if (version === 0) {
|
||||
if (ops > consensus.MAX_SCRIPT_OPS)
|
||||
throw new ScriptError('OP_COUNT');
|
||||
}
|
||||
|
||||
const path = [];
|
||||
|
||||
for (let j = 0; j < depth; j++)
|
||||
path.push(pathdata.slice(j * 32, j * 32 + 32));
|
||||
|
||||
const posdata = stack.get(-3);
|
||||
|
||||
if (posdata.length > 4)
|
||||
throw new ScriptError('INVALID_MAST_STACK');
|
||||
|
||||
let pos = 0;
|
||||
if (posdata.length > 0) {
|
||||
if (posdata[posdata.length - 1] === 0x00)
|
||||
throw new ScriptError('INVALID_MAST_STACK');
|
||||
|
||||
for (let j = 0; j < posdata.length; j++)
|
||||
pos |= posdata[j] << 8 * j;
|
||||
|
||||
if (pos < 0)
|
||||
pos += 0x100000000;
|
||||
}
|
||||
|
||||
if (depth < 32) {
|
||||
if (pos >= ((1 << depth) >>> 0))
|
||||
throw new ScriptError('INVALID_MAST_STACK');
|
||||
}
|
||||
|
||||
let scripts = bio.write();
|
||||
scripts.writeBytes(output.raw);
|
||||
|
||||
for (let j = 0; j < subscripts; j++) {
|
||||
const script = stack.get(-(4 + j));
|
||||
if (version === 0) {
|
||||
if ((scripts.offset + script.length) > consensus.MAX_SCRIPT_SIZE)
|
||||
throw new ScriptError('SCRIPT_SIZE');
|
||||
}
|
||||
scriptRoot.writeBytes(hash256.digest(script));
|
||||
scripts.writeBytes(script);
|
||||
}
|
||||
|
||||
scriptRoot = hash256.digest(scriptRoot.render());
|
||||
scriptRoot = merkle.verifyBranch(scriptRoot, path, pos);
|
||||
|
||||
mastRoot.writeBytes(scriptRoot);
|
||||
mastRoot = hash256.digest(mastRoot.render());
|
||||
|
||||
if (!mastRoot.equals(program.data))
|
||||
throw new ScriptError('WITNESS_PROGRAM_MISMATCH');
|
||||
|
||||
if (version === 0) {
|
||||
stack.length -= 3 + subscripts;
|
||||
|
||||
for (let j = 0; j < stack.length; j++) {
|
||||
if (stack.get(j).length > consensus.MAX_SCRIPT_PUSH)
|
||||
throw new ScriptError('PUSH_SIZE');
|
||||
}
|
||||
|
||||
scripts = scripts.render();
|
||||
output = Script.fromRaw(scripts);
|
||||
output.execute(stack, flags, tx, index, value, 1);
|
||||
|
||||
if (stack.length !== 0)
|
||||
throw new ScriptError('EVAL_FALSE');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
|
||||
Loading…
Reference in New Issue
Block a user