refactor and comments/explanation.
This commit is contained in:
parent
cbe2e2f28d
commit
11ef30b942
@ -1982,18 +1982,18 @@ Script.array = function(value) {
|
|||||||
|
|
||||||
Script.prototype.removeData = function removeData(data) {
|
Script.prototype.removeData = function removeData(data) {
|
||||||
var total = 0;
|
var total = 0;
|
||||||
var op, sig, raw, i, a, b;
|
var opcode, sig, raw, i, a, b;
|
||||||
|
|
||||||
if (!this.raw)
|
if (!this.raw)
|
||||||
return this.removeDataFast(data);
|
return this.removeDataFast(data);
|
||||||
|
|
||||||
// We need to reserialize
|
// We need to reserialize
|
||||||
// the signature as minimaldata.
|
// the signature as minimaldata.
|
||||||
op = data.op;
|
opcode = data.opcode;
|
||||||
delete data.op;
|
delete data.opcode;
|
||||||
sig = Script.encode([data]);
|
sig = Script.encode([data]);
|
||||||
if (op != null)
|
if (opcode != null)
|
||||||
utils.hidden(data, 'op', op);
|
data.opcode = opcode;
|
||||||
|
|
||||||
raw = this.encode();
|
raw = this.encode();
|
||||||
|
|
||||||
@ -2080,7 +2080,7 @@ Script.checkMinimal = function checkMinimal(value, flags) {
|
|||||||
if (!(flags & constants.flags.VERIFY_MINIMALDATA))
|
if (!(flags & constants.flags.VERIFY_MINIMALDATA))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (value.op == null)
|
if (value.opcode == null)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (value.length === 1 && value[0] >= 1 && value[0] <= 16)
|
if (value.length === 1 && value[0] >= 1 && value[0] <= 16)
|
||||||
@ -2090,13 +2090,13 @@ Script.checkMinimal = function checkMinimal(value, flags) {
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (value.length <= 75)
|
if (value.length <= 75)
|
||||||
return value.op === value.length;
|
return value.opcode === value.length;
|
||||||
|
|
||||||
if (value.length <= 255)
|
if (value.length <= 255)
|
||||||
return value.op === opcodes.OP_PUSHDATA1;
|
return value.opcode === opcodes.OP_PUSHDATA1;
|
||||||
|
|
||||||
if (value.length <= 65535)
|
if (value.length <= 65535)
|
||||||
return value.op === opcodes.OP_PUSHDATA2;
|
return value.opcode === opcodes.OP_PUSHDATA2;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@ -4040,16 +4040,6 @@ Script.fromRaw = function fromRaw(data, enc) {
|
|||||||
* @returns {Array} Script code.
|
* @returns {Array} Script code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Script.isBadPush = function isBadPush(op) {
|
|
||||||
if (Buffer.isBuffer(op))
|
|
||||||
return false;
|
|
||||||
if (op >= 0x01 && op <= 0x4b)
|
|
||||||
return true;
|
|
||||||
if (op >= opcodes.OP_PUSHDATA1 && op <= opcodes.OP_PUSHDATA4)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
Script.decode = function decode(buf) {
|
Script.decode = function decode(buf) {
|
||||||
var code = [];
|
var code = [];
|
||||||
var p = new BufferReader(buf, true);
|
var p = new BufferReader(buf, true);
|
||||||
@ -4068,7 +4058,7 @@ Script.decode = function decode(buf) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
data = p.readBytes(op);
|
data = p.readBytes(op);
|
||||||
utils.hidden(data, 'op', op);
|
data.opcode = op;
|
||||||
code.push(data);
|
code.push(data);
|
||||||
} else if (op === opcodes.OP_PUSHDATA1) {
|
} else if (op === opcodes.OP_PUSHDATA1) {
|
||||||
if (p.left() < 1) {
|
if (p.left() < 1) {
|
||||||
@ -4086,7 +4076,7 @@ Script.decode = function decode(buf) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
data = p.readBytes(size);
|
data = p.readBytes(size);
|
||||||
utils.hidden(data, 'op', op);
|
data.opcode = op;
|
||||||
code.push(data);
|
code.push(data);
|
||||||
} else if (op === opcodes.OP_PUSHDATA2) {
|
} else if (op === opcodes.OP_PUSHDATA2) {
|
||||||
if (p.left() < 2) {
|
if (p.left() < 2) {
|
||||||
@ -4105,7 +4095,7 @@ Script.decode = function decode(buf) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
data = p.readBytes(size);
|
data = p.readBytes(size);
|
||||||
utils.hidden(data, 'op', op);
|
data.opcode = op;
|
||||||
code.push(data);
|
code.push(data);
|
||||||
} else if (op === opcodes.OP_PUSHDATA4) {
|
} else if (op === opcodes.OP_PUSHDATA4) {
|
||||||
if (p.left() < 4) {
|
if (p.left() < 4) {
|
||||||
@ -4126,7 +4116,7 @@ Script.decode = function decode(buf) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
data = p.readBytes(size);
|
data = p.readBytes(size);
|
||||||
utils.hidden(data, 'op', op);
|
data.opcode = op;
|
||||||
code.push(data);
|
code.push(data);
|
||||||
} else {
|
} else {
|
||||||
code.push(op);
|
code.push(op);
|
||||||
@ -4136,7 +4126,6 @@ Script.decode = function decode(buf) {
|
|||||||
return code;
|
return code;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode and serialize script code. This will _not_
|
* Encode and serialize script code. This will _not_
|
||||||
* include the varint size at the start. This will
|
* include the varint size at the start. This will
|
||||||
@ -4162,19 +4151,19 @@ Script.encode = function encode(code, writer) {
|
|||||||
if (Buffer.isBuffer(op)) {
|
if (Buffer.isBuffer(op)) {
|
||||||
// Check for nonstandard pushdatas that
|
// Check for nonstandard pushdatas that
|
||||||
// may have been decoded from before.
|
// may have been decoded from before.
|
||||||
if (op.op != null) {
|
if (op.opcode != null) {
|
||||||
if (op.op <= 0x4b) {
|
if (op.opcode <= 0x4b) {
|
||||||
p.writeU8(op.length);
|
p.writeU8(op.length);
|
||||||
p.writeBytes(op);
|
p.writeBytes(op);
|
||||||
} else if (op.op === opcodes.OP_PUSHDATA1) {
|
} else if (op.opcode === opcodes.OP_PUSHDATA1) {
|
||||||
p.writeU8(opcodes.OP_PUSHDATA1);
|
p.writeU8(opcodes.OP_PUSHDATA1);
|
||||||
p.writeU8(op.length);
|
p.writeU8(op.length);
|
||||||
p.writeBytes(op);
|
p.writeBytes(op);
|
||||||
} else if (op.op === opcodes.OP_PUSHDATA2) {
|
} else if (op.opcode === opcodes.OP_PUSHDATA2) {
|
||||||
p.writeU8(opcodes.OP_PUSHDATA2);
|
p.writeU8(opcodes.OP_PUSHDATA2);
|
||||||
p.writeU16(op.length);
|
p.writeU16(op.length);
|
||||||
p.writeBytes(op);
|
p.writeBytes(op);
|
||||||
} else if (op.op === opcodes.OP_PUSHDATA4) {
|
} else if (op.opcode === opcodes.OP_PUSHDATA4) {
|
||||||
p.writeU8(opcodes.OP_PUSHDATA4);
|
p.writeU8(opcodes.OP_PUSHDATA4);
|
||||||
p.writeU32(op.length);
|
p.writeU32(op.length);
|
||||||
p.writeBytes(op);
|
p.writeBytes(op);
|
||||||
@ -4230,6 +4219,47 @@ Script.encode = function encode(code, writer) {
|
|||||||
return p;
|
return p;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether GetOp2 should fail
|
||||||
|
* on a given op due to a bad push (either
|
||||||
|
* not enough size bytes after a PUSHDATA,
|
||||||
|
* or not enough data after the size.
|
||||||
|
*
|
||||||
|
* If bitcoind comes across a bad push, it
|
||||||
|
* will return an invalid opcode. The problem
|
||||||
|
* is bitcoind parses scripts _as_ they are
|
||||||
|
* executing, which can be slow for us because
|
||||||
|
* now every function that needs to test the
|
||||||
|
* script needs to parse the raw data. It's
|
||||||
|
* also impossible to read a script
|
||||||
|
* _backwards_ making testing for things like
|
||||||
|
* multisig outputs even more difficult.
|
||||||
|
*
|
||||||
|
* If BCoin comes accross a bad push in its
|
||||||
|
* initial parsing, it simply will _not
|
||||||
|
* consider the pushdata to be a pushdata_
|
||||||
|
* but just another opcode in the code array
|
||||||
|
* (all of the data after the pushdata op
|
||||||
|
* will also be considered opcodes rather
|
||||||
|
* than data). This function checks to see
|
||||||
|
* if an op is a direct push, or PUSHDATA1
|
||||||
|
* to PUSHDATA4 -- these opcodes cannot
|
||||||
|
* exist in the code array of valid parsed
|
||||||
|
* scripts.
|
||||||
|
* @param {Number|Buffer} op
|
||||||
|
* @returns {Boolean}
|
||||||
|
*/
|
||||||
|
|
||||||
|
Script.isBadPush = function isBadPush(op) {
|
||||||
|
if (Buffer.isBuffer(op))
|
||||||
|
return false;
|
||||||
|
if (op >= 0x01 && op <= 0x4b)
|
||||||
|
return true;
|
||||||
|
if (op >= opcodes.OP_PUSHDATA1 && op <= opcodes.OP_PUSHDATA4)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test an object to see if it is a Script.
|
* Test an object to see if it is a Script.
|
||||||
* @param {Object} obj
|
* @param {Object} obj
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user