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,
|
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
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user