script encoding.
This commit is contained in:
parent
94b20355ea
commit
4b1e055a05
@ -2466,25 +2466,16 @@ Script.sign = function sign(msg, key, type) {
|
||||
|
||||
Script.decode = function decode(buf) {
|
||||
var code = [];
|
||||
var i = 0;
|
||||
var off = 0;
|
||||
var b, opcode, len;
|
||||
|
||||
if (!buf)
|
||||
return [];
|
||||
|
||||
while (i < buf.length) {
|
||||
b = buf[i++];
|
||||
|
||||
// Next `b` bytes should be pushed to stack
|
||||
if (b >= 0x01 && b <= 0x4b) {
|
||||
code.push(utils.slice(buf, i, i + b));
|
||||
i += b;
|
||||
utils.hidden(code[code.length - 1], 'pushdata', {
|
||||
opcode: null,
|
||||
len: b
|
||||
});
|
||||
continue;
|
||||
}
|
||||
// NOTE: We can't use a BufferReader here since
|
||||
// script parsing was originally non-strict.
|
||||
while (off < buf.length) {
|
||||
b = buf[off++];
|
||||
|
||||
// OP_0, OP_FALSE
|
||||
// Special case: this is an empty array
|
||||
@ -2494,6 +2485,17 @@ Script.decode = function decode(buf) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Next `b` bytes should be pushed to stack
|
||||
if (b >= 0x01 && b <= 0x4b) {
|
||||
code.push(utils.slice(buf, off, off + b));
|
||||
off += b;
|
||||
utils.hidden(code[code.length - 1], 'pushdata', {
|
||||
opcode: null,
|
||||
len: b
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// OP_1, OP_TRUE, OP_2-OP_16
|
||||
// Special case: these get to be number
|
||||
// literals. Note: 1negate is not included.
|
||||
@ -2504,34 +2506,34 @@ Script.decode = function decode(buf) {
|
||||
|
||||
opcode = constants.opcodesByVal[b];
|
||||
|
||||
if (i >= buf.length) {
|
||||
if (off >= buf.length) {
|
||||
code.push(opcode || b);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (opcode === 'pushdata1') {
|
||||
len = buf[i];
|
||||
i += 1;
|
||||
code.push(utils.slice(buf, i, i + len));
|
||||
i += len;
|
||||
len = buf[off];
|
||||
off += 1;
|
||||
code.push(utils.slice(buf, off, off + len));
|
||||
off += len;
|
||||
utils.hidden(code[code.length - 1], 'pushdata', {
|
||||
opcode: opcode,
|
||||
len: len
|
||||
});
|
||||
} else if (opcode === 'pushdata2') {
|
||||
len = utils.readU16(buf, i);
|
||||
i += 2;
|
||||
code.push(utils.slice(buf, i, i + len));
|
||||
i += len;
|
||||
len = utils.readU16(buf, off);
|
||||
off += 2;
|
||||
code.push(utils.slice(buf, off, off + len));
|
||||
off += len;
|
||||
utils.hidden(code[code.length - 1], 'pushdata', {
|
||||
opcode: opcode,
|
||||
len: len
|
||||
});
|
||||
} else if (opcode === 'pushdata4') {
|
||||
len = utils.readU32(buf, i);
|
||||
i += 4;
|
||||
code.push(utils.slice(buf, i, i + len));
|
||||
i += len;
|
||||
len = utils.readU32(buf, off);
|
||||
off += 4;
|
||||
code.push(utils.slice(buf, off, off + len));
|
||||
off += len;
|
||||
utils.hidden(code[code.length - 1], 'pushdata', {
|
||||
opcode: opcode,
|
||||
len: len
|
||||
@ -2545,111 +2547,65 @@ Script.decode = function decode(buf) {
|
||||
};
|
||||
|
||||
Script.encode = function encode(code) {
|
||||
var p = new bcoin.protocol.framer.BufferWriter();
|
||||
var opcodes = constants.opcodes;
|
||||
var i = 0;
|
||||
var instr;
|
||||
var total = 0;
|
||||
var off = 0;
|
||||
var buf;
|
||||
|
||||
if (!code)
|
||||
return new Buffer([]);
|
||||
|
||||
if (code._raw)
|
||||
return code._raw;
|
||||
var op;
|
||||
|
||||
for (i = 0; i < code.length; i++) {
|
||||
instr = code[i];
|
||||
|
||||
if (Buffer.isBuffer(instr)) {
|
||||
if (instr.pushdata) {
|
||||
if (instr.pushdata.opcode === null) {
|
||||
total += 1 + instr.length;
|
||||
} else if (instr.pushdata.opcode === 'pushdata1') {
|
||||
total += 1 + 1 + instr.length;
|
||||
} else if (instr.pushdata.opcode === 'pushdata2') {
|
||||
total += 1 + 2 + instr.length;
|
||||
} else if (instr.pushdata.opcode === 'pushdata4') {
|
||||
total += 1 + 4 + instr.length;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (instr.length === 0) {
|
||||
total += 1;
|
||||
} else if (1 <= instr.length && instr.length <= 0x4b) {
|
||||
total += 1 + instr.length;
|
||||
} else if (instr.length <= 0xff) {
|
||||
total += 1 + 1 + instr.length;
|
||||
} else if (instr.length <= 0xffff) {
|
||||
total += 1 + 2 + instr.length;
|
||||
} else {
|
||||
total += 1 + 4 + instr.length;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
total += 1;
|
||||
}
|
||||
|
||||
buf = new Buffer(total);
|
||||
|
||||
for (i = 0; i < code.length; i++) {
|
||||
instr = code[i];
|
||||
|
||||
assert(!Array.isArray(instr));
|
||||
op = code[i];
|
||||
|
||||
// Push value to stack
|
||||
if (Buffer.isBuffer(instr)) {
|
||||
if (Buffer.isBuffer(op)) {
|
||||
// Check for nonstandard pushdatas that
|
||||
// may have been decoded from before.
|
||||
if (instr.pushdata) {
|
||||
if (instr.pushdata.opcode === null) {
|
||||
buf[off++] = instr.pushdata.len;
|
||||
off += instr.copy(buf, off, 0, instr.length);
|
||||
} else if (instr.pushdata.opcode === 'pushdata1') {
|
||||
buf[off++] = opcodes.pushdata1;
|
||||
buf[off++] = instr.pushdata.len;
|
||||
off += instr.copy(buf, off, 0, instr.length);
|
||||
} else if (instr.pushdata.opcode === 'pushdata2') {
|
||||
buf[off++] = opcodes.pushdata2;
|
||||
off += utils.writeU16(buf, instr.pushdata.len, off);
|
||||
off += instr.copy(buf, off, 0, instr.length);
|
||||
} else if (instr.pushdata.opcode === 'pushdata4') {
|
||||
buf[off++] = opcodes.pushdata4;
|
||||
off += utils.writeU32(buf, instr.pushdata.len, off);
|
||||
off += instr.copy(buf, off, 0, instr.length);
|
||||
if (op.pushdata) {
|
||||
if (op.pushdata.opcode === null) {
|
||||
p.writeU8(op.pushdata.len);
|
||||
p.writeBytes(op);
|
||||
} else if (op.pushdata.opcode === 'pushdata1') {
|
||||
p.writeU8(opcodes.pushdata1);
|
||||
p.writeU8(op.pushdata.len);
|
||||
p.writeBytes(op);
|
||||
} else if (op.pushdata.opcode === 'pushdata2') {
|
||||
p.writeU8(opcodes.pushdata2);
|
||||
p.writeU16(op.pushdata.len);
|
||||
p.writeBytes(op);
|
||||
} else if (op.pushdata.opcode === 'pushdata4') {
|
||||
p.writeU8(opcodes.pushdata4);
|
||||
p.writeU32(op.pushdata.len);
|
||||
p.writeBytes(op);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (instr.length === 0) {
|
||||
buf[off++] = opcodes['0'];
|
||||
} else if (1 <= instr.length && instr.length <= 0x4b) {
|
||||
buf[off++] = instr.length;
|
||||
off += instr.copy(buf, off, 0, instr.length);
|
||||
} else if (instr.length <= 0xff) {
|
||||
buf[off++] = opcodes.pushdata1;
|
||||
buf[off++] = instr.length;
|
||||
off += instr.copy(buf, off, 0, instr.length);
|
||||
} else if (instr.length <= 0xffff) {
|
||||
buf[off++] = opcodes.pushdata2;
|
||||
off += utils.writeU16(buf, instr.length, off);
|
||||
off += instr.copy(buf, off, 0, instr.length);
|
||||
// Standard minimaldata encoding
|
||||
if (op.length === 0) {
|
||||
p.writeU8(opcodes['0']);
|
||||
} else if (op.length <= 0x4b) {
|
||||
p.writeU8(op.length);
|
||||
p.writeBytes(op);
|
||||
} else if (op.length <= 0xff) {
|
||||
p.writeU8(opcodes.pushdata1);
|
||||
p.writeU8(op.length);
|
||||
p.writeBytes(op);
|
||||
} else if (op.length <= 0xffff) {
|
||||
p.writeU8(opcodes.pushdata2);
|
||||
p.writeU16(op.length);
|
||||
p.writeBytes(op);
|
||||
} else {
|
||||
buf[off++] = opcodes.pushdata4;
|
||||
off += utils.writeU32(buf, instr.length, off);
|
||||
off += instr.copy(buf, off, 0, instr.length);
|
||||
p.writeU8(opcodes.pushdata4);
|
||||
p.writeU32(op.length);
|
||||
p.writeBytes(op);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(opcodes[instr] != null || typeof instr === 'number');
|
||||
assert(opcodes[op] != null || typeof op === 'number');
|
||||
|
||||
buf[off++] = opcodes[instr] || instr;
|
||||
p.writeU8(opcodes[op] || op);
|
||||
}
|
||||
|
||||
assert(off === buf.length);
|
||||
|
||||
return buf;
|
||||
return p.render();
|
||||
};
|
||||
|
||||
Script.witness = Witness;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user