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, checksig: 0xac,
checksigverify: 0xad, checksigverify: 0xad,
checkmultisig: 0xae, checkmultisig: 0xae,
checkmultisigverify: 0xaf checkmultisigverify: 0xaf,
checklocktimeverify: 0xb1
}; };
for (var i = 1; i <= 16; i++) for (var i = 1; i <= 16; i++)
@ -169,3 +170,5 @@ exports.block = {
maxSigops: 1000000 / 50, maxSigops: 1000000 / 50,
maxOrphanTx: 1000000 / 100 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) if (s.length > 10000)
return false; return false;
var input = tx.inputs[index];
for (var pc = 0; pc < s.length; pc++) { for (var pc = 0; pc < s.length; pc++) {
var o = s[pc]; var o = s[pc];
if (Array.isArray(o)) { if (Array.isArray(o)) {
@ -145,6 +147,8 @@ script.execute = function execute(s, stack, hasher) {
return false; return false;
stack.push(stack[stack.length - 1]); stack.push(stack[stack.length - 1]);
} else if (o === 'drop') {
stack.pop();
} else if (o === 'hash160') { } else if (o === 'hash160') {
if (stack.length === 0) if (stack.length === 0)
return false; return false;
@ -163,7 +167,7 @@ script.execute = function execute(s, stack, hasher) {
} }
} else if (o === 'checksigverify' || o === 'checksig') { } else if (o === 'checksigverify' || o === 'checksig') {
if (!hasher || stack.length < 2) if (!tx || stack.length < 2)
return false; return false;
var pub = stack.pop(); var pub = stack.pop();
@ -172,9 +176,8 @@ script.execute = function execute(s, stack, hasher) {
if (!constants.rhashType[type & 0x7f]) if (!constants.rhashType[type & 0x7f])
return false; return false;
var hash = hasher; var subscript = input.out.tx.getSubscript(input.out.index);
if (typeof hash === 'function') var hash = tx.subscriptHash(index, subscript, type);
hash = hash(type);
var res = script.verify(hash, sig.slice(0, -1), pub); var res = script.verify(hash, sig.slice(0, -1), pub);
if (o === 'checksigverify') { if (o === 'checksigverify') {
@ -184,7 +187,7 @@ script.execute = function execute(s, stack, hasher) {
stack.push(res ? [ 1 ] : []); stack.push(res ? [ 1 ] : []);
} }
} else if (o === 'checkmultisigverify' || o === 'checkmultisig') { } else if (o === 'checkmultisigverify' || o === 'checkmultisig') {
if (!hasher || stack.length < 3) if (!tx || stack.length < 3)
return false; return false;
var n = stack.pop(); var n = stack.pop();
@ -220,9 +223,8 @@ script.execute = function execute(s, stack, hasher) {
if (!constants.rhashType[type & 0x7f]) if (!constants.rhashType[type & 0x7f])
return false; return false;
var hash = hasher; var subscript = input.out.tx.getSubscript(input.out.index);
if (typeof hash === 'function') var hash = tx.subscriptHash(index, subscript, type);
hash = hash(type);
var res = false; var res = false;
for (; !res && j < n; j++) for (; !res && j < n; j++)
@ -241,6 +243,35 @@ script.execute = function execute(s, stack, hasher) {
} else { } else {
stack.push(res ? [ 1 ] : []); 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 { } else {
// Unknown operation // Unknown operation
return false; return false;

View File

@ -427,13 +427,10 @@ TX.prototype.verify = function verify(index, force) {
assert(input.out.tx.outputs.length > input.out.index); 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 = []; 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 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) if (!res)
return false; return false;