improve input checks with keys/hashes/redeemscript.
This commit is contained in:
parent
6caa6b91dd
commit
6abfc10a28
@ -762,6 +762,15 @@ script.execute = function execute(s, stack, tx, index) {
|
||||
return true;
|
||||
};
|
||||
|
||||
script.exec = function(input, output, tx, i) {
|
||||
var stack = [];
|
||||
script.execute(input, stack, tx, i);
|
||||
var res = script.execute(output, stack, tx, i);
|
||||
if (!res || stack.length === 0 || !utils.isEqual(stack.pop(), [ 1 ]))
|
||||
return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
script.multisig = function(keys, m, n) {
|
||||
if (keys.length < m)
|
||||
throw new Error('Wrong amount of pubkeys for multisig script');
|
||||
@ -889,11 +898,13 @@ script.isMultisig = function isMultisig(s, pubs) {
|
||||
if (!pubs)
|
||||
return keys;
|
||||
|
||||
return m === keys.filter(function(k) {
|
||||
var total = keys.filter(function(k) {
|
||||
return pubs.some(function(pub) {
|
||||
return utils.isEqual(k, pub);
|
||||
});
|
||||
}).length;
|
||||
|
||||
return total >= m;
|
||||
};
|
||||
|
||||
script.isScripthash = function isScripthash(s, hash) {
|
||||
@ -903,12 +914,12 @@ script.isScripthash = function isScripthash(s, hash) {
|
||||
if (s.length !== 3)
|
||||
return false;
|
||||
|
||||
var ret = s[0] === 'hash160' &&
|
||||
var res = s[0] === 'hash160' &&
|
||||
Array.isArray(s[1]) &&
|
||||
s[1].length === 20 &&
|
||||
s[2] === 'eq';
|
||||
|
||||
if (!ret)
|
||||
if (!res)
|
||||
return false;
|
||||
|
||||
if (hash)
|
||||
@ -941,29 +952,32 @@ script.standardInput = function standardInput(s) {
|
||||
|| null;
|
||||
};
|
||||
|
||||
script.isPubkeyInput = function isPubkeyInput(s, key) {
|
||||
if (key)
|
||||
throw new Error('Cannot check for pubkey in p2pk input.');
|
||||
|
||||
script.isPubkeyInput = function isPubkeyInput(s, key, tx, i) {
|
||||
if (s.length !== 1 || !Array.isArray(s[0]))
|
||||
return false;
|
||||
|
||||
// return script.isValidSig(s[0]);
|
||||
// var res = script.isValidSig(s[0]);
|
||||
var res = 9 <= s[0].length && s[0].length <= 73;
|
||||
if (!res)
|
||||
return false;
|
||||
|
||||
return 9 <= s[0].length && s[0].length <= 73;
|
||||
if (key)
|
||||
return script.exec(s, [key, 'checksig'], tx, i);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
script.isPubkeyhashInput = function isPubkeyhashInput(s, key) {
|
||||
if (s.length !== 2 || !Array.isArray(s[0]) || !Array.isArray(s[1]))
|
||||
return false;
|
||||
|
||||
// var ret = script.isValidSig(s[0]) &&
|
||||
// var res = script.isValidSig(s[0]) &&
|
||||
// 33 <= s[1].length && s[1].length <= 65;
|
||||
|
||||
var ret = 9 <= s[0].length && s[0].length <= 73 &&
|
||||
var res = 9 <= s[0].length && s[0].length <= 73 &&
|
||||
33 <= s[1].length && s[1].length <= 65;
|
||||
|
||||
if (!ret)
|
||||
if (!res)
|
||||
return false;
|
||||
|
||||
if (key)
|
||||
@ -972,71 +986,50 @@ script.isPubkeyhashInput = function isPubkeyhashInput(s, key) {
|
||||
return true;
|
||||
};
|
||||
|
||||
script.isMultisigInput = function isMultisigInput(s, pubs) {
|
||||
script.isMultisigInput = function isMultisigInput(s, pubs, tx, i) {
|
||||
if (s.length < 3)
|
||||
return false;
|
||||
|
||||
if (!Array.isArray(s[0]) || s[0].length !== 0)
|
||||
return false;
|
||||
|
||||
if (pubs && !Array.isArray(pubs[0]))
|
||||
pubs = [pubs];
|
||||
|
||||
var total = 0;
|
||||
for (var i = 1; i < s.length; i++) {
|
||||
var ret = Array.isArray(s[i]) && 33 <= s[i].length && s[i].length <= 65;
|
||||
if (!ret)
|
||||
// var res = Array.isArray(s[i]) && script.isValidSig(s[i]);
|
||||
var res = Array.isArray(s[i]) && 9 <= s[i].length && s[i].length <= 73;
|
||||
if (!res)
|
||||
return false;
|
||||
if (pubs) {
|
||||
var has = pubs.some(function(pub) {
|
||||
return utils.isEqual(s[i], pub);
|
||||
});
|
||||
if (has)
|
||||
total++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pubs)
|
||||
return true;
|
||||
if (pubs && pubs.length >= 2) {
|
||||
var o = script.multisig(pubs, 2, pubs.length);
|
||||
return script.exec(s, o, tx, i);
|
||||
}
|
||||
|
||||
return total;
|
||||
return true;
|
||||
};
|
||||
|
||||
script.isScripthashInput = function isScripthashInput(s, pubs) {
|
||||
script.isScripthashInput = function isScripthashInput(s, redeem) {
|
||||
if (s.length < 4)
|
||||
return false;
|
||||
|
||||
if (!Array.isArray(s[0]) || s[0].length !== 0)
|
||||
return false;
|
||||
|
||||
if (pubs && !Array.isArray(pubs[0]))
|
||||
pubs = [pubs];
|
||||
|
||||
var total = 0;
|
||||
for (var i = 1; i < s.length - 1; i++) {
|
||||
var ret = Array.isArray(s[i]) && 33 <= s[i].length && s[i].length <= 65;
|
||||
if (!ret)
|
||||
// var res = Array.isArray(s[i]) && script.isValidSig(s[i]);
|
||||
var res = Array.isArray(s[i]) && 9 <= s[i].length && s[i].length <= 73;
|
||||
if (!res)
|
||||
return false;
|
||||
if (pubs) {
|
||||
var has = pubs.some(function(pub) {
|
||||
return utils.isEqual(s[i], pub);
|
||||
});
|
||||
if (has)
|
||||
total++;
|
||||
}
|
||||
}
|
||||
|
||||
var r = Array.isArray(s[s.length - 1]) && s[s.length - 1];
|
||||
if (r[r.length - 1] !== constants.opcodes.checkmultisig)
|
||||
return false;
|
||||
|
||||
if (!pubs)
|
||||
return true;
|
||||
if (redeem)
|
||||
return utils.isEqual(redeem, r);
|
||||
|
||||
// var m = r[0];
|
||||
// return m === total;
|
||||
|
||||
return total;
|
||||
return true;
|
||||
};
|
||||
|
||||
// https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki
|
||||
|
||||
@ -125,18 +125,40 @@ TX.prototype._inputIndex = function _inputIndex(hash, index) {
|
||||
return -1;
|
||||
};
|
||||
|
||||
TX.prototype.signature = function(input, key, type) {
|
||||
TX.prototype.signatureHash = function(i, type) {
|
||||
if (typeof i === 'object')
|
||||
i = this.inputs.indexOf(i);
|
||||
|
||||
if (!type)
|
||||
type = 'all';
|
||||
|
||||
if (typeof type === 'string')
|
||||
type = constants.hashType[type];
|
||||
|
||||
// Get the current input.
|
||||
var input = this.inputs[i];
|
||||
|
||||
// Get the previous output's subscript
|
||||
var s = input.out.tx.getSubscript(input.out.index);
|
||||
|
||||
// Get the hash of the current tx, minus the other inputs, plus the sighash.
|
||||
var hash = this.subscriptHash(tx.inputs.indexOf(input), s, type);
|
||||
var hash = this.subscriptHash(i, s, type);
|
||||
|
||||
return hash;
|
||||
};
|
||||
|
||||
TX.prototype.signature = function(i, key, type) {
|
||||
if (typeof i === 'object')
|
||||
i = this.inputs.indexOf(i);
|
||||
|
||||
if (!type)
|
||||
type = 'all';
|
||||
|
||||
if (typeof type === 'string')
|
||||
type = constants.hashType[type];
|
||||
|
||||
// Get the hash of the current tx, minus the other inputs, plus the sighash.
|
||||
var hash = this.sigHash(i, type);
|
||||
|
||||
// Sign the transaction with our one input
|
||||
var signature = bcoin.ecdsa.sign(hash, key.priv).toDER();
|
||||
|
||||
@ -357,6 +357,7 @@ Wallet.validateAddress = Wallet.prototype.validateAddress;
|
||||
Wallet.prototype.ownOutput = function ownOutput(tx, index) {
|
||||
var scriptHash = this.getFullHash();
|
||||
var hash = this.getOwnHash();
|
||||
var key = this.getOwnPublicKey();
|
||||
var keys = this.getPublicKeys();
|
||||
|
||||
var outputs = tx.outputs.filter(function(output, i) {
|
||||
@ -365,7 +366,7 @@ Wallet.prototype.ownOutput = function ownOutput(tx, index) {
|
||||
|
||||
var s = output.script;
|
||||
|
||||
if (bcoin.script.isPubkey(s, hash))
|
||||
if (bcoin.script.isPubkey(s, key))
|
||||
return true;
|
||||
|
||||
if (bcoin.script.isPubkeyhash(s, hash))
|
||||
@ -390,19 +391,33 @@ Wallet.prototype.ownInput = function ownInput(tx, index) {
|
||||
var scriptHash = this.getFullHash();
|
||||
var hash = this.getOwnHash();
|
||||
var key = this.getOwnPublicKey();
|
||||
var redeem = this.getFullPublicKey();
|
||||
var keys = this.getPublicKeys();
|
||||
|
||||
var inputs = tx.inputs.filter(function(input, i) {
|
||||
if (index !== undefined && index !== i)
|
||||
return false;
|
||||
|
||||
// if (bcoin.script.isPubkeyInput(input.script, key, tx, i))
|
||||
// return true;
|
||||
|
||||
if (bcoin.script.isPubkeyhashInput(input.script, key))
|
||||
return true;
|
||||
|
||||
if (bcoin.script.isScripthashInput(input.script, redeem))
|
||||
return true;
|
||||
|
||||
// if (bcoin.script.isMultisigInput(input.script, key, tx, i))
|
||||
// return true;
|
||||
|
||||
if (!input.out.tx)
|
||||
return false;
|
||||
|
||||
var s = input.out.tx.outputs[input.out.index].script;
|
||||
|
||||
if (bcoin.script.isPubkey(s, key))
|
||||
return true;
|
||||
|
||||
if (bcoin.script.isPubkeyhash(s, hash))
|
||||
return true;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user