standard opcodes. remove tx methods.
This commit is contained in:
parent
6f4609792f
commit
3745577837
@ -38,22 +38,54 @@ exports.filterFlags = {
|
||||
};
|
||||
|
||||
exports.opcodes = {
|
||||
0: 0,
|
||||
// 'false': 0x00,
|
||||
'0': 0x00,
|
||||
|
||||
pushdata1: 0x4c,
|
||||
pushdata2: 0x4d,
|
||||
pushdata4: 0x4e,
|
||||
// negate1: 0x4f,
|
||||
|
||||
'1negate': 0x4f,
|
||||
|
||||
reserved: 0x50,
|
||||
|
||||
// 'true': 0x51,
|
||||
'1': 0x51,
|
||||
'2': 0x52,
|
||||
'3': 0x53,
|
||||
'4': 0x54,
|
||||
'5': 0x55,
|
||||
'6': 0x56,
|
||||
'7': 0x57,
|
||||
'8': 0x58,
|
||||
'9': 0x59,
|
||||
'10': 0x5a,
|
||||
'11': 0x5b,
|
||||
'12': 0x5c,
|
||||
'13': 0x5d,
|
||||
'14': 0x5e,
|
||||
'15': 0x5f,
|
||||
'16': 0x60,
|
||||
|
||||
nop: 0x61,
|
||||
if_: 0x63,
|
||||
ver: 0x62,
|
||||
'if': 0x63,
|
||||
notif: 0x64,
|
||||
else_: 0x67,
|
||||
verif: 0x65,
|
||||
vernotif: 0x66,
|
||||
'else': 0x67,
|
||||
endif: 0x68,
|
||||
verify: 0x69,
|
||||
ret: 0x6a,
|
||||
'return': 0x6a,
|
||||
|
||||
toaltstack: 0x6b,
|
||||
fromaltstack: 0x6c,
|
||||
'2drop': 0x6d,
|
||||
'2dup': 0x6e,
|
||||
'3dup': 0x6f,
|
||||
'2over': 0x70,
|
||||
'2rot': 0x71,
|
||||
'2swap': 0x72,
|
||||
ifdup: 0x73,
|
||||
depth: 0x74,
|
||||
drop: 0x75,
|
||||
@ -65,14 +97,8 @@ exports.opcodes = {
|
||||
rot: 0x7b,
|
||||
swap: 0x7c,
|
||||
tuck: 0x7d,
|
||||
drop2: 0x6d,
|
||||
dup2: 0x6e,
|
||||
dup3: 0x6f,
|
||||
over2: 0x70,
|
||||
rot2: 0x71,
|
||||
swap2: 0x72,
|
||||
|
||||
cat: 0x74,
|
||||
cat: 0x7e,
|
||||
substr: 0x7f,
|
||||
left: 0x80,
|
||||
right: 0x81,
|
||||
@ -82,17 +108,20 @@ exports.opcodes = {
|
||||
and: 0x84,
|
||||
or: 0x85,
|
||||
xor: 0x86,
|
||||
eq: 0x87,
|
||||
eqverify: 0x88,
|
||||
equal: 0x87,
|
||||
equalverify: 0x88,
|
||||
|
||||
add1: 0x8b,
|
||||
sub1: 0x8c,
|
||||
mul2: 0x8d,
|
||||
div2: 0x8e,
|
||||
reserved1: 0x89,
|
||||
reserved2: 0x8a,
|
||||
|
||||
'1add': 0x8b,
|
||||
'1sub': 0x8c,
|
||||
'2mul': 0x8d,
|
||||
'2div': 0x8e,
|
||||
negate: 0x8f,
|
||||
abs: 0x90,
|
||||
not: 0x91,
|
||||
noteq0: 0x92,
|
||||
'0notequal': 0x92,
|
||||
add: 0x93,
|
||||
sub: 0x94,
|
||||
mul: 0x95,
|
||||
@ -102,13 +131,13 @@ exports.opcodes = {
|
||||
rshift: 0x99,
|
||||
booland: 0x9a,
|
||||
boolor: 0x9b,
|
||||
numeq: 0x9c,
|
||||
numeqverify: 0x9d,
|
||||
numneq: 0x9e,
|
||||
lt: 0x9f,
|
||||
gt: 0xa0,
|
||||
lte: 0xa1,
|
||||
gte: 0xa2,
|
||||
numequal: 0x9c,
|
||||
numequalverify: 0x9d,
|
||||
numnotequal: 0x9e,
|
||||
lessthan: 0x9f,
|
||||
greaterthan: 0xa0,
|
||||
lessthanorequal: 0xa1,
|
||||
greaterthanorequal: 0xa2,
|
||||
min: 0xa3,
|
||||
max: 0xa4,
|
||||
within: 0xa5,
|
||||
@ -118,27 +147,36 @@ exports.opcodes = {
|
||||
sha256: 0xa8,
|
||||
hash160: 0xa9,
|
||||
hash256: 0xaa,
|
||||
codesep: 0xab,
|
||||
codeseparator: 0xab,
|
||||
checksig: 0xac,
|
||||
checksigverify: 0xad,
|
||||
checkmultisig: 0xae,
|
||||
checkmultisigverify: 0xaf,
|
||||
|
||||
eval_: 0xb0,
|
||||
checklocktimeverify: 0xb1
|
||||
// 'eval': 0xb0,
|
||||
nop1: 0xb0,
|
||||
// nop2: 0xb1,
|
||||
checklocktimeverify: 0xb1,
|
||||
nop3: 0xb2,
|
||||
nop4: 0xb3,
|
||||
nop5: 0xb4,
|
||||
nop6: 0xb5,
|
||||
nop7: 0xb6,
|
||||
nop8: 0xb7,
|
||||
nop9: 0xb8,
|
||||
nop10: 0xb9,
|
||||
|
||||
pubkeyhash: 0xfd,
|
||||
pubkey: 0xfe,
|
||||
invalidopcode: 0xff
|
||||
};
|
||||
|
||||
exports.opcodes['-1'] = 0x50 + -1;
|
||||
|
||||
for (i = 1; i <= 16; i++)
|
||||
exports.opcodes[i] = 0x50 + i;
|
||||
|
||||
for (i = 0; i <= 7; i++)
|
||||
exports.opcodes['nop' + (i + 3)] = 0xb2 + i;
|
||||
|
||||
exports.opcodesByVal = new Array(256);
|
||||
Object.keys(exports.opcodes).forEach(function(name) {
|
||||
exports.opcodesByVal[exports.opcodes[name]] = name;
|
||||
var val = exports.opcodes[name];
|
||||
// if (val === 0x00 || (val >= 0x51 && val <= 0x60))
|
||||
// name = +name;
|
||||
exports.opcodesByVal[val] = name;
|
||||
});
|
||||
|
||||
exports.hashType = {
|
||||
|
||||
@ -37,14 +37,18 @@ script.decode = function decode(s) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Zero
|
||||
if (b === 0) {
|
||||
// OP_0, OP_FALSE
|
||||
// Special case: this is an empty array
|
||||
// because it can be seen as an empty pushdata.
|
||||
if (b === 0x00) {
|
||||
opcodes.push([]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Raw number (-1 and 1-16)
|
||||
if (b === 0x4f || (b >= 0x51 && b <= 0x60)) {
|
||||
// OP_1, OP_TRUE, OP_2-OP_16
|
||||
// Special case: these get to be number
|
||||
// literals. Note: 1negate is not included.
|
||||
if (b >= 0x51 && b <= 0x60) {
|
||||
opcodes.push(b - 0x50);
|
||||
continue;
|
||||
}
|
||||
@ -126,8 +130,7 @@ script.encode = function encode(s) {
|
||||
continue;
|
||||
}
|
||||
if (instr.length === 0) {
|
||||
// OP_FALSE
|
||||
res.push(0);
|
||||
res.push(opcodes['0']);
|
||||
} else if (1 <= instr.length && instr.length <= 0x4b) {
|
||||
res = res.concat(instr.length, instr);
|
||||
} else if (instr.length <= 0xff) {
|
||||
@ -150,6 +153,47 @@ script.encode = function encode(s) {
|
||||
return res;
|
||||
};
|
||||
|
||||
script.normalize = function normalize(s) {
|
||||
var i, op;
|
||||
|
||||
// Remove OP_ prefixes and lowercase
|
||||
for (i = 0; i < s.length; i++) {
|
||||
op = s[i];
|
||||
if (typeof op === 'string') {
|
||||
op = op.toLowerCase();
|
||||
if (op.indexOf('op_') === 0)
|
||||
op = op.slice(3);
|
||||
}
|
||||
s[i] = op;
|
||||
}
|
||||
|
||||
// Convert OP_0 to array, convert OP_1-OP_16
|
||||
// to number literals, convert -1 to OP_1NEGATE.
|
||||
// Convert hex strings to arrays.
|
||||
for (i = 0; i < s.length; i++) {
|
||||
op = s[i];
|
||||
|
||||
if (op === '-1' || op === -1)
|
||||
op = '1negate';
|
||||
else if (op === '0' || op === 0 || op === 'false')
|
||||
op = [];
|
||||
else if (op === 'true')
|
||||
op = 1;
|
||||
else if (+op >= 1 && +op <= 16)
|
||||
op = +op;
|
||||
|
||||
if (typeof op === 'string' && constants.opcodes[op] == null) {
|
||||
if (op[0] === '[')
|
||||
op = op.slice(1, -1);
|
||||
op = utils.toArray(op, 'hex');
|
||||
}
|
||||
|
||||
s[i] = op;
|
||||
}
|
||||
|
||||
return s;
|
||||
};
|
||||
|
||||
script.verify = function verify(input, output, tx, i, flags) {
|
||||
var copy, res, redeem;
|
||||
var stack = [];
|
||||
@ -218,11 +262,11 @@ script.subscript = function subscript(s, lastSep) {
|
||||
if (lastSep == null)
|
||||
lastSep = -1;
|
||||
|
||||
assert(lastSep <= 0 || s[lastSep] === 'codesep');
|
||||
assert(lastSep <= 0 || s[lastSep] === 'codeseparator');
|
||||
|
||||
res = [];
|
||||
for (i = lastSep + 1; i < s.length; i++) {
|
||||
if (s[i] !== 'codesep')
|
||||
if (s[i] !== 'codeseparator')
|
||||
res.push(s[i]);
|
||||
}
|
||||
|
||||
@ -263,9 +307,9 @@ script._next = function _next(to, s, pc) {
|
||||
while (s[pc]) {
|
||||
o = s[pc];
|
||||
|
||||
if (o === 'if_' || o === 'notif')
|
||||
if (o === 'if' || o === 'notif')
|
||||
depth++;
|
||||
else if (o === 'else_')
|
||||
else if (o === 'else')
|
||||
depth--;
|
||||
else if (o === 'endif')
|
||||
depth--;
|
||||
@ -276,7 +320,7 @@ script._next = function _next(to, s, pc) {
|
||||
if (depth === 0 && o === to)
|
||||
return pc;
|
||||
|
||||
if (o === 'else_')
|
||||
if (o === 'else')
|
||||
depth++;
|
||||
|
||||
pc++;
|
||||
@ -319,7 +363,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (o === -1 || (o >= 1 && o <= 16)) {
|
||||
if (o >= 1 && o <= 16) {
|
||||
stack.push([o]);
|
||||
continue;
|
||||
}
|
||||
@ -336,7 +380,11 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
case 'nop10': {
|
||||
break;
|
||||
}
|
||||
case 'if_':
|
||||
case '1negate': {
|
||||
stack.push([-1]);
|
||||
break;
|
||||
}
|
||||
case 'if':
|
||||
case 'notif': {
|
||||
if (stack.length < 1)
|
||||
return false;
|
||||
@ -345,7 +393,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
if (o === 'notif')
|
||||
val = !val;
|
||||
if_ = pc;
|
||||
else_ = script._next('else_', s, pc);
|
||||
else_ = script._next('else', s, pc);
|
||||
endif = script._next('endif', s, pc);
|
||||
// Splice out the statement blocks we don't need
|
||||
if (val) {
|
||||
@ -372,7 +420,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
pc--;
|
||||
break;
|
||||
}
|
||||
case 'else_': {
|
||||
case 'else': {
|
||||
return false;
|
||||
}
|
||||
case 'endif': {
|
||||
@ -385,7 +433,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case 'ret': {
|
||||
case 'return': {
|
||||
return false;
|
||||
}
|
||||
case 'toaltstack': {
|
||||
@ -479,14 +527,14 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
stack.splice(stack.length - 2, 0, stack[stack.length - 1]);
|
||||
break;
|
||||
}
|
||||
case 'drop2': {
|
||||
case '2drop': {
|
||||
if (stack.length < 2)
|
||||
return false;
|
||||
stack.pop();
|
||||
stack.pop();
|
||||
break;
|
||||
}
|
||||
case 'dup2': {
|
||||
case '2dup': {
|
||||
if (stack.length < 2)
|
||||
return false;
|
||||
v1 = stack[stack.length - 2];
|
||||
@ -495,7 +543,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
stack.push(v2);
|
||||
break;
|
||||
}
|
||||
case 'dup3': {
|
||||
case '3dup': {
|
||||
if (stack.length < 3)
|
||||
return false;
|
||||
v1 = stack[stack.length - 3];
|
||||
@ -506,7 +554,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
stack.push(v3);
|
||||
break;
|
||||
}
|
||||
case 'over2': {
|
||||
case '2over': {
|
||||
if (stack.length < 4)
|
||||
return false;
|
||||
v1 = stack[stack.length - 4];
|
||||
@ -515,7 +563,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
stack.push(v2);
|
||||
break;
|
||||
}
|
||||
case 'rot2': {
|
||||
case '2rot': {
|
||||
if (stack.length < 6)
|
||||
return false;
|
||||
v1 = stack[stack.length - 6];
|
||||
@ -525,7 +573,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
stack.push(v2);
|
||||
break;
|
||||
}
|
||||
case 'swap2': {
|
||||
case '2swap': {
|
||||
if (stack.length < 4)
|
||||
return false;
|
||||
v4 = stack[stack.length - 4];
|
||||
@ -544,20 +592,20 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
stack.push(script.array(stack[stack.length - 1].length || 0));
|
||||
break;
|
||||
}
|
||||
case 'add1':
|
||||
case 'sub1':
|
||||
case '1add':
|
||||
case '1sub':
|
||||
case 'negate':
|
||||
case 'abs':
|
||||
case 'not':
|
||||
case 'noteq0': {
|
||||
case '0notequal': {
|
||||
if (stack.length < 1)
|
||||
return false;
|
||||
n = script.num(stack.pop());
|
||||
switch (o) {
|
||||
case 'add1':
|
||||
case '1add':
|
||||
n.iadd(1);
|
||||
break;
|
||||
case 'sub1':
|
||||
case '1sub':
|
||||
n.isub(1);
|
||||
break;
|
||||
case 'negate':
|
||||
@ -570,7 +618,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
case 'not':
|
||||
n = n.cmpn(0) === 0;
|
||||
break;
|
||||
case 'noteq0':
|
||||
case '0notequal':
|
||||
n = n.cmpn(0) !== 0;
|
||||
break;
|
||||
default:
|
||||
@ -585,13 +633,13 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
case 'sub':
|
||||
case 'booland':
|
||||
case 'boolor':
|
||||
case 'numeq':
|
||||
case 'numeqverify':
|
||||
case 'numneq':
|
||||
case 'lt':
|
||||
case 'gt':
|
||||
case 'lte':
|
||||
case 'gte':
|
||||
case 'numequal':
|
||||
case 'numequalverify':
|
||||
case 'numnotequal':
|
||||
case 'lessthan':
|
||||
case 'greaterthan':
|
||||
case 'lessthanorequal':
|
||||
case 'greaterthanorequal':
|
||||
case 'min':
|
||||
case 'max': {
|
||||
switch (o) {
|
||||
@ -599,13 +647,13 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
case 'sub':
|
||||
case 'booland':
|
||||
case 'boolor':
|
||||
case 'numeq':
|
||||
case 'numeqverify':
|
||||
case 'numneq':
|
||||
case 'lt':
|
||||
case 'gt':
|
||||
case 'lte':
|
||||
case 'gte':
|
||||
case 'numequal':
|
||||
case 'numequalverify':
|
||||
case 'numnotequal':
|
||||
case 'lessthan':
|
||||
case 'greaterthan':
|
||||
case 'lessthanorequal':
|
||||
case 'greaterthanorequal':
|
||||
case 'min':
|
||||
case 'max':
|
||||
if (stack.length < 2)
|
||||
@ -626,25 +674,25 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
case 'boolor':
|
||||
n = n1.cmpn(0) !== 0 || n2.cmpn(0) !== 0;
|
||||
break;
|
||||
case 'numeq':
|
||||
case 'numequal':
|
||||
n = n1.cmp(n2) === 0;
|
||||
break;
|
||||
case 'numeqverify':
|
||||
case 'numequalverify':
|
||||
n = n1.cmp(n2) === 0;
|
||||
break;
|
||||
case 'numneq':
|
||||
case 'numnotequal':
|
||||
n = n1.cmp(n2) !== 0;
|
||||
break;
|
||||
case 'lt':
|
||||
case 'lessthan':
|
||||
n = n1.cmp(n2) < 0;
|
||||
break;
|
||||
case 'gt':
|
||||
case 'greaterthan':
|
||||
n = n1.cmp(n2) > 0;
|
||||
break;
|
||||
case 'lte':
|
||||
case 'lessthanorequal':
|
||||
n = n1.cmp(n2) <= 0;
|
||||
break;
|
||||
case 'gte':
|
||||
case 'greaterthanorequal':
|
||||
n = n1.cmp(n2) >= 0;
|
||||
break;
|
||||
case 'min':
|
||||
@ -659,7 +707,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
if (typeof n === 'boolean')
|
||||
n = script.num(+n);
|
||||
res = n.cmpn(0) !== 0;
|
||||
if (o === 'numeqverify') {
|
||||
if (o === 'numequalverify') {
|
||||
if (!res)
|
||||
return false;
|
||||
} else {
|
||||
@ -679,7 +727,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
|
||||
break;
|
||||
}
|
||||
case 'codesep': {
|
||||
case 'codeseparator': {
|
||||
lastSep = pc;
|
||||
break;
|
||||
}
|
||||
@ -713,12 +761,12 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
stack.push(utils.ripesha(stack.pop()));
|
||||
break;
|
||||
}
|
||||
case 'eqverify':
|
||||
case 'eq': {
|
||||
case 'equalverify':
|
||||
case 'equal': {
|
||||
if (stack.length < 2)
|
||||
return false;
|
||||
res = utils.isEqual(stack.pop(), stack.pop());
|
||||
if (o === 'eqverify') {
|
||||
if (o === 'equalverify') {
|
||||
if (!res)
|
||||
return false;
|
||||
} else {
|
||||
@ -886,7 +934,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
|
||||
break;
|
||||
}
|
||||
case 'eval_': {
|
||||
case 'nop1': {
|
||||
// OP_EVAL = OP_NOP1
|
||||
if (!flags.allowEval)
|
||||
break;
|
||||
@ -904,7 +952,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
|
||||
evalScript = script.decode(evalScript);
|
||||
|
||||
res = evalScript.some(function(op) {
|
||||
return op === 'codesep';
|
||||
return op === 'codeseparator';
|
||||
});
|
||||
|
||||
if (res)
|
||||
@ -1023,7 +1071,7 @@ script.checkPush = function checkPush(op, value) {
|
||||
return op >= constants.opcodes['1'] && op <= constants.opcodes['16'];
|
||||
|
||||
if (value.length === 1 && value[0] === -1)
|
||||
return op === constants.opcodes['-1'];
|
||||
return op === constants.opcodes['1negate'];
|
||||
|
||||
if (value.length <= 75)
|
||||
return op === value.length;
|
||||
@ -1037,24 +1085,26 @@ script.checkPush = function checkPush(op, value) {
|
||||
return true;
|
||||
};
|
||||
|
||||
script.redeem = function redeem(keys, m, n) {
|
||||
script.createMultisig = function createMultisig(keys, m, 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 multisig script');
|
||||
|
||||
assert(m >= 1 && m <= n);
|
||||
assert(n >= 1 && n <= 15);
|
||||
|
||||
while (keys.length < n)
|
||||
keys.push([]);
|
||||
|
||||
keys = utils.sortKeys(keys);
|
||||
|
||||
return [m].concat(
|
||||
keys,
|
||||
utils.sortKeys(keys),
|
||||
[n, 'checkmultisig']
|
||||
);
|
||||
};
|
||||
|
||||
script.redeem = function redeem(s) {
|
||||
if (!Array.isArray(s[s.length - 1]))
|
||||
return;
|
||||
|
||||
return bcoin.script.decode(s[s.length - 1]);
|
||||
};
|
||||
|
||||
script.standard = function standard(s) {
|
||||
return (script.isPubkey(s) && 'pubkey')
|
||||
|| (script.isPubkeyhash(s) && 'pubkeyhash')
|
||||
@ -1099,7 +1149,7 @@ script.isLockTime = function isLockTime(s, check) {
|
||||
&& Array.isArray(s[0])
|
||||
&& s[1] === 'checklocktimeverify'
|
||||
&& s[2] === 'drop'
|
||||
&& s[3] === 'codesep';
|
||||
&& s[3] === 'codeseparator';
|
||||
};
|
||||
|
||||
script.lockTime = function lockTime(s) {
|
||||
@ -1292,7 +1342,7 @@ script.isPubkeyhash = function isPubkeyhash(s, hash) {
|
||||
res = s[0] === 'dup'
|
||||
&& s[1] === 'hash160'
|
||||
&& script.isHash(s[2])
|
||||
&& s[3] === 'eqverify'
|
||||
&& s[3] === 'equalverify'
|
||||
&& s[4] === 'checksig';
|
||||
|
||||
if (!res)
|
||||
@ -1386,7 +1436,7 @@ script.isScripthash = function isScripthash(s, hash) {
|
||||
|
||||
res = s[0] === 'hash160'
|
||||
&& script.isHash(s[1])
|
||||
&& s[2] === 'eq';
|
||||
&& s[2] === 'equal';
|
||||
|
||||
if (!res)
|
||||
return false;
|
||||
@ -1405,7 +1455,7 @@ script.isNulldata = function isNulldata(s) {
|
||||
if (s.length !== 2)
|
||||
return false;
|
||||
|
||||
res = s[0] === 'ret' && script.isData(s[1]);
|
||||
res = s[0] === 'return' && script.isData(s[1]);
|
||||
|
||||
if (!res)
|
||||
return false;
|
||||
@ -1485,7 +1535,7 @@ script.isMultisigInput = function isMultisigInput(s, keys, tx, i) {
|
||||
assert(keys.length >= 2);
|
||||
assert(tx);
|
||||
assert(i != null);
|
||||
o = script.redeem(keys, s.length - 1, keys.length);
|
||||
o = script.createMultisig(keys, s.length - 1, keys.length);
|
||||
if (!script.verify(s, o, tx, i))
|
||||
return false;
|
||||
}
|
||||
@ -1494,7 +1544,7 @@ script.isMultisigInput = function isMultisigInput(s, keys, tx, i) {
|
||||
// var recovered = [];
|
||||
// for (i = 1; i < s.length; i++) {
|
||||
// var sig = s[i];
|
||||
// var prev = script.redeem(keys, s.length - 1, keys.length);
|
||||
// var prev = script.createMultisig(keys, s.length - 1, keys.length);
|
||||
// var msg = tx.signatureHash(i, prev, s[s.length - 1]);
|
||||
// var key = bcoin.ecdsa.recoverPubKey(msg, sig.slice(0, -1), 0).toArray();
|
||||
// recovered.push(key);
|
||||
@ -1889,9 +1939,7 @@ script.pushOnly = function pushOnly(s) {
|
||||
var i, op;
|
||||
for (i = 0; i < s.length; i++) {
|
||||
op = s[i];
|
||||
// if (Array.isArray(op) || (constants.opcodes[op] <= constants.opcodes['16']))
|
||||
// continue;
|
||||
if (Array.isArray(op) || (op >= -1 && op <= 16))
|
||||
if (Array.isArray(op) || op === '1negate' || (op >= 1 && op <= 16))
|
||||
continue;
|
||||
if (constants.opcodes[op] == null)
|
||||
return false;
|
||||
|
||||
@ -450,68 +450,6 @@ TX.prototype.signInput = function signInput(index, key, type) {
|
||||
return signatures === m;
|
||||
};
|
||||
|
||||
TX.prototype.prevOut = function outputScript(i) {
|
||||
var input;
|
||||
|
||||
if (typeof i !== 'number')
|
||||
i = this.inputs.indexOf(i);
|
||||
|
||||
input = this.inputs[i];
|
||||
|
||||
if (!input.out.tx)
|
||||
return;
|
||||
|
||||
return input.out.tx.outputs[input.out.index];
|
||||
};
|
||||
|
||||
TX.prototype.outputScript = function outputScript(i) {
|
||||
var output = this.prevOut(i);
|
||||
if (!output)
|
||||
return;
|
||||
return output.script;
|
||||
};
|
||||
|
||||
bcoin.script.redeemScript = function redeemScript(s) {
|
||||
if (!Array.isArray(s[s.length - 1]))
|
||||
return;
|
||||
|
||||
return bcoin.script.decode(s[s.length - 1]);
|
||||
};
|
||||
|
||||
TX.prototype.redeemScript = function redeemScript(i) {
|
||||
var input, prev;
|
||||
|
||||
if (typeof i !== 'number')
|
||||
i = this.inputs.indexOf(i);
|
||||
|
||||
input = this.inputs[i];
|
||||
prev = this.outputScript(i);
|
||||
|
||||
if (prev && bcoin.script.isScripthash(prev))
|
||||
return bcoin.script.redeemScript(input.script);
|
||||
|
||||
return prev;
|
||||
};
|
||||
|
||||
TX.prototype.finalize = function finalize() {
|
||||
var i, input, s, len, j;
|
||||
for (i = 0; i < this.inputs.length; i++) {
|
||||
input = this.inputs[i];
|
||||
s = input.out.tx.getSubscript(input.out.index);
|
||||
len = s.length;
|
||||
|
||||
if (bcoin.script.isScripthash(s))
|
||||
len--;
|
||||
|
||||
for (j = len - 1; j >= 1; j--) {
|
||||
if (bcoin.script.isEmpty(input.script[j])) {
|
||||
input.script.splice(j, 1);
|
||||
len--;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TX.prototype.scriptSig = function scriptSig(index, key, pub, redeem, type) {
|
||||
var input;
|
||||
|
||||
@ -621,7 +559,7 @@ TX.prototype.scriptOutput = function scriptOutput(index, options) {
|
||||
if (!(n >= 1 && n <= (options.scripthash ? 15 : 3)))
|
||||
return;
|
||||
|
||||
script = bcoin.script.redeem(keys, m, n);
|
||||
script = bcoin.script.createMultisig(keys, m, n);
|
||||
} else if (bcoin.wallet.validateAddress(options.address, 'scripthash')) {
|
||||
// P2SH Transaction
|
||||
// https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki
|
||||
@ -629,7 +567,7 @@ TX.prototype.scriptOutput = function scriptOutput(index, options) {
|
||||
script = [
|
||||
'hash160',
|
||||
bcoin.wallet.addr2hash(options.address, 'scripthash'),
|
||||
'eq'
|
||||
'equal'
|
||||
];
|
||||
} else if (options.address) {
|
||||
// P2PKH Transaction
|
||||
@ -638,7 +576,7 @@ TX.prototype.scriptOutput = function scriptOutput(index, options) {
|
||||
'dup',
|
||||
'hash160',
|
||||
bcoin.wallet.addr2hash(options.address, 'pubkeyhash'),
|
||||
'eqverify',
|
||||
'equalverify',
|
||||
'checksig'
|
||||
];
|
||||
} else if (options.key) {
|
||||
@ -650,14 +588,14 @@ TX.prototype.scriptOutput = function scriptOutput(index, options) {
|
||||
];
|
||||
} else if (options.flags) {
|
||||
// Nulldata Transaction
|
||||
// ret [data]
|
||||
// return [data]
|
||||
flags = options.flags;
|
||||
if (typeof flags === 'string')
|
||||
flags = utils.ascii2array(flags);
|
||||
assert(utils.isBuffer(flags));
|
||||
assert(flags.length <= constants.script.maxOpReturn);
|
||||
script = [
|
||||
'ret',
|
||||
'return',
|
||||
flags
|
||||
];
|
||||
}
|
||||
@ -670,14 +608,14 @@ TX.prototype.scriptOutput = function scriptOutput(index, options) {
|
||||
bcoin.script.array(options.lock),
|
||||
'checklocktimeverify',
|
||||
'drop',
|
||||
'codesep'
|
||||
'codeseparator'
|
||||
].concat(script);
|
||||
}
|
||||
hash = utils.ripesha(bcoin.script.encode(script));
|
||||
script = [
|
||||
'hash160',
|
||||
hash,
|
||||
'eq'
|
||||
'equal'
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@ -261,12 +261,14 @@ Wallet.prototype.getScript = function getScript() {
|
||||
'dup',
|
||||
'hash160',
|
||||
this.getKeyHash(),
|
||||
'eqverify',
|
||||
'equalverify',
|
||||
'checksig'
|
||||
]);
|
||||
}
|
||||
|
||||
return bcoin.script.encode(bcoin.script.redeem(this.keys, this.m, this.n));
|
||||
return bcoin.script.encode(
|
||||
bcoin.script.createMultisig(this.keys, this.m, this.n)
|
||||
);
|
||||
};
|
||||
|
||||
Wallet.prototype.getScriptHash = function getScriptHash() {
|
||||
|
||||
@ -47,7 +47,7 @@ describe('Script', function() {
|
||||
|
||||
it('should handle if statements correctly', function () {
|
||||
var inputScript = [1, 2];
|
||||
var prevOutScript = [2, 'eq', 'if_', 3, 'else_', 4, 'endif', 5];
|
||||
var prevOutScript = [2, 'equal', 'if', 3, 'else', 4, 'endif', 5];
|
||||
var stack = [];
|
||||
bcoin.script.execute(inputScript, stack);
|
||||
var res = bcoin.script.execute(prevOutScript, stack);
|
||||
@ -55,7 +55,7 @@ describe('Script', function() {
|
||||
assert.deepEqual(stack.slice(), [[1], [3], [5]]);
|
||||
|
||||
var inputScript = [1, 2];
|
||||
var prevOutScript = [9, 'eq', 'if_', 3, 'else_', 4, 'endif', 5];
|
||||
var prevOutScript = [9, 'equal', 'if', 3, 'else', 4, 'endif', 5];
|
||||
var stack = [];
|
||||
bcoin.script.execute(inputScript, stack);
|
||||
var res = bcoin.script.execute(prevOutScript, stack);
|
||||
@ -63,7 +63,7 @@ describe('Script', function() {
|
||||
assert.deepEqual(stack.slice(), [[1], [4], [5]]);
|
||||
|
||||
var inputScript = [1, 2];
|
||||
var prevOutScript = [2, 'eq', 'if_', 3, 'endif', 5];
|
||||
var prevOutScript = [2, 'equal', 'if', 3, 'endif', 5];
|
||||
var stack = [];
|
||||
bcoin.script.execute(inputScript, stack);
|
||||
var res = bcoin.script.execute(prevOutScript, stack);
|
||||
@ -71,7 +71,7 @@ describe('Script', function() {
|
||||
assert.deepEqual(stack.slice(), [[1], [3], [5]]);
|
||||
|
||||
var inputScript = [1, 2];
|
||||
var prevOutScript = [9, 'eq', 'if_', 3, 'endif', 5];
|
||||
var prevOutScript = [9, 'equal', 'if', 3, 'endif', 5];
|
||||
var stack = [];
|
||||
bcoin.script.execute(inputScript, stack);
|
||||
var res = bcoin.script.execute(prevOutScript, stack);
|
||||
@ -79,7 +79,7 @@ describe('Script', function() {
|
||||
assert.deepEqual(stack.slice(), [[1], [5]]);
|
||||
|
||||
var inputScript = [1, 2];
|
||||
var prevOutScript = [9, 'eq', 'notif', 3, 'endif', 5];
|
||||
var prevOutScript = [9, 'equal', 'notif', 3, 'endif', 5];
|
||||
var stack = [];
|
||||
bcoin.script.execute(inputScript, stack);
|
||||
var res = bcoin.script.execute(prevOutScript, stack);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user