script: toCode/fromCode.
This commit is contained in:
parent
b77aa9240e
commit
e754621dd4
@ -174,7 +174,7 @@ Opcode.prototype.fromRaw = function fromRaw(data) {
|
||||
*/
|
||||
|
||||
Opcode.fromReader = function fromReader(br) {
|
||||
return new Opcode().fromReader(br);
|
||||
return new Opcode(0, null).fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -184,7 +184,7 @@ Opcode.fromReader = function fromReader(br) {
|
||||
*/
|
||||
|
||||
Opcode.fromRaw = function fromRaw(data) {
|
||||
return new Opcode().fromRaw(data);
|
||||
return new Opcode(0, null).fromRaw(data);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -194,7 +194,7 @@ Opcode.fromRaw = function fromRaw(data) {
|
||||
*/
|
||||
|
||||
Opcode.fromOp = function fromOp(op) {
|
||||
return new Opcode(op);
|
||||
return new Opcode(op, null);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -206,14 +206,14 @@ Opcode.fromOp = function fromOp(op) {
|
||||
|
||||
Opcode.fromData = function fromData(data) {
|
||||
if (data.length === 0)
|
||||
return new Opcode(opcodes.OP_0);
|
||||
return Opcode.fromOp(opcodes.OP_0);
|
||||
|
||||
if (data.length === 1) {
|
||||
if (data[0] >= 1 && data[0] <= 16)
|
||||
return new Opcode(data[0] + 0x50);
|
||||
return Opcode.fromOp(data[0] + 0x50);
|
||||
|
||||
if (data[0] === 0x81)
|
||||
return new Opcode(opcodes.OP_1NEGATE);
|
||||
return Opcode.fromOp(opcodes.OP_1NEGATE);
|
||||
}
|
||||
|
||||
return Opcode.fromPush(data);
|
||||
@ -261,7 +261,7 @@ Opcode.fromNumber = function fromNumber(num) {
|
||||
|
||||
Opcode.fromSmall = function fromSmall(num) {
|
||||
assert(util.isNumber(num) && num >= 0 && num <= 16);
|
||||
return new Opcode(num === 0 ? 0 : num + 0x50);
|
||||
return Opcode.fromOp(num === 0 ? 0 : num + 0x50);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -302,6 +302,32 @@ Opcode.from = function from(data) {
|
||||
assert(false, 'Bad data for opcode.');
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate a pushdata opcode from symbolic name.
|
||||
* @example
|
||||
* Opcode.fromSymbol('checksequenceverify')
|
||||
* @param {String} name
|
||||
* @returns {Opcode}
|
||||
*/
|
||||
|
||||
Opcode.fromSymbol = function fromSymbol(name) {
|
||||
var op;
|
||||
|
||||
assert(typeof name === 'string');
|
||||
assert(name.length > 0);
|
||||
|
||||
if (!util.isUpperCase(name))
|
||||
name = name.toUpperCase();
|
||||
|
||||
if (!util.startsWith(name, 'OP_'))
|
||||
name = 'OP_' + name;
|
||||
|
||||
op = constants.opcodes[name];
|
||||
assert(op != null, 'Unknown opcode.');
|
||||
|
||||
return Opcode.fromOp(op);
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether an object an Opcode.
|
||||
* @param {Object} obj
|
||||
|
||||
@ -83,7 +83,7 @@ Script.prototype.fromOptions = function fromOptions(options) {
|
||||
|
||||
if (options.code) {
|
||||
if (!options.raw)
|
||||
return this.fromArray(options.code);
|
||||
return this.fromCode(options.code);
|
||||
assert(Array.isArray(options.code));
|
||||
this.code = options.code;
|
||||
}
|
||||
@ -124,18 +124,44 @@ Script.prototype.toArray = function toArray() {
|
||||
* Inject properties from an array of
|
||||
* of buffers and numbers.
|
||||
* @private
|
||||
* @param {Array} code
|
||||
* @returns {Script}
|
||||
*/
|
||||
|
||||
Script.prototype.fromArray = function fromArray(code) {
|
||||
var i, op;
|
||||
|
||||
assert(Array.isArray(code));
|
||||
this.code = Script.parseArray(code);
|
||||
|
||||
if (code.length === 0)
|
||||
return this;
|
||||
|
||||
if (code[0] instanceof Opcode)
|
||||
return this.fromCode(code);
|
||||
|
||||
for (i = 0; i < code.length; i++) {
|
||||
op = code[i];
|
||||
if (Buffer.isBuffer(op)) {
|
||||
this.code.push(Opcode.fromData(op));
|
||||
continue;
|
||||
}
|
||||
if (typeof op === 'string') {
|
||||
this.code.push(Opcode.fromSymbol(op));
|
||||
continue;
|
||||
}
|
||||
assert(typeof op === 'number');
|
||||
this.code.push(Opcode.fromOp(op));
|
||||
}
|
||||
|
||||
this.compile();
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate script from an array
|
||||
* of buffers and numbers.
|
||||
* @param {Array} code
|
||||
* @returns {Script}
|
||||
*/
|
||||
|
||||
@ -143,6 +169,45 @@ Script.fromArray = function fromArray(code) {
|
||||
return new Script().fromArray(code);
|
||||
};
|
||||
|
||||
/**
|
||||
* Return an array of opcodes.
|
||||
* @returns {Opcode[]}
|
||||
*/
|
||||
|
||||
Script.prototype.toCode = function toCode() {
|
||||
return this.code.slice();
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from an array of opcodes.
|
||||
* @param {Opcode[]} code
|
||||
* @private
|
||||
*/
|
||||
|
||||
Script.prototype.fromCode = function fromCode(code) {
|
||||
assert(Array.isArray(code));
|
||||
|
||||
if (code.length === 0)
|
||||
return this;
|
||||
|
||||
assert(code[0] instanceof Opcode);
|
||||
|
||||
this.code = code;
|
||||
this.compile();
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate script from an array of opcodes.
|
||||
* @param {Opcode[]} code
|
||||
* @returns {Script}
|
||||
*/
|
||||
|
||||
Script.fromCode = function fromCode(code) {
|
||||
return new Script().fromCode(code);
|
||||
};
|
||||
|
||||
/**
|
||||
* Clone the script.
|
||||
* @returns {Script} Cloned script.
|
||||
@ -2210,6 +2275,9 @@ Script.prototype.isWitnessMasthash = function isWitnessMasthash() {
|
||||
*/
|
||||
|
||||
Script.prototype.isUnspendable = function isUnspendable() {
|
||||
if (this.raw.length > constants.script.MAX_SIZE)
|
||||
return true;
|
||||
|
||||
return this.raw.length > 0 && this.raw[0] === opcodes.OP_RETURN;
|
||||
};
|
||||
|
||||
@ -3018,9 +3086,12 @@ Script.prototype.fromString = function fromString(code) {
|
||||
|
||||
for (i = 0; i < code.length; i++) {
|
||||
op = code[i];
|
||||
symbol = op;
|
||||
|
||||
symbol = op.toUpperCase();
|
||||
if (symbol.indexOf('OP_') !== 0)
|
||||
if (!util.isUpperCase(symbol))
|
||||
symbol = symbol.toUpperCase();
|
||||
|
||||
if (!util.startsWith(symbol, 'OP_'))
|
||||
symbol = 'OP_' + symbol;
|
||||
|
||||
if (opcodes[symbol] == null) {
|
||||
@ -3507,38 +3578,6 @@ Script.fromRaw = function fromRaw(data, enc) {
|
||||
return new Script().fromRaw(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Convert an array of Buffers and
|
||||
* Numbers into an array of Opcodes.
|
||||
* @param {Array} code
|
||||
* @returns {Opcode[]}
|
||||
*/
|
||||
|
||||
Script.parseArray = function parseArray(code) {
|
||||
var out = [];
|
||||
var i, op;
|
||||
|
||||
assert(Array.isArray(code));
|
||||
|
||||
if (code.length === 0)
|
||||
return code;
|
||||
|
||||
if (code[0] instanceof Opcode)
|
||||
return code;
|
||||
|
||||
for (i = 0; i < code.length; i++) {
|
||||
op = code[i];
|
||||
if (Buffer.isBuffer(op)) {
|
||||
out.push(Opcode.fromData(op));
|
||||
continue;
|
||||
}
|
||||
assert(typeof op === 'number');
|
||||
out.push(new Opcode(op));
|
||||
}
|
||||
|
||||
return out;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculate the size (including
|
||||
* the opcode) of a pushdata.
|
||||
|
||||
@ -1034,6 +1034,35 @@ util.fastProp = function fastProp(obj) {
|
||||
({ __proto__: obj });
|
||||
};
|
||||
|
||||
/**
|
||||
* Quick test to see if a string is uppercase.
|
||||
* @param {String} str
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
util.isUpperCase = function isUpperCase(str) {
|
||||
if (str.length === 0)
|
||||
return false;
|
||||
return (str.charCodeAt(0) & 32) === 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test to see if a string starts with a prefix.
|
||||
* @param {String} str
|
||||
* @param {String} prefix
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
util.startsWith = function startsWiths(str, prefix) {
|
||||
return str.startsWith(prefix);
|
||||
};
|
||||
|
||||
if (!''.startsWith) {
|
||||
util.startsWith = function startsWith(str, prefix) {
|
||||
return str.indexOf(prefix) === 0;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Promisify a function.
|
||||
* @param {Function} func
|
||||
|
||||
Loading…
Reference in New Issue
Block a user