no strings in scripting.
This commit is contained in:
parent
2c9756f38b
commit
a598a4850c
@ -13,6 +13,7 @@ var constants = bcoin.protocol.constants;
|
||||
var network = bcoin.protocol.network;
|
||||
var Script = bcoin.script;
|
||||
var Witness = bcoin.script.witness;
|
||||
var opc = constants.opcodes;
|
||||
|
||||
/**
|
||||
* MTX
|
||||
@ -188,7 +189,7 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
|
||||
redeemScript = addr.program.encode();
|
||||
vector = input.witness.items;
|
||||
dummy = new Buffer([]);
|
||||
assert(addr.program.code[0] === 0, 'Non-zero version passed to address.');
|
||||
assert(addr.program.code[0] === opc['0'], 'Non-zero version passed to address.');
|
||||
if (addr.program.code[1].length === 32) {
|
||||
// P2WSH nested within pay-to-scripthash
|
||||
// (it had to be this complicated, didn't it?)
|
||||
@ -205,7 +206,7 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
|
||||
redeemScript = addr.script.encode();
|
||||
vector = input.script.code;
|
||||
prev = addr.script;
|
||||
dummy = 0;
|
||||
dummy = opc['0'];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@ -214,7 +215,7 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
|
||||
vector = input.witness.items;
|
||||
dummy = new Buffer([]);
|
||||
|
||||
if (prev.code[0] !== 0)
|
||||
if (prev.code[0] !== opc['0'])
|
||||
return false;
|
||||
|
||||
if (prev.code[1].length === 32) {
|
||||
@ -237,7 +238,7 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
|
||||
} else {
|
||||
// Wow, a normal output! Praise be to Jengus and Gord.
|
||||
vector = input.script.code;
|
||||
dummy = 0;
|
||||
dummy = opc['0'];
|
||||
}
|
||||
|
||||
if (prev.isPubkey()) {
|
||||
@ -276,7 +277,7 @@ MTX.prototype.scriptInput = function scriptInput(index, addr) {
|
||||
vector[0] = dummy;
|
||||
|
||||
// Grab `n` value (number of keys).
|
||||
n = prev.code[prev.code.length - 2];
|
||||
n = prev.code[prev.code.length - 2] - 0x50;
|
||||
|
||||
// Fill script with `n` signature slots.
|
||||
for (i = 0; i < n; i++)
|
||||
@ -359,7 +360,7 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
||||
|
||||
vector = input.script.code;
|
||||
len = vector.length;
|
||||
dummy = 0;
|
||||
dummy = opc['0'];
|
||||
version = 0;
|
||||
|
||||
// We need to grab the redeem script when
|
||||
@ -433,10 +434,10 @@ MTX.prototype.signInput = function signInput(index, addr, type) {
|
||||
keys = prev.code.slice(1, -2);
|
||||
|
||||
// Grab `m` value (number of sigs required).
|
||||
m = prev.code[0];
|
||||
m = prev.code[0] - 0x50;
|
||||
|
||||
// Grab `n` value (number of keys).
|
||||
n = prev.code[prev.code.length - 2];
|
||||
n = prev.code[prev.code.length - 2] - 0x50;
|
||||
} else {
|
||||
// Only allow non-standard signing for
|
||||
// scripthash.
|
||||
@ -583,9 +584,7 @@ MTX.prototype.isSigned = function isSigned(m) {
|
||||
return false;
|
||||
} else if (prev.isMultisig()) {
|
||||
// Grab `m` value (number of required sigs).
|
||||
m = prev.code[0];
|
||||
if (Buffer.isBuffer(m))
|
||||
m = m[0] || 0;
|
||||
m = prev.code[0] - 0x50;
|
||||
|
||||
// Ensure all members are signatures.
|
||||
for (j = 1; j < len; j++) {
|
||||
@ -738,7 +737,7 @@ MTX.prototype.maxSize = function maxSize(maxM, maxN) {
|
||||
} else if (prev.isMultisig()) {
|
||||
// Bare Multisig
|
||||
// Get the previous m value:
|
||||
m = prev.code[0];
|
||||
m = prev.code[0] - 0x50;
|
||||
// OP_0
|
||||
size += 1;
|
||||
// OP_PUSHDATA0 [signature] ...
|
||||
|
||||
@ -10,6 +10,7 @@ var constants = bcoin.protocol.constants;
|
||||
var utils = require('./utils');
|
||||
var assert = utils.assert;
|
||||
var BufferWriter = require('./writer');
|
||||
var opc = constants.opcodes;
|
||||
|
||||
function Witness(items) {
|
||||
if (!(this instanceof Witness))
|
||||
@ -221,21 +222,21 @@ Stack.prototype._swap = function _swap(i1, i2) {
|
||||
|
||||
Stack.prototype.toalt = function toalt() {
|
||||
if (this.length === 0)
|
||||
throw new ScriptError('Stack too small.', 'toaltstack');
|
||||
throw new ScriptError('Stack too small.', opc.toaltstack);
|
||||
|
||||
this.alt.push(this.pop());
|
||||
};
|
||||
|
||||
Stack.prototype.fromalt = function fromalt() {
|
||||
if (this.alt.length === 0)
|
||||
throw new ScriptError('Stack too small.', 'fromaltstack');
|
||||
throw new ScriptError('Stack too small.', opc.fromaltstack);
|
||||
|
||||
this.push(this.alt.pop());
|
||||
};
|
||||
|
||||
Stack.prototype.ifdup = function ifdup() {
|
||||
if (this.length === 0)
|
||||
throw new ScriptError('Stack too small.', 'ifdup');
|
||||
throw new ScriptError('Stack too small.', opc.ifdup);
|
||||
|
||||
if (Script.bool(this.top(-1)))
|
||||
this.push(Script.array(this.top(-1)));
|
||||
@ -247,38 +248,38 @@ Stack.prototype.depth = function depth() {
|
||||
|
||||
Stack.prototype.drop = function drop() {
|
||||
if (this.length === 0)
|
||||
throw new ScriptError('Stack too small.', 'drop');
|
||||
throw new ScriptError('Stack too small.', opc.drop);
|
||||
|
||||
this.pop();
|
||||
};
|
||||
|
||||
Stack.prototype.dup = function dup() {
|
||||
if (this.length === 0)
|
||||
throw new ScriptError('Stack too small.', 'dup');
|
||||
throw new ScriptError('Stack too small.', opc.dup);
|
||||
|
||||
this.push(this.top(-1));
|
||||
};
|
||||
|
||||
Stack.prototype.nip = function nip() {
|
||||
if (this.length < 2)
|
||||
throw new ScriptError('Stack too small.', 'nip');
|
||||
throw new ScriptError('Stack too small.', opc.nip);
|
||||
|
||||
this.splice(this.length - 2, 1);
|
||||
};
|
||||
|
||||
Stack.prototype.over = function over() {
|
||||
if (this.length < 2)
|
||||
throw new ScriptError('Stack too small.', 'over');
|
||||
throw new ScriptError('Stack too small.', opc.over);
|
||||
|
||||
this.push(this.top(-2));
|
||||
};
|
||||
|
||||
Stack.prototype.pick = function pick(flags) {
|
||||
return this._pickroll('pick', flags);
|
||||
return this._pickroll(opc.pick, flags);
|
||||
};
|
||||
|
||||
Stack.prototype.roll = function roll(flags) {
|
||||
return this._pickroll('roll', flags);
|
||||
return this._pickroll(opc.roll, flags);
|
||||
};
|
||||
|
||||
Stack.prototype._pickroll = function pickroll(op, flags) {
|
||||
@ -295,7 +296,7 @@ Stack.prototype._pickroll = function pickroll(op, flags) {
|
||||
|
||||
val = this.get(-n - 1);
|
||||
|
||||
if (op === 'roll')
|
||||
if (op === opc.roll)
|
||||
this.splice(this.length - n - 1, 1);
|
||||
|
||||
this.push(val);
|
||||
@ -303,7 +304,7 @@ Stack.prototype._pickroll = function pickroll(op, flags) {
|
||||
|
||||
Stack.prototype.rot = function rot() {
|
||||
if (this.length < 3)
|
||||
throw new ScriptError('Stack too small.', 'rot');
|
||||
throw new ScriptError('Stack too small.', opc.rot);
|
||||
|
||||
this._swap(-3, -2);
|
||||
this._swap(-2, -1);
|
||||
@ -311,21 +312,21 @@ Stack.prototype.rot = function rot() {
|
||||
|
||||
Stack.prototype.swap = function swap() {
|
||||
if (this.length < 2)
|
||||
throw new ScriptError('Stack too small.', 'swap');
|
||||
throw new ScriptError('Stack too small.', opc.swap);
|
||||
|
||||
this._swap(-2, -1);
|
||||
};
|
||||
|
||||
Stack.prototype.tuck = function tuck() {
|
||||
if (this.length < 2)
|
||||
throw new ScriptError('Stack too small.', 'tuck');
|
||||
throw new ScriptError('Stack too small.', opc.tuck);
|
||||
|
||||
this.splice(this.length - 2, 0, this.top(-1));
|
||||
};
|
||||
|
||||
Stack.prototype.drop2 = function drop2() {
|
||||
if (this.length < 2)
|
||||
throw new ScriptError('Stack too small.', '2drop');
|
||||
throw new ScriptError('Stack too small.', opc['2drop']);
|
||||
|
||||
this.pop();
|
||||
this.pop();
|
||||
@ -335,7 +336,7 @@ Stack.prototype.dup2 = function dup2() {
|
||||
var v1, v2;
|
||||
|
||||
if (this.length < 2)
|
||||
throw new ScriptError('Stack too small.', '2dup');
|
||||
throw new ScriptError('Stack too small.', opc['2dup']);
|
||||
|
||||
v1 = this.top(-2);
|
||||
v2 = this.top(-1);
|
||||
@ -348,7 +349,7 @@ Stack.prototype.dup3 = function dup3() {
|
||||
var v1, v2, v3;
|
||||
|
||||
if (this.length < 3)
|
||||
throw new ScriptError('Stack too small.', '3dup');
|
||||
throw new ScriptError('Stack too small.', opc['3dup']);
|
||||
|
||||
v1 = this.top(-3);
|
||||
v2 = this.top(-2);
|
||||
@ -363,7 +364,7 @@ Stack.prototype.over2 = function over2() {
|
||||
var v1, v2;
|
||||
|
||||
if (this.length < 4)
|
||||
throw new ScriptError('Stack too small.', '2over');
|
||||
throw new ScriptError('Stack too small.', opc['2over']);
|
||||
|
||||
v1 = this.top(-4);
|
||||
v2 = this.top(-3);
|
||||
@ -376,7 +377,7 @@ Stack.prototype.rot2 = function rot2() {
|
||||
var v1, v2;
|
||||
|
||||
if (this.length < 6)
|
||||
throw new ScriptError('Stack too small.', '2rot');
|
||||
throw new ScriptError('Stack too small.', opc['2rot']);
|
||||
|
||||
v1 = this.top(-6);
|
||||
v2 = this.top(-5);
|
||||
@ -393,7 +394,7 @@ Stack.prototype.swap2 = function swap2() {
|
||||
|
||||
Stack.prototype.size = function size() {
|
||||
if (this.length < 1)
|
||||
throw new ScriptError('Stack too small.', 'size');
|
||||
throw new ScriptError('Stack too small.', opc.size);
|
||||
|
||||
this.push(Script.array(this.top(-1).length));
|
||||
};
|
||||
@ -445,10 +446,10 @@ Script.prototype.getSubscript = function getSubscript(lastSep) {
|
||||
if (lastSep == null)
|
||||
lastSep = -1;
|
||||
|
||||
assert(lastSep <= 0 || this.code[lastSep] === 'codeseparator');
|
||||
assert(lastSep <= 0 || this.code[lastSep] === opc.codeseparator);
|
||||
|
||||
for (i = lastSep + 1; i < this.code.length; i++) {
|
||||
if (this.code[i] !== 'codeseparator')
|
||||
if (this.code[i] !== opc.codeseparator)
|
||||
res.push(this.code[i]);
|
||||
}
|
||||
|
||||
@ -470,11 +471,11 @@ Script.prototype._next = function _next(to, code, ip) {
|
||||
while (code[ip]) {
|
||||
op = code[ip];
|
||||
|
||||
if (op === 'if' || op === 'notif')
|
||||
if (op === opc['if'] || op === opc.notif)
|
||||
depth++;
|
||||
else if (op === 'else')
|
||||
else if (op === opc['else'])
|
||||
depth--;
|
||||
else if (op === 'endif')
|
||||
else if (op === opc.endif)
|
||||
depth--;
|
||||
|
||||
if (depth < 0)
|
||||
@ -483,7 +484,7 @@ Script.prototype._next = function _next(to, code, ip) {
|
||||
if (depth === 0 && op === to)
|
||||
return ip;
|
||||
|
||||
if (op === 'else')
|
||||
if (op === opc['else'])
|
||||
depth++;
|
||||
|
||||
ip++;
|
||||
@ -537,44 +538,44 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
|
||||
continue;
|
||||
}
|
||||
|
||||
if (op === 0) {
|
||||
if (op === opc['0']) {
|
||||
stack.push(new Buffer([]));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (op >= 1 && op <= 16) {
|
||||
stack.push(new Buffer([op]));
|
||||
if (op >= opc['1'] && op <= opc['16']) {
|
||||
stack.push(new Buffer([op - 0x50]));
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
case 'nop':
|
||||
case 'nop1':
|
||||
case 'nop4':
|
||||
case 'nop5':
|
||||
case 'nop6':
|
||||
case 'nop7':
|
||||
case 'nop8':
|
||||
case 'nop9':
|
||||
case 'nop10': {
|
||||
case opc.nop:
|
||||
case opc.nop1:
|
||||
case opc.nop4:
|
||||
case opc.nop5:
|
||||
case opc.nop6:
|
||||
case opc.nop7:
|
||||
case opc.nop8:
|
||||
case opc.nop9:
|
||||
case opc.nop10: {
|
||||
if (flags & constants.flags.VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
|
||||
throw new ScriptError('Upgradable NOP used.', op, ip);
|
||||
break;
|
||||
}
|
||||
case '1negate': {
|
||||
case opc['1negate']: {
|
||||
stack.push(new Buffer([0xff]));
|
||||
break;
|
||||
}
|
||||
case 'if':
|
||||
case 'notif': {
|
||||
case opc['if']:
|
||||
case opc.notif: {
|
||||
if (stack.length < 1)
|
||||
throw new ScriptError('Stack too small.', op, ip);
|
||||
val = Script.bool(stack.pop());
|
||||
if (op === 'notif')
|
||||
if (op === opc.notif)
|
||||
val = !val;
|
||||
if_ = ip;
|
||||
else_ = this._next('else', code, ip);
|
||||
endif = this._next('endif', code, ip);
|
||||
else_ = this._next(opc['else'], code, ip);
|
||||
endif = this._next(opc.endif, code, ip);
|
||||
// Splice out the statement blocks we don't need
|
||||
if (val) {
|
||||
if (endif === -1)
|
||||
@ -600,129 +601,129 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
|
||||
ip--;
|
||||
break;
|
||||
}
|
||||
case 'else': {
|
||||
case opc['else']: {
|
||||
throw new ScriptError('Unexpected else.', op, ip);
|
||||
}
|
||||
case 'endif': {
|
||||
case opc.endif: {
|
||||
throw new ScriptError('Unexpected endif.', op, ip);
|
||||
}
|
||||
case 'verify': {
|
||||
case opc.verify: {
|
||||
if (stack.length === 0)
|
||||
throw new ScriptError('Stack too small.', op, ip);
|
||||
if (!Script.bool(stack.pop()))
|
||||
throw new ScriptError('Verification failed.', op, ip);
|
||||
break;
|
||||
}
|
||||
case 'return': {
|
||||
case opc['return']: {
|
||||
throw new ScriptError('Script returned.', op, ip);
|
||||
}
|
||||
case 'toaltstack': {
|
||||
case opc.toaltstack: {
|
||||
stack.toalt();
|
||||
break;
|
||||
}
|
||||
case 'fromaltstack': {
|
||||
case opc.fromaltstack: {
|
||||
stack.fromalt();
|
||||
break;
|
||||
}
|
||||
case 'ifdup': {
|
||||
case opc.ifdup: {
|
||||
stack.ifdup();
|
||||
break;
|
||||
}
|
||||
case 'depth': {
|
||||
case opc.depth: {
|
||||
stack.depth();
|
||||
break;
|
||||
}
|
||||
case 'drop': {
|
||||
case opc.drop: {
|
||||
stack.drop();
|
||||
break;
|
||||
}
|
||||
case 'dup': {
|
||||
case opc.dup: {
|
||||
stack.dup();
|
||||
break;
|
||||
}
|
||||
case 'nip': {
|
||||
case opc.nip: {
|
||||
stack.nip();
|
||||
break;
|
||||
}
|
||||
case 'over': {
|
||||
case opc.over: {
|
||||
stack.over();
|
||||
break;
|
||||
}
|
||||
case 'pick': {
|
||||
case opc.pick: {
|
||||
stack.pick(flags);
|
||||
break;
|
||||
}
|
||||
case 'roll': {
|
||||
case opc.roll: {
|
||||
stack.roll(flags);
|
||||
break;
|
||||
}
|
||||
case 'rot': {
|
||||
case opc.rot: {
|
||||
stack.rot();
|
||||
break;
|
||||
}
|
||||
case 'swap': {
|
||||
case opc.swap: {
|
||||
stack.swap();
|
||||
break;
|
||||
}
|
||||
case 'tuck': {
|
||||
case opc.tuck: {
|
||||
stack.tuck();
|
||||
break;
|
||||
}
|
||||
case '2drop': {
|
||||
case opc['2drop']: {
|
||||
stack.drop2();
|
||||
break;
|
||||
}
|
||||
case '2dup': {
|
||||
case opc['2dup']: {
|
||||
stack.dup2();
|
||||
break;
|
||||
}
|
||||
case '3dup': {
|
||||
case opc['3dup']: {
|
||||
stack.dup3();
|
||||
break;
|
||||
}
|
||||
case '2over': {
|
||||
case opc['2over']: {
|
||||
stack.over2();
|
||||
break;
|
||||
}
|
||||
case '2rot': {
|
||||
case opc['2rot']: {
|
||||
stack.rot2();
|
||||
break;
|
||||
}
|
||||
case '2swap': {
|
||||
case opc['2swap']: {
|
||||
stack.swap2();
|
||||
break;
|
||||
}
|
||||
case 'size': {
|
||||
case opc.size: {
|
||||
stack.size();
|
||||
break;
|
||||
}
|
||||
case '1add':
|
||||
case '1sub':
|
||||
case 'negate':
|
||||
case 'abs':
|
||||
case 'not':
|
||||
case '0notequal': {
|
||||
case opc['1add']:
|
||||
case opc['1sub']:
|
||||
case opc.negate:
|
||||
case opc.abs:
|
||||
case opc.not:
|
||||
case opc['0notequal']: {
|
||||
if (stack.length < 1)
|
||||
throw new ScriptError('Stack too small.', op, ip);
|
||||
n = Script.num(stack.pop(), flags);
|
||||
switch (op) {
|
||||
case '1add':
|
||||
case opc['1add']:
|
||||
n.iadd(1);
|
||||
break;
|
||||
case '1sub':
|
||||
case opc['1sub']:
|
||||
n.isub(1);
|
||||
break;
|
||||
case 'negate':
|
||||
case opc.negate:
|
||||
n = n.neg();
|
||||
break;
|
||||
case 'abs':
|
||||
case opc.abs:
|
||||
if (n.cmpn(0) < 0)
|
||||
n = n.neg();
|
||||
break;
|
||||
case 'not':
|
||||
case opc.not:
|
||||
n = n.cmpn(0) === 0;
|
||||
break;
|
||||
case '0notequal':
|
||||
case opc['0notequal']:
|
||||
n = n.cmpn(0) !== 0;
|
||||
break;
|
||||
default:
|
||||
@ -733,76 +734,76 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
|
||||
stack.push(Script.array(n));
|
||||
break;
|
||||
}
|
||||
case 'add':
|
||||
case 'sub':
|
||||
case 'booland':
|
||||
case 'boolor':
|
||||
case 'numequal':
|
||||
case 'numequalverify':
|
||||
case 'numnotequal':
|
||||
case 'lessthan':
|
||||
case 'greaterthan':
|
||||
case 'lessthanorequal':
|
||||
case 'greaterthanorequal':
|
||||
case 'min':
|
||||
case 'max': {
|
||||
case opc.add:
|
||||
case opc.sub:
|
||||
case opc.booland:
|
||||
case opc.boolor:
|
||||
case opc.numequal:
|
||||
case opc.numequalverify:
|
||||
case opc.numnotequal:
|
||||
case opc.lessthan:
|
||||
case opc.greaterthan:
|
||||
case opc.lessthanorequal:
|
||||
case opc.greaterthanorequal:
|
||||
case opc.min:
|
||||
case opc.max: {
|
||||
switch (op) {
|
||||
case 'add':
|
||||
case 'sub':
|
||||
case 'booland':
|
||||
case 'boolor':
|
||||
case 'numequal':
|
||||
case 'numequalverify':
|
||||
case 'numnotequal':
|
||||
case 'lessthan':
|
||||
case 'greaterthan':
|
||||
case 'lessthanorequal':
|
||||
case 'greaterthanorequal':
|
||||
case 'min':
|
||||
case 'max':
|
||||
case opc.add:
|
||||
case opc.sub:
|
||||
case opc.booland:
|
||||
case opc.boolor:
|
||||
case opc.numequal:
|
||||
case opc.numequalverify:
|
||||
case opc.numnotequal:
|
||||
case opc.lessthan:
|
||||
case opc.greaterthan:
|
||||
case opc.lessthanorequal:
|
||||
case opc.greaterthanorequal:
|
||||
case opc.min:
|
||||
case opc.max:
|
||||
if (stack.length < 2)
|
||||
throw new ScriptError('Stack too small.', op, ip);
|
||||
n2 = Script.num(stack.pop(), flags);
|
||||
n1 = Script.num(stack.pop(), flags);
|
||||
n = new bn(0, 'le');
|
||||
switch (op) {
|
||||
case 'add':
|
||||
case opc.add:
|
||||
n = n1.add(n2);
|
||||
break;
|
||||
case 'sub':
|
||||
case opc.sub:
|
||||
n = n1.sub(n2);
|
||||
break;
|
||||
case 'booland':
|
||||
case opc.booland:
|
||||
n = n1.cmpn(0) !== 0 && n2.cmpn(0) !== 0;
|
||||
break;
|
||||
case 'boolor':
|
||||
case opc.boolor:
|
||||
n = n1.cmpn(0) !== 0 || n2.cmpn(0) !== 0;
|
||||
break;
|
||||
case 'numequal':
|
||||
case opc.numequal:
|
||||
n = n1.cmp(n2) === 0;
|
||||
break;
|
||||
case 'numequalverify':
|
||||
case opc.numequalverify:
|
||||
n = n1.cmp(n2) === 0;
|
||||
break;
|
||||
case 'numnotequal':
|
||||
case opc.numnotequal:
|
||||
n = n1.cmp(n2) !== 0;
|
||||
break;
|
||||
case 'lessthan':
|
||||
case opc.lessthan:
|
||||
n = n1.cmp(n2) < 0;
|
||||
break;
|
||||
case 'greaterthan':
|
||||
case opc.greaterthan:
|
||||
n = n1.cmp(n2) > 0;
|
||||
break;
|
||||
case 'lessthanorequal':
|
||||
case opc.lessthanorequal:
|
||||
n = n1.cmp(n2) <= 0;
|
||||
break;
|
||||
case 'greaterthanorequal':
|
||||
case opc.greaterthanorequal:
|
||||
n = n1.cmp(n2) >= 0;
|
||||
break;
|
||||
case 'min':
|
||||
case opc.min:
|
||||
n = n1.cmp(n2) < 0 ? n1 : n2;
|
||||
break;
|
||||
case 'max':
|
||||
case opc.max:
|
||||
n = n1.cmp(n2) > 0 ? n1 : n2;
|
||||
break;
|
||||
default:
|
||||
@ -811,14 +812,14 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
|
||||
if (typeof n === 'boolean')
|
||||
n = new bn(n ? 1 : 0, 'le');
|
||||
res = Script.bool(n);
|
||||
if (op === 'numequalverify') {
|
||||
if (op === opc.numequalverify) {
|
||||
if (!res)
|
||||
return false;
|
||||
} else {
|
||||
stack.push(Script.array(n));
|
||||
}
|
||||
break;
|
||||
case 'within':
|
||||
case opc.within:
|
||||
if (stack.length < 3)
|
||||
throw new ScriptError('Stack too small.', op, ip);
|
||||
n3 = Script.num(stack.pop(), flags);
|
||||
@ -831,46 +832,46 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
|
||||
|
||||
break;
|
||||
}
|
||||
case 'codeseparator': {
|
||||
case opc.codeseparator: {
|
||||
lastSep = ip;
|
||||
break;
|
||||
}
|
||||
case 'ripemd160': {
|
||||
case opc.ripemd160: {
|
||||
if (stack.length === 0)
|
||||
throw new ScriptError('Stack too small.', op, ip);
|
||||
stack.push(utils.ripemd160(stack.pop()));
|
||||
break;
|
||||
}
|
||||
case 'sha1': {
|
||||
case opc.sha1: {
|
||||
if (stack.length === 0)
|
||||
throw new ScriptError('Stack too small.', op, ip);
|
||||
stack.push(utils.sha1(stack.pop()));
|
||||
break;
|
||||
}
|
||||
case 'sha256': {
|
||||
case opc.sha256: {
|
||||
if (stack.length === 0)
|
||||
throw new ScriptError('Stack too small.', op, ip);
|
||||
stack.push(utils.sha256(stack.pop()));
|
||||
break;
|
||||
}
|
||||
case 'hash256': {
|
||||
case opc.hash256: {
|
||||
if (stack.length === 0)
|
||||
throw new ScriptError('Stack too small.', op, ip);
|
||||
stack.push(utils.dsha256(stack.pop()));
|
||||
break;
|
||||
}
|
||||
case 'hash160': {
|
||||
case opc.hash160: {
|
||||
if (stack.length === 0)
|
||||
throw new ScriptError('Stack too small.', op, ip);
|
||||
stack.push(utils.ripesha(stack.pop()));
|
||||
break;
|
||||
}
|
||||
case 'equalverify':
|
||||
case 'equal': {
|
||||
case opc.equalverify:
|
||||
case opc.equal: {
|
||||
if (stack.length < 2)
|
||||
throw new ScriptError('Stack too small.', op, ip);
|
||||
res = utils.isEqual(stack.pop(), stack.pop());
|
||||
if (op === 'equalverify') {
|
||||
if (op === opc.equalverify) {
|
||||
if (!res)
|
||||
throw new ScriptError('Equal verification failed.', op, ip);
|
||||
} else {
|
||||
@ -878,8 +879,8 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'checksigverify':
|
||||
case 'checksig': {
|
||||
case opc.checksigverify:
|
||||
case opc.checksig: {
|
||||
if (!tx)
|
||||
throw new ScriptError('No TX passed in.', op, ip);
|
||||
|
||||
@ -903,7 +904,7 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
|
||||
hash = tx.signatureHash(index, subscript, type, version);
|
||||
|
||||
res = Script.checksig(hash, sig, key, flags);
|
||||
if (op === 'checksigverify') {
|
||||
if (op === opc.checksigverify) {
|
||||
if (!res)
|
||||
throw new ScriptError('Signature verification failed.', op, ip);
|
||||
} else {
|
||||
@ -912,8 +913,8 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
|
||||
|
||||
break;
|
||||
}
|
||||
case 'checkmultisigverify':
|
||||
case 'checkmultisig': {
|
||||
case opc.checkmultisigverify:
|
||||
case opc.checkmultisig: {
|
||||
if (!tx)
|
||||
throw new ScriptError('No TX passed in.', op, ip);
|
||||
|
||||
@ -984,7 +985,7 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
|
||||
|
||||
res = succ >= m;
|
||||
|
||||
if (op === 'checkmultisigverify') {
|
||||
if (op === opc.checkmultisigverify) {
|
||||
if (!res)
|
||||
throw new ScriptError('Signature verification failed.', op, ip);
|
||||
} else {
|
||||
@ -993,7 +994,7 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
|
||||
|
||||
break;
|
||||
}
|
||||
case 'checklocktimeverify': {
|
||||
case opc.checklocktimeverify: {
|
||||
// OP_CHECKLOCKTIMEVERIFY = OP_NOP2
|
||||
if (!(flags & constants.flags.VERIFY_CHECKLOCKTIMEVERIFY)) {
|
||||
if (flags & constants.flags.VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
|
||||
@ -1019,7 +1020,7 @@ Script.prototype.interpret = function interpret(stack, flags, tx, index, version
|
||||
|
||||
break;
|
||||
}
|
||||
case 'checksequenceverify': {
|
||||
case opc.checksequenceverify: {
|
||||
// OP_CHECKSEQUENCEVERIFY = OP_NOP3
|
||||
if (!(flags & constants.flags.VERIFY_CHECKSEQUENCEVERIFY)) {
|
||||
if (flags & constants.flags.VERIFY_DISCOURAGE_UPGRADABLE_NOPS)
|
||||
@ -1274,16 +1275,16 @@ Script.prototype.concat = function concat(scripts) {
|
||||
};
|
||||
|
||||
Script.createPubkey = function createPubkey(key) {
|
||||
return new Script([key, 'checksig']);
|
||||
return new Script([key, opc.checksig]);
|
||||
};
|
||||
|
||||
Script.createPubkeyhash = function createPubkeyhash(hash) {
|
||||
return new Script([
|
||||
'dup',
|
||||
'hash160',
|
||||
opc.dup,
|
||||
opc.hash160,
|
||||
hash,
|
||||
'equalverify',
|
||||
'checksig'
|
||||
opc.equalverify,
|
||||
opc.checksig
|
||||
]);
|
||||
};
|
||||
|
||||
@ -1294,23 +1295,23 @@ Script.createMultisig = function createMultisig(keys, m, n) {
|
||||
assert(m >= 1 && m <= n);
|
||||
assert(n >= 1 && n <= 15);
|
||||
|
||||
return new Script([m].concat(
|
||||
return new Script([m + 0x50].concat(
|
||||
utils.sortKeys(keys),
|
||||
[n, 'checkmultisig']
|
||||
[n + 0x50, opc.checkmultisig]
|
||||
));
|
||||
};
|
||||
|
||||
Script.createScripthash = function createScripthash(hash) {
|
||||
return new Script([
|
||||
'hash160',
|
||||
opc.hash160,
|
||||
hash,
|
||||
'equal'
|
||||
opc.equal
|
||||
]);
|
||||
};
|
||||
|
||||
Script.createNulldata = function createNulldata(flags) {
|
||||
return new Script([
|
||||
'return',
|
||||
opc['return'],
|
||||
flags
|
||||
]);
|
||||
};
|
||||
@ -1356,8 +1357,8 @@ Script.prototype.isStandard = function isStandard() {
|
||||
var m, n;
|
||||
|
||||
if (type === 'multisig') {
|
||||
m = this.code[0];
|
||||
n = this.code[this.code.length - 2];
|
||||
m = this.code[0] - 0x50;
|
||||
n = this.code[this.code.length - 2] - 0x50;
|
||||
|
||||
if (n < 1 || n > 3)
|
||||
return false;
|
||||
@ -1479,7 +1480,7 @@ Script.prototype.isPubkey = function isPubkey(key) {
|
||||
if (this.code.length !== 2)
|
||||
return false;
|
||||
|
||||
res = Script.isKey(this.code[0]) && this.code[1] === 'checksig';
|
||||
res = Script.isKey(this.code[0]) && this.code[1] === opc.checksig;
|
||||
|
||||
if (!res)
|
||||
return false;
|
||||
@ -1498,11 +1499,11 @@ Script.prototype.isPubkeyhash = function isPubkeyhash(hash) {
|
||||
if (this.code.length !== 5)
|
||||
return false;
|
||||
|
||||
res = this.code[0] === 'dup'
|
||||
&& this.code[1] === 'hash160'
|
||||
res = this.code[0] === opc.dup
|
||||
&& this.code[1] === opc.hash160
|
||||
&& Script.isHash(this.code[2])
|
||||
&& this.code[3] === 'equalverify'
|
||||
&& this.code[4] === 'checksig';
|
||||
&& this.code[3] === opc.equalverify
|
||||
&& this.code[4] === opc.checksig;
|
||||
|
||||
if (!res)
|
||||
return false;
|
||||
@ -1522,20 +1523,16 @@ Script.prototype.isMultisig = function isMultisig(keys) {
|
||||
if (this.code.length < 4)
|
||||
return false;
|
||||
|
||||
if (this.code[this.code.length - 1] !== 'checkmultisig')
|
||||
if (this.code[this.code.length - 1] !== opc.checkmultisig)
|
||||
return false;
|
||||
|
||||
n = this.code[this.code.length - 2];
|
||||
|
||||
if (Buffer.isBuffer(n)) {
|
||||
if (n.length !== 0)
|
||||
return false;
|
||||
n = 0;
|
||||
}
|
||||
|
||||
if (typeof n !== 'number')
|
||||
if (!(n >= opc['1'] && n <= opc['16']))
|
||||
return false;
|
||||
|
||||
n -= 0x50;
|
||||
|
||||
// Bitcoind technically doesn't check for the
|
||||
// 15 limit here. It just counts the sigops
|
||||
// later.
|
||||
@ -1544,15 +1541,11 @@ Script.prototype.isMultisig = function isMultisig(keys) {
|
||||
|
||||
m = this.code[0];
|
||||
|
||||
if (Buffer.isBuffer(m)) {
|
||||
if (m.length !== 0)
|
||||
return false;
|
||||
m = 0;
|
||||
}
|
||||
|
||||
if (typeof m !== 'number')
|
||||
if (!(m >= opc['1'] && m <= opc['16']))
|
||||
return false;
|
||||
|
||||
m -= 0x50;
|
||||
|
||||
if (!(m >= 1 && m <= n))
|
||||
return false;
|
||||
|
||||
@ -1587,9 +1580,9 @@ Script.prototype.isScripthash = function isScripthash(hash) {
|
||||
if (this.code.length !== 3)
|
||||
return false;
|
||||
|
||||
res = this.code[0] === 'hash160'
|
||||
res = this.code[0] === opc.hash160
|
||||
&& Script.isHash(this.code[1])
|
||||
&& this.code[2] === 'equal';
|
||||
&& this.code[2] === opc.equal;
|
||||
|
||||
if (!res)
|
||||
return false;
|
||||
@ -1608,7 +1601,7 @@ Script.prototype.isNulldata = function isNulldata() {
|
||||
if (this.code.length !== 2)
|
||||
return false;
|
||||
|
||||
res = this.code[0] === 'return' && Script.isData(this.code[1]);
|
||||
res = this.code[0] === opc['return'] && Script.isData(this.code[1]);
|
||||
|
||||
if (!res)
|
||||
return false;
|
||||
@ -1618,7 +1611,7 @@ Script.prototype.isNulldata = function isNulldata() {
|
||||
|
||||
Script.prototype.isCommitment = function isCommitment() {
|
||||
return this.code.length >= 2
|
||||
&& this.code[0] === 'return'
|
||||
&& this.code[0] === opc['return']
|
||||
&& Buffer.isBuffer(this.code[1])
|
||||
&& this.code[1].length === 36
|
||||
&& utils.readU32BE(this.code[1], 0) === 0xaa21a9ed;
|
||||
@ -1641,7 +1634,7 @@ Script.prototype.isWitnessProgram = function isWitnessProgram() {
|
||||
if (!Buffer.isBuffer(this.code[1]))
|
||||
return false;
|
||||
|
||||
return this.code[0] >= 0 && this.code[0] <= 16
|
||||
return this.code[0] >= opc['0'] && this.code[0] <= opc['16']
|
||||
&& this.code[1].length >= 2 && this.code[1].length <= 32;
|
||||
};
|
||||
|
||||
@ -1657,9 +1650,9 @@ Script.prototype.getWitnessProgram = function getWitnessProgram() {
|
||||
if (version > 0) {
|
||||
// No interpretation of script (anyone can spend)
|
||||
type = 'unknown';
|
||||
} else if (version === 0 && data.length === 20) {
|
||||
} else if (version === opc['0'] && data.length === 20) {
|
||||
type = 'witnesspubkeyhash';
|
||||
} else if (version === 0 && data.length === 32) {
|
||||
} else if (version === opc['0'] && data.length === 32) {
|
||||
type = 'witnessscripthash';
|
||||
} else {
|
||||
// Fail on bad version=0
|
||||
@ -1667,7 +1660,7 @@ Script.prototype.getWitnessProgram = function getWitnessProgram() {
|
||||
}
|
||||
|
||||
return {
|
||||
version: version,
|
||||
version: version === opc['0'] ? 0 : version - 0x50,
|
||||
type: type,
|
||||
data: data
|
||||
};
|
||||
@ -1677,21 +1670,21 @@ Script.prototype.isWitnessPubkeyhash = function isWitnessPubkeyhash() {
|
||||
if (!this.isWitnessProgram())
|
||||
return false;
|
||||
|
||||
return this.code[0] === 0 && this.code[1].length === 20;
|
||||
return this.code[0] === opc['0'] && this.code[1].length === 20;
|
||||
};
|
||||
|
||||
Script.prototype.isWitnessScripthash = function isWitnessScripthash() {
|
||||
if (!this.isWitnessProgram())
|
||||
return false;
|
||||
|
||||
return this.code[0] === 0 && this.code[1].length === 32;
|
||||
return this.code[0] === opc['0'] && this.code[1].length === 32;
|
||||
};
|
||||
|
||||
Script.createWitnessProgram = function createWitnessProgram(version, data) {
|
||||
assert(typeof version === 'number' && version >= 0 && version <= 16);
|
||||
assert(Buffer.isBuffer(data));
|
||||
assert(data.length === 20 || data.length === 32);
|
||||
return new Script([version, data]);
|
||||
return new Script([opc[version], data]);
|
||||
};
|
||||
|
||||
Script.prototype.getInputType = function getInputType(prev) {
|
||||
@ -1769,8 +1762,8 @@ Script.createOutputScript = function(options) {
|
||||
if (options.locktime != null) {
|
||||
script = new Script([
|
||||
Script.array(options.locktime),
|
||||
'checklocktimeverify',
|
||||
'drop'
|
||||
opc.checklocktimeverify,
|
||||
opc.drop
|
||||
].concat(script.code));
|
||||
}
|
||||
redeem = script;
|
||||
@ -2217,7 +2210,7 @@ Script.format = function format(code) {
|
||||
return '[' + utils.toHex(chunk) + ']';
|
||||
|
||||
if (typeof chunk === 'number')
|
||||
return chunk + '';
|
||||
return constants.opcodesByVal[chunk] || chunk;
|
||||
|
||||
return chunk;
|
||||
}).join(' ');
|
||||
@ -2227,7 +2220,7 @@ Script.prototype.isPushOnly = function isPushOnly() {
|
||||
var i, op;
|
||||
for (i = 0; i < this.code.length; i++) {
|
||||
op = this.code[i];
|
||||
if (Buffer.isBuffer(op) || op === '1negate' || (op >= 0 && op <= 16))
|
||||
if (Buffer.isBuffer(op) || op === opc['1negate'] || op === opc['0'] || (op >= opc['1'] && op <= opc['16']))
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
@ -2248,10 +2241,10 @@ Script.prototype.getSigops = function getSigops(accurate) {
|
||||
if (constants.opcodes[op] == null)
|
||||
return 0;
|
||||
|
||||
if (op === 'checksig' || op === 'checksigverify') {
|
||||
if (op === opc.checksig || op === opc.checksigverify) {
|
||||
total++;
|
||||
} else if (op === 'checkmultisig' || op === 'checkmultisigverify') {
|
||||
if (accurate && lastOp >= 1 && lastOp <= 16)
|
||||
} else if (op === opc.checkmultisig || op === opc.checkmultisigverify) {
|
||||
if (accurate && lastOp >= opc['1'] && lastOp <= opc['16'])
|
||||
total += lastOp;
|
||||
else
|
||||
total += constants.script.maxPubkeysPerMultisig;
|
||||
@ -2274,7 +2267,7 @@ Script.prototype.getArgs = function getArgs() {
|
||||
|
||||
if (this.isMultisig()) {
|
||||
keys = this.code.slice(1, -2);
|
||||
m = this.code[0];
|
||||
m = this.code[0] - 0x50;
|
||||
if (keys.length < 1 || m < 1)
|
||||
return -1;
|
||||
return m + 1;
|
||||
@ -2332,9 +2325,11 @@ Script.fromString = function fromString(code) {
|
||||
op = op.substring(2);
|
||||
assert(utils.isHex(op), 'Non hex-string.');
|
||||
op = new Buffer(op, 'hex');
|
||||
code[i] = op;
|
||||
continue;
|
||||
}
|
||||
|
||||
code[i] = op;
|
||||
code[i] = constants.opcodes[op];
|
||||
}
|
||||
|
||||
return new Script(code);
|
||||
@ -2517,7 +2512,7 @@ Script.concat = function concat(scripts) {
|
||||
s = s.concat(scripts[0].code);
|
||||
|
||||
for (i = 1; i < scripts.length; i++) {
|
||||
s.push('codeseparator');
|
||||
s.push(opc.codeseparator);
|
||||
s = s.concat(scripts[i].code);
|
||||
}
|
||||
|
||||
@ -2575,12 +2570,6 @@ Script.decode = function decode(buf) {
|
||||
while (off < buf.length) {
|
||||
b = buf[off++];
|
||||
|
||||
// OP_0, OP_FALSE
|
||||
if (b === 0x00) {
|
||||
code.push(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Direct Push
|
||||
// Next `b` bytes should be pushed to stack
|
||||
if (b >= 0x01 && b <= 0x4b) {
|
||||
@ -2595,16 +2584,8 @@ Script.decode = function decode(buf) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
code.push(b - 0x50);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (off >= buf.length) {
|
||||
code.push(constants.opcodesByVal[b] || b);
|
||||
code.push(b);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -2642,7 +2623,7 @@ Script.decode = function decode(buf) {
|
||||
});
|
||||
}
|
||||
} else {
|
||||
code.push(constants.opcodesByVal[b] || b);
|
||||
code.push(b);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2705,9 +2686,9 @@ Script.encode = function encode(code) {
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(opcodes[op] != null || typeof op === 'number');
|
||||
assert(typeof op === 'number');
|
||||
|
||||
p.writeU8(opcodes[op] || op);
|
||||
p.writeU8(op);
|
||||
}
|
||||
|
||||
return p.render();
|
||||
|
||||
@ -3,6 +3,7 @@ var bcoin = require('../');
|
||||
var constants = bcoin.protocol.constants;
|
||||
var utils = bcoin.utils;
|
||||
var assert = utils.assert;
|
||||
var opc = constants.opcodes;
|
||||
|
||||
describe('Wallet', function() {
|
||||
process.env.BCOIN_DB = 'memdown';
|
||||
@ -30,7 +31,7 @@ describe('Wallet', function() {
|
||||
|
||||
// Coinbase
|
||||
var t1 = bcoin.mtx().addOutput(w, 50000).addOutput(w, 10000); // 10000 instead of 1000
|
||||
var prev = new bcoin.script([w.publicKey, 'checksig']);
|
||||
var prev = new bcoin.script([w.publicKey, opc['checksig']]);
|
||||
var dummyInput = {
|
||||
prevout: {
|
||||
hash: constants.oneHash,
|
||||
|
||||
@ -2,6 +2,7 @@ var assert = require('assert');
|
||||
var bcoin = require('../');
|
||||
var Script = bcoin.script;
|
||||
var Stack = bcoin.script.stack;
|
||||
var opc = bcoin.protocol.constants.opcodes;
|
||||
|
||||
describe('Script', function() {
|
||||
it('should encode/decode script', function() {
|
||||
@ -19,12 +20,13 @@ describe('Script', function() {
|
||||
assert.equal(
|
||||
bcoin.utils.toHex(decoded[1]),
|
||||
'101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f');
|
||||
assert.equal(decoded[2], 'checksig');
|
||||
assert.equal(decoded[2], opc['checksig']);
|
||||
|
||||
var dst = bcoin.script.encode(decoded);
|
||||
assert.equal(bcoin.utils.toHex(dst), src);
|
||||
});
|
||||
|
||||
if (0)
|
||||
it('should encode/decode numbers', function() {
|
||||
var script = [ 0, 1, 2, 16 ];
|
||||
var encoded = bcoin.script.encode(script);
|
||||
@ -48,40 +50,40 @@ describe('Script', function() {
|
||||
});
|
||||
|
||||
it('should handle if statements correctly', function () {
|
||||
var inputScript = new Script([1, 2]);
|
||||
var prevOutScript = new Script([2, 'equal', 'if', 3, 'else', 4, 'endif', 5]);
|
||||
var inputScript = new Script([opc['1'], opc['2']]);
|
||||
var prevOutScript = new Script([opc['2'], opc.equal, opc['if'], opc[3], opc['else'], opc[4], opc.endif, opc[5]]);
|
||||
var stack = new Stack();
|
||||
inputScript.execute(stack);
|
||||
var res = prevOutScript.execute(stack);
|
||||
assert(res);
|
||||
assert.deepEqual(stack.slice(), [[1], [3], [5]]);
|
||||
|
||||
var inputScript = new Script([1, 2]);
|
||||
var prevOutScript = new Script([9, 'equal', 'if', 3, 'else', 4, 'endif', 5]);
|
||||
var inputScript = new Script([opc[1], opc[2]]);
|
||||
var prevOutScript = new Script([opc[9], opc['equal'], opc['if'], opc[3], opc['else'], opc[4], opc['endif'], opc[5]]);
|
||||
var stack = new Stack();
|
||||
inputScript.execute(stack);
|
||||
var res = prevOutScript.execute(stack);
|
||||
assert(res);
|
||||
assert.deepEqual(stack.slice(), [[1], [4], [5]]);
|
||||
|
||||
var inputScript = new Script([1, 2]);
|
||||
var prevOutScript = new Script([2, 'equal', 'if', 3, 'endif', 5]);
|
||||
var inputScript = new Script([opc[1], opc[2]]);
|
||||
var prevOutScript = new Script([opc[2], opc['equal'], opc['if'], opc[3], opc['endif'], opc[5]]);
|
||||
var stack = new Stack();
|
||||
inputScript.execute(stack);
|
||||
var res = prevOutScript.execute(stack);
|
||||
assert(res);
|
||||
assert.deepEqual(stack.slice(), [[1], [3], [5]]);
|
||||
|
||||
var inputScript = new Script([1, 2]);
|
||||
var prevOutScript = new Script([9, 'equal', 'if', 3, 'endif', 5]);
|
||||
var inputScript = new Script([opc[1], opc[2]]);
|
||||
var prevOutScript = new Script([opc[9], opc['equal'], opc['if'], opc[3], opc['endif'], opc[5]]);
|
||||
var stack = new Stack();
|
||||
inputScript.execute(stack);
|
||||
var res = prevOutScript.execute(stack);
|
||||
assert(res);
|
||||
assert.deepEqual(stack.slice(), [[1], [5]]);
|
||||
|
||||
var inputScript = new Script([1, 2]);
|
||||
var prevOutScript = new Script([9, 'equal', 'notif', 3, 'endif', 5]);
|
||||
var inputScript = new Script([opc[1], opc[2]]);
|
||||
var prevOutScript = new Script([opc[9], opc['equal'], opc['notif'], opc[3], opc['endif'], opc[5]]);
|
||||
var stack = new Stack();
|
||||
inputScript.execute(stack);
|
||||
var res = prevOutScript.execute(stack);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user