more script data extraction improvements.
This commit is contained in:
parent
b389dd1b5f
commit
ebbb417283
@ -909,7 +909,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
val = stack.pop();
|
||||
|
||||
if (flags.verifynulldummy !== false) {
|
||||
if (!Array.isArray(val) || val.length > 0)
|
||||
if (!script.isDummy(val))
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1170,6 +1170,15 @@ script.createMultisig = function createMultisig(keys, m, n) {
|
||||
);
|
||||
};
|
||||
|
||||
script.createScripthash = function createScripthash(s) {
|
||||
assert(Array.isArray(s));
|
||||
return [
|
||||
'hash160',
|
||||
utils.ripesha(script.encode(s)),
|
||||
'equal'
|
||||
];
|
||||
};
|
||||
|
||||
script.redeem = function redeem(s) {
|
||||
if (!Array.isArray(s[s.length - 1]))
|
||||
return;
|
||||
@ -1249,13 +1258,13 @@ script.spendable = function spendable(s, lockTime) {
|
||||
};
|
||||
|
||||
script.getInputData = function getData(s, prev) {
|
||||
var output;
|
||||
var output, type;
|
||||
|
||||
if (prev && !script.isScripthash(prev)) {
|
||||
output = script.getOutputData(prev);
|
||||
output.side = 'input';
|
||||
|
||||
// We could call getInputData, but
|
||||
// We could call _getInputData, but
|
||||
// we really only need the signatures.
|
||||
if (output.type === 'pubkey') {
|
||||
output.signatures = [s[0]];
|
||||
@ -1264,6 +1273,11 @@ script.getInputData = function getData(s, prev) {
|
||||
output.keys = [s[1]];
|
||||
} else if (output.type === 'multisig') {
|
||||
output.signatures = s.slice(1);
|
||||
} else if (output.type === 'scripthash') {
|
||||
// Scripthash is the only case where
|
||||
// we get more data from the input
|
||||
// than the output.
|
||||
output = script._getInputData(s, output.type);
|
||||
} else {
|
||||
output.signatures = script.getUnknownData(s).signatures;
|
||||
}
|
||||
@ -1271,13 +1285,24 @@ script.getInputData = function getData(s, prev) {
|
||||
return output;
|
||||
}
|
||||
|
||||
return script._getInputData(s);
|
||||
if (script.isPubkeyInput(s))
|
||||
type = 'pubkey';
|
||||
else if (script.isPubkeyhashInput(s))
|
||||
type = 'pubkeyhash';
|
||||
else if (script.isMultisigInput(s))
|
||||
type = 'multisig';
|
||||
else if (script.isScripthashInput(s))
|
||||
type = 'scripthash';
|
||||
|
||||
return script._getInputData(s, type);
|
||||
};
|
||||
|
||||
script._getInputData = function _getInputData(s) {
|
||||
script._getInputData = function _getInputData(s, type) {
|
||||
var sig, key, hash, raw, redeem, lock, hash, address, input, output;
|
||||
|
||||
if (script.isPubkeyInput(s)) {
|
||||
assert(typeof type === 'string');
|
||||
|
||||
if (type === 'pubkey') {
|
||||
sig = s[0];
|
||||
return {
|
||||
type: 'pubkey',
|
||||
@ -1287,7 +1312,7 @@ script._getInputData = function _getInputData(s) {
|
||||
};
|
||||
}
|
||||
|
||||
if (script.isPubkeyhashInput(s)) {
|
||||
if (type === 'pubkeyhash') {
|
||||
sig = s[0];
|
||||
key = s[1];
|
||||
hash = bcoin.wallet.key2hash(key);
|
||||
@ -1302,7 +1327,7 @@ script._getInputData = function _getInputData(s) {
|
||||
};
|
||||
}
|
||||
|
||||
if (script.isMultisigInput(s)) {
|
||||
if (type === 'multisig') {
|
||||
sig = s.slice(1);
|
||||
return {
|
||||
type: 'multisig',
|
||||
@ -1313,15 +1338,15 @@ script._getInputData = function _getInputData(s) {
|
||||
};
|
||||
}
|
||||
|
||||
if (script.isScripthashInput(s)) {
|
||||
if (type === 'scripthash') {
|
||||
raw = s[s.length - 1];
|
||||
redeem = script.decode(raw);
|
||||
lock = script.lockTime(redeem);
|
||||
hash = bcoin.wallet.key2hash(raw);
|
||||
address = bcoin.wallet.hash2addr(hash, 'scripthash');
|
||||
input = script.getInputData(s.slice(0, -1));
|
||||
delete input.none;
|
||||
output = script.getOutputData(script.subscript(redeem));
|
||||
input = script._getInputData(s.slice(0, -1), output.type);
|
||||
delete input.none;
|
||||
return utils.merge(input, output, {
|
||||
type: 'scripthash',
|
||||
side: 'input',
|
||||
@ -1620,8 +1645,10 @@ script.isPubkeyhashInput = function isPubkeyhashInput(s, key) {
|
||||
script.isMultisigInput = function isMultisigInput(s, keys, tx, i) {
|
||||
var i, o;
|
||||
|
||||
// We need to rule out scripthash
|
||||
// because it may look like multisig
|
||||
// We need to rule out scripthash because
|
||||
// it may look like multisig. This is
|
||||
// strange because it's technically a
|
||||
// recursive call.
|
||||
if (script.isScripthashInput(s))
|
||||
return false;
|
||||
|
||||
@ -1664,7 +1691,7 @@ script.isMultisigInput = function isMultisigInput(s, keys, tx, i) {
|
||||
};
|
||||
};
|
||||
|
||||
script.isScripthashInput = function isScripthashInput(s, data) {
|
||||
script.isScripthashInput = function isScripthashInput(s, data, strict) {
|
||||
var raw, redeem;
|
||||
|
||||
// Grab the raw redeem script.
|
||||
@ -1680,6 +1707,25 @@ script.isScripthashInput = function isScripthashInput(s, data) {
|
||||
if (!Array.isArray(raw))
|
||||
return false;
|
||||
|
||||
// If the last data element is a valid
|
||||
// signature or key, it's _extremely_
|
||||
// unlikely this is a scripthash.
|
||||
if (script.isSignatureEncoding(raw))
|
||||
return false;
|
||||
|
||||
if (script.isKeyEncoding(raw))
|
||||
return false;
|
||||
|
||||
// Check data against last array in case
|
||||
// a raw redeem script was passed in.
|
||||
if (data && utils.isEqual(data, raw))
|
||||
return raw;
|
||||
|
||||
// Return here if we do not want to check
|
||||
// against standard transaction types.
|
||||
if (!strict)
|
||||
return raw;
|
||||
|
||||
// P2SH redeem scripts can be nonstandard: make
|
||||
// it easier for other functions to parse this.
|
||||
redeem = script.subscript(script.decode(raw));
|
||||
@ -1694,11 +1740,6 @@ script.isScripthashInput = function isScripthashInput(s, data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check data against last array in case
|
||||
// a raw redeem script was passed in.
|
||||
if (data && utils.isEqual(data, raw))
|
||||
return raw;
|
||||
|
||||
// Test against all other script types
|
||||
if (!script.isPubkey(redeem, data)
|
||||
&& !script.isPubkeyhash(redeem, data)
|
||||
@ -1840,7 +1881,7 @@ script.isSignature = function isSignature(sig) {
|
||||
return sig.length >= 9 && sig.length <= 73;
|
||||
};
|
||||
|
||||
script.isEmpty = function isEmpty(data) {
|
||||
script.isDummy = function isDummy(data) {
|
||||
if (!utils.isBuffer(data))
|
||||
return false;
|
||||
|
||||
|
||||
@ -423,7 +423,7 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
||||
// and increment the total number of
|
||||
// signatures.
|
||||
if (ki < len && signatures < m) {
|
||||
if (bcoin.script.isEmpty(input.script[ki])) {
|
||||
if (bcoin.script.isDummy(input.script[ki])) {
|
||||
input.script[ki] = signature;
|
||||
signatures++;
|
||||
}
|
||||
@ -433,7 +433,7 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
||||
if (signatures >= m) {
|
||||
// Remove empty slots left over.
|
||||
for (i = len - 1; i >= 1; i--) {
|
||||
if (bcoin.script.isEmpty(input.script[i])) {
|
||||
if (bcoin.script.isDummy(input.script[i])) {
|
||||
input.script.splice(i, 1);
|
||||
len--;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user