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