script: use asMinimalOP for ASM/decompile
This commit is contained in:
parent
152eed57a0
commit
e7c59c4b8b
3 changed files with 31 additions and 23 deletions
|
@ -24,6 +24,13 @@ function isPushOnly (value) {
|
||||||
return types.Array(value) && value.every(isPushOnlyChunk)
|
return types.Array(value) && value.every(isPushOnlyChunk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function asMinimalOP (buffer) {
|
||||||
|
if (buffer.length === 0) return OPS.OP_0
|
||||||
|
if (buffer.length !== 1) return
|
||||||
|
if (buffer[0] >= 1 && buffer[0] <= 16) return OP_INT_BASE + buffer[0]
|
||||||
|
if (buffer[0] === 0x81) return OPS.OP_1NEGATE
|
||||||
|
}
|
||||||
|
|
||||||
function compile (chunks) {
|
function compile (chunks) {
|
||||||
// TODO: remove me
|
// TODO: remove me
|
||||||
if (Buffer.isBuffer(chunks)) return chunks
|
if (Buffer.isBuffer(chunks)) return chunks
|
||||||
|
@ -34,7 +41,7 @@ function compile (chunks) {
|
||||||
// data chunk
|
// data chunk
|
||||||
if (Buffer.isBuffer(chunk)) {
|
if (Buffer.isBuffer(chunk)) {
|
||||||
// adhere to BIP62.3, minimal push policy
|
// adhere to BIP62.3, minimal push policy
|
||||||
if (chunk.length === 1 && (chunk[0] === 0x81 || (chunk[0] >= 1 && chunk[0] <= 16))) {
|
if (chunk.length === 1 && asMinimalOP(chunk) !== undefined) {
|
||||||
return accum + 1
|
return accum + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,21 +59,14 @@ function compile (chunks) {
|
||||||
// data chunk
|
// data chunk
|
||||||
if (Buffer.isBuffer(chunk)) {
|
if (Buffer.isBuffer(chunk)) {
|
||||||
// adhere to BIP62.3, minimal push policy
|
// adhere to BIP62.3, minimal push policy
|
||||||
if (chunk.length === 1 && chunk[0] >= 1 && chunk[0] <= 16) {
|
var opcode = asMinimalOP(chunk)
|
||||||
var opcode = OP_INT_BASE + chunk[0]
|
if (opcode !== undefined) {
|
||||||
buffer.writeUInt8(opcode, offset)
|
buffer.writeUInt8(opcode, offset)
|
||||||
offset += 1
|
offset += 1
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chunk.length === 1 && chunk[0] === 0x81) {
|
|
||||||
buffer.writeUInt8(OPS.OP_1NEGATE, offset)
|
|
||||||
offset += 1
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += pushdata.encode(buffer, chunk.length, offset)
|
offset += pushdata.encode(buffer, chunk.length, offset)
|
||||||
|
|
||||||
chunk.copy(buffer, offset)
|
chunk.copy(buffer, offset)
|
||||||
offset += chunk.length
|
offset += chunk.length
|
||||||
|
|
||||||
|
@ -107,7 +107,13 @@ function decompile (buffer) {
|
||||||
var data = buffer.slice(i, i + d.number)
|
var data = buffer.slice(i, i + d.number)
|
||||||
i += d.number
|
i += d.number
|
||||||
|
|
||||||
chunks.push(data)
|
// decompile minimally
|
||||||
|
var op = asMinimalOP(data)
|
||||||
|
if (op !== undefined) {
|
||||||
|
chunks.push(op)
|
||||||
|
} else {
|
||||||
|
chunks.push(data)
|
||||||
|
}
|
||||||
|
|
||||||
// opcode
|
// opcode
|
||||||
} else {
|
} else {
|
||||||
|
@ -127,7 +133,11 @@ function toASM (chunks) {
|
||||||
|
|
||||||
return chunks.map(function (chunk) {
|
return chunks.map(function (chunk) {
|
||||||
// data?
|
// data?
|
||||||
if (Buffer.isBuffer(chunk)) return chunk.toString('hex')
|
if (Buffer.isBuffer(chunk)) {
|
||||||
|
var op = asMinimalOP(chunk)
|
||||||
|
if (op === undefined) return chunk.toString('hex')
|
||||||
|
chunk = op
|
||||||
|
}
|
||||||
|
|
||||||
// opcode!
|
// opcode!
|
||||||
return REVERSE_OPS[chunk]
|
return REVERSE_OPS[chunk]
|
||||||
|
|
2
test/fixtures/script.json
vendored
2
test/fixtures/script.json
vendored
|
@ -155,7 +155,7 @@
|
||||||
"06"
|
"06"
|
||||||
],
|
],
|
||||||
"nonstandard": {
|
"nonstandard": {
|
||||||
"scriptSig": "06",
|
"scriptSig": "OP_6",
|
||||||
"scriptSigHex": "0106"
|
"scriptSigHex": "0106"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -24,7 +24,6 @@ describe('script', function () {
|
||||||
fixtures.valid.forEach(function (f) {
|
fixtures.valid.forEach(function (f) {
|
||||||
it('encodes/decodes ' + f.asm, function () {
|
it('encodes/decodes ' + f.asm, function () {
|
||||||
var scriptSig = bscript.fromASM(f.asm)
|
var scriptSig = bscript.fromASM(f.asm)
|
||||||
|
|
||||||
assert.strictEqual(bscript.toASM(scriptSig), f.asm)
|
assert.strictEqual(bscript.toASM(scriptSig), f.asm)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -52,17 +51,16 @@ describe('script', function () {
|
||||||
describe('toStack', function () {
|
describe('toStack', function () {
|
||||||
fixtures.valid.forEach(function (f) {
|
fixtures.valid.forEach(function (f) {
|
||||||
it('returns ' + !!f.stack + ' for ' + f.asm, function () {
|
it('returns ' + !!f.stack + ' for ' + f.asm, function () {
|
||||||
|
if (!f.stack || !f.asm) return
|
||||||
|
|
||||||
var script = bscript.fromASM(f.asm)
|
var script = bscript.fromASM(f.asm)
|
||||||
|
|
||||||
if (f.stack && f.asm) {
|
var stack = bscript.toStack(script)
|
||||||
try {
|
assert.deepEqual(stack.map(function (x) {
|
||||||
var stack = bscript.toStack(script)
|
return x.toString('hex')
|
||||||
assert.deepEqual(stack.map(function (x) { return x.toString('hex') }), f.stack)
|
}), f.stack)
|
||||||
assert.equal(bscript.toASM(bscript.compile(stack)), f.asm, 'should rebuild same script from stack')
|
|
||||||
} catch (e) {
|
assert.equal(bscript.toASM(bscript.compile(stack)), f.asm, 'should rebuild same script from stack')
|
||||||
assert.strictEqual(f.stack, undefined)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue