script: start using scriptnum implementation.
This commit is contained in:
parent
1b0ae3ca79
commit
a6b2c23a41
@ -3,13 +3,13 @@ Scripts are array-like objects with some helper functions.
|
||||
``` js
|
||||
var bcoin = require('bcoin');
|
||||
var assert = require('assert');
|
||||
var BN = bcoin.bn;
|
||||
var ScriptNum = bcoin.scriptnum;
|
||||
var opcodes = bcoin.script.opcodes;
|
||||
|
||||
var output = new bcoin.script();
|
||||
output.push(opcodes.OP_DROP);
|
||||
output.push(opcodes.OP_ADD);
|
||||
output.push(new BN(7));
|
||||
output.push(new ScriptNum(7));
|
||||
output.push(opcodes.OP_NUMEQUAL);
|
||||
// Compile the script to its binary representation
|
||||
// (you must do this if you change something!).
|
||||
@ -18,8 +18,8 @@ assert(output.getSmall(2) === 7); // compiled as OP_7
|
||||
|
||||
var input = new bcoin.script();
|
||||
input.set(0, 'hello world'); // add some metadata
|
||||
input.push(new BN(2));
|
||||
input.push(new BN(5));
|
||||
input.push(new ScriptNum(2));
|
||||
input.push(new ScriptNum(5));
|
||||
input.push(input.shift());
|
||||
assert(input.getString(2) === 'hello world');
|
||||
input.compile();
|
||||
@ -40,10 +40,10 @@ Stack object (an array-like object containing Buffers).
|
||||
|
||||
``` js
|
||||
var witness = new bcoin.witness();
|
||||
witness.push(new BN(2));
|
||||
witness.push(new BN(5));
|
||||
witness.push(new ScriptNum(2));
|
||||
witness.push(new ScriptNum(5));
|
||||
witness.push('hello world');
|
||||
|
||||
var stack = witness.toStack();
|
||||
output.execute(stack);
|
||||
```
|
||||
```
|
||||
|
||||
@ -240,6 +240,7 @@ bcoin.txscript = require('./script');
|
||||
bcoin.opcode = require('./script/opcode');
|
||||
bcoin.program = require('./script/program');
|
||||
bcoin.script = require('./script/script');
|
||||
bcoin.scriptnum = require('./script/scriptnum');
|
||||
bcoin.sigcache = require('./script/sigcache');
|
||||
bcoin.stack = require('./script/stack');
|
||||
bcoin.witness = require('./script/witness');
|
||||
|
||||
@ -277,6 +277,7 @@ bcoin.define('txscript', './script');
|
||||
bcoin.define('opcode', './script/opcode');
|
||||
bcoin.define('program', './script/program');
|
||||
bcoin.define('script', './script/script');
|
||||
bcoin.define('scriptnum', './script/scriptnum');
|
||||
bcoin.define('sigcache', './script/sigcache');
|
||||
bcoin.define('stack', './script/stack');
|
||||
bcoin.define('witness', './script/witness');
|
||||
|
||||
@ -11,7 +11,6 @@ const assert = require('assert');
|
||||
const util = require('../utils/util');
|
||||
const digest = require('../crypto/digest');
|
||||
const merkle = require('../crypto/merkle');
|
||||
const BN = require('../crypto/bn');
|
||||
const StaticWriter = require('../utils/staticwriter');
|
||||
const Address = require('../primitives/address');
|
||||
const TX = require('../primitives/tx');
|
||||
@ -23,6 +22,7 @@ const policy = require('../protocol/policy');
|
||||
const encoding = require('../utils/encoding');
|
||||
const CoinView = require('../coins/coinview');
|
||||
const Script = require('../script/script');
|
||||
const ScriptNum = require('../script/scriptnum');
|
||||
const common = require('./common');
|
||||
const DUMMY = Buffer.alloc(0);
|
||||
|
||||
@ -241,7 +241,8 @@ BlockTemplate.prototype.createCoinbase = function createCoinbase(hash) {
|
||||
const input = new Input();
|
||||
|
||||
// Height (required in v2+ blocks)
|
||||
input.script.push(new BN(this.height));
|
||||
const height = ScriptNum.fromNumber(this.height);
|
||||
input.script.push(height);
|
||||
|
||||
// Coinbase flags.
|
||||
input.script.push(encoding.ZERO_HASH160);
|
||||
|
||||
@ -12,7 +12,6 @@
|
||||
*/
|
||||
|
||||
const assert = require('assert');
|
||||
const BN = require('../crypto/bn');
|
||||
const util = require('../utils/util');
|
||||
const secp256k1 = require('../crypto/secp256k1');
|
||||
|
||||
@ -532,6 +531,28 @@ exports.isSignatureEncoding = function isSignatureEncoding(sig) {
|
||||
return true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Cast a big number or Buffer to a bool.
|
||||
* @see CastToBool
|
||||
* @param {Buffer} value
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
exports.toBool = function toBool(value) {
|
||||
assert(Buffer.isBuffer(value));
|
||||
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
if (value[i] !== 0) {
|
||||
// Cannot be negative zero
|
||||
if (i === value.length - 1 && value[i] === 0x80)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Format script code into a human readable-string.
|
||||
* @param {Array} code
|
||||
@ -692,109 +713,6 @@ exports.formatStackASM = function formatStackASM(items, decode) {
|
||||
return out.join(' ');
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a CScriptNum.
|
||||
* @param {Buffer} value
|
||||
* @param {Boolean?} minimal
|
||||
* @param {Number?} size - Max size in bytes.
|
||||
* @returns {BN}
|
||||
* @throws {ScriptError}
|
||||
*/
|
||||
|
||||
exports.num = function num(value, minimal, size) {
|
||||
assert(Buffer.isBuffer(value));
|
||||
|
||||
if (size == null)
|
||||
size = 4;
|
||||
|
||||
if (value.length > size)
|
||||
throw new exports.ScriptError('UNKNOWN_ERROR', 'Script number overflow.');
|
||||
|
||||
if (minimal && value.length > 0) {
|
||||
// If the low bits on the last byte are unset,
|
||||
// fail if the value's second to last byte does
|
||||
// not have the high bit set. A number can't
|
||||
// justify having the last byte's low bits unset
|
||||
// unless they ran out of space for the sign bit
|
||||
// in the second to last bit. We also fail on [0]
|
||||
// to avoid negative zero (also avoids positive
|
||||
// zero).
|
||||
if (!(value[value.length - 1] & 0x7f)) {
|
||||
if (value.length === 1 || !(value[value.length - 2] & 0x80)) {
|
||||
throw new exports.ScriptError(
|
||||
'UNKNOWN_ERROR',
|
||||
'Non-minimally encoded Script number.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (value.length === 0)
|
||||
return new BN(0);
|
||||
|
||||
const result = new BN(value, 'le');
|
||||
|
||||
// If the input vector's most significant byte is
|
||||
// 0x80, remove it from the result's msb and return
|
||||
// a negative.
|
||||
// Equivalent to:
|
||||
// -(result & ~(0x80 << (8 * (value.length - 1))))
|
||||
if (value[value.length - 1] & 0x80)
|
||||
result.setn((value.length * 8) - 1, 0).ineg();
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a script array. Will convert Numbers and big
|
||||
* numbers to a little-endian buffer while taking into
|
||||
* account negative zero, minimaldata, etc.
|
||||
* @example
|
||||
* assert.deepEqual(Script.array(0), Buffer.alloc(0));
|
||||
* assert.deepEqual(Script.array(0xffee), Buffer.from('eeff00', 'hex'));
|
||||
* assert.deepEqual(Script.array(new BN(0xffee)), Buffer.from('eeff00', 'hex'));
|
||||
* assert.deepEqual(Script.array(new BN(0x1e).neg()), Buffer.from('9e', 'hex'));
|
||||
* @param {Number|BN} value
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
exports.array = function array(value) {
|
||||
if (typeof value === 'number') {
|
||||
assert(util.isInt(value));
|
||||
value = new BN(value);
|
||||
}
|
||||
|
||||
assert(BN.isBN(value));
|
||||
|
||||
if (value.cmpn(0) === 0)
|
||||
return exports.STACK_FALSE;
|
||||
|
||||
// If the most significant byte is >= 0x80
|
||||
// and the value is positive, push a new
|
||||
// zero-byte to make the significant
|
||||
// byte < 0x80 again.
|
||||
|
||||
// If the most significant byte is >= 0x80
|
||||
// and the value is negative, push a new
|
||||
// 0x80 byte that will be popped off when
|
||||
// converting to an integral.
|
||||
|
||||
// If the most significant byte is < 0x80
|
||||
// and the value is negative, add 0x80 to
|
||||
// it, since it will be subtracted and
|
||||
// interpreted as a negative when
|
||||
// converting to an integral.
|
||||
|
||||
const neg = value.cmpn(0) < 0;
|
||||
const result = value.toArray('le');
|
||||
|
||||
if (result[result.length - 1] & 0x80)
|
||||
result.push(neg ? 0x80 : 0);
|
||||
else if (neg)
|
||||
result[result.length - 1] |= 0x80;
|
||||
|
||||
return Buffer.from(result);
|
||||
};
|
||||
|
||||
/**
|
||||
* An error thrown from the scripting system,
|
||||
* potentially pertaining to Script execution.
|
||||
|
||||
@ -14,7 +14,7 @@ exports.common = require('./common');
|
||||
exports.Opcode = require('./opcode');
|
||||
exports.Program = require('./program');
|
||||
exports.Script = require('./script');
|
||||
// exports.ScriptNum = require('./scriptnum');
|
||||
exports.ScriptNum = require('./scriptnum');
|
||||
exports.sigcache = require('./sigcache');
|
||||
exports.Stack = require('./stack');
|
||||
exports.Witness = require('./witness');
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const BN = require('../crypto/bn');
|
||||
const ScriptNum = require('./scriptnum');
|
||||
const util = require('../utils/util');
|
||||
const common = require('./common');
|
||||
const BufferReader = require('../utils/reader');
|
||||
@ -334,12 +334,23 @@ Opcode.fromPush = function fromPush(data) {
|
||||
|
||||
/**
|
||||
* Instantiate an opcode from a Number.
|
||||
* @param {Number|BN} num
|
||||
* @param {Number|ScriptNum|BN} num
|
||||
* @returns {Opcode}
|
||||
*/
|
||||
|
||||
Opcode.fromNumber = function fromNumber(num) {
|
||||
return Opcode.fromData(common.array(num));
|
||||
return Opcode.fromData(ScriptNum.encode(num));
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate an opcode from a Number.
|
||||
* @param {Boolean} value
|
||||
* @returns {Opcode}
|
||||
*/
|
||||
|
||||
Opcode.fromBool = function fromBool(value) {
|
||||
assert(typeof value === 'boolean');
|
||||
return Opcode.fromSmall(value ? 1 : 0);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -368,7 +379,7 @@ Opcode.fromString = function fromString(data, enc) {
|
||||
|
||||
/**
|
||||
* Instantiate a pushdata opcode from anything.
|
||||
* @param {String|Buffer|Number|BN|Opcode} data
|
||||
* @param {String|Buffer|Number|ScriptNum|Opcode} data
|
||||
* @returns {Opcode}
|
||||
*/
|
||||
|
||||
@ -385,7 +396,10 @@ Opcode.from = function from(data) {
|
||||
if (typeof data === 'string')
|
||||
return Opcode.fromString(data, 'utf8');
|
||||
|
||||
if (BN.isBN(data))
|
||||
if (typeof data === 'boolean')
|
||||
return Opcode.fromBool(data);
|
||||
|
||||
if (ScriptNum.isEncodable(data))
|
||||
return Opcode.fromNumber(data);
|
||||
|
||||
throw new Error('Bad data for opcode.');
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const BN = require('../crypto/bn');
|
||||
const consensus = require('../protocol/consensus');
|
||||
const policy = require('../protocol/policy');
|
||||
const util = require('../utils/util');
|
||||
@ -20,6 +19,7 @@ const StaticWriter = require('../utils/staticwriter');
|
||||
const Program = require('./program');
|
||||
const Opcode = require('./opcode');
|
||||
const Stack = require('./stack');
|
||||
const ScriptNum = require('./scriptnum');
|
||||
const common = require('./common');
|
||||
const encoding = require('../utils/encoding');
|
||||
const secp256k1 = require('../crypto/secp256k1');
|
||||
@ -27,9 +27,7 @@ const Address = require('../primitives/address');
|
||||
const opcodes = common.opcodes;
|
||||
const scriptTypes = common.types;
|
||||
const ScriptError = common.ScriptError;
|
||||
const STACK_TRUE = common.STACK_TRUE;
|
||||
const STACK_FALSE = common.STACK_FALSE;
|
||||
const STACK_NEGATE = common.STACK_NEGATE;
|
||||
|
||||
/**
|
||||
* Represents a input or output script.
|
||||
@ -521,17 +519,14 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
|
||||
switch (op.value) {
|
||||
case opcodes.OP_0: {
|
||||
stack.push(STACK_FALSE);
|
||||
stack.pushInt(0);
|
||||
break;
|
||||
}
|
||||
case opcodes.OP_1NEGATE: {
|
||||
stack.push(STACK_NEGATE);
|
||||
break;
|
||||
}
|
||||
case opcodes.OP_1: {
|
||||
stack.push(STACK_TRUE);
|
||||
stack.pushInt(-1);
|
||||
break;
|
||||
}
|
||||
case opcodes.OP_1:
|
||||
case opcodes.OP_2:
|
||||
case opcodes.OP_3:
|
||||
case opcodes.OP_4:
|
||||
@ -547,7 +542,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
case opcodes.OP_14:
|
||||
case opcodes.OP_15:
|
||||
case opcodes.OP_16: {
|
||||
stack.push(Buffer.from([op.value - 0x50]));
|
||||
stack.pushInt(op.value - 0x50);
|
||||
break;
|
||||
}
|
||||
case opcodes.OP_NOP: {
|
||||
@ -567,9 +562,9 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
if (stack.length === 0)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', op, ip);
|
||||
|
||||
let locktime = Script.num(stack.top(-1), minimal, 5);
|
||||
let locktime = stack.num(-1, minimal, 5);
|
||||
|
||||
if (locktime.cmpn(0) < 0)
|
||||
if (locktime.isNeg())
|
||||
throw new ScriptError('NEGATIVE_LOCKTIME', op, ip);
|
||||
|
||||
locktime = locktime.toNumber();
|
||||
@ -593,9 +588,9 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
if (stack.length === 0)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', op, ip);
|
||||
|
||||
let locktime = Script.num(stack.top(-1), minimal, 5);
|
||||
let locktime = stack.num(-1, minimal, 5);
|
||||
|
||||
if (locktime.cmpn(0) < 0)
|
||||
if (locktime.isNeg())
|
||||
throw new ScriptError('NEGATIVE_LOCKTIME', op, ip);
|
||||
|
||||
locktime = locktime.toNumber();
|
||||
@ -625,17 +620,17 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
if (stack.length < 1)
|
||||
throw new ScriptError('UNBALANCED_CONDITIONAL', op, ip);
|
||||
|
||||
val = stack.top(-1);
|
||||
|
||||
if (version === 1 && (flags & Script.flags.VERIFY_MINIMALIF)) {
|
||||
if (val.length > 1)
|
||||
const item = stack.top(-1);
|
||||
|
||||
if (item.length > 1)
|
||||
throw new ScriptError('MINIMALIF');
|
||||
|
||||
if (val.length === 1 && val[0] !== 1)
|
||||
if (item.length === 1 && item[0] !== 1)
|
||||
throw new ScriptError('MINIMALIF');
|
||||
}
|
||||
|
||||
val = Script.bool(val);
|
||||
val = stack.bool(-1);
|
||||
|
||||
if (op.value === opcodes.OP_NOTIF)
|
||||
val = !val;
|
||||
@ -676,7 +671,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
if (stack.length === 0)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', op, ip);
|
||||
|
||||
if (!Script.bool(stack.top(-1)))
|
||||
if (!stack.bool(-1))
|
||||
throw new ScriptError('VERIFY', op, ip);
|
||||
|
||||
stack.pop();
|
||||
@ -767,14 +762,15 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
if (stack.length === 0)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', op, ip);
|
||||
|
||||
const val = stack.top(-1);
|
||||
|
||||
if (Script.bool(val))
|
||||
if (stack.bool(-1)) {
|
||||
const val = stack.top(-1);
|
||||
stack.push(val);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case opcodes.OP_DEPTH: {
|
||||
stack.push(Script.array(stack.length));
|
||||
stack.pushInt(stack.length);
|
||||
break;
|
||||
}
|
||||
case opcodes.OP_DROP: {
|
||||
@ -810,7 +806,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
if (stack.length < 2)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', op, ip);
|
||||
|
||||
const num = Script.num(stack.top(-1), minimal).toNumber();
|
||||
const num = stack.int(-1, minimal);
|
||||
stack.pop();
|
||||
|
||||
if (num < 0 || num >= stack.length)
|
||||
@ -850,7 +846,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
if (stack.length < 1)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', op, ip);
|
||||
|
||||
stack.push(Script.array(stack.top(-1).length));
|
||||
stack.pushInt(stack.top(-1).length);
|
||||
break;
|
||||
}
|
||||
case opcodes.OP_EQUAL:
|
||||
@ -866,7 +862,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
stack.pop();
|
||||
stack.pop();
|
||||
|
||||
stack.push(res ? STACK_TRUE : STACK_FALSE);
|
||||
stack.pushBool(res);
|
||||
|
||||
if (op.value === opcodes.OP_EQUALVERIFY) {
|
||||
if (!res)
|
||||
@ -885,7 +881,8 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
if (stack.length < 1)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', op, ip);
|
||||
|
||||
let num = Script.num(stack.top(-1), minimal);
|
||||
let num = stack.num(-1, minimal);
|
||||
let cmp;
|
||||
|
||||
switch (op.value) {
|
||||
case opcodes.OP_1ADD:
|
||||
@ -901,12 +898,12 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
num.iabs();
|
||||
break;
|
||||
case opcodes.OP_NOT:
|
||||
num = num.cmpn(0) === 0;
|
||||
num = new BN(num ? 1 : 0);
|
||||
cmp = num.isZero();
|
||||
num = ScriptNum.fromBool(cmp);
|
||||
break;
|
||||
case opcodes.OP_0NOTEQUAL:
|
||||
num = num.cmpn(0) !== 0;
|
||||
num = new BN(num ? 1 : 0);
|
||||
cmp = !num.isZero();
|
||||
num = ScriptNum.fromBool(cmp);
|
||||
break;
|
||||
default:
|
||||
assert(false, 'Fatal script error.');
|
||||
@ -914,7 +911,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
}
|
||||
|
||||
stack.pop();
|
||||
stack.push(Script.array(num));
|
||||
stack.pushNum(num);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -934,9 +931,9 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
if (stack.length < 2)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', op, ip);
|
||||
|
||||
const n1 = Script.num(stack.top(-2), minimal);
|
||||
const n2 = Script.num(stack.top(-1), minimal);
|
||||
let num;
|
||||
const n1 = stack.num(-2, minimal);
|
||||
const n2 = stack.num(-1, minimal);
|
||||
let num, cmp;
|
||||
|
||||
switch (op.value) {
|
||||
case opcodes.OP_ADD:
|
||||
@ -946,46 +943,46 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
num = n1.isub(n2);
|
||||
break;
|
||||
case opcodes.OP_BOOLAND:
|
||||
num = n1.cmpn(0) !== 0 && n2.cmpn(0) !== 0;
|
||||
num = new BN(num ? 1 : 0);
|
||||
cmp = n1.toBool() && n2.toBool();
|
||||
num = ScriptNum.fromBool(cmp);
|
||||
break;
|
||||
case opcodes.OP_BOOLOR:
|
||||
num = n1.cmpn(0) !== 0 || n2.cmpn(0) !== 0;
|
||||
num = new BN(num ? 1 : 0);
|
||||
cmp = n1.toBool() || n2.toBool();
|
||||
num = ScriptNum.fromBool(cmp);
|
||||
break;
|
||||
case opcodes.OP_NUMEQUAL:
|
||||
num = n1.cmp(n2) === 0;
|
||||
num = new BN(num ? 1 : 0);
|
||||
cmp = n1.eq(n2);
|
||||
num = ScriptNum.fromBool(cmp);
|
||||
break;
|
||||
case opcodes.OP_NUMEQUALVERIFY:
|
||||
num = n1.cmp(n2) === 0;
|
||||
num = new BN(num ? 1 : 0);
|
||||
cmp = n1.eq(n2);
|
||||
num = ScriptNum.fromBool(cmp);
|
||||
break;
|
||||
case opcodes.OP_NUMNOTEQUAL:
|
||||
num = n1.cmp(n2) !== 0;
|
||||
num = new BN(num ? 1 : 0);
|
||||
cmp = !n1.eq(n2);
|
||||
num = ScriptNum.fromBool(cmp);
|
||||
break;
|
||||
case opcodes.OP_LESSTHAN:
|
||||
num = n1.cmp(n2) < 0;
|
||||
num = new BN(num ? 1 : 0);
|
||||
cmp = n1.lt(n2);
|
||||
num = ScriptNum.fromBool(cmp);
|
||||
break;
|
||||
case opcodes.OP_GREATERTHAN:
|
||||
num = n1.cmp(n2) > 0;
|
||||
num = new BN(num ? 1 : 0);
|
||||
cmp = n1.gt(n2);
|
||||
num = ScriptNum.fromBool(cmp);
|
||||
break;
|
||||
case opcodes.OP_LESSTHANOREQUAL:
|
||||
num = n1.cmp(n2) <= 0;
|
||||
num = new BN(num ? 1 : 0);
|
||||
cmp = n1.lte(n2);
|
||||
num = ScriptNum.fromBool(cmp);
|
||||
break;
|
||||
case opcodes.OP_GREATERTHANOREQUAL:
|
||||
num = n1.cmp(n2) >= 0;
|
||||
num = new BN(num ? 1 : 0);
|
||||
cmp = n1.gte(n2);
|
||||
num = ScriptNum.fromBool(cmp);
|
||||
break;
|
||||
case opcodes.OP_MIN:
|
||||
num = n1.cmp(n2) < 0 ? n1 : n2;
|
||||
num = ScriptNum.min(n1, n2);
|
||||
break;
|
||||
case opcodes.OP_MAX:
|
||||
num = n1.cmp(n2) > 0 ? n1 : n2;
|
||||
num = ScriptNum.max(n1, n2);
|
||||
break;
|
||||
default:
|
||||
assert(false, 'Fatal script error.');
|
||||
@ -994,10 +991,10 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
|
||||
stack.pop();
|
||||
stack.pop();
|
||||
stack.push(Script.array(num));
|
||||
stack.pushNum(num);
|
||||
|
||||
if (op.value === opcodes.OP_NUMEQUALVERIFY) {
|
||||
if (!Script.bool(stack.top(-1)))
|
||||
if (!stack.bool(-1))
|
||||
throw new ScriptError('NUMEQUALVERIFY', op, ip);
|
||||
stack.pop();
|
||||
}
|
||||
@ -1008,17 +1005,17 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
if (stack.length < 3)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', op, ip);
|
||||
|
||||
const n1 = Script.num(stack.top(-3), minimal);
|
||||
const n2 = Script.num(stack.top(-2), minimal);
|
||||
const n3 = Script.num(stack.top(-1), minimal);
|
||||
const n1 = stack.num(-3, minimal);
|
||||
const n2 = stack.num(-2, minimal);
|
||||
const n3 = stack.num(-1, minimal);
|
||||
|
||||
const val = n2.cmp(n1) <= 0 && n1.cmp(n3) < 0;
|
||||
const val = n2.lte(n1) && n1.lt(n3);
|
||||
|
||||
stack.pop();
|
||||
stack.pop();
|
||||
stack.pop();
|
||||
|
||||
stack.push(val ? STACK_TRUE : STACK_FALSE);
|
||||
stack.pushBool(val);
|
||||
break;
|
||||
}
|
||||
case opcodes.OP_RIPEMD160: {
|
||||
@ -1095,7 +1092,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
stack.pop();
|
||||
stack.pop();
|
||||
|
||||
stack.push(res ? STACK_TRUE : STACK_FALSE);
|
||||
stack.pushBool(res);
|
||||
|
||||
if (op.value === opcodes.OP_CHECKSIGVERIFY) {
|
||||
if (!res)
|
||||
@ -1114,7 +1111,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
if (stack.length < i)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', op, ip);
|
||||
|
||||
let n = Script.num(stack.top(-i), minimal).toNumber();
|
||||
let n = stack.int(-i, minimal);
|
||||
let ikey2 = n + 2;
|
||||
|
||||
if (!(n >= 0 && n <= consensus.MAX_MULTISIG_PUBKEYS))
|
||||
@ -1132,7 +1129,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
if (stack.length < i)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', op, ip);
|
||||
|
||||
let m = Script.num(stack.top(-i), minimal).toNumber();
|
||||
let m = stack.int(-i, minimal);
|
||||
|
||||
if (!(m >= 0 && m <= n))
|
||||
throw new ScriptError('SIG_COUNT', op, ip);
|
||||
@ -1203,7 +1200,7 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
|
||||
stack.pop();
|
||||
|
||||
stack.push(res ? STACK_TRUE : STACK_FALSE);
|
||||
stack.pushBool(res);
|
||||
|
||||
if (op.value === opcodes.OP_CHECKMULTISIGVERIFY) {
|
||||
if (!res)
|
||||
@ -1226,58 +1223,6 @@ Script.prototype.execute = function execute(stack, flags, tx, index, value, vers
|
||||
throw new ScriptError('UNBALANCED_CONDITIONAL');
|
||||
};
|
||||
|
||||
/**
|
||||
* Cast a big number or Buffer to a bool.
|
||||
* @see CastToBool
|
||||
* @param {BN|Buffer} value
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Script.bool = function bool(value) {
|
||||
assert(Buffer.isBuffer(value));
|
||||
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
if (value[i] !== 0) {
|
||||
// Cannot be negative zero
|
||||
if (i === value.length - 1 && value[i] === 0x80)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a CScriptNum.
|
||||
* @param {Buffer} value
|
||||
* @param {Boolean?} minimal
|
||||
* @param {Number?} size - Max size in bytes.
|
||||
* @returns {BN}
|
||||
* @throws {ScriptError}
|
||||
*/
|
||||
|
||||
Script.num = function num(value, minimal, size) {
|
||||
return common.num(value, minimal, size);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a script array. Will convert Numbers and big
|
||||
* numbers to a little-endian buffer while taking into
|
||||
* account negative zero, minimaldata, etc.
|
||||
* @example
|
||||
* assert.deepEqual(Script.array(0), Buffer.alloc(0));
|
||||
* assert.deepEqual(Script.array(0xffee), Buffer.from('eeff00', 'hex'));
|
||||
* assert.deepEqual(Script.array(new BN(0xffee)), Buffer.from('eeff00', 'hex'));
|
||||
* assert.deepEqual(Script.array(new BN(0x1e).neg()), Buffer.from('9e', 'hex'));
|
||||
* @param {Number|BN} value
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
Script.array = function array(value) {
|
||||
return common.array(value);
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove all matched data elements from
|
||||
* a script's code (used to remove signatures
|
||||
@ -2288,7 +2233,7 @@ Script.getCoinbaseHeight = function getCoinbaseHeight(raw) {
|
||||
// Deserialize the height.
|
||||
let height;
|
||||
try {
|
||||
height = Script.num(data, true, 6);
|
||||
height = ScriptNum.decode(data, true, 6);
|
||||
} catch (e) {
|
||||
return -1;
|
||||
}
|
||||
@ -2331,7 +2276,7 @@ Script.prototype.test = function test(filter) {
|
||||
|
||||
/**
|
||||
* Unshift an item onto the `code` array.
|
||||
* @param {Number|String|BN|Buffer} data
|
||||
* @param {Number|String|ScriptNum|Buffer} data
|
||||
* @returns {Number} Length.
|
||||
*/
|
||||
|
||||
@ -2341,7 +2286,7 @@ Script.prototype.unshift = function unshift(data) {
|
||||
|
||||
/**
|
||||
* Push an item onto the `code` array.
|
||||
* @param {Number|String|BN|Buffer} data
|
||||
* @param {Number|String|ScriptNum|Buffer} data
|
||||
* @returns {Number} Length.
|
||||
*/
|
||||
|
||||
@ -2395,7 +2340,7 @@ Script.prototype.remove = function remove(i) {
|
||||
/**
|
||||
* Insert an item into the `code` array.
|
||||
* @param {Number} index
|
||||
* @param {Number|String|BN|Buffer} data
|
||||
* @param {Number|String|ScriptNum|Buffer} data
|
||||
*/
|
||||
|
||||
Script.prototype.insert = function insert(i, data) {
|
||||
@ -2436,7 +2381,7 @@ Script.prototype.getSmall = function getSmall(i) {
|
||||
/**
|
||||
* Get a number from the `code` array (5-byte limit).
|
||||
* @params {Number} index
|
||||
* @returns {BN}
|
||||
* @returns {ScriptNum}
|
||||
*/
|
||||
|
||||
Script.prototype.getNumber = function getNumber(i) {
|
||||
@ -2444,12 +2389,12 @@ Script.prototype.getNumber = function getNumber(i) {
|
||||
const op = this.code[i];
|
||||
|
||||
if (small !== -1)
|
||||
return new BN(small);
|
||||
return ScriptNum.fromInt(small);
|
||||
|
||||
if (!op || !op.data || op.data.length > 5)
|
||||
return null;
|
||||
|
||||
return Script.num(op.data, false, 5);
|
||||
return ScriptNum.decode(op.data, false, 5);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -2478,7 +2423,7 @@ Script.prototype.clear = function clear() {
|
||||
/**
|
||||
* Set an item in the `code` array.
|
||||
* @param {Number} index
|
||||
* @param {Buffer|Number|String|BN} data
|
||||
* @param {Buffer|Number|String|ScriptNum} data
|
||||
*/
|
||||
|
||||
Script.prototype.set = function set(i, data) {
|
||||
@ -2688,7 +2633,7 @@ Script.prototype.fromString = function fromString(code) {
|
||||
}
|
||||
|
||||
if (/^-?\d+$/.test(item)) {
|
||||
const num = new BN(item, 10);
|
||||
const num = ScriptNum.fromString(item, 10);
|
||||
const op = Opcode.fromNumber(num);
|
||||
bw.writeBytes(op.toRaw());
|
||||
continue;
|
||||
@ -2760,7 +2705,7 @@ Script.verify = function verify(input, witness, output, tx, index, value, flags)
|
||||
output.execute(stack, flags, tx, index, value, 0);
|
||||
|
||||
// Verify the stack values.
|
||||
if (stack.length === 0 || !Script.bool(stack.top(-1)))
|
||||
if (stack.length === 0 || !stack.bool(-1))
|
||||
throw new ScriptError('EVAL_FALSE');
|
||||
|
||||
let hadWitness = false;
|
||||
@ -2800,7 +2745,7 @@ Script.verify = function verify(input, witness, output, tx, index, value, flags)
|
||||
redeem.execute(stack, flags, tx, index, value, 0);
|
||||
|
||||
// Verify the the stack values.
|
||||
if (stack.length === 0 || !Script.bool(stack.top(-1)))
|
||||
if (stack.length === 0 || !stack.bool(-1))
|
||||
throw new ScriptError('EVAL_FALSE');
|
||||
|
||||
if ((flags & Script.flags.VERIFY_WITNESS) && redeem.isProgram()) {
|
||||
@ -2901,7 +2846,7 @@ Script.verifyProgram = function verifyProgram(witness, output, flags, tx, index,
|
||||
redeem.execute(stack, flags, tx, index, value, 1);
|
||||
|
||||
// Verify the stack values.
|
||||
if (stack.length !== 1 || !Script.bool(stack.top(-1)))
|
||||
if (stack.length !== 1 || !stack.bool(-1))
|
||||
throw new ScriptError('EVAL_FALSE');
|
||||
};
|
||||
|
||||
|
||||
@ -7,7 +7,13 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const common = require('./common');
|
||||
const ScriptNum = require('./scriptnum');
|
||||
const ScriptError = common.ScriptError;
|
||||
const STACK_FALSE = common.STACK_FALSE;
|
||||
const STACK_TRUE = common.STACK_TRUE;
|
||||
const STACK_NEGATE = common.STACK_NEGATE;
|
||||
|
||||
/**
|
||||
* Represents the stack of a Script during execution.
|
||||
@ -84,9 +90,63 @@ Stack.prototype.clone = function clone() {
|
||||
*/
|
||||
|
||||
Stack.prototype.push = function push(item) {
|
||||
assert(Buffer.isBuffer(item));
|
||||
return this.items.push(item);
|
||||
};
|
||||
|
||||
/**
|
||||
* Push boolean onto stack.
|
||||
* @see Array#push
|
||||
* @param {Boolean} value
|
||||
* @returns {Number} Stack size.
|
||||
*/
|
||||
|
||||
Stack.prototype.pushBool = function pushBool(value) {
|
||||
assert(typeof value === 'boolean');
|
||||
return this.items.push(value ? STACK_TRUE : STACK_FALSE);
|
||||
};
|
||||
|
||||
/**
|
||||
* Push script number onto stack.
|
||||
* @see Array#push
|
||||
* @param {ScriptNum} num
|
||||
* @returns {Number} Stack size.
|
||||
*/
|
||||
|
||||
Stack.prototype.pushNum = function pushNum(num) {
|
||||
assert(ScriptNum.isScriptNum(num));
|
||||
return this.items.push(num.encode());
|
||||
};
|
||||
|
||||
/**
|
||||
* Push integer onto stack.
|
||||
* @see Array#push
|
||||
* @param {Number} value
|
||||
* @returns {Number} Stack size.
|
||||
*/
|
||||
|
||||
Stack.prototype.pushInt = function pushInt(value) {
|
||||
assert(typeof value === 'number');
|
||||
|
||||
if (value >= -1 && value <= 16) {
|
||||
switch (value) {
|
||||
case -1:
|
||||
return this.items.push(STACK_NEGATE);
|
||||
case 0:
|
||||
return this.items.push(STACK_FALSE);
|
||||
case 1:
|
||||
return this.items.push(STACK_TRUE);
|
||||
}
|
||||
const item = Buffer.allocUnsafe(1);
|
||||
item[0] = value;
|
||||
return this.items.push(item);
|
||||
}
|
||||
|
||||
const num = ScriptNum.fromNumber(value);
|
||||
|
||||
return this.items.push(num.encode());
|
||||
};
|
||||
|
||||
/**
|
||||
* Unshift item from stack.
|
||||
* @see Array#unshift
|
||||
@ -95,6 +155,7 @@ Stack.prototype.push = function push(item) {
|
||||
*/
|
||||
|
||||
Stack.prototype.unshift = function unshift(item) {
|
||||
assert(Buffer.isBuffer(item));
|
||||
return this.items.unshift(item);
|
||||
};
|
||||
|
||||
@ -127,6 +188,8 @@ Stack.prototype.splice = function splice(i, remove, insert) {
|
||||
if (insert === undefined)
|
||||
return this.items.splice(i, remove);
|
||||
|
||||
assert(Buffer.isBuffer(insert));
|
||||
|
||||
return this.items.splice(i, remove, insert);
|
||||
};
|
||||
|
||||
@ -158,6 +221,8 @@ Stack.prototype.insert = function insert(i, item) {
|
||||
if (i < 0)
|
||||
i = this.items.length + i;
|
||||
|
||||
assert(Buffer.isBuffer(item));
|
||||
|
||||
this.items.splice(i, 0, item);
|
||||
};
|
||||
|
||||
@ -204,9 +269,69 @@ Stack.prototype.shift = function shift() {
|
||||
*/
|
||||
|
||||
Stack.prototype.get = function get(i) {
|
||||
if (i < 0)
|
||||
i = this.items.length + i;
|
||||
|
||||
return this.items[i];
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a stack item by index
|
||||
* and decode as a boolean.
|
||||
* @param {Number} index
|
||||
* @returns {Boolean}
|
||||
* @throws on invalid stack operation
|
||||
*/
|
||||
|
||||
Stack.prototype.bool = function bool(i) {
|
||||
if (i < 0)
|
||||
i = this.items.length + i;
|
||||
|
||||
if (i < 0 || i >= this.items.length)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', -1, -1);
|
||||
|
||||
return common.toBool(this.items[i]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a stack item by index
|
||||
* and decode as a scriptnum.
|
||||
* @param {Number} index
|
||||
* @param {Boolean?} minimal
|
||||
* @param {Number?} limit
|
||||
* @returns {ScriptNum}
|
||||
* @throws on invalid stack operation
|
||||
*/
|
||||
|
||||
Stack.prototype.num = function num(i, minimal, limit) {
|
||||
if (i < 0)
|
||||
i = this.items.length + i;
|
||||
|
||||
if (i < 0 || i >= this.items.length)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', -1, -1);
|
||||
|
||||
return ScriptNum.decode(this.items[i], minimal, limit);
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a stack item by index
|
||||
* and decode as an integer.
|
||||
* @param {Number} index
|
||||
* @param {Boolean?} minimal
|
||||
* @returns {Number}
|
||||
* @throws on invalid stack operation
|
||||
*/
|
||||
|
||||
Stack.prototype.int = function int(i, minimal) {
|
||||
if (i < 0)
|
||||
i = this.items.length + i;
|
||||
|
||||
if (i < 0 || i >= this.items.length)
|
||||
throw new ScriptError('INVALID_STACK_OPERATION', -1, -1);
|
||||
|
||||
return ScriptNum.decode(this.items[i], minimal).getInt();
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a stack item relative to
|
||||
* the top of the stack.
|
||||
@ -239,6 +364,8 @@ Stack.prototype.set = function set(i, value) {
|
||||
if (i < 0)
|
||||
i = this.items.length + i;
|
||||
|
||||
assert(Buffer.isBuffer(value));
|
||||
|
||||
this.items[i] = value;
|
||||
|
||||
return value;
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const BN = require('../crypto/bn');
|
||||
const ScriptNum = require('./scriptnum');
|
||||
const util = require('../utils/util');
|
||||
const Script = require('./script');
|
||||
const common = require('./common');
|
||||
@ -20,6 +20,7 @@ const Address = require('../primitives/address');
|
||||
const Stack = require('./stack');
|
||||
const opcodes = common.opcodes;
|
||||
const scriptTypes = common.types;
|
||||
const STACK_TRUE = common.STACK_TRUE;
|
||||
const STACK_FALSE = common.STACK_FALSE;
|
||||
const STACK_NEGATE = common.STACK_NEGATE;
|
||||
|
||||
@ -391,7 +392,7 @@ Witness.fromJSON = function fromJSON(json) {
|
||||
|
||||
/**
|
||||
* Unshift an item onto the witness vector.
|
||||
* @param {Number|String|Buffer|BN} data
|
||||
* @param {Number|String|Buffer|ScriptNum} data
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
@ -401,7 +402,7 @@ Witness.prototype.unshift = function unshift(data) {
|
||||
|
||||
/**
|
||||
* Push an item onto the witness vector.
|
||||
* @param {Number|String|Buffer|BN} data
|
||||
* @param {Number|String|Buffer|ScriptNum} data
|
||||
* @returns {Number}
|
||||
*/
|
||||
|
||||
@ -440,7 +441,7 @@ Witness.prototype.remove = function remove(i) {
|
||||
/**
|
||||
* Insert an item into the witness vector.
|
||||
* @param {Number} index
|
||||
* @param {Number|String|Buffer|BN} data
|
||||
* @param {Number|String|Buffer|ScriptNum} data
|
||||
*/
|
||||
|
||||
Witness.prototype.insert = function insert(i, data) {
|
||||
@ -478,7 +479,7 @@ Witness.prototype.getSmall = function getSmall(i) {
|
||||
/**
|
||||
* Get a number from the witness vector.
|
||||
* @param {Number} index
|
||||
* @returns {BN}
|
||||
* @returns {ScriptNum}
|
||||
*/
|
||||
|
||||
Witness.prototype.getNumber = function getNumber(i) {
|
||||
@ -487,7 +488,7 @@ Witness.prototype.getNumber = function getNumber(i) {
|
||||
if (!item || item.length > 5)
|
||||
return null;
|
||||
|
||||
return common.num(item, false, 5);
|
||||
return ScriptNum.decode(item, false, 5);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -516,7 +517,7 @@ Witness.prototype.clear = function clear() {
|
||||
/**
|
||||
* Set an item in the witness vector.
|
||||
* @param {Number} index
|
||||
* @param {Number|String|Buffer|BN} data
|
||||
* @param {Number|String|Buffer|ScriptNum} data
|
||||
*/
|
||||
|
||||
Witness.prototype.set = function set(i, data) {
|
||||
@ -526,7 +527,7 @@ Witness.prototype.set = function set(i, data) {
|
||||
|
||||
/**
|
||||
* Encode a witness item.
|
||||
* @param {Number|String|Buffer|BN} data
|
||||
* @param {Number|String|Buffer|ScriptNum} data
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
@ -534,6 +535,9 @@ Witness.encodeItem = function encodeItem(data) {
|
||||
if (data instanceof Opcode)
|
||||
data = data.data || data.value;
|
||||
|
||||
if (Buffer.isBuffer(data))
|
||||
return data;
|
||||
|
||||
if (typeof data === 'number') {
|
||||
if (data === opcodes.OP_1NEGATE)
|
||||
return STACK_NEGATE;
|
||||
@ -547,13 +551,16 @@ Witness.encodeItem = function encodeItem(data) {
|
||||
throw new Error('Non-push opcode in witness.');
|
||||
}
|
||||
|
||||
if (BN.isBN(data))
|
||||
return common.array(data);
|
||||
|
||||
if (typeof data === 'string')
|
||||
return Buffer.from(data, 'utf8');
|
||||
|
||||
return data;
|
||||
if (typeof data === 'boolean')
|
||||
return data ? STACK_TRUE : STACK_FALSE;
|
||||
|
||||
if (ScriptNum.isEncodable(data))
|
||||
return ScriptNum.encode(data);
|
||||
|
||||
throw new Error('Not a witness item.');
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -308,7 +308,7 @@ function fuzzSimple(flags) {
|
||||
if (stack.length === 0)
|
||||
continue;
|
||||
|
||||
if (!Script.bool(stack.top(-1)))
|
||||
if (!stack.bool(-1))
|
||||
continue;
|
||||
|
||||
if (isPushOnly(output))
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const BN = require('../lib/crypto/bn');
|
||||
const util = require('../lib/utils/util');
|
||||
const consensus = require('../lib/protocol/consensus');
|
||||
const encoding = require('../lib/utils/encoding');
|
||||
@ -8,6 +7,7 @@ const TX = require('../lib/primitives/tx');
|
||||
const Block = require('../lib/primitives/block');
|
||||
const Script = require('../lib/script/script');
|
||||
const Opcode = require('../lib/script/opcode');
|
||||
const ScriptNum = require('../lib/script/scriptnum');
|
||||
const opcodes = Script.opcodes;
|
||||
|
||||
function createGenesisBlock(options) {
|
||||
@ -41,7 +41,7 @@ function createGenesisBlock(options) {
|
||||
index: 0xffffffff
|
||||
},
|
||||
script: [
|
||||
Opcode.fromNumber(new BN(486604799)),
|
||||
Opcode.fromNumber(new ScriptNum(486604799)),
|
||||
Opcode.fromPush(Buffer.from([4])),
|
||||
Opcode.fromData(flags)
|
||||
],
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('./util/assert');
|
||||
const BN = require('../lib/crypto/bn');
|
||||
const ScriptNum = require('../lib/script/scriptnum');
|
||||
const consensus = require('../lib/protocol/consensus');
|
||||
const encoding = require('../lib/utils/encoding');
|
||||
const Coin = require('../lib/primitives/coin');
|
||||
@ -79,7 +79,7 @@ async function mineCSV(fund) {
|
||||
|
||||
spend.addOutput({
|
||||
script: [
|
||||
Script.array(new BN(1)),
|
||||
ScriptNum.encode(1),
|
||||
Script.opcodes.OP_CHECKSEQUENCEVERIFY
|
||||
],
|
||||
value: 10000
|
||||
@ -419,7 +419,7 @@ describe('Chain', function() {
|
||||
|
||||
spend.addOutput({
|
||||
script: [
|
||||
Script.array(new BN(2)),
|
||||
ScriptNum.encode(2),
|
||||
Script.opcodes.OP_CHECKSEQUENCEVERIFY
|
||||
],
|
||||
value: 10000
|
||||
@ -444,7 +444,7 @@ describe('Chain', function() {
|
||||
|
||||
spend.addOutput({
|
||||
script: [
|
||||
Script.array(new BN(1)),
|
||||
ScriptNum.encode(1),
|
||||
Script.opcodes.OP_CHECKSEQUENCEVERIFY
|
||||
],
|
||||
value: 1 * 1e8
|
||||
@ -479,7 +479,7 @@ describe('Chain', function() {
|
||||
|
||||
spend.addOutput({
|
||||
script: [
|
||||
Script.array(new BN(2)),
|
||||
ScriptNum.encode(2),
|
||||
Script.opcodes.OP_CHECKSEQUENCEVERIFY
|
||||
],
|
||||
value: 1 * 1e8
|
||||
@ -787,12 +787,12 @@ describe('Chain', function() {
|
||||
const flags = common.flags.DEFAULT_FLAGS & ~common.flags.VERIFY_POW;
|
||||
|
||||
const redeem = new Script();
|
||||
redeem.push(new BN(20));
|
||||
redeem.push(new ScriptNum(20));
|
||||
|
||||
for (let i = 0; i < 20; i++)
|
||||
redeem.push(encoding.ZERO_KEY);
|
||||
|
||||
redeem.push(new BN(20));
|
||||
redeem.push(new ScriptNum(20));
|
||||
redeem.push(opcodes.OP_CHECKMULTISIG);
|
||||
redeem.compile();
|
||||
|
||||
@ -828,12 +828,12 @@ describe('Chain', function() {
|
||||
const job = await cpu.createJob();
|
||||
|
||||
const script = new Script();
|
||||
script.push(new BN(20));
|
||||
script.push(new ScriptNum(20));
|
||||
|
||||
for (let i = 0; i < 20; i++)
|
||||
script.push(encoding.ZERO_KEY);
|
||||
|
||||
script.push(new BN(20));
|
||||
script.push(new ScriptNum(20));
|
||||
script.push(opcodes.OP_CHECKMULTISIG);
|
||||
script.compile();
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
'use strict';
|
||||
|
||||
const assert = require('./util/assert');
|
||||
const BN = require('../lib/crypto/bn');
|
||||
const ScriptNum = require('../lib/script/scriptnum');
|
||||
const consensus = require('../lib/protocol/consensus');
|
||||
const co = require('../lib/utils/co');
|
||||
const Coin = require('../lib/primitives/coin');
|
||||
@ -63,7 +63,7 @@ async function mineCSV(fund) {
|
||||
|
||||
spend.addOutput({
|
||||
script: [
|
||||
Script.array(new BN(1)),
|
||||
ScriptNum.encode(1),
|
||||
Script.opcodes.OP_CHECKSEQUENCEVERIFY
|
||||
],
|
||||
value: 10 * 1e8
|
||||
@ -348,7 +348,7 @@ describe('Node', function() {
|
||||
|
||||
spend.addOutput({
|
||||
script: [
|
||||
Script.array(new BN(2)),
|
||||
ScriptNum.encode(2),
|
||||
Script.opcodes.OP_CHECKSEQUENCEVERIFY
|
||||
],
|
||||
value: 10 * 1e8
|
||||
@ -373,7 +373,7 @@ describe('Node', function() {
|
||||
|
||||
spend.addOutput({
|
||||
script: [
|
||||
Script.array(new BN(1)),
|
||||
ScriptNum.encode(1),
|
||||
Script.opcodes.OP_CHECKSEQUENCEVERIFY
|
||||
],
|
||||
value: 10 * 1e8
|
||||
@ -418,7 +418,7 @@ describe('Node', function() {
|
||||
|
||||
spend.addOutput({
|
||||
script: [
|
||||
Script.array(new BN(2)),
|
||||
ScriptNum.encode(2),
|
||||
Script.opcodes.OP_CHECKSEQUENCEVERIFY
|
||||
],
|
||||
value: 10 * 1e8
|
||||
|
||||
@ -18,7 +18,7 @@ function isSuccess(stack) {
|
||||
if (stack.length === 0)
|
||||
return false;
|
||||
|
||||
if (!Script.bool(stack.top(-1)))
|
||||
if (!stack.bool(-1))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user