script: toCode/fromCode.

This commit is contained in:
Christopher Jeffrey 2016-12-10 21:20:22 -08:00
parent b77aa9240e
commit e754621dd4
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
3 changed files with 137 additions and 43 deletions

View File

@ -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

View File

@ -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.

View File

@ -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