2018-07-23 09:45:01 +02:00
|
|
|
const { describe, it } = require('mocha')
|
2018-06-25 08:25:12 +02:00
|
|
|
const assert = require('assert')
|
|
|
|
const bscript = require('../src/script')
|
|
|
|
const minimalData = require('minimaldata')
|
2014-06-12 13:14:22 +02:00
|
|
|
|
2018-06-25 08:25:12 +02:00
|
|
|
const fixtures = require('./fixtures/script.json')
|
|
|
|
const fixtures2 = require('./fixtures/templates.json')
|
2014-06-12 13:14:22 +02:00
|
|
|
|
2015-08-20 05:31:29 +02:00
|
|
|
describe('script', function () {
|
2014-11-28 03:49:43 +01:00
|
|
|
// TODO
|
2016-11-01 16:06:01 +01:00
|
|
|
describe('isCanonicalPubKey', function () {
|
|
|
|
it('rejects if not provided a Buffer', function () {
|
|
|
|
assert.strictEqual(false, bscript.isCanonicalPubKey(0))
|
|
|
|
})
|
|
|
|
it('rejects smaller than 33', function () {
|
|
|
|
for (var i = 0; i < 33; i++) {
|
2017-04-19 09:39:16 +02:00
|
|
|
assert.strictEqual(false, bscript.isCanonicalPubKey(Buffer.from('', i)))
|
2016-11-01 16:06:01 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
2018-06-05 09:17:40 +02:00
|
|
|
describe.skip('isCanonicalScriptSignature', function () {
|
|
|
|
})
|
2014-11-28 03:49:43 +01:00
|
|
|
|
2015-08-14 03:16:17 +02:00
|
|
|
describe('fromASM/toASM', function () {
|
|
|
|
fixtures.valid.forEach(function (f) {
|
2016-12-15 01:12:26 +01:00
|
|
|
it('encodes/decodes ' + f.asm, function () {
|
2018-06-25 08:37:45 +02:00
|
|
|
const script = bscript.fromASM(f.asm)
|
2017-09-22 03:33:32 +02:00
|
|
|
assert.strictEqual(bscript.toASM(script), f.asm)
|
2016-12-15 01:12:26 +01:00
|
|
|
})
|
2015-08-14 03:16:17 +02:00
|
|
|
})
|
2016-12-17 04:29:42 +01:00
|
|
|
|
|
|
|
fixtures.invalid.fromASM.forEach(function (f) {
|
|
|
|
it('throws ' + f.description, function () {
|
|
|
|
assert.throws(function () {
|
|
|
|
bscript.fromASM(f.script)
|
|
|
|
}, new RegExp(f.description))
|
|
|
|
})
|
|
|
|
})
|
2015-08-14 03:16:17 +02:00
|
|
|
})
|
|
|
|
|
2017-09-22 03:33:32 +02:00
|
|
|
describe('fromASM/toASM (templates)', function () {
|
|
|
|
fixtures2.valid.forEach(function (f) {
|
|
|
|
if (f.inputHex) {
|
2018-06-25 08:37:45 +02:00
|
|
|
const ih = bscript.toASM(Buffer.from(f.inputHex, 'hex'))
|
2017-09-22 03:33:32 +02:00
|
|
|
|
|
|
|
it('encodes/decodes ' + ih, function () {
|
2018-06-25 08:37:45 +02:00
|
|
|
const script = bscript.fromASM(f.input)
|
2017-09-22 03:33:32 +02:00
|
|
|
assert.strictEqual(script.toString('hex'), f.inputHex)
|
|
|
|
assert.strictEqual(bscript.toASM(script), f.input)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if (f.outputHex) {
|
|
|
|
it('encodes/decodes ' + f.output, function () {
|
2018-06-25 08:37:45 +02:00
|
|
|
const script = bscript.fromASM(f.output)
|
2017-09-22 03:33:32 +02:00
|
|
|
assert.strictEqual(script.toString('hex'), f.outputHex)
|
|
|
|
assert.strictEqual(bscript.toASM(script), f.output)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2016-12-14 05:52:15 +01:00
|
|
|
describe('isPushOnly', function () {
|
2016-11-14 01:17:27 +01:00
|
|
|
fixtures.valid.forEach(function (f) {
|
2016-12-15 01:12:26 +01:00
|
|
|
it('returns ' + !!f.stack + ' for ' + f.asm, function () {
|
2018-06-25 08:37:45 +02:00
|
|
|
const script = bscript.fromASM(f.asm)
|
|
|
|
const chunks = bscript.decompile(script)
|
2016-12-14 05:52:15 +01:00
|
|
|
|
2016-12-15 01:12:26 +01:00
|
|
|
assert.strictEqual(bscript.isPushOnly(chunks), !!f.stack)
|
|
|
|
})
|
2016-11-14 01:17:27 +01:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2016-12-15 00:57:53 +01:00
|
|
|
describe('toStack', function () {
|
|
|
|
fixtures.valid.forEach(function (f) {
|
2016-12-15 01:12:26 +01:00
|
|
|
it('returns ' + !!f.stack + ' for ' + f.asm, function () {
|
2017-08-23 09:11:47 +02:00
|
|
|
if (!f.stack || !f.asm) return
|
|
|
|
|
2018-06-25 08:37:45 +02:00
|
|
|
const script = bscript.fromASM(f.asm)
|
2016-12-15 00:57:53 +01:00
|
|
|
|
2018-06-25 08:37:45 +02:00
|
|
|
const stack = bscript.toStack(script)
|
2017-08-23 09:11:47 +02:00
|
|
|
assert.deepEqual(stack.map(function (x) {
|
|
|
|
return x.toString('hex')
|
|
|
|
}), f.stack)
|
|
|
|
|
|
|
|
assert.equal(bscript.toASM(bscript.compile(stack)), f.asm, 'should rebuild same script from stack')
|
2016-12-15 00:57:53 +01:00
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2016-09-29 05:48:17 +02:00
|
|
|
describe('compile (via fromASM)', function () {
|
2015-08-14 03:16:17 +02:00
|
|
|
fixtures.valid.forEach(function (f) {
|
2016-12-15 01:12:26 +01:00
|
|
|
it('(' + f.type + ') compiles ' + f.asm, function () {
|
2018-06-25 08:37:45 +02:00
|
|
|
const scriptSig = bscript.fromASM(f.asm)
|
2016-09-29 05:48:17 +02:00
|
|
|
|
2016-12-15 01:12:26 +01:00
|
|
|
assert.strictEqual(scriptSig.toString('hex'), f.script)
|
2016-09-29 05:48:17 +02:00
|
|
|
|
2016-12-15 01:12:26 +01:00
|
|
|
if (f.nonstandard) {
|
2018-06-25 08:37:45 +02:00
|
|
|
const scriptSigNS = bscript.fromASM(f.nonstandard.scriptSig)
|
2015-08-14 03:16:17 +02:00
|
|
|
|
2016-12-15 01:12:26 +01:00
|
|
|
assert.strictEqual(scriptSigNS.toString('hex'), f.script)
|
|
|
|
}
|
|
|
|
})
|
2015-08-14 03:16:17 +02:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe('decompile', function () {
|
|
|
|
fixtures.valid.forEach(function (f) {
|
2016-12-15 01:12:26 +01:00
|
|
|
it('decompiles ' + f.asm, function () {
|
2018-06-25 08:37:45 +02:00
|
|
|
const chunks = bscript.decompile(Buffer.from(f.script, 'hex'))
|
2015-08-14 03:16:17 +02:00
|
|
|
|
2016-12-15 01:12:26 +01:00
|
|
|
assert.strictEqual(bscript.compile(chunks).toString('hex'), f.script)
|
|
|
|
assert.strictEqual(bscript.toASM(chunks), f.asm)
|
2016-09-29 05:48:17 +02:00
|
|
|
|
2016-12-15 01:12:26 +01:00
|
|
|
if (f.nonstandard) {
|
2018-06-25 08:37:45 +02:00
|
|
|
const chunksNS = bscript.decompile(Buffer.from(f.nonstandard.scriptSigHex, 'hex'))
|
2016-09-29 05:48:17 +02:00
|
|
|
|
2016-12-15 01:12:26 +01:00
|
|
|
assert.strictEqual(bscript.compile(chunksNS).toString('hex'), f.script)
|
2016-09-29 05:48:17 +02:00
|
|
|
|
2016-12-15 01:12:26 +01:00
|
|
|
// toASM converts verbatim, only `compile` transforms the script to a minimalpush compliant script
|
|
|
|
assert.strictEqual(bscript.toASM(chunksNS), f.nonstandard.scriptSig)
|
|
|
|
}
|
|
|
|
})
|
2015-08-14 03:16:17 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
fixtures.invalid.decompile.forEach(function (f) {
|
2018-04-13 17:42:48 +02:00
|
|
|
it('fails to decompile ' + f.script + ', because "' + f.description + '"', function () {
|
2018-06-25 08:37:45 +02:00
|
|
|
const chunks = bscript.decompile(Buffer.from(f.script, 'hex'))
|
2015-08-14 03:16:17 +02:00
|
|
|
|
2018-04-13 17:42:48 +02:00
|
|
|
assert.strictEqual(chunks, null)
|
2015-08-14 03:16:17 +02:00
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2016-08-31 07:21:36 +02:00
|
|
|
describe('SCRIPT_VERIFY_MINIMALDATA policy', function () {
|
|
|
|
fixtures.valid.forEach(function (f) {
|
2016-12-15 01:12:26 +01:00
|
|
|
it('compliant for ' + f.type + ' scriptSig ' + f.asm, function () {
|
2018-06-25 08:37:45 +02:00
|
|
|
const script = Buffer.from(f.script, 'hex')
|
2016-08-31 07:21:36 +02:00
|
|
|
|
2016-12-15 01:12:26 +01:00
|
|
|
assert(minimalData(script))
|
|
|
|
})
|
2016-08-31 07:21:36 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
function testEncodingForSize (i) {
|
|
|
|
it('compliant for data PUSH of length ' + i, function () {
|
2018-06-25 08:37:45 +02:00
|
|
|
const buffer = Buffer.alloc(i)
|
|
|
|
const script = bscript.compile([buffer])
|
2016-08-31 07:21:36 +02:00
|
|
|
|
2016-09-29 05:48:17 +02:00
|
|
|
assert(minimalData(script), 'Failed for ' + i + ' length script: ' + script.toString('hex'))
|
2016-08-31 07:21:36 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = 0; i < 520; ++i) {
|
|
|
|
testEncodingForSize(i)
|
|
|
|
}
|
|
|
|
})
|
2014-06-12 13:14:22 +02:00
|
|
|
})
|