add checklocktimeverify. pass in tx and input to execute() instead of using hasher callback.

This commit is contained in:
Christopher Jeffrey 2015-12-08 11:24:22 -08:00
parent a770e2bd7b
commit adbb0099a1
3 changed files with 46 additions and 15 deletions

View File

@ -137,7 +137,8 @@ exports.opcodes = {
checksig: 0xac,
checksigverify: 0xad,
checkmultisig: 0xae,
checkmultisigverify: 0xaf
checkmultisigverify: 0xaf,
checklocktimeverify: 0xb1
};
for (var i = 1; i <= 16; i++)
@ -169,3 +170,5 @@ exports.block = {
maxSigops: 1000000 / 50,
maxOrphanTx: 1000000 / 100
};
exports.locktimeThreshold = 500000000; // Tue Nov 5 00:53:20 1985 UTC

View File

@ -130,10 +130,12 @@ script.verify = function verify(hash, sig, pub) {
}
};
script.execute = function execute(s, stack, hasher) {
script.execute = function execute(s, stack, tx, index) {
if (s.length > 10000)
return false;
var input = tx.inputs[index];
for (var pc = 0; pc < s.length; pc++) {
var o = s[pc];
if (Array.isArray(o)) {
@ -145,6 +147,8 @@ script.execute = function execute(s, stack, hasher) {
return false;
stack.push(stack[stack.length - 1]);
} else if (o === 'drop') {
stack.pop();
} else if (o === 'hash160') {
if (stack.length === 0)
return false;
@ -163,7 +167,7 @@ script.execute = function execute(s, stack, hasher) {
}
} else if (o === 'checksigverify' || o === 'checksig') {
if (!hasher || stack.length < 2)
if (!tx || stack.length < 2)
return false;
var pub = stack.pop();
@ -172,9 +176,8 @@ script.execute = function execute(s, stack, hasher) {
if (!constants.rhashType[type & 0x7f])
return false;
var hash = hasher;
if (typeof hash === 'function')
hash = hash(type);
var subscript = input.out.tx.getSubscript(input.out.index);
var hash = tx.subscriptHash(index, subscript, type);
var res = script.verify(hash, sig.slice(0, -1), pub);
if (o === 'checksigverify') {
@ -184,7 +187,7 @@ script.execute = function execute(s, stack, hasher) {
stack.push(res ? [ 1 ] : []);
}
} else if (o === 'checkmultisigverify' || o === 'checkmultisig') {
if (!hasher || stack.length < 3)
if (!tx || stack.length < 3)
return false;
var n = stack.pop();
@ -220,9 +223,8 @@ script.execute = function execute(s, stack, hasher) {
if (!constants.rhashType[type & 0x7f])
return false;
var hash = hasher;
if (typeof hash === 'function')
hash = hash(type);
var subscript = input.out.tx.getSubscript(input.out.index);
var hash = tx.subscriptHash(index, subscript, type);
var res = false;
for (; !res && j < n; j++)
@ -241,6 +243,35 @@ script.execute = function execute(s, stack, hasher) {
} else {
stack.push(res ? [ 1 ] : []);
}
} else if (o === 'checklocktimeverify') {
// input: [[], sig1, sig2, 1]
// prev_out: [[lock], 'checklocktimeverify', 'drop',
// 'dup', 'hash160', pubkey, 'equalverify', 'checksig']
if (stack.length === 0)
return false;
var lock = stack[stack.length - 1];
if (lock.length !== 1)
return false;
lock = lock[0];
if (lock < 0)
return false;
var threshold = constants.locktimeThreshold;
if (!(
(tx.lock < threshold && lock < threshold) ||
(tx.lock >= threshold && lock >= threshold)
)) {
return false;
}
if (lock > tx.lock)
return false;
if (input.seq === 0xffffffff)
return false;
} else {
// Unknown operation
return false;

View File

@ -427,13 +427,10 @@ TX.prototype.verify = function verify(index, force) {
assert(input.out.tx.outputs.length > input.out.index);
var subscript = input.out.tx.getSubscript(input.out.index);
var hasher = this.subscriptHash.bind(this, i, subscript);
var stack = [];
bcoin.script.execute(input.script, stack);
bcoin.script.execute(input.script, stack, this, i);
var prev = input.out.tx.outputs[input.out.index].script;
var res = bcoin.script.execute(prev, stack, hasher);
var res = bcoin.script.execute(prev, stack, this, i);
if (!res)
return false;