add more opcodes to script.execute. handle codesep properly.
This commit is contained in:
parent
fd7d20be9c
commit
a9a9cf0879
@ -59,7 +59,7 @@ exports.opcodes = {
|
||||
pushdata4: 0x4e,
|
||||
negate1: 0x4f,
|
||||
|
||||
nop: 0x61,
|
||||
nop1: 0x61,
|
||||
if_: 0x63,
|
||||
notif: 0x64,
|
||||
else_: 0x67,
|
||||
@ -144,8 +144,14 @@ exports.opcodes = {
|
||||
for (var i = 1; i <= 16; i++)
|
||||
exports.opcodes[i] = 0x50 + i;
|
||||
|
||||
exports.opcodes['false'] = exports.opcodes['0'];
|
||||
exports.opcodes['true'] = exports.opcodes['1'];
|
||||
for (var i = 0; i <= 7; i++)
|
||||
exports.opcodes['nop' + (i + 3)] = 0xb2 + i;
|
||||
|
||||
// exports.opcodes['false'] = exports.opcodes['0'];
|
||||
// exports.opcodes['true'] = exports.opcodes['1'];
|
||||
|
||||
// exports.opcodes['if'] = exports.opcodes.if_;
|
||||
// exports.opcodes['else'] = exports.opcodes.else_;
|
||||
|
||||
exports.opcodesByVal = new Array(256);
|
||||
Object.keys(exports.opcodes).forEach(function(name) {
|
||||
|
||||
@ -135,9 +135,15 @@ script.execute = function execute(s, stack, tx, index) {
|
||||
return false;
|
||||
|
||||
var input = tx.inputs[index];
|
||||
var lastSep = -1;
|
||||
|
||||
stack.alt = stack.alt || [];
|
||||
|
||||
// TODO: if statements
|
||||
|
||||
for (var pc = 0; pc < s.length; pc++) {
|
||||
var o = s[pc];
|
||||
|
||||
if (Array.isArray(o)) {
|
||||
stack.push(o);
|
||||
} else if (typeof o === 'number' && o >= 1 && o <= 16) {
|
||||
@ -148,7 +154,287 @@ script.execute = function execute(s, stack, tx, index) {
|
||||
|
||||
stack.push(stack[stack.length - 1]);
|
||||
} else if (o === 'drop') {
|
||||
if (stack.length === 0)
|
||||
return false;
|
||||
|
||||
stack.pop();
|
||||
} else if (o === 'nop1' || o === 'nop3' || o === 'nop4'
|
||||
|| o === 'nop5' || o === 'nop6' || o === 'nop7'
|
||||
|| o === 'nop8' || o === 'nop9' || o === 'nop10') {
|
||||
;
|
||||
// OP_EVAL
|
||||
// if (o === 'nop1') {
|
||||
// var evalScript = script.decode(stack.pop());
|
||||
// var res = script.execute(evalScript, stack, tx, index);
|
||||
// if (!res)
|
||||
// return false;
|
||||
// }
|
||||
} else if (o === 'verify') {
|
||||
if (stack.length === 0)
|
||||
return false;
|
||||
if (new bn(stack[stack.length - 1]).cmp(0) === 0)
|
||||
return false;
|
||||
} else if (o === 'return') {
|
||||
return false;
|
||||
} else if (o === 'toaltstack') {
|
||||
if (stack.length === 0)
|
||||
return false;
|
||||
stack.alt.push(stack.pop());
|
||||
} else if (o === 'fromaltstack') {
|
||||
if (stack.alt.length === 0)
|
||||
return false;
|
||||
stack.push(stack.alt.pop());
|
||||
} else if (o === 'ifdup') {
|
||||
if (stack.length === 0)
|
||||
return false;
|
||||
if (new bn(stack[stack.length - 1]).cmp(0) !== 0)
|
||||
stack.push(new bn(stack[stack.length - 1]).toArray());
|
||||
} else if (o === 'depth') {
|
||||
stack.push(new bn(stack.length).toArray());
|
||||
} else if (o === 'nip') {
|
||||
if (stack.length < 2)
|
||||
return false;
|
||||
stack.splice(stack.length - 2, 1);
|
||||
} else if (o === 'over') {
|
||||
if (stack.length < 2)
|
||||
return false;
|
||||
stack.push(stack[stack.length - 2]);
|
||||
} else if (o === 'pick' || o === 'roll') {
|
||||
if (stack.length < 2)
|
||||
return false;
|
||||
var n = new bn(stack.pop()).toNumber();
|
||||
if (n < 0 || n >= stack.length)
|
||||
return false;
|
||||
var v = stack[-n - 1];
|
||||
if (o === 'roll')
|
||||
stack.splice(stack.length - n - 1, 1);
|
||||
stack.push(v);
|
||||
} else if (o === 'rot') {
|
||||
if (stack.length < 3)
|
||||
return false;
|
||||
var v3 = stack[stack.length - 3];
|
||||
var v2 = stack[stack.length - 2];
|
||||
var v1 = stack[stack.length - 1];
|
||||
stack[stack.length - 3] = v2;
|
||||
stack[stack.length - 2] = v3;
|
||||
|
||||
v2 = stack[stack.length - 2];
|
||||
stack[stack.length - 2] = v1;
|
||||
stack[stack.length - 1] = v2;
|
||||
} else if (o === 'swap') {
|
||||
if (stack.length < 2)
|
||||
return false;
|
||||
var v2 = stack[stack.length - 2];
|
||||
var v1 = stack[stack.length - 1];
|
||||
stack[stack.length - 2] = v1;
|
||||
stack[stack.length - 1] = v2;
|
||||
} else if (o === 'tuck') {
|
||||
if (stack.length < 2)
|
||||
return false;
|
||||
stack.splice(stack.length - 2, 0, stack[stack.length - 1]);
|
||||
} else if (o === 'drop2') {
|
||||
if (stack.length < 2)
|
||||
return false;
|
||||
stack.pop();
|
||||
stack.pop();
|
||||
} else if (o === 'dup2') {
|
||||
if (stack.length < 2)
|
||||
return false;
|
||||
var v1 = stack[stack.length - 1];
|
||||
var v2 = stack[stack.length - 2];
|
||||
stack.push(v1);
|
||||
stack.push(v2);
|
||||
} else if (o === 'dup3') {
|
||||
if (stack.length < 3)
|
||||
return false;
|
||||
var v1 = stack[stack.length - 1];
|
||||
var v2 = stack[stack.length - 2];
|
||||
var v3 = stack[stack.length - 3];
|
||||
stack.push(v1);
|
||||
stack.push(v2);
|
||||
stack.push(v3);
|
||||
} else if (o === 'over2') {
|
||||
if (stack.length < 4)
|
||||
return false;
|
||||
var v1 = stack[stack.length - 4];
|
||||
var v2 = stack[stack.length - 3];
|
||||
stack.push(v1);
|
||||
stack.push(v2);
|
||||
} else if (o === 'rot2') {
|
||||
if (stack.length < 6)
|
||||
return false;
|
||||
var v1 = stack[stack.length - 6];
|
||||
var v2 = stack[stack.length - 5];
|
||||
stack.splice(stack.length - 6, 2);
|
||||
stack.push(v1);
|
||||
stack.push(v2);
|
||||
} else if (o === 'swap2') {
|
||||
if (stack.length < 4)
|
||||
return false;
|
||||
var v4 = stack[stack.length - 4];
|
||||
var v3 = stack[stack.length - 3];
|
||||
var v2 = stack[stack.length - 2];
|
||||
var v1 = stack[stack.length - 1];
|
||||
stack[stack.length - 4] = v2;
|
||||
stack[stack.length - 2] = v4;
|
||||
stack[stack.length - 3] = v1;
|
||||
stack[stack.length - 1] = v3;
|
||||
} else if (o === 'size') {
|
||||
if (stack.length < 1)
|
||||
return false;
|
||||
stack.push(new bn(stack[stack.length - 1].length || 0).toArray());
|
||||
} else if (o === 'add1'
|
||||
|| o === 'sub1'
|
||||
|| o === 'negate'
|
||||
|| o === 'abs'
|
||||
|| o === 'not'
|
||||
|| o === 'noteq0') {
|
||||
if (stack.length < 1)
|
||||
return false;
|
||||
var n = new bn(stack.pop());
|
||||
switch (o) {
|
||||
case 'add1':
|
||||
n.iadd(1);
|
||||
break;
|
||||
case 'sub1':
|
||||
n.isub(1);
|
||||
break;
|
||||
case 'negate':
|
||||
n = n.neg();
|
||||
break;
|
||||
case 'abs':
|
||||
if (n.cmp(0) < 0)
|
||||
n = n.neg();
|
||||
break;
|
||||
case 'not':
|
||||
n = n.cmp(0) === 0;
|
||||
break;
|
||||
case 'noteq0':
|
||||
n = n.cmp(0) !== 0;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
stack.push(n.toArray());
|
||||
} else if (o === 'add'
|
||||
|| o === 'sub'
|
||||
|| o === 'booland'
|
||||
|| o === 'boolor'
|
||||
|| o === 'numeq'
|
||||
|| o === 'numeqverify'
|
||||
|| o === 'numneq'
|
||||
|| o === 'lt'
|
||||
|| o === 'gt'
|
||||
|| o === 'lte'
|
||||
|| o === 'gte'
|
||||
|| o === 'min'
|
||||
|| o === 'max') {
|
||||
switch (o) {
|
||||
case 'add':
|
||||
case 'sub':
|
||||
case 'booland':
|
||||
case 'boolor':
|
||||
case 'numeq':
|
||||
case 'numeqverify':
|
||||
case 'numneq':
|
||||
case 'lt':
|
||||
case 'gt':
|
||||
case 'lte':
|
||||
case 'gte':
|
||||
case 'min':
|
||||
case 'max':
|
||||
if (stack.length < 2)
|
||||
return false;
|
||||
var n2 = new bn(stack.pop());
|
||||
var n1 = new bn(stack.pop());
|
||||
var n = new bn(0);
|
||||
switch (o) {
|
||||
case 'add':
|
||||
n = n1.add(b2);
|
||||
break;
|
||||
case 'sub':
|
||||
n = n1.sub(n2);
|
||||
break;
|
||||
case 'booland':
|
||||
n = n1.cmp(0) !== 0 && n2.cmp(0) !== 0;
|
||||
break;
|
||||
case 'boolor':
|
||||
n = n1.cmp(0) !== 0 || n2.cmp(0) !== 0;
|
||||
break;
|
||||
case 'numeq':
|
||||
n = n1.cmp(n2) === 0;
|
||||
break;
|
||||
case 'numeqverify':
|
||||
n = n1.cmp(n2) === 0;
|
||||
break;
|
||||
case 'numneq':
|
||||
n = n1.cmp(n2) !== 0;
|
||||
break;
|
||||
case 'lt':
|
||||
n = n1.cmp(n2) < 0;
|
||||
break;
|
||||
case 'gt':
|
||||
n = n1.cmp(n2) > 0;
|
||||
break;
|
||||
case 'lte':
|
||||
n = n1.cmp(n2) <= 0;
|
||||
break;
|
||||
case 'gte':
|
||||
n = n1.cmp(n2) >= 0;
|
||||
break;
|
||||
case 'min':
|
||||
n = n1.cmp(n2) < 0 ? n1 : n2;
|
||||
break;
|
||||
case 'max':
|
||||
n = n1.cmp(n2) > 0 ? n1 : n2;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
var res = n.cmp(0) !== 0;
|
||||
if (o === 'numeqverify') {
|
||||
if (!res)
|
||||
return false;
|
||||
} else {
|
||||
stack.push(n.toArray());
|
||||
// stack.push(res ? [ 1 ] : []);
|
||||
}
|
||||
// stack.push(n.toArray());
|
||||
// if (op == 'numeqverify') {
|
||||
// if (n.cmp(0) !== 0)
|
||||
// stack.pop();
|
||||
// else
|
||||
// return false;
|
||||
// }
|
||||
break;
|
||||
case 'within':
|
||||
if (stack.length < 3)
|
||||
return false;
|
||||
var n3 = new bn(stack.pop());
|
||||
var n2 = new bn(stack.pop());
|
||||
var n1 = new bn(stack.pop());
|
||||
var val = n2.cmp(n1) <= 0 && n1.cmp(n3) < 0;
|
||||
stack.push(val.cmp(0) !== 0 ? [ 1 ] : []);
|
||||
break;
|
||||
}
|
||||
} else if (o === 'codesep') {
|
||||
lastSep = pc;
|
||||
} else if (o === 'ripemd160') {
|
||||
if (stack.length === 0)
|
||||
return false;
|
||||
stack.push(utils.ripemd160(stack.pop()));
|
||||
} else if (o === 'sha1') {
|
||||
if (stack.length === 0)
|
||||
return false;
|
||||
stack.push(utils.sha1(stack.pop()));
|
||||
} else if (o === 'sha256') {
|
||||
if (stack.length === 0)
|
||||
return false;
|
||||
stack.push(utils.sha256(stack.pop()));
|
||||
} else if (o === 'hash256') {
|
||||
if (stack.length === 0)
|
||||
return false;
|
||||
stack.push(utils.dsha256(stack.pop()));
|
||||
} else if (o === 'hash160') {
|
||||
if (stack.length === 0)
|
||||
return false;
|
||||
@ -165,7 +451,6 @@ script.execute = function execute(s, stack, tx, index) {
|
||||
} else {
|
||||
stack.push(res ? [ 1 ] : []);
|
||||
}
|
||||
|
||||
} else if (o === 'checksigverify' || o === 'checksig') {
|
||||
if (!tx || stack.length < 2)
|
||||
return false;
|
||||
@ -179,7 +464,8 @@ script.execute = function execute(s, stack, tx, index) {
|
||||
if (!script.isValidSig(sig))
|
||||
return false;
|
||||
|
||||
var subscript = input.out.tx.getSubscript(input.out.index);
|
||||
// var subscript = input.out.tx.getSubscript(input.out.index);
|
||||
var subscript = s.slice(lastSep + 1);
|
||||
var hash = tx.subscriptHash(index, subscript, type);
|
||||
|
||||
var res = script.verify(hash, sig.slice(0, -1), pub);
|
||||
@ -227,7 +513,8 @@ script.execute = function execute(s, stack, tx, index) {
|
||||
if (!constants.rhashType[type & 0x7f])
|
||||
return false;
|
||||
|
||||
var subscript = input.out.tx.getSubscript(input.out.index);
|
||||
// var subscript = input.out.tx.getSubscript(input.out.index);
|
||||
var subscript = s.slice(lastSep + 1);
|
||||
var hash = tx.subscriptHash(index, subscript, type);
|
||||
|
||||
if (!script.isValidSig(sig))
|
||||
@ -260,11 +547,7 @@ script.execute = function execute(s, stack, tx, index) {
|
||||
if (stack.length === 0)
|
||||
return false;
|
||||
|
||||
var lock = stack[stack.length - 1];
|
||||
if (lock.length !== 1)
|
||||
return false;
|
||||
|
||||
lock = lock[0];
|
||||
var lock = new bn(stack[stack.length - 1]).toNumber();
|
||||
|
||||
if (lock < 0)
|
||||
return false;
|
||||
@ -288,7 +571,7 @@ script.execute = function execute(s, stack, tx, index) {
|
||||
}
|
||||
}
|
||||
|
||||
if (stack.length > 1000)
|
||||
if (stack.length + stack.alt.length > 1000)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
@ -118,6 +118,14 @@ utils.fromBase58 = function fromBase58(str) {
|
||||
return z.concat(res.toArray());
|
||||
};
|
||||
|
||||
utils.ripemd160 = function ripemd160(data, enc) {
|
||||
return hash.ripemd160().update(data, enc).digest();
|
||||
};
|
||||
|
||||
utils.sha1 = function sha1(data, enc) {
|
||||
return hash.sha1().update(data, enc).digest();
|
||||
};
|
||||
|
||||
utils.ripesha = function ripesha(data, enc) {
|
||||
return hash.ripemd160().update(utils.sha256(data, enc)).digest();
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user