script standardness.
This commit is contained in:
parent
bfca638025
commit
282639b5b1
@ -942,6 +942,25 @@ script.execute = function execute(s, stack, tx, index, flags, recurse) {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
script.num = function num(value, useNum) {
|
||||||
|
if (utils.isFinite(value))
|
||||||
|
return useNum ? value : new bn(value, 'le');
|
||||||
|
|
||||||
|
assert(utils.isBuffer(value));
|
||||||
|
|
||||||
|
value = new bn(value, 'le');
|
||||||
|
|
||||||
|
if (useNum) {
|
||||||
|
try {
|
||||||
|
return value.toNumber();
|
||||||
|
} catch (e) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
script.redeem = function redeem(keys, m, n) {
|
script.redeem = function redeem(keys, m, n) {
|
||||||
if (keys.length !== n)
|
if (keys.length !== n)
|
||||||
throw new Error(n + ' keys are required to generate redeem script');
|
throw new Error(n + ' keys are required to generate redeem script');
|
||||||
@ -1041,15 +1060,10 @@ script.spendable = function spendable(s, lockTime) {
|
|||||||
script.isPubkey = function isPubkey(s, key) {
|
script.isPubkey = function isPubkey(s, key) {
|
||||||
var res;
|
var res;
|
||||||
|
|
||||||
s = script.subscript(s);
|
|
||||||
|
|
||||||
if (script.lockTime(s))
|
|
||||||
s = s.slice(3);
|
|
||||||
|
|
||||||
if (s.length !== 2)
|
if (s.length !== 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
res = Array.isArray(s[0]) && s[1] === 'checksig';
|
res = script.isKey(s[0]) && s[1] === 'checksig';
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
return false;
|
return false;
|
||||||
@ -1063,17 +1077,12 @@ script.isPubkey = function isPubkey(s, key) {
|
|||||||
script.isPubkeyhash = function isPubkeyhash(s, hash) {
|
script.isPubkeyhash = function isPubkeyhash(s, hash) {
|
||||||
var res;
|
var res;
|
||||||
|
|
||||||
s = script.subscript(s);
|
|
||||||
|
|
||||||
if (script.lockTime(s))
|
|
||||||
s = s.slice(3);
|
|
||||||
|
|
||||||
if (s.length !== 5)
|
if (s.length !== 5)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
res = s[0] === 'dup'
|
res = s[0] === 'dup'
|
||||||
&& s[1] === 'hash160'
|
&& s[1] === 'hash160'
|
||||||
&& Array.isArray(s[2])
|
&& script.isHash(s[2])
|
||||||
&& s[3] === 'eqverify'
|
&& s[3] === 'eqverify'
|
||||||
&& s[4] === 'checksig';
|
&& s[4] === 'checksig';
|
||||||
|
|
||||||
@ -1090,11 +1099,6 @@ script.isMultisig = function isMultisig(s, keys) {
|
|||||||
var m, n, i, j;
|
var m, n, i, j;
|
||||||
var total = 0;
|
var total = 0;
|
||||||
|
|
||||||
s = script.subscript(s);
|
|
||||||
|
|
||||||
if (script.lockTime(s))
|
|
||||||
s = s.slice(3);
|
|
||||||
|
|
||||||
if (s.length < 4)
|
if (s.length < 4)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1103,23 +1107,14 @@ script.isMultisig = function isMultisig(s, keys) {
|
|||||||
|
|
||||||
n = s[s.length - 2];
|
n = s[s.length - 2];
|
||||||
|
|
||||||
if (Array.isArray(n)) {
|
// Bitcoind technically doesn't check for the
|
||||||
if (n.length !== 1)
|
// 15 limit here. It just counts the sigops
|
||||||
return false;
|
// later.
|
||||||
n = n[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(n >= 1 && n <= 15))
|
if (!(n >= 1 && n <= 15))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m = s[0];
|
m = s[0];
|
||||||
|
|
||||||
if (Array.isArray(m)) {
|
|
||||||
if (m.length !== 1)
|
|
||||||
return false;
|
|
||||||
m = m[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(m >= 1 && m <= n))
|
if (!(m >= 1 && m <= n))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1127,7 +1122,7 @@ script.isMultisig = function isMultisig(s, keys) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (i = 1; i < n + 1; i++) {
|
for (i = 1; i < n + 1; i++) {
|
||||||
if (!Array.isArray(s[i]))
|
if (!script.isKey(s[i]))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1151,17 +1146,11 @@ script.isMultisig = function isMultisig(s, keys) {
|
|||||||
script.isScripthash = function isScripthash(s, hash) {
|
script.isScripthash = function isScripthash(s, hash) {
|
||||||
var res;
|
var res;
|
||||||
|
|
||||||
s = script.subscript(s);
|
|
||||||
|
|
||||||
if (script.lockTime(s))
|
|
||||||
s = s.slice(3);
|
|
||||||
|
|
||||||
if (s.length !== 3)
|
if (s.length !== 3)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
res = s[0] === 'hash160'
|
res = s[0] === 'hash160'
|
||||||
&& Array.isArray(s[1])
|
&& script.isHash(s[1])
|
||||||
&& s[1].length === 20
|
|
||||||
&& s[2] === 'eq';
|
&& s[2] === 'eq';
|
||||||
|
|
||||||
if (!res)
|
if (!res)
|
||||||
@ -1174,8 +1163,6 @@ script.isScripthash = function isScripthash(s, hash) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
script.isNulldata = function isNulldata(s) {
|
script.isNulldata = function isNulldata(s) {
|
||||||
s = script.subscript(s);
|
|
||||||
|
|
||||||
if (s.length !== 2)
|
if (s.length !== 2)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1188,7 +1175,7 @@ script.nulldata = function nulldata(s) {
|
|||||||
if (!script.isNulldata(s))
|
if (!script.isNulldata(s))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return script.subscript(s)[1];
|
return s[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
script.standardInput = function standardInput(s) {
|
script.standardInput = function standardInput(s) {
|
||||||
@ -1200,8 +1187,6 @@ script.standardInput = function standardInput(s) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
script.isPubkeyInput = function isPubkeyInput(s, key, tx, i) {
|
script.isPubkeyInput = function isPubkeyInput(s, key, tx, i) {
|
||||||
s = script.subscript(s);
|
|
||||||
|
|
||||||
if (s.length !== 1 || !Array.isArray(s[0]))
|
if (s.length !== 1 || !Array.isArray(s[0]))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1221,8 +1206,6 @@ script.isPubkeyInput = function isPubkeyInput(s, key, tx, i) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
script.isPubkeyhashInput = function isPubkeyhashInput(s, key) {
|
script.isPubkeyhashInput = function isPubkeyhashInput(s, key) {
|
||||||
s = script.subscript(s);
|
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
@ -1246,8 +1229,6 @@ script.isMultisigInput = function isMultisigInput(s, keys, tx, i) {
|
|||||||
if (script.isScripthashInput(s))
|
if (script.isScripthashInput(s))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
s = script.subscript(s);
|
|
||||||
|
|
||||||
if (s.length < 3)
|
if (s.length < 3)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -1286,8 +1267,6 @@ script.isMultisigInput = function isMultisigInput(s, keys, tx, i) {
|
|||||||
script.isScripthashInput = function isScripthashInput(s, data) {
|
script.isScripthashInput = function isScripthashInput(s, data) {
|
||||||
var raw, redeem;
|
var raw, redeem;
|
||||||
|
|
||||||
s = script.subscript(s);
|
|
||||||
|
|
||||||
// Grab the raw redeem script.
|
// Grab the raw redeem script.
|
||||||
raw = s[s.length - 1];
|
raw = s[s.length - 1];
|
||||||
|
|
||||||
@ -1303,7 +1282,7 @@ script.isScripthashInput = function isScripthashInput(s, data) {
|
|||||||
|
|
||||||
// P2SH redeem scripts can be nonstandard: make
|
// P2SH redeem scripts can be nonstandard: make
|
||||||
// it easier for other functions to parse this.
|
// it easier for other functions to parse this.
|
||||||
redeem = script.normalize(raw);
|
redeem = script.subscript(script.decode(raw));
|
||||||
|
|
||||||
// Get the "real" scriptSig
|
// Get the "real" scriptSig
|
||||||
s = s.slice(0, -1);
|
s = s.slice(0, -1);
|
||||||
@ -1429,6 +1408,13 @@ script.isCoinbase = function isCoinbase(s, block, strict) {
|
|||||||
return coinbase;
|
return coinbase;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
script.isHash = function isHash(hash) {
|
||||||
|
if (!utils.isBuffer(hash))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return hash.length === 20;
|
||||||
|
};
|
||||||
|
|
||||||
script.isKey = function isKey(key) {
|
script.isKey = function isKey(key) {
|
||||||
if (!utils.isBuffer(key))
|
if (!utils.isBuffer(key))
|
||||||
return false;
|
return false;
|
||||||
@ -1636,7 +1622,9 @@ script.pushOnly = function pushOnly(s) {
|
|||||||
var i, op;
|
var i, op;
|
||||||
for (i = 0; i < s.length; i++) {
|
for (i = 0; i < s.length; i++) {
|
||||||
op = s[i];
|
op = s[i];
|
||||||
if (Array.isArray(op) || (op >= 1 && op <= 16))
|
// if (Array.isArray(op) || (constants.opcodes[op] <= constants.opcodes['16']))
|
||||||
|
// continue;
|
||||||
|
if (Array.isArray(op) || (op >= -1 && op <= 16))
|
||||||
continue;
|
continue;
|
||||||
if (constants.opcodes[op] == null)
|
if (constants.opcodes[op] == null)
|
||||||
return false;
|
return false;
|
||||||
@ -1678,7 +1666,7 @@ script.sigopsScripthash = function sigopsScripthash(s) {
|
|||||||
if (!script.pushOnly(s))
|
if (!script.pushOnly(s))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
s = script.decode(s[s.length - 1]);
|
s = script.subscript(script.decode(s[s.length - 1]));
|
||||||
|
|
||||||
return script.sigops(s, true);
|
return script.sigops(s, true);
|
||||||
};
|
};
|
||||||
@ -1686,11 +1674,6 @@ script.sigopsScripthash = function sigopsScripthash(s) {
|
|||||||
script.args = function args(s) {
|
script.args = function args(s) {
|
||||||
var keys, m;
|
var keys, m;
|
||||||
|
|
||||||
s = bcoin.script.subscript(s);
|
|
||||||
|
|
||||||
if (script.lockTime(s))
|
|
||||||
s = s.slice(3);
|
|
||||||
|
|
||||||
if (script.isPubkey(s))
|
if (script.isPubkey(s))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|||||||
@ -177,7 +177,7 @@ TX.prototype.scriptInput = function scriptInput(index, pub, redeem) {
|
|||||||
// P2SH
|
// P2SH
|
||||||
if (bcoin.script.isScripthash(s)) {
|
if (bcoin.script.isScripthash(s)) {
|
||||||
assert(redeem);
|
assert(redeem);
|
||||||
s = bcoin.script.normalize(redeem);
|
s = bcoin.script.subscript(bcoin.script.decode(redeem));
|
||||||
} else {
|
} else {
|
||||||
redeem = null;
|
redeem = null;
|
||||||
}
|
}
|
||||||
@ -268,7 +268,7 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
|||||||
|
|
||||||
// P2SH
|
// P2SH
|
||||||
if (bcoin.script.isScripthash(s)) {
|
if (bcoin.script.isScripthash(s)) {
|
||||||
s = bcoin.script.normalize(redeem);
|
s = bcoin.script.subscript(redeem);
|
||||||
// Decrement `len` to avoid the redeem script
|
// Decrement `len` to avoid the redeem script
|
||||||
len--;
|
len--;
|
||||||
}
|
}
|
||||||
@ -325,7 +325,7 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
|||||||
|
|
||||||
// Something is very wrong here. Abort.
|
// Something is very wrong here. Abort.
|
||||||
if (len - 1 > n)
|
if (len - 1 > n)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
// Count the number of current signatures.
|
// Count the number of current signatures.
|
||||||
signatures = 0;
|
signatures = 0;
|
||||||
@ -336,7 +336,7 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
|||||||
|
|
||||||
// Signatures are already finalized.
|
// Signatures are already finalized.
|
||||||
if (signatures === m && len - 1 === m)
|
if (signatures === m && len - 1 === m)
|
||||||
return;
|
return true;
|
||||||
|
|
||||||
// This can happen in a case where another
|
// This can happen in a case where another
|
||||||
// implementation adds signatures willy-nilly
|
// implementation adds signatures willy-nilly
|
||||||
@ -362,7 +362,7 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
|||||||
// script. We tried to sign a transaction
|
// script. We tried to sign a transaction
|
||||||
// that is not redeemable by us.
|
// that is not redeemable by us.
|
||||||
if (ki === keys.length)
|
if (ki === keys.length)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
// Offset key index by one to turn it into
|
// Offset key index by one to turn it into
|
||||||
// "sig index". Accounts for OP_0 byte at
|
// "sig index". Accounts for OP_0 byte at
|
||||||
@ -740,7 +740,7 @@ TX.prototype.maxSize = function maxSize() {
|
|||||||
// the isMultisig clause.
|
// the isMultisig clause.
|
||||||
// OP_PUSHDATA2 [redeem]
|
// OP_PUSHDATA2 [redeem]
|
||||||
size += 3 + s.length;
|
size += 3 + s.length;
|
||||||
s = bcoin.script.normalize(s);
|
s = bcoin.script.subscript(bcoin.script.decode(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bcoin.script.isPubkey(s)) {
|
if (bcoin.script.isPubkey(s)) {
|
||||||
@ -1169,7 +1169,7 @@ TX.prototype.isStandardInputs = function isStandardInputs(flags) {
|
|||||||
if (!Array.isArray(s))
|
if (!Array.isArray(s))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
s = bcoin.script.decode(s);
|
s = bcoin.script.subscript(bcoin.script.decode(s));
|
||||||
|
|
||||||
if (bcoin.script.standard(s)) {
|
if (bcoin.script.standard(s)) {
|
||||||
targs = bcoin.script.args(s);
|
targs = bcoin.script.args(s);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user