add checklocktimeverify. pass in tx and input to execute() instead of using hasher callback.
This commit is contained in:
parent
a770e2bd7b
commit
adbb0099a1
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user