Files
bch-js/test/unit/scripts.js
T

488 lines
16 KiB
JavaScript
Raw Normal View History

// Public npm libraries
2021-01-02 15:41:12 -08:00
const assert = require('assert')
const Buffer = require('safe-buffer').Buffer
// Mocks
2021-01-02 15:41:12 -08:00
const fixtures = require('./fixtures/script.json')
// Unit under test (uut)
2021-01-02 15:41:12 -08:00
const BCHJS = require('../../src/bch-js')
let bchjs
2021-01-02 15:41:12 -08:00
describe('#Script', () => {
beforeEach(() => {
bchjs = new BCHJS()
})
2021-01-02 15:41:12 -08:00
describe('#decode', () => {
describe('P2PKH scriptSig', () => {
fixtures.decodeScriptSig.forEach(fixture => {
2021-01-02 15:41:12 -08:00
it('should decode scriptSig buffer', () => {
const decodedScriptSig = bchjs.Script.decode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.scriptSigHex, 'hex')
)
2021-01-02 15:41:12 -08:00
assert.equal(typeof decodedScriptSig, 'object')
})
it(`should decode scriptSig buffer to cash address ${fixture.cashAddress}`, () => {
const decodedScriptSig = bchjs.Script.decode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.scriptSigHex, 'hex')
)
const address = bchjs.HDNode.toCashAddress(
bchjs.ECPair.fromPublicKey(decodedScriptSig[1])
)
assert.equal(address, fixture.cashAddress)
})
it(`should decode scriptSig buffer to legacy address ${fixture.legacyAddress}`, () => {
const decodedScriptSig = bchjs.Script.decode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.scriptSigHex, 'hex')
)
const address = bchjs.HDNode.toLegacyAddress(
bchjs.ECPair.fromPublicKey(decodedScriptSig[1])
)
assert.equal(address, fixture.legacyAddress)
})
})
})
2021-01-02 15:41:12 -08:00
describe('P2PKH scriptPubKey', () => {
fixtures.decodeScriptPubKey.forEach(fixture => {
2021-01-02 15:41:12 -08:00
it('should decode scriptSig buffer', () => {
const decodedScriptPubKey = bchjs.Script.decode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.scriptPubKeyHex, 'hex')
)
assert.equal(decodedScriptPubKey.length, 5)
})
it(`should match hashed pubKey ${fixture.pubKeyHex}`, () => {
const decodedScriptPubKey = bchjs.Script.decode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.scriptPubKeyHex, 'hex')
)
2021-01-02 15:41:12 -08:00
const data = Buffer.from(fixture.pubKeyHex, 'hex')
const hash160 = bchjs.Crypto.hash160(data).toString('hex')
assert.equal(decodedScriptPubKey[2].toString('hex'), hash160)
})
})
})
})
2021-01-02 15:41:12 -08:00
describe('#encode', () => {
describe('P2PKH scriptSig', () => {
fixtures.encodeScriptSig.forEach(fixture => {
2021-01-02 15:41:12 -08:00
it('should encode scriptSig chunks to buffer', () => {
const arr = [
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.scriptSigChunks[0], 'hex'),
Buffer.from(fixture.scriptSigChunks[1], 'hex')
]
const encodedScriptSig = bchjs.Script.encode(arr)
2021-01-02 15:41:12 -08:00
assert.equal(typeof encodedScriptSig, 'object')
})
})
})
2021-01-02 15:41:12 -08:00
describe('P2PKH scriptPubKey', () => {
fixtures.encodeScriptPubKey.forEach(fixture => {
2021-01-02 15:41:12 -08:00
it('should encode scriptPubKey buffer', () => {
const decodedScriptPubKey = bchjs.Script.decode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.scriptPubKeyHex, 'hex')
)
const compiledScriptPubKey = bchjs.Script.encode(decodedScriptPubKey)
assert.equal(
2021-01-02 15:41:12 -08:00
compiledScriptPubKey.toString('hex'),
fixture.scriptPubKeyHex
)
})
})
})
2021-01-02 15:41:12 -08:00
describe('Encode SLP SEND OP_RETURN properly', () => {
it('should correctly compile OP_RETURN SLP SEND transaction', () => {
const scriptArr = [
bchjs.Script.opcodes.OP_RETURN,
2021-01-02 15:41:12 -08:00
Buffer.from('534c5000', 'hex'),
Buffer.from('01', 'hex'),
Buffer.from('SEND'),
Buffer.from(
2021-01-02 15:41:12 -08:00
'73db55368981e4878440637e448d4abe7f661be5c3efdcbcb63bd86a01a76b5a',
'hex'
),
2021-01-02 15:41:12 -08:00
Buffer.from('00000001', 'hex')
]
const data = bchjs.Script.encode2(scriptArr)
// convert data to a hex string
2021-01-02 15:41:12 -08:00
let str = ''
for (let i = 0; i < data.length; i++) {
let hex = Number(data[i]).toString(16)
// zero pad when its a single digit.
hex = `0${hex}`
hex = hex.slice(-2)
2021-01-02 15:41:12 -08:00
// console.log(`hex: ${hex}`)
str += hex
}
console.log(`Hex string: ${str}`)
2021-01-02 15:41:12 -08:00
// console.log(`scriptArr: ${JSON.stringify(data,null,2)}`)
const correctStr =
2021-01-02 15:41:12 -08:00
'6a04534c500001010453454e442073db55368981e4878440637e448d4abe7f661be5c3efdcbcb63bd86a01a76b5a0400000001'
assert.equal(str, correctStr)
})
})
})
2021-01-02 15:41:12 -08:00
describe('#toASM', () => {
describe('P2PKH scriptSig', () => {
fixtures.scriptSigToASM.forEach(fixture => {
it(`should encode scriptSig buffer to ${fixture.asm}`, () => {
const arr = [
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.scriptSigChunks[0], 'hex'),
Buffer.from(fixture.scriptSigChunks[1], 'hex')
]
const compiledScriptSig = bchjs.Script.encode(arr)
const asm = bchjs.Script.toASM(compiledScriptSig)
assert.equal(asm, fixture.asm)
})
})
})
2021-01-02 15:41:12 -08:00
describe('P2PKH scriptPubKey', () => {
fixtures.scriptPubKeyToASM.forEach(fixture => {
it(`should compile scriptPubKey buffer to ${fixture.asm}`, () => {
const asm = bchjs.Script.toASM(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.scriptPubKeyHex, 'hex')
)
assert.equal(asm, fixture.asm)
})
})
})
})
2021-01-02 15:41:12 -08:00
describe('#fromASM', () => {
describe('P2PKH scriptSig', () => {
fixtures.scriptSigFromASM.forEach(fixture => {
2021-01-02 15:41:12 -08:00
it('should decode scriptSig asm to buffer', () => {
const buf = bchjs.Script.fromASM(fixture.asm)
2021-01-02 15:41:12 -08:00
assert.equal(typeof buf, 'object')
})
})
})
2021-01-02 15:41:12 -08:00
describe('P2PKH scriptPubKey', () => {
fixtures.scriptPubKeyFromASM.forEach(fixture => {
2021-01-02 15:41:12 -08:00
it('should decode scriptPubKey asm to buffer', () => {
const buf = bchjs.Script.fromASM(fixture.asm)
2021-01-02 15:41:12 -08:00
assert.equal(typeof buf, 'object')
})
})
})
})
2021-01-02 15:41:12 -08:00
describe('#OPCodes', () => {
for (const opcode in fixtures.opcodes) {
it(`should have OP Code ${opcode}`, () => {
assert.equal(bchjs.Script.opcodes[opcode], fixtures.opcodes[opcode])
})
}
})
2021-01-02 15:41:12 -08:00
describe('#classifyInput', () => {
fixtures.classifyInput.forEach(fixture => {
it(`should classify input type ${fixture.type}`, () => {
const type = bchjs.Script.classifyInput(
bchjs.Script.fromASM(fixture.script)
)
assert.equal(type, fixture.type)
})
})
})
2021-01-02 15:41:12 -08:00
describe('#classifyOutput', () => {
fixtures.classifyOutput.forEach(fixture => {
it(`should classify ouput type ${fixture.type}`, () => {
const type = bchjs.Script.classifyOutput(
bchjs.Script.fromASM(fixture.script)
)
assert.equal(type, fixture.type)
})
})
})
2021-01-02 15:41:12 -08:00
describe('#nullDataTemplate', () => {
fixtures.nullDataTemplate.forEach(fixture => {
2021-01-02 15:41:12 -08:00
it('should encode nulldata output', () => {
const buf = bchjs.Script.nullData.output.encode(
2021-01-02 15:41:12 -08:00
Buffer.from(`${fixture.data}`, 'ascii')
)
2021-01-02 15:41:12 -08:00
assert.equal(buf.toString('hex'), fixture.hex)
})
2021-01-02 15:41:12 -08:00
it('should decode nulldata output', () => {
const buf = bchjs.Script.nullData.output.decode(
2021-01-02 15:41:12 -08:00
Buffer.from(`${fixture.hex}`, 'hex')
)
2021-01-02 15:41:12 -08:00
assert.equal(buf.toString('ascii'), fixture.data)
})
2021-01-02 15:41:12 -08:00
it('should confirm correctly formatted nulldata output', () => {
const buf = bchjs.Script.nullData.output.encode(
2021-01-02 15:41:12 -08:00
Buffer.from(`${fixture.data}`, 'ascii')
)
const valid = bchjs.Script.nullData.output.check(buf)
assert.equal(valid, true)
})
})
})
2021-01-02 15:41:12 -08:00
describe('#pubKeyTemplate', () => {
describe('#pubKeyInputTemplate', () => {
fixtures.pubKeyInputTemplate.forEach(fixture => {
2021-01-02 15:41:12 -08:00
it('should encode pubKey input', () => {
const buf = bchjs.Script.pubKey.input.encode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.signature, 'hex')
)
2021-01-02 15:41:12 -08:00
assert.equal(buf.toString('hex'), fixture.hex)
})
2021-01-02 15:41:12 -08:00
it('should decode pubKey input', () => {
const buf = bchjs.Script.pubKey.input.decode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.hex, 'hex')
)
2021-01-02 15:41:12 -08:00
assert.equal(buf.toString('hex'), fixture.signature)
})
2021-01-02 15:41:12 -08:00
it('should confirm correctly formatted pubKeyHash input', () => {
const buf = bchjs.Script.pubKey.input.encode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.signature, 'hex')
)
const valid = bchjs.Script.pubKey.input.check(buf)
assert.equal(valid, true)
})
})
})
2021-01-02 15:41:12 -08:00
describe('#pubKeyOutputTemplate', () => {
fixtures.pubKeyOutputTemplate.forEach(fixture => {
2021-01-02 15:41:12 -08:00
it('should encode pubKey output', () => {
const buf = bchjs.Script.pubKey.output.encode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.pubKey, 'hex')
)
2021-01-02 15:41:12 -08:00
assert.equal(buf.toString('hex'), fixture.hex)
})
2021-01-02 15:41:12 -08:00
it('should decode pubKey output', () => {
const buf = bchjs.Script.pubKey.output.decode(
2021-01-02 15:41:12 -08:00
Buffer.from(`${fixture.hex}`, 'hex')
)
2021-01-02 15:41:12 -08:00
assert.equal(buf.toString('hex'), fixture.pubKey)
})
2021-01-02 15:41:12 -08:00
it('should confirm correctly formatted pubKey output', () => {
const buf = bchjs.Script.pubKey.output.encode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.pubKey, 'hex')
)
const valid = bchjs.Script.pubKey.output.check(buf)
assert.equal(valid, true)
})
})
})
})
2021-01-02 15:41:12 -08:00
describe('#pubKeyHashTemplate', () => {
describe('#pubKeyHashInputTemplate', () => {
fixtures.pubKeyHashInputTemplate.forEach(fixture => {
2021-01-02 15:41:12 -08:00
it('should encode pubKeyHash input', () => {
const buf = bchjs.Script.pubKeyHash.input.encode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.signature, 'hex'),
Buffer.from(fixture.pubKey, 'hex')
)
2021-01-02 15:41:12 -08:00
assert.equal(buf.toString('hex'), fixture.hex)
})
2021-01-02 15:41:12 -08:00
it('should decode pubKeyHash input signature', () => {
const buf = bchjs.Script.pubKeyHash.input.decode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.hex, 'hex')
)
2021-01-02 15:41:12 -08:00
assert.equal(buf.signature.toString('hex'), fixture.signature)
})
2021-01-02 15:41:12 -08:00
it('should decode pubKeyHash input pubkey', () => {
const buf = bchjs.Script.pubKeyHash.input.decode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.hex, 'hex')
)
2021-01-02 15:41:12 -08:00
assert.equal(buf.pubKey.toString('hex'), fixture.pubKey)
})
2021-01-02 15:41:12 -08:00
it('should confirm correctly formatted pubKeyHash input', () => {
const buf = bchjs.Script.pubKeyHash.input.encode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.signature, 'hex'),
Buffer.from(fixture.pubKey, 'hex')
)
const valid = bchjs.Script.pubKeyHash.input.check(buf)
assert.equal(valid, true)
})
})
})
2021-01-02 15:41:12 -08:00
describe('#pubKeyHashOutputTemplate', () => {
it('should exercise pubKeyHashOutputTemplate', () => {
fixtures.pubKeyHashOutputTemplate.forEach(fixture => {
const node = bchjs.HDNode.fromXPriv(fixture.xpriv)
const identifier = bchjs.HDNode.toIdentifier(node)
2021-01-02 15:41:12 -08:00
it('should encode pubKeyHash output', () => {
const buf = bchjs.Script.pubKeyHash.output.encode(identifier)
2021-01-02 15:41:12 -08:00
assert.equal(buf.toString('hex'), fixture.hex)
})
2021-01-02 15:41:12 -08:00
it('should decode pubKeyHash output', () => {
const buf = bchjs.Script.pubKeyHash.output.decode(
2021-01-02 15:41:12 -08:00
Buffer.from(`${fixture.hex}`, 'hex')
)
2021-01-02 15:41:12 -08:00
assert.equal(buf.toString('hex'), identifier.toString('hex'))
})
2021-01-02 15:41:12 -08:00
it('should confirm correctly formatted pubKeyHash output', () => {
const buf = bchjs.Script.pubKeyHash.output.encode(identifier)
const valid = bchjs.Script.pubKeyHash.output.check(buf)
assert.equal(valid, true)
})
})
})
})
})
2021-01-02 15:41:12 -08:00
describe('#multisigTemplate', () => {
describe('#multisigInputTemplate', () => {
fixtures.multisigInputTemplate.forEach(fixture => {
2021-01-02 15:41:12 -08:00
it('should encode multisig input', () => {
const signatures = fixture.signatures.map(signature =>
signature
2021-01-02 15:41:12 -08:00
? Buffer.from(signature, 'hex')
: bchjs.Script.opcodes.OP_0
)
const buf = bchjs.Script.multisig.input.encode(signatures)
2021-01-02 15:41:12 -08:00
assert.equal(buf.toString('hex'), fixture.hex)
})
2021-01-02 15:41:12 -08:00
it('should decode multisig input', () => {
const buf = bchjs.Script.multisig.input.decode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.hex, 'hex')
)
2021-01-02 15:41:12 -08:00
assert.equal(buf[0].toString('hex'), fixture.signatures[0])
})
2021-01-02 15:41:12 -08:00
it('should confirm correctly formatted multisig input', () => {
const signatures = fixture.signatures.map(signature =>
signature
2021-01-02 15:41:12 -08:00
? Buffer.from(signature, 'hex')
: bchjs.Script.opcodes.OP_0
)
const buf = bchjs.Script.multisig.input.encode(signatures)
const valid = bchjs.Script.multisig.input.check(buf)
assert.equal(valid, true)
})
})
})
2021-01-02 15:41:12 -08:00
describe('#multisigOutputTemplate', () => {
fixtures.multisigOutputTemplate.forEach(fixture => {
2021-01-02 15:41:12 -08:00
it('should encode multisig output', () => {
const pubKeys = fixture.pubKeys.map(p => Buffer.from(p, 'hex'))
const m = pubKeys.length
const buf = bchjs.Script.multisig.output.encode(m, pubKeys)
2021-01-02 15:41:12 -08:00
assert.equal(buf.toString('hex'), fixture.hex)
})
2021-01-02 15:41:12 -08:00
it('should decode multisig output', () => {
const output = bchjs.Script.multisig.output.decode(
2021-01-02 15:41:12 -08:00
Buffer.from(`${fixture.hex}`, 'hex')
)
assert.equal(output.m, fixture.pubKeys.length)
})
2021-01-02 15:41:12 -08:00
it('should confirm correctly formatted multisig output', () => {
const pubKeys = fixture.pubKeys.map(p => Buffer.from(p, 'hex'))
const m = pubKeys.length
const buf = bchjs.Script.multisig.output.encode(m, pubKeys)
const valid = bchjs.Script.multisig.output.check(buf)
assert.equal(valid, true)
})
})
})
})
2021-01-02 15:41:12 -08:00
describe('#scriptHashTemplate', () => {
describe('#scriptHashInputTemplate', () => {
fixtures.scriptHashInputTemplate.forEach(fixture => {
2021-01-02 15:41:12 -08:00
it('should encode scriptHash input', () => {
const buf = bchjs.Script.scriptHash.input.encode(
bchjs.Script.fromASM(fixture.redeemScriptSig),
bchjs.Script.fromASM(fixture.redeemScript)
)
2021-01-02 15:41:12 -08:00
assert.equal(buf.toString('hex'), fixture.hex)
})
2021-01-02 15:41:12 -08:00
it('should decode scriptHash input', () => {
const redeemScriptSig = bchjs.Script.fromASM(fixture.redeemScriptSig)
const redeemScript = bchjs.Script.fromASM(fixture.redeemScript)
assert.deepEqual(
bchjs.Script.scriptHash.input.decode(
2021-01-02 15:41:12 -08:00
Buffer.from(fixture.hex, 'hex')
),
{
redeemScriptSig: redeemScriptSig,
redeemScript: redeemScript
}
)
})
2021-01-02 15:41:12 -08:00
it('should confirm correctly formatted scriptHash input', () => {
const buf = bchjs.Script.scriptHash.input.encode(
bchjs.Script.fromASM(fixture.redeemScriptSig),
bchjs.Script.fromASM(fixture.redeemScript)
)
const valid = bchjs.Script.scriptHash.input.check(buf)
assert.equal(valid, true)
})
})
})
2021-01-02 15:41:12 -08:00
describe('#scriptHashOutputTemplate', () => {
fixtures.scriptHashOutputTemplate.forEach(fixture => {
2021-01-02 15:41:12 -08:00
it('should encode scriptHash output', () => {
const redeemScript = bchjs.Script.fromASM(fixture.output)
const scriptHash = bchjs.Crypto.hash160(redeemScript)
const buf = bchjs.Script.scriptHash.output.encode(scriptHash)
2021-01-02 15:41:12 -08:00
assert.equal(buf.toString('hex'), fixture.hex)
})
2021-01-02 15:41:12 -08:00
it('should decode scriptHash output', () => {
const redeemScript = bchjs.Script.fromASM(fixture.output)
const scriptHash = bchjs.Crypto.hash160(redeemScript)
const buf = bchjs.Script.scriptHash.output.decode(
2021-01-02 15:41:12 -08:00
Buffer.from(`${fixture.hex}`, 'hex')
)
assert.deepEqual(buf, scriptHash)
})
2021-01-02 15:41:12 -08:00
it('should confirm correctly formatted scriptHash output', () => {
const redeemScript = bchjs.Script.fromASM(fixture.output)
const scriptHash = bchjs.Crypto.hash160(redeemScript)
const buf = bchjs.Script.scriptHash.output.encode(scriptHash)
const valid = bchjs.Script.scriptHash.output.check(buf)
assert.equal(valid, true)
})
})
})
})
})