standard opcodes. remove tx methods.

This commit is contained in:
Christopher Jeffrey 2016-01-17 15:01:22 -08:00
parent 6f4609792f
commit 3745577837
5 changed files with 214 additions and 188 deletions

View File

@ -38,22 +38,54 @@ exports.filterFlags = {
}; };
exports.opcodes = { exports.opcodes = {
0: 0, // 'false': 0x00,
'0': 0x00,
pushdata1: 0x4c, pushdata1: 0x4c,
pushdata2: 0x4d, pushdata2: 0x4d,
pushdata4: 0x4e, 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, nop: 0x61,
if_: 0x63, ver: 0x62,
'if': 0x63,
notif: 0x64, notif: 0x64,
else_: 0x67, verif: 0x65,
vernotif: 0x66,
'else': 0x67,
endif: 0x68, endif: 0x68,
verify: 0x69, verify: 0x69,
ret: 0x6a, 'return': 0x6a,
toaltstack: 0x6b, toaltstack: 0x6b,
fromaltstack: 0x6c, fromaltstack: 0x6c,
'2drop': 0x6d,
'2dup': 0x6e,
'3dup': 0x6f,
'2over': 0x70,
'2rot': 0x71,
'2swap': 0x72,
ifdup: 0x73, ifdup: 0x73,
depth: 0x74, depth: 0x74,
drop: 0x75, drop: 0x75,
@ -65,14 +97,8 @@ exports.opcodes = {
rot: 0x7b, rot: 0x7b,
swap: 0x7c, swap: 0x7c,
tuck: 0x7d, tuck: 0x7d,
drop2: 0x6d,
dup2: 0x6e,
dup3: 0x6f,
over2: 0x70,
rot2: 0x71,
swap2: 0x72,
cat: 0x74, cat: 0x7e,
substr: 0x7f, substr: 0x7f,
left: 0x80, left: 0x80,
right: 0x81, right: 0x81,
@ -82,17 +108,20 @@ exports.opcodes = {
and: 0x84, and: 0x84,
or: 0x85, or: 0x85,
xor: 0x86, xor: 0x86,
eq: 0x87, equal: 0x87,
eqverify: 0x88, equalverify: 0x88,
add1: 0x8b, reserved1: 0x89,
sub1: 0x8c, reserved2: 0x8a,
mul2: 0x8d,
div2: 0x8e, '1add': 0x8b,
'1sub': 0x8c,
'2mul': 0x8d,
'2div': 0x8e,
negate: 0x8f, negate: 0x8f,
abs: 0x90, abs: 0x90,
not: 0x91, not: 0x91,
noteq0: 0x92, '0notequal': 0x92,
add: 0x93, add: 0x93,
sub: 0x94, sub: 0x94,
mul: 0x95, mul: 0x95,
@ -102,13 +131,13 @@ exports.opcodes = {
rshift: 0x99, rshift: 0x99,
booland: 0x9a, booland: 0x9a,
boolor: 0x9b, boolor: 0x9b,
numeq: 0x9c, numequal: 0x9c,
numeqverify: 0x9d, numequalverify: 0x9d,
numneq: 0x9e, numnotequal: 0x9e,
lt: 0x9f, lessthan: 0x9f,
gt: 0xa0, greaterthan: 0xa0,
lte: 0xa1, lessthanorequal: 0xa1,
gte: 0xa2, greaterthanorequal: 0xa2,
min: 0xa3, min: 0xa3,
max: 0xa4, max: 0xa4,
within: 0xa5, within: 0xa5,
@ -118,27 +147,36 @@ exports.opcodes = {
sha256: 0xa8, sha256: 0xa8,
hash160: 0xa9, hash160: 0xa9,
hash256: 0xaa, hash256: 0xaa,
codesep: 0xab, codeseparator: 0xab,
checksig: 0xac, checksig: 0xac,
checksigverify: 0xad, checksigverify: 0xad,
checkmultisig: 0xae, checkmultisig: 0xae,
checkmultisigverify: 0xaf, checkmultisigverify: 0xaf,
eval_: 0xb0, // 'eval': 0xb0,
checklocktimeverify: 0xb1 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); exports.opcodesByVal = new Array(256);
Object.keys(exports.opcodes).forEach(function(name) { 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 = { exports.hashType = {

View File

@ -37,14 +37,18 @@ script.decode = function decode(s) {
continue; continue;
} }
// Zero // OP_0, OP_FALSE
if (b === 0) { // Special case: this is an empty array
// because it can be seen as an empty pushdata.
if (b === 0x00) {
opcodes.push([]); opcodes.push([]);
continue; continue;
} }
// Raw number (-1 and 1-16) // OP_1, OP_TRUE, OP_2-OP_16
if (b === 0x4f || (b >= 0x51 && b <= 0x60)) { // Special case: these get to be number
// literals. Note: 1negate is not included.
if (b >= 0x51 && b <= 0x60) {
opcodes.push(b - 0x50); opcodes.push(b - 0x50);
continue; continue;
} }
@ -126,8 +130,7 @@ script.encode = function encode(s) {
continue; continue;
} }
if (instr.length === 0) { if (instr.length === 0) {
// OP_FALSE res.push(opcodes['0']);
res.push(0);
} else if (1 <= instr.length && instr.length <= 0x4b) { } else if (1 <= instr.length && instr.length <= 0x4b) {
res = res.concat(instr.length, instr); res = res.concat(instr.length, instr);
} else if (instr.length <= 0xff) { } else if (instr.length <= 0xff) {
@ -150,6 +153,47 @@ script.encode = function encode(s) {
return res; 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) { script.verify = function verify(input, output, tx, i, flags) {
var copy, res, redeem; var copy, res, redeem;
var stack = []; var stack = [];
@ -218,11 +262,11 @@ script.subscript = function subscript(s, lastSep) {
if (lastSep == null) if (lastSep == null)
lastSep = -1; lastSep = -1;
assert(lastSep <= 0 || s[lastSep] === 'codesep'); assert(lastSep <= 0 || s[lastSep] === 'codeseparator');
res = []; res = [];
for (i = lastSep + 1; i < s.length; i++) { for (i = lastSep + 1; i < s.length; i++) {
if (s[i] !== 'codesep') if (s[i] !== 'codeseparator')
res.push(s[i]); res.push(s[i]);
} }
@ -263,9 +307,9 @@ script._next = function _next(to, s, pc) {
while (s[pc]) { while (s[pc]) {
o = s[pc]; o = s[pc];
if (o === 'if_' || o === 'notif') if (o === 'if' || o === 'notif')
depth++; depth++;
else if (o === 'else_') else if (o === 'else')
depth--; depth--;
else if (o === 'endif') else if (o === 'endif')
depth--; depth--;
@ -276,7 +320,7 @@ script._next = function _next(to, s, pc) {
if (depth === 0 && o === to) if (depth === 0 && o === to)
return pc; return pc;
if (o === 'else_') if (o === 'else')
depth++; depth++;
pc++; pc++;
@ -319,7 +363,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
continue; continue;
} }
if (o === -1 || (o >= 1 && o <= 16)) { if (o >= 1 && o <= 16) {
stack.push([o]); stack.push([o]);
continue; continue;
} }
@ -336,7 +380,11 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
case 'nop10': { case 'nop10': {
break; break;
} }
case 'if_': case '1negate': {
stack.push([-1]);
break;
}
case 'if':
case 'notif': { case 'notif': {
if (stack.length < 1) if (stack.length < 1)
return false; return false;
@ -345,7 +393,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
if (o === 'notif') if (o === 'notif')
val = !val; val = !val;
if_ = pc; if_ = pc;
else_ = script._next('else_', s, pc); else_ = script._next('else', s, pc);
endif = script._next('endif', s, pc); endif = script._next('endif', s, pc);
// Splice out the statement blocks we don't need // Splice out the statement blocks we don't need
if (val) { if (val) {
@ -372,7 +420,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
pc--; pc--;
break; break;
} }
case 'else_': { case 'else': {
return false; return false;
} }
case 'endif': { case 'endif': {
@ -385,7 +433,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
return false; return false;
break; break;
} }
case 'ret': { case 'return': {
return false; return false;
} }
case 'toaltstack': { 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]); stack.splice(stack.length - 2, 0, stack[stack.length - 1]);
break; break;
} }
case 'drop2': { case '2drop': {
if (stack.length < 2) if (stack.length < 2)
return false; return false;
stack.pop(); stack.pop();
stack.pop(); stack.pop();
break; break;
} }
case 'dup2': { case '2dup': {
if (stack.length < 2) if (stack.length < 2)
return false; return false;
v1 = stack[stack.length - 2]; v1 = stack[stack.length - 2];
@ -495,7 +543,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
stack.push(v2); stack.push(v2);
break; break;
} }
case 'dup3': { case '3dup': {
if (stack.length < 3) if (stack.length < 3)
return false; return false;
v1 = stack[stack.length - 3]; v1 = stack[stack.length - 3];
@ -506,7 +554,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
stack.push(v3); stack.push(v3);
break; break;
} }
case 'over2': { case '2over': {
if (stack.length < 4) if (stack.length < 4)
return false; return false;
v1 = stack[stack.length - 4]; v1 = stack[stack.length - 4];
@ -515,7 +563,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
stack.push(v2); stack.push(v2);
break; break;
} }
case 'rot2': { case '2rot': {
if (stack.length < 6) if (stack.length < 6)
return false; return false;
v1 = stack[stack.length - 6]; v1 = stack[stack.length - 6];
@ -525,7 +573,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
stack.push(v2); stack.push(v2);
break; break;
} }
case 'swap2': { case '2swap': {
if (stack.length < 4) if (stack.length < 4)
return false; return false;
v4 = stack[stack.length - 4]; 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)); stack.push(script.array(stack[stack.length - 1].length || 0));
break; break;
} }
case 'add1': case '1add':
case 'sub1': case '1sub':
case 'negate': case 'negate':
case 'abs': case 'abs':
case 'not': case 'not':
case 'noteq0': { case '0notequal': {
if (stack.length < 1) if (stack.length < 1)
return false; return false;
n = script.num(stack.pop()); n = script.num(stack.pop());
switch (o) { switch (o) {
case 'add1': case '1add':
n.iadd(1); n.iadd(1);
break; break;
case 'sub1': case '1sub':
n.isub(1); n.isub(1);
break; break;
case 'negate': case 'negate':
@ -570,7 +618,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
case 'not': case 'not':
n = n.cmpn(0) === 0; n = n.cmpn(0) === 0;
break; break;
case 'noteq0': case '0notequal':
n = n.cmpn(0) !== 0; n = n.cmpn(0) !== 0;
break; break;
default: default:
@ -585,13 +633,13 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
case 'sub': case 'sub':
case 'booland': case 'booland':
case 'boolor': case 'boolor':
case 'numeq': case 'numequal':
case 'numeqverify': case 'numequalverify':
case 'numneq': case 'numnotequal':
case 'lt': case 'lessthan':
case 'gt': case 'greaterthan':
case 'lte': case 'lessthanorequal':
case 'gte': case 'greaterthanorequal':
case 'min': case 'min':
case 'max': { case 'max': {
switch (o) { switch (o) {
@ -599,13 +647,13 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
case 'sub': case 'sub':
case 'booland': case 'booland':
case 'boolor': case 'boolor':
case 'numeq': case 'numequal':
case 'numeqverify': case 'numequalverify':
case 'numneq': case 'numnotequal':
case 'lt': case 'lessthan':
case 'gt': case 'greaterthan':
case 'lte': case 'lessthanorequal':
case 'gte': case 'greaterthanorequal':
case 'min': case 'min':
case 'max': case 'max':
if (stack.length < 2) if (stack.length < 2)
@ -626,25 +674,25 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
case 'boolor': case 'boolor':
n = n1.cmpn(0) !== 0 || n2.cmpn(0) !== 0; n = n1.cmpn(0) !== 0 || n2.cmpn(0) !== 0;
break; break;
case 'numeq': case 'numequal':
n = n1.cmp(n2) === 0; n = n1.cmp(n2) === 0;
break; break;
case 'numeqverify': case 'numequalverify':
n = n1.cmp(n2) === 0; n = n1.cmp(n2) === 0;
break; break;
case 'numneq': case 'numnotequal':
n = n1.cmp(n2) !== 0; n = n1.cmp(n2) !== 0;
break; break;
case 'lt': case 'lessthan':
n = n1.cmp(n2) < 0; n = n1.cmp(n2) < 0;
break; break;
case 'gt': case 'greaterthan':
n = n1.cmp(n2) > 0; n = n1.cmp(n2) > 0;
break; break;
case 'lte': case 'lessthanorequal':
n = n1.cmp(n2) <= 0; n = n1.cmp(n2) <= 0;
break; break;
case 'gte': case 'greaterthanorequal':
n = n1.cmp(n2) >= 0; n = n1.cmp(n2) >= 0;
break; break;
case 'min': case 'min':
@ -659,7 +707,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
if (typeof n === 'boolean') if (typeof n === 'boolean')
n = script.num(+n); n = script.num(+n);
res = n.cmpn(0) !== 0; res = n.cmpn(0) !== 0;
if (o === 'numeqverify') { if (o === 'numequalverify') {
if (!res) if (!res)
return false; return false;
} else { } else {
@ -679,7 +727,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
break; break;
} }
case 'codesep': { case 'codeseparator': {
lastSep = pc; lastSep = pc;
break; break;
} }
@ -713,12 +761,12 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
stack.push(utils.ripesha(stack.pop())); stack.push(utils.ripesha(stack.pop()));
break; break;
} }
case 'eqverify': case 'equalverify':
case 'eq': { case 'equal': {
if (stack.length < 2) if (stack.length < 2)
return false; return false;
res = utils.isEqual(stack.pop(), stack.pop()); res = utils.isEqual(stack.pop(), stack.pop());
if (o === 'eqverify') { if (o === 'equalverify') {
if (!res) if (!res)
return false; return false;
} else { } else {
@ -886,7 +934,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
break; break;
} }
case 'eval_': { case 'nop1': {
// OP_EVAL = OP_NOP1 // OP_EVAL = OP_NOP1
if (!flags.allowEval) if (!flags.allowEval)
break; break;
@ -904,7 +952,7 @@ script.execute = function execute(data, stack, tx, index, flags, recurse) {
evalScript = script.decode(evalScript); evalScript = script.decode(evalScript);
res = evalScript.some(function(op) { res = evalScript.some(function(op) {
return op === 'codesep'; return op === 'codeseparator';
}); });
if (res) if (res)
@ -1023,7 +1071,7 @@ script.checkPush = function checkPush(op, value) {
return op >= constants.opcodes['1'] && op <= constants.opcodes['16']; return op >= constants.opcodes['1'] && op <= constants.opcodes['16'];
if (value.length === 1 && value[0] === -1) if (value.length === 1 && value[0] === -1)
return op === constants.opcodes['-1']; return op === constants.opcodes['1negate'];
if (value.length <= 75) if (value.length <= 75)
return op === value.length; return op === value.length;
@ -1037,24 +1085,26 @@ script.checkPush = function checkPush(op, value) {
return true; return true;
}; };
script.redeem = function redeem(keys, m, n) { script.createMultisig = function createMultisig(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 multisig script');
assert(m >= 1 && m <= n); assert(m >= 1 && m <= n);
assert(n >= 1 && n <= 15); assert(n >= 1 && n <= 15);
while (keys.length < n)
keys.push([]);
keys = utils.sortKeys(keys);
return [m].concat( return [m].concat(
keys, utils.sortKeys(keys),
[n, 'checkmultisig'] [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) { script.standard = function standard(s) {
return (script.isPubkey(s) && 'pubkey') return (script.isPubkey(s) && 'pubkey')
|| (script.isPubkeyhash(s) && 'pubkeyhash') || (script.isPubkeyhash(s) && 'pubkeyhash')
@ -1099,7 +1149,7 @@ script.isLockTime = function isLockTime(s, check) {
&& Array.isArray(s[0]) && Array.isArray(s[0])
&& s[1] === 'checklocktimeverify' && s[1] === 'checklocktimeverify'
&& s[2] === 'drop' && s[2] === 'drop'
&& s[3] === 'codesep'; && s[3] === 'codeseparator';
}; };
script.lockTime = function lockTime(s) { script.lockTime = function lockTime(s) {
@ -1292,7 +1342,7 @@ script.isPubkeyhash = function isPubkeyhash(s, hash) {
res = s[0] === 'dup' res = s[0] === 'dup'
&& s[1] === 'hash160' && s[1] === 'hash160'
&& script.isHash(s[2]) && script.isHash(s[2])
&& s[3] === 'eqverify' && s[3] === 'equalverify'
&& s[4] === 'checksig'; && s[4] === 'checksig';
if (!res) if (!res)
@ -1386,7 +1436,7 @@ script.isScripthash = function isScripthash(s, hash) {
res = s[0] === 'hash160' res = s[0] === 'hash160'
&& script.isHash(s[1]) && script.isHash(s[1])
&& s[2] === 'eq'; && s[2] === 'equal';
if (!res) if (!res)
return false; return false;
@ -1405,7 +1455,7 @@ script.isNulldata = function isNulldata(s) {
if (s.length !== 2) if (s.length !== 2)
return false; return false;
res = s[0] === 'ret' && script.isData(s[1]); res = s[0] === 'return' && script.isData(s[1]);
if (!res) if (!res)
return false; return false;
@ -1485,7 +1535,7 @@ script.isMultisigInput = function isMultisigInput(s, keys, tx, i) {
assert(keys.length >= 2); assert(keys.length >= 2);
assert(tx); assert(tx);
assert(i != null); 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)) if (!script.verify(s, o, tx, i))
return false; return false;
} }
@ -1494,7 +1544,7 @@ script.isMultisigInput = function isMultisigInput(s, keys, tx, i) {
// var recovered = []; // var recovered = [];
// for (i = 1; i < s.length; i++) { // for (i = 1; i < s.length; i++) {
// var sig = s[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 msg = tx.signatureHash(i, prev, s[s.length - 1]);
// var key = bcoin.ecdsa.recoverPubKey(msg, sig.slice(0, -1), 0).toArray(); // var key = bcoin.ecdsa.recoverPubKey(msg, sig.slice(0, -1), 0).toArray();
// recovered.push(key); // recovered.push(key);
@ -1889,9 +1939,7 @@ 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) || (constants.opcodes[op] <= constants.opcodes['16'])) if (Array.isArray(op) || op === '1negate' || (op >= 1 && op <= 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;

View File

@ -450,68 +450,6 @@ TX.prototype.signInput = function signInput(index, key, type) {
return signatures === m; 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) { TX.prototype.scriptSig = function scriptSig(index, key, pub, redeem, type) {
var input; var input;
@ -621,7 +559,7 @@ TX.prototype.scriptOutput = function scriptOutput(index, options) {
if (!(n >= 1 && n <= (options.scripthash ? 15 : 3))) if (!(n >= 1 && n <= (options.scripthash ? 15 : 3)))
return; return;
script = bcoin.script.redeem(keys, m, n); script = bcoin.script.createMultisig(keys, m, n);
} else if (bcoin.wallet.validateAddress(options.address, 'scripthash')) { } else if (bcoin.wallet.validateAddress(options.address, 'scripthash')) {
// P2SH Transaction // P2SH Transaction
// https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki // https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki
@ -629,7 +567,7 @@ TX.prototype.scriptOutput = function scriptOutput(index, options) {
script = [ script = [
'hash160', 'hash160',
bcoin.wallet.addr2hash(options.address, 'scripthash'), bcoin.wallet.addr2hash(options.address, 'scripthash'),
'eq' 'equal'
]; ];
} else if (options.address) { } else if (options.address) {
// P2PKH Transaction // P2PKH Transaction
@ -638,7 +576,7 @@ TX.prototype.scriptOutput = function scriptOutput(index, options) {
'dup', 'dup',
'hash160', 'hash160',
bcoin.wallet.addr2hash(options.address, 'pubkeyhash'), bcoin.wallet.addr2hash(options.address, 'pubkeyhash'),
'eqverify', 'equalverify',
'checksig' 'checksig'
]; ];
} else if (options.key) { } else if (options.key) {
@ -650,14 +588,14 @@ TX.prototype.scriptOutput = function scriptOutput(index, options) {
]; ];
} else if (options.flags) { } else if (options.flags) {
// Nulldata Transaction // Nulldata Transaction
// ret [data] // return [data]
flags = options.flags; flags = options.flags;
if (typeof flags === 'string') if (typeof flags === 'string')
flags = utils.ascii2array(flags); flags = utils.ascii2array(flags);
assert(utils.isBuffer(flags)); assert(utils.isBuffer(flags));
assert(flags.length <= constants.script.maxOpReturn); assert(flags.length <= constants.script.maxOpReturn);
script = [ script = [
'ret', 'return',
flags flags
]; ];
} }
@ -670,14 +608,14 @@ TX.prototype.scriptOutput = function scriptOutput(index, options) {
bcoin.script.array(options.lock), bcoin.script.array(options.lock),
'checklocktimeverify', 'checklocktimeverify',
'drop', 'drop',
'codesep' 'codeseparator'
].concat(script); ].concat(script);
} }
hash = utils.ripesha(bcoin.script.encode(script)); hash = utils.ripesha(bcoin.script.encode(script));
script = [ script = [
'hash160', 'hash160',
hash, hash,
'eq' 'equal'
]; ];
} }

View File

@ -261,12 +261,14 @@ Wallet.prototype.getScript = function getScript() {
'dup', 'dup',
'hash160', 'hash160',
this.getKeyHash(), this.getKeyHash(),
'eqverify', 'equalverify',
'checksig' '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() { Wallet.prototype.getScriptHash = function getScriptHash() {

View File

@ -47,7 +47,7 @@ describe('Script', function() {
it('should handle if statements correctly', function () { it('should handle if statements correctly', function () {
var inputScript = [1, 2]; 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 = []; var stack = [];
bcoin.script.execute(inputScript, stack); bcoin.script.execute(inputScript, stack);
var res = bcoin.script.execute(prevOutScript, stack); var res = bcoin.script.execute(prevOutScript, stack);
@ -55,7 +55,7 @@ describe('Script', function() {
assert.deepEqual(stack.slice(), [[1], [3], [5]]); assert.deepEqual(stack.slice(), [[1], [3], [5]]);
var inputScript = [1, 2]; 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 = []; var stack = [];
bcoin.script.execute(inputScript, stack); bcoin.script.execute(inputScript, stack);
var res = bcoin.script.execute(prevOutScript, stack); var res = bcoin.script.execute(prevOutScript, stack);
@ -63,7 +63,7 @@ describe('Script', function() {
assert.deepEqual(stack.slice(), [[1], [4], [5]]); assert.deepEqual(stack.slice(), [[1], [4], [5]]);
var inputScript = [1, 2]; var inputScript = [1, 2];
var prevOutScript = [2, 'eq', 'if_', 3, 'endif', 5]; var prevOutScript = [2, 'equal', 'if', 3, 'endif', 5];
var stack = []; var stack = [];
bcoin.script.execute(inputScript, stack); bcoin.script.execute(inputScript, stack);
var res = bcoin.script.execute(prevOutScript, stack); var res = bcoin.script.execute(prevOutScript, stack);
@ -71,7 +71,7 @@ describe('Script', function() {
assert.deepEqual(stack.slice(), [[1], [3], [5]]); assert.deepEqual(stack.slice(), [[1], [3], [5]]);
var inputScript = [1, 2]; var inputScript = [1, 2];
var prevOutScript = [9, 'eq', 'if_', 3, 'endif', 5]; var prevOutScript = [9, 'equal', 'if', 3, 'endif', 5];
var stack = []; var stack = [];
bcoin.script.execute(inputScript, stack); bcoin.script.execute(inputScript, stack);
var res = bcoin.script.execute(prevOutScript, stack); var res = bcoin.script.execute(prevOutScript, stack);
@ -79,7 +79,7 @@ describe('Script', function() {
assert.deepEqual(stack.slice(), [[1], [5]]); assert.deepEqual(stack.slice(), [[1], [5]]);
var inputScript = [1, 2]; var inputScript = [1, 2];
var prevOutScript = [9, 'eq', 'notif', 3, 'endif', 5]; var prevOutScript = [9, 'equal', 'notif', 3, 'endif', 5];
var stack = []; var stack = [];
bcoin.script.execute(inputScript, stack); bcoin.script.execute(inputScript, stack);
var res = bcoin.script.execute(prevOutScript, stack); var res = bcoin.script.execute(prevOutScript, stack);