Tests to arrow functions, use strict asserts, travis uses docker instead of regtest server

This commit is contained in:
junderw 2019-04-09 15:09:50 +09:00
parent 16823e9013
commit dc1ef5958b
No known key found for this signature in database
GPG key ID: B256185D3A971908
24 changed files with 505 additions and 498 deletions

View file

@ -1,5 +1,11 @@
sudo: false
language: node_js
services:
- docker
before_install:
- docker pull junderw/bitcoinjs-regtest-server
- docker run -d -p 127.0.0.1:8080:8080 junderw/bitcoinjs-regtest-server
- docker ps -a
node_js:
- "8"
- "lts/*"
@ -15,5 +21,5 @@ matrix:
env: TEST_SUITE=coverage
env:
- TEST_SUITE=unit
- TEST_SUITE=integration
- TEST_SUITE=integration APIURL=http://127.0.0.1:8080/1
script: npm run-script $TEST_SUITE

View file

@ -16,12 +16,12 @@ const NETWORKS = Object.assign({
}
}, require('../src/networks'))
describe('address', function () {
describe('fromBase58Check', function () {
fixtures.standard.forEach(function (f) {
describe('address', () => {
describe('fromBase58Check', () => {
fixtures.standard.forEach(f => {
if (!f.base58check) return
it('decodes ' + f.base58check, function () {
it('decodes ' + f.base58check, () => {
const decode = baddress.fromBase58Check(f.base58check)
assert.strictEqual(decode.version, f.version)
@ -29,20 +29,20 @@ describe('address', function () {
})
})
fixtures.invalid.fromBase58Check.forEach(function (f) {
it('throws on ' + f.exception, function () {
assert.throws(function () {
fixtures.invalid.fromBase58Check.forEach(f => {
it('throws on ' + f.exception, () => {
assert.throws(() => {
baddress.fromBase58Check(f.address)
}, new RegExp(f.address + ' ' + f.exception))
})
})
})
describe('fromBech32', function () {
fixtures.standard.forEach((f) => {
describe('fromBech32', () => {
fixtures.standard.forEach(f => {
if (!f.bech32) return
it('decodes ' + f.bech32, function () {
it('decodes ' + f.bech32, () => {
const actual = baddress.fromBech32(f.bech32)
assert.strictEqual(actual.version, f.version)
@ -52,17 +52,17 @@ describe('address', function () {
})
fixtures.invalid.bech32.forEach((f, i) => {
it('decode fails for ' + f.bech32 + '(' + f.exception + ')', function () {
assert.throws(function () {
it('decode fails for ' + f.bech32 + '(' + f.exception + ')', () => {
assert.throws(() => {
baddress.fromBech32(f.address)
}, new RegExp(f.exception))
})
})
})
describe('fromOutputScript', function () {
fixtures.standard.forEach(function (f) {
it('encodes ' + f.script.slice(0, 30) + '... (' + f.network + ')', function () {
describe('fromOutputScript', () => {
fixtures.standard.forEach(f => {
it('encodes ' + f.script.slice(0, 30) + '... (' + f.network + ')', () => {
const script = bscript.fromASM(f.script)
const address = baddress.fromOutputScript(script, NETWORKS[f.network])
@ -70,22 +70,22 @@ describe('address', function () {
})
})
fixtures.invalid.fromOutputScript.forEach(function (f) {
it('throws when ' + f.script.slice(0, 30) + '... ' + f.exception, function () {
fixtures.invalid.fromOutputScript.forEach(f => {
it('throws when ' + f.script.slice(0, 30) + '... ' + f.exception, () => {
const script = bscript.fromASM(f.script)
assert.throws(function () {
assert.throws(() => {
baddress.fromOutputScript(script)
}, new RegExp(f.exception))
})
})
})
describe('toBase58Check', function () {
fixtures.standard.forEach(function (f) {
describe('toBase58Check', () => {
fixtures.standard.forEach(f => {
if (!f.base58check) return
it('encodes ' + f.hash + ' (' + f.network + ')', function () {
it('encodes ' + f.hash + ' (' + f.network + ')', () => {
const address = baddress.toBase58Check(Buffer.from(f.hash, 'hex'), f.version)
assert.strictEqual(address, f.base58check)
@ -93,39 +93,39 @@ describe('address', function () {
})
})
describe('toBech32', function () {
describe('toBech32', () => {
fixtures.bech32.forEach((f, i) => {
if (!f.bech32) return
const data = Buffer.from(f.data, 'hex')
it('encode ' + f.address, function () {
assert.deepEqual(baddress.toBech32(data, f.version, f.prefix), f.address)
it('encode ' + f.address, () => {
assert.deepStrictEqual(baddress.toBech32(data, f.version, f.prefix), f.address)
})
})
fixtures.invalid.bech32.forEach((f, i) => {
if (!f.prefix || f.version === undefined || f.data === undefined) return
it('encode fails (' + f.exception, function () {
assert.throws(function () {
it('encode fails (' + f.exception, () => {
assert.throws(() => {
baddress.toBech32(Buffer.from(f.data, 'hex'), f.version, f.prefix)
}, new RegExp(f.exception))
})
})
})
describe('toOutputScript', function () {
fixtures.standard.forEach(function (f) {
it('decodes ' + f.script.slice(0, 30) + '... (' + f.network + ')', function () {
describe('toOutputScript', () => {
fixtures.standard.forEach(f => {
it('decodes ' + f.script.slice(0, 30) + '... (' + f.network + ')', () => {
const script = baddress.toOutputScript(f.base58check || f.bech32, NETWORKS[f.network])
assert.strictEqual(bscript.toASM(script), f.script)
})
})
fixtures.invalid.toOutputScript.forEach(function (f) {
it('throws when ' + f.exception, function () {
assert.throws(function () {
fixtures.invalid.toOutputScript.forEach(f => {
it('throws when ' + f.exception, () => {
assert.throws(() => {
baddress.toOutputScript(f.address, f.network)
}, new RegExp(f.address + ' ' + f.exception))
})

View file

@ -12,21 +12,21 @@ const sigHash = require('./fixtures/core/sighash.json')
const sigNoncanonical = require('./fixtures/core/sig_noncanonical.json')
const txValid = require('./fixtures/core/tx_valid.json')
describe('Bitcoin-core', function () {
describe('Bitcoin-core', () => {
// base58EncodeDecode
describe('base58', function () {
base58EncodeDecode.forEach(function (f) {
describe('base58', () => {
base58EncodeDecode.forEach(f => {
const fhex = f[0]
const fb58 = f[1]
it('can decode ' + fb58, function () {
it('can decode ' + fb58, () => {
const buffer = base58.decode(fb58)
const actual = buffer.toString('hex')
assert.strictEqual(actual, fhex)
})
it('can encode ' + fhex, function () {
it('can encode ' + fhex, () => {
const buffer = Buffer.from(fhex, 'hex')
const actual = base58.encode(buffer)
@ -36,13 +36,13 @@ describe('Bitcoin-core', function () {
})
// base58KeysValid
describe('address.toBase58Check', function () {
describe('address.toBase58Check', () => {
const typeMap = {
'pubkey': 'pubKeyHash',
'script': 'scriptHash'
}
base58KeysValid.forEach(function (f) {
base58KeysValid.forEach(f => {
const expected = f[0]
const hash = Buffer.from(f[1], 'hex')
const params = f[2]
@ -52,14 +52,14 @@ describe('Bitcoin-core', function () {
const network = params.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin
const version = network[typeMap[params.addrType]]
it('can export ' + expected, function () {
it('can export ' + expected, () => {
assert.strictEqual(bitcoin.address.toBase58Check(hash, version), expected)
})
})
})
// base58KeysInvalid
describe('address.fromBase58Check', function () {
describe('address.fromBase58Check', () => {
const allowedNetworks = [
bitcoin.networks.bitcoin.pubkeyhash,
bitcoin.networks.bitcoin.scripthash,
@ -67,22 +67,22 @@ describe('Bitcoin-core', function () {
bitcoin.networks.testnet.scripthash
]
base58KeysInvalid.forEach(function (f) {
base58KeysInvalid.forEach(f => {
const string = f[0]
it('throws on ' + string, function () {
assert.throws(function () {
it('throws on ' + string, () => {
assert.throws(() => {
const address = bitcoin.address.fromBase58Check(string)
assert.notEqual(allowedNetworks.indexOf(address.version), -1, 'Invalid network')
assert.notStrictEqual(allowedNetworks.indexOf(address.version), -1, 'Invalid network')
}, /(Invalid (checksum|network))|(too (short|long))/)
})
})
})
// base58KeysValid
describe('ECPair', function () {
base58KeysValid.forEach(function (f) {
describe('ECPair', () => {
base58KeysValid.forEach(f => {
const string = f[0]
const hex = f[1]
const params = f[2]
@ -92,38 +92,38 @@ describe('Bitcoin-core', function () {
const network = params.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin
const keyPair = bitcoin.ECPair.fromWIF(string, network)
it('fromWIF imports ' + string, function () {
it('fromWIF imports ' + string, () => {
assert.strictEqual(keyPair.privateKey.toString('hex'), hex)
assert.strictEqual(keyPair.compressed, params.isCompressed)
})
it('toWIF exports ' + hex + ' to ' + string, function () {
it('toWIF exports ' + hex + ' to ' + string, () => {
assert.strictEqual(keyPair.toWIF(), string)
})
})
})
// base58KeysInvalid
describe('ECPair.fromWIF', function () {
describe('ECPair.fromWIF', () => {
const allowedNetworks = [
bitcoin.networks.bitcoin,
bitcoin.networks.testnet
]
base58KeysInvalid.forEach(function (f) {
base58KeysInvalid.forEach(f => {
const string = f[0]
it('throws on ' + string, function () {
assert.throws(function () {
it('throws on ' + string, () => {
assert.throws(() => {
bitcoin.ECPair.fromWIF(string, allowedNetworks)
}, /(Invalid|Unknown) (checksum|compression flag|network version|WIF length)/)
})
})
})
describe('Block.fromHex', function () {
blocksValid.forEach(function (f) {
it('can parse ' + f.id, function () {
describe('Block.fromHex', () => {
blocksValid.forEach(f => {
it('can parse ' + f.id, () => {
const block = bitcoin.Block.fromHex(f.hex)
assert.strictEqual(block.getId(), f.id)
@ -133,8 +133,8 @@ describe('Bitcoin-core', function () {
})
// txValid
describe('Transaction.fromHex', function () {
txValid.forEach(function (f) {
describe('Transaction.fromHex', () => {
txValid.forEach(f => {
// Objects that are only a single string are ignored
if (f.length === 1) return
@ -142,17 +142,17 @@ describe('Bitcoin-core', function () {
const fhex = f[1]
// const verifyFlags = f[2] // TODO: do we need to test this?
it('can decode ' + fhex, function () {
it('can decode ' + fhex, () => {
const transaction = bitcoin.Transaction.fromHex(fhex)
transaction.ins.forEach(function (txIn, i) {
transaction.ins.forEach((txIn, i) => {
const input = inputs[i]
// reverse because test data is reversed
const prevOutHash = Buffer.from(input[0], 'hex').reverse()
const prevOutIndex = input[1]
assert.deepEqual(txIn.hash, prevOutHash)
assert.deepStrictEqual(txIn.hash, prevOutHash)
// we read UInt32, not Int32
assert.strictEqual(txIn.index & 0xffffffff, prevOutIndex)
@ -162,8 +162,8 @@ describe('Bitcoin-core', function () {
})
// sighash
describe('Transaction', function () {
sigHash.forEach(function (f) {
describe('Transaction', () => {
sigHash.forEach(f => {
// Objects that are only a single string are ignored
if (f.length === 1) return
@ -181,7 +181,7 @@ describe('Bitcoin-core', function () {
const hashTypeName = hashTypes.join(' | ')
it('should hash ' + txHex.slice(0, 40) + '... (' + hashTypeName + ')', function () {
it('should hash ' + txHex.slice(0, 40) + '... (' + hashTypeName + ')', () => {
const transaction = bitcoin.Transaction.fromHex(txHex)
assert.strictEqual(transaction.toHex(), txHex)
@ -192,16 +192,16 @@ describe('Bitcoin-core', function () {
const hash = transaction.hashForSignature(inIndex, script, hashType)
// reverse because test data is reversed
assert.equal(hash.reverse().toString('hex'), expectedHash)
assert.strictEqual(hash.reverse().toString('hex'), expectedHash)
})
})
})
describe('script.signature.decode', function () {
sigCanonical.forEach(function (hex) {
describe('script.signature.decode', () => {
sigCanonical.forEach(hex => {
const buffer = Buffer.from(hex, 'hex')
it('can parse ' + hex, function () {
it('can parse ' + hex, () => {
const parsed = bitcoin.script.signature.decode(buffer)
const actual = bitcoin.script.signature.encode(parsed.signature, parsed.hashType)
@ -209,15 +209,15 @@ describe('Bitcoin-core', function () {
})
})
sigNoncanonical.forEach(function (hex, i) {
sigNoncanonical.forEach((hex, i) => {
if (i === 0) return
if (i % 2 !== 0) return
const description = sigNoncanonical[i - 1].slice(0, -1)
const buffer = Buffer.from(hex, 'hex')
it('throws on ' + description, function () {
assert.throws(function () {
it('throws on ' + description, () => {
assert.throws(() => {
bitcoin.script.signature.decode(buffer)
}, /Expected DER (integer|sequence)|(R|S) value (excessively padded|is negative)|(R|S|DER sequence) length is (zero|too short|too long|invalid)|Invalid hashType/)
})

View file

@ -4,29 +4,29 @@ const Block = require('..').Block
const fixtures = require('./fixtures/block')
describe('Block', function () {
describe('version', function () {
it('should be interpreted as an int32le', function () {
describe('Block', () => {
describe('version', () => {
it('should be interpreted as an int32le', () => {
const blockHex = 'ffffffff0000000000000000000000000000000000000000000000000000000000000000414141414141414141414141414141414141414141414141414141414141414101000000020000000300000000'
const block = Block.fromHex(blockHex)
assert.equal(-1, block.version)
assert.equal(1, block.timestamp)
assert.strictEqual(-1, block.version)
assert.strictEqual(1, block.timestamp)
})
})
describe('calculateTarget', function () {
fixtures.targets.forEach(function (f) {
it('returns ' + f.expected + ' for 0x' + f.bits, function () {
describe('calculateTarget', () => {
fixtures.targets.forEach(f => {
it('returns ' + f.expected + ' for 0x' + f.bits, () => {
const bits = parseInt(f.bits, 16)
assert.equal(Block.calculateTarget(bits).toString('hex'), f.expected)
assert.strictEqual(Block.calculateTarget(bits).toString('hex'), f.expected)
})
})
})
describe('fromBuffer/fromHex', function () {
fixtures.valid.forEach(function (f) {
it('imports ' + f.description, function () {
describe('fromBuffer/fromHex', () => {
fixtures.valid.forEach(f => {
it('imports ' + f.description, () => {
const block = Block.fromHex(f.hex)
assert.strictEqual(block.version, f.version)
@ -42,54 +42,54 @@ describe('Block', function () {
})
})
fixtures.invalid.forEach(function (f) {
it('throws on ' + f.exception, function () {
assert.throws(function () {
fixtures.invalid.forEach(f => {
it('throws on ' + f.exception, () => {
assert.throws(() => {
Block.fromHex(f.hex)
}, new RegExp(f.exception))
})
})
})
describe('toBuffer/toHex', function () {
fixtures.valid.forEach(function (f) {
describe('toBuffer/toHex', () => {
fixtures.valid.forEach(f => {
let block
beforeEach(function () {
beforeEach(() => {
block = Block.fromHex(f.hex)
})
it('exports ' + f.description, function () {
it('exports ' + f.description, () => {
assert.strictEqual(block.toHex(true), f.hex.slice(0, 160))
assert.strictEqual(block.toHex(), f.hex)
})
})
})
describe('getHash/getId', function () {
fixtures.valid.forEach(function (f) {
describe('getHash/getId', () => {
fixtures.valid.forEach(f => {
let block
beforeEach(function () {
beforeEach(() => {
block = Block.fromHex(f.hex)
})
it('returns ' + f.id + ' for ' + f.description, function () {
it('returns ' + f.id + ' for ' + f.description, () => {
assert.strictEqual(block.getHash().toString('hex'), f.hash)
assert.strictEqual(block.getId(), f.id)
})
})
})
describe('getUTCDate', function () {
fixtures.valid.forEach(function (f) {
describe('getUTCDate', () => {
fixtures.valid.forEach(f => {
let block
beforeEach(function () {
beforeEach(() => {
block = Block.fromHex(f.hex)
})
it('returns UTC date of ' + f.id, function () {
it('returns UTC date of ' + f.id, () => {
const utcDate = block.getUTCDate().getTime()
assert.strictEqual(utcDate, f.timestamp * 1e3)
@ -97,59 +97,59 @@ describe('Block', function () {
})
})
describe('calculateMerkleRoot', function () {
it('should throw on zero-length transaction array', function () {
assert.throws(function () {
describe('calculateMerkleRoot', () => {
it('should throw on zero-length transaction array', () => {
assert.throws(() => {
Block.calculateMerkleRoot([])
}, /Cannot compute merkle root for zero transactions/)
})
fixtures.valid.forEach(function (f) {
fixtures.valid.forEach(f => {
if (f.hex.length === 160) return
let block
beforeEach(function () {
beforeEach(() => {
block = Block.fromHex(f.hex)
})
it('returns ' + f.merkleRoot + ' for ' + f.id, function () {
it('returns ' + f.merkleRoot + ' for ' + f.id, () => {
assert.strictEqual(Block.calculateMerkleRoot(block.transactions).toString('hex'), f.merkleRoot)
})
if (f.witnessCommit) {
it('returns witness commit ' + f.witnessCommit + ' for ' + f.id, function () {
it('returns witness commit ' + f.witnessCommit + ' for ' + f.id, () => {
assert.strictEqual(Block.calculateMerkleRoot(block.transactions, true).toString('hex'), f.witnessCommit)
})
}
})
})
describe('checkTxRoots', function () {
fixtures.valid.forEach(function (f) {
describe('checkTxRoots', () => {
fixtures.valid.forEach(f => {
if (f.hex.length === 160) return
let block
beforeEach(function () {
beforeEach(() => {
block = Block.fromHex(f.hex)
})
it('returns ' + f.valid + ' for ' + f.id, function () {
it('returns ' + f.valid + ' for ' + f.id, () => {
assert.strictEqual(block.checkTxRoots(), true)
})
})
})
describe('checkProofOfWork', function () {
fixtures.valid.forEach(function (f) {
describe('checkProofOfWork', () => {
fixtures.valid.forEach(f => {
let block
beforeEach(function () {
beforeEach(() => {
block = Block.fromHex(f.hex)
})
it('returns ' + f.valid + ' for ' + f.id, function () {
it('returns ' + f.valid + ' for ' + f.id, () => {
assert.strictEqual(block.checkProofOfWork(), f.valid)
})
})

View file

@ -4,10 +4,10 @@ const bufferutils = require('../src/bufferutils')
const fixtures = require('./fixtures/bufferutils.json')
describe('bufferutils', function () {
describe('readUInt64LE', function () {
fixtures.valid.forEach(function (f) {
it('decodes ' + f.hex, function () {
describe('bufferutils', () => {
describe('readUInt64LE', () => {
fixtures.valid.forEach(f => {
it('decodes ' + f.hex, () => {
const buffer = Buffer.from(f.hex, 'hex')
const number = bufferutils.readUInt64LE(buffer, 0)
@ -15,20 +15,20 @@ describe('bufferutils', function () {
})
})
fixtures.invalid.readUInt64LE.forEach(function (f) {
it('throws on ' + f.description, function () {
fixtures.invalid.readUInt64LE.forEach(f => {
it('throws on ' + f.description, () => {
const buffer = Buffer.from(f.hex, 'hex')
assert.throws(function () {
assert.throws(() => {
bufferutils.readUInt64LE(buffer, 0)
}, new RegExp(f.exception))
})
})
})
describe('writeUInt64LE', function () {
fixtures.valid.forEach(function (f) {
it('encodes ' + f.dec, function () {
describe('writeUInt64LE', () => {
fixtures.valid.forEach(f => {
it('encodes ' + f.dec, () => {
const buffer = Buffer.alloc(8, 0)
bufferutils.writeUInt64LE(buffer, f.dec, 0)
@ -36,11 +36,11 @@ describe('bufferutils', function () {
})
})
fixtures.invalid.readUInt64LE.forEach(function (f) {
it('throws on ' + f.description, function () {
fixtures.invalid.readUInt64LE.forEach(f => {
it('throws on ' + f.description, () => {
const buffer = Buffer.alloc(8, 0)
assert.throws(function () {
assert.throws(() => {
bufferutils.writeUInt64LE(buffer, f.dec, 0)
}, new RegExp(f.exception))
})

View file

@ -25,12 +25,12 @@ const tmap = {
witnessCommitment
}
describe('classify', function () {
describe('input', function () {
fixtures.valid.forEach(function (f) {
describe('classify', () => {
describe('input', () => {
fixtures.valid.forEach(f => {
if (!f.input) return
it('classifies ' + f.input + ' as ' + f.type, function () {
it('classifies ' + f.input + ' as ' + f.type, () => {
const input = bscript.fromASM(f.input)
const type = classify.input(input)
@ -38,11 +38,11 @@ describe('classify', function () {
})
})
fixtures.valid.forEach(function (f) {
fixtures.valid.forEach(f => {
if (!f.input) return
if (!f.typeIncomplete) return
it('classifies incomplete ' + f.input + ' as ' + f.typeIncomplete, function () {
it('classifies incomplete ' + f.input + ' as ' + f.typeIncomplete, () => {
const input = bscript.fromASM(f.input)
const type = classify.input(input, true)
@ -51,11 +51,11 @@ describe('classify', function () {
})
})
describe('classifyOutput', function () {
fixtures.valid.forEach(function (f) {
describe('classifyOutput', () => {
fixtures.valid.forEach(f => {
if (!f.output) return
it('classifies ' + f.output + ' as ' + f.type, function () {
it('classifies ' + f.output + ' as ' + f.type, () => {
const output = bscript.fromASM(f.output)
const type = classify.output(output)
@ -73,12 +73,12 @@ describe('classify', function () {
'multisig',
'nullData',
'witnessCommitment'
].forEach(function (name) {
].forEach(name => {
const inputType = tmap[name].input
const outputType = tmap[name].output
describe(name + '.input.check', function () {
fixtures.valid.forEach(function (f) {
describe(name + '.input.check', () => {
fixtures.valid.forEach(f => {
if (name.toLowerCase() === classify.types.P2WPKH) return
if (name.toLowerCase() === classify.types.P2WSH) return
const expected = name.toLowerCase() === f.type.toLowerCase()
@ -86,14 +86,14 @@ describe('classify', function () {
if (inputType && f.input) {
const input = bscript.fromASM(f.input)
it('returns ' + expected + ' for ' + f.input, function () {
it('returns ' + expected + ' for ' + f.input, () => {
assert.strictEqual(inputType.check(input), expected)
})
if (f.typeIncomplete) {
const expectedIncomplete = name.toLowerCase() === f.typeIncomplete
it('returns ' + expected + ' for ' + f.input, function () {
it('returns ' + expected + ' for ' + f.input, () => {
assert.strictEqual(inputType.check(input, true), expectedIncomplete)
})
}
@ -102,10 +102,10 @@ describe('classify', function () {
if (!(fixtures.invalid[name])) return
fixtures.invalid[name].inputs.forEach(function (f) {
fixtures.invalid[name].inputs.forEach(f => {
if (!f.input && !f.inputHex) return
it('returns false for ' + f.description + ' (' + (f.input || f.inputHex) + ')', function () {
it('returns false for ' + f.description + ' (' + (f.input || f.inputHex) + ')', () => {
let input
if (f.input) {
@ -119,12 +119,12 @@ describe('classify', function () {
})
})
describe(name + '.output.check', function () {
fixtures.valid.forEach(function (f) {
describe(name + '.output.check', () => {
fixtures.valid.forEach(f => {
const expected = name.toLowerCase() === f.type
if (outputType && f.output) {
it('returns ' + expected + ' for ' + f.output, function () {
it('returns ' + expected + ' for ' + f.output, () => {
const output = bscript.fromASM(f.output)
if (name.toLowerCase() === 'nulldata' && f.type === classify.types.WITNESS_COMMITMENT) return
@ -136,10 +136,10 @@ describe('classify', function () {
if (!(fixtures.invalid[name])) return
fixtures.invalid[name].outputs.forEach(function (f) {
fixtures.invalid[name].outputs.forEach(f => {
if (!f.output && !f.outputHex) return
it('returns false for ' + f.description + ' (' + (f.output || f.outputHex) + ')', function () {
it('returns false for ' + f.description + ' (' + (f.output || f.outputHex) + ')', () => {
let output
if (f.output) {

View file

@ -4,14 +4,14 @@ const bcrypto = require('../src/crypto')
const fixtures = require('./fixtures/crypto')
describe('crypto', function () {
['hash160', 'hash256', 'ripemd160', 'sha1', 'sha256'].forEach(function (algorithm) {
describe(algorithm, function () {
fixtures.forEach(function (f) {
describe('crypto', () => {
['hash160', 'hash256', 'ripemd160', 'sha1', 'sha256'].forEach(algorithm => {
describe(algorithm, () => {
fixtures.forEach(f => {
const fn = bcrypto[algorithm]
const expected = f[algorithm]
it('returns ' + expected + ' for ' + f.hex, function () {
it('returns ' + expected + ' for ' + f.hex, () => {
const data = Buffer.from(f.hex, 'hex')
const actual = fn(data).toString('hex')

View file

@ -19,15 +19,15 @@ const ONE = Buffer.from('0000000000000000000000000000000000000000000000000000000
const GROUP_ORDER = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 'hex')
const GROUP_ORDER_LESS_1 = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140', 'hex')
describe('ECPair', function () {
describe('getPublicKey', function () {
describe('ECPair', () => {
describe('getPublicKey', () => {
let keyPair
beforeEach(function () {
beforeEach(() => {
keyPair = ECPair.fromPrivateKey(ONE)
})
it('calls pointFromScalar lazily', hoodwink(function () {
it('calls pointFromScalar lazily', hoodwink(() => {
assert.strictEqual(keyPair.__Q, undefined)
// .publicKey forces the memoization
@ -36,14 +36,14 @@ describe('ECPair', function () {
}))
})
describe('fromPrivateKey', function () {
it('defaults to compressed', function () {
describe('fromPrivateKey', () => {
it('defaults to compressed', () => {
const keyPair = ECPair.fromPrivateKey(ONE)
assert.strictEqual(keyPair.compressed, true)
})
it('supports the uncompressed option', function () {
it('supports the uncompressed option', () => {
const keyPair = ECPair.fromPrivateKey(ONE, {
compressed: false
})
@ -51,7 +51,7 @@ describe('ECPair', function () {
assert.strictEqual(keyPair.compressed, false)
})
it('supports the network option', function () {
it('supports the network option', () => {
const keyPair = ECPair.fromPrivateKey(ONE, {
compressed: false,
network: NETWORKS.testnet
@ -60,8 +60,8 @@ describe('ECPair', function () {
assert.strictEqual(keyPair.network, NETWORKS.testnet)
})
fixtures.valid.forEach(function (f) {
it('derives public key for ' + f.WIF, function () {
fixtures.valid.forEach(f => {
it('derives public key for ' + f.WIF, () => {
const d = Buffer.from(f.d, 'hex')
const keyPair = ECPair.fromPrivateKey(d, {
compressed: f.compressed
@ -71,30 +71,30 @@ describe('ECPair', function () {
})
})
fixtures.invalid.fromPrivateKey.forEach(function (f) {
it('throws ' + f.exception, function () {
fixtures.invalid.fromPrivateKey.forEach(f => {
it('throws ' + f.exception, () => {
const d = Buffer.from(f.d, 'hex')
assert.throws(function () {
assert.throws(() => {
ECPair.fromPrivateKey(d, f.options)
}, new RegExp(f.exception))
})
})
})
describe('fromPublicKey', function () {
fixtures.invalid.fromPublicKey.forEach(function (f) {
it('throws ' + f.exception, function () {
describe('fromPublicKey', () => {
fixtures.invalid.fromPublicKey.forEach(f => {
it('throws ' + f.exception, () => {
const Q = Buffer.from(f.Q, 'hex')
assert.throws(function () {
assert.throws(() => {
ECPair.fromPublicKey(Q, f.options)
}, new RegExp(f.exception))
})
})
})
describe('fromWIF', function () {
fixtures.valid.forEach(function (f) {
it('imports ' + f.WIF + ' (' + f.network + ')', function () {
describe('fromWIF', () => {
fixtures.valid.forEach(f => {
it('imports ' + f.WIF + ' (' + f.network + ')', () => {
const network = NETWORKS[f.network]
const keyPair = ECPair.fromWIF(f.WIF, network)
@ -104,8 +104,8 @@ describe('ECPair', function () {
})
})
fixtures.valid.forEach(function (f) {
it('imports ' + f.WIF + ' (via list of networks)', function () {
fixtures.valid.forEach(f => {
it('imports ' + f.WIF + ' (via list of networks)', () => {
const keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST)
assert.strictEqual(keyPair.privateKey.toString('hex'), f.d)
@ -114,9 +114,9 @@ describe('ECPair', function () {
})
})
fixtures.invalid.fromWIF.forEach(function (f) {
it('throws on ' + f.WIF, function () {
assert.throws(function () {
fixtures.invalid.fromWIF.forEach(f => {
it('throws on ' + f.WIF, () => {
assert.throws(() => {
const networks = f.network ? NETWORKS[f.network] : NETWORKS_LIST
ECPair.fromWIF(f.WIF, networks)
@ -125,9 +125,9 @@ describe('ECPair', function () {
})
})
describe('toWIF', function () {
fixtures.valid.forEach(function (f) {
it('exports ' + f.WIF, function () {
describe('toWIF', () => {
fixtures.valid.forEach(f => {
it('exports ' + f.WIF, () => {
const keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST)
const result = keyPair.toWIF()
assert.strictEqual(result, f.WIF)
@ -135,13 +135,13 @@ describe('ECPair', function () {
})
})
describe('makeRandom', function () {
describe('makeRandom', () => {
const d = Buffer.alloc(32, 4)
const exWIF = 'KwMWvwRJeFqxYyhZgNwYuYjbQENDAPAudQx5VEmKJrUZcq6aL2pv'
describe('uses randombytes RNG', function () {
it('generates a ECPair', function () {
const stub = { randombytes: function () { return d } }
describe('uses randombytes RNG', () => {
it('generates a ECPair', () => {
const stub = { randombytes: () => { return d } }
const ProxiedECPair = proxyquire('../src/ecpair', stub)
const keyPair = ProxiedECPair.makeRandom()
@ -149,22 +149,22 @@ describe('ECPair', function () {
})
})
it('allows a custom RNG to be used', function () {
it('allows a custom RNG to be used', () => {
const keyPair = ECPair.makeRandom({
rng: function (size) { return d.slice(0, size) }
rng: size => { return d.slice(0, size) }
})
assert.strictEqual(keyPair.toWIF(), exWIF)
})
it('retains the same defaults as ECPair constructor', function () {
it('retains the same defaults as ECPair constructor', () => {
const keyPair = ECPair.makeRandom()
assert.strictEqual(keyPair.compressed, true)
assert.strictEqual(keyPair.network, NETWORKS.bitcoin)
})
it('supports the options parameter', function () {
it('supports the options parameter', () => {
const keyPair = ECPair.makeRandom({
compressed: false,
network: NETWORKS.testnet
@ -174,18 +174,18 @@ describe('ECPair', function () {
assert.strictEqual(keyPair.network, NETWORKS.testnet)
})
it('throws if d is bad length', function () {
it('throws if d is bad length', () => {
function rng () {
return Buffer.alloc(28)
}
assert.throws(function () {
assert.throws(() => {
ECPair.makeRandom({ rng: rng })
}, /Expected Buffer\(Length: 32\), got Buffer\(Length: 28\)/)
})
it('loops until d is within interval [1, n) : 1', hoodwink(function () {
const rng = this.stub(function () {
const rng = this.stub(() => {
if (rng.calls === 0) return ZERO // 0
return ONE // >0
}, 2)
@ -194,7 +194,7 @@ describe('ECPair', function () {
}))
it('loops until d is within interval [1, n) : n - 1', hoodwink(function () {
const rng = this.stub(function () {
const rng = this.stub(() => {
if (rng.calls === 0) return ZERO // <1
if (rng.calls === 1) return GROUP_ORDER // >n-1
return GROUP_ORDER_LESS_1 // n-1
@ -204,9 +204,9 @@ describe('ECPair', function () {
}))
})
describe('.network', function () {
fixtures.valid.forEach(function (f) {
it('returns ' + f.network + ' for ' + f.WIF, function () {
describe('.network', () => {
fixtures.valid.forEach(f => {
it('returns ' + f.network + ' for ' + f.WIF, () => {
const network = NETWORKS[f.network]
const keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST)
@ -215,20 +215,20 @@ describe('ECPair', function () {
})
})
describe('tinysecp wrappers', function () {
describe('tinysecp wrappers', () => {
let keyPair
let hash
let signature
beforeEach(function () {
beforeEach(() => {
keyPair = ECPair.makeRandom()
hash = ZERO
signature = Buffer.alloc(64, 1)
})
describe('signing', function () {
describe('signing', () => {
it('wraps tinysecp.sign', hoodwink(function () {
this.mock(tinysecp, 'sign', function (h, d) {
this.mock(tinysecp, 'sign', (h, d) => {
assert.strictEqual(h, hash)
assert.strictEqual(d, keyPair.privateKey)
return signature
@ -237,18 +237,18 @@ describe('ECPair', function () {
assert.strictEqual(keyPair.sign(hash), signature)
}))
it('throws if no private key is found', function () {
it('throws if no private key is found', () => {
delete keyPair.__D
assert.throws(function () {
assert.throws(() => {
keyPair.sign(hash)
}, /Missing private key/)
})
})
describe('verify', function () {
describe('verify', () => {
it('wraps tinysecp.verify', hoodwink(function () {
this.mock(tinysecp, 'verify', function (h, q, s) {
this.mock(tinysecp, 'verify', (h, q, s) => {
assert.strictEqual(h, hash)
assert.strictEqual(q, keyPair.publicKey)
assert.strictEqual(s, signature)

View file

@ -47,7 +47,7 @@ async function faucet (address, value) {
let _unspents = []
const sleep = ms => new Promise((resolve, reject) => setTimeout(resolve, ms))
const randInt = (min, max) => min + Math.floor((max - min + 1) * Math.random())
do {
while (_unspents.length === 0) {
if (count > 0) {
if (count >= 5) throw new Error('Missing Inputs')
console.log('Missing Inputs, retry #' + count)
@ -78,7 +78,7 @@ async function faucet (address, value) {
_unspents = results.filter(x => x.txId === txId)
count++
} while (_unspents.length === 0)
}
return _unspents.pop()
}

View file

@ -4,8 +4,8 @@ const bitcoin = require('../../')
const dhttp = require('./_regtest').dhttp
const TESTNET = bitcoin.networks.testnet
describe('bitcoinjs-lib (addresses)', function () {
it('can generate a random address [and support the retrieval of transactions for that address (via 3PBP)', async function () {
describe('bitcoinjs-lib (addresses)', () => {
it('can generate a random address [and support the retrieval of transactions for that address (via 3PBP)', async () => {
const keyPair = bitcoin.ECPair.makeRandom()
const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey })
@ -23,14 +23,14 @@ describe('bitcoinjs-lib (addresses)', function () {
assert.strictEqual(result.total_sent, 0)
})
it('can import an address via WIF', function () {
it('can import an address via WIF', () => {
const keyPair = bitcoin.ECPair.fromWIF('KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn')
const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey })
assert.strictEqual(address, '1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH')
})
it('can generate a P2SH, pay-to-multisig (2-of-3) address', function () {
it('can generate a P2SH, pay-to-multisig (2-of-3) address', () => {
const pubkeys = [
'026477115981fe981a6918a6297d9803c4dc04f328f22041bedff886bbc2962e01',
'02c96db2302d19b43d4c69368babace7854cc84eb9e061cde51cfa77ca4a22b8b9',
@ -43,14 +43,14 @@ describe('bitcoinjs-lib (addresses)', function () {
assert.strictEqual(address, '36NUkt6FWUi3LAWBqWRdDmdTWbt91Yvfu7')
})
it('can generate a SegWit address', function () {
it('can generate a SegWit address', () => {
const keyPair = bitcoin.ECPair.fromWIF('KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn')
const { address } = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey })
assert.strictEqual(address, 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4')
})
it('can generate a SegWit address (via P2SH)', function () {
it('can generate a SegWit address (via P2SH)', () => {
const keyPair = bitcoin.ECPair.fromWIF('KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn')
const { address } = bitcoin.payments.p2sh({
redeem: bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey })
@ -59,7 +59,7 @@ describe('bitcoinjs-lib (addresses)', function () {
assert.strictEqual(address, '3JvL6Ymt8MVWiCNHC7oWU6nLeHNJKLZGLN')
})
it('can generate a P2WSH (SegWit), pay-to-multisig (3-of-4) address', function () {
it('can generate a P2WSH (SegWit), pay-to-multisig (3-of-4) address', () => {
const pubkeys = [
'026477115981fe981a6918a6297d9803c4dc04f328f22041bedff886bbc2962e01',
'02c96db2302d19b43d4c69368babace7854cc84eb9e061cde51cfa77ca4a22b8b9',
@ -73,7 +73,7 @@ describe('bitcoinjs-lib (addresses)', function () {
assert.strictEqual(address, 'bc1q75f6dv4q8ug7zhujrsp5t0hzf33lllnr3fe7e2pra3v24mzl8rrqtp3qul')
})
it('can generate a P2SH(P2WSH(...)), pay-to-multisig (2-of-2) address', function () {
it('can generate a P2SH(P2WSH(...)), pay-to-multisig (2-of-2) address', () => {
const pubkeys = [
'026477115981fe981a6918a6297d9803c4dc04f328f22041bedff886bbc2962e01',
'02c96db2302d19b43d4c69368babace7854cc84eb9e061cde51cfa77ca4a22b8b9'
@ -88,7 +88,7 @@ describe('bitcoinjs-lib (addresses)', function () {
})
// examples using other network information
it('can generate a Testnet address', function () {
it('can generate a Testnet address', () => {
const keyPair = bitcoin.ECPair.makeRandom({ network: TESTNET })
const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: TESTNET })
@ -96,7 +96,7 @@ describe('bitcoinjs-lib (addresses)', function () {
assert.strictEqual(address.startsWith('m') || address.startsWith('n'), true)
})
it('can generate a Litecoin address', function () {
it('can generate a Litecoin address', () => {
// WARNING: although possible, bitcoinjs is NOT necessarily compatible with Litecoin
const LITECOIN = {
messagePrefix: '\x19Litecoin Signed Message:\n',

View file

@ -8,15 +8,15 @@ function getAddress (node, network) {
return bitcoin.payments.p2pkh({ pubkey: node.publicKey, network }).address
}
describe('bitcoinjs-lib (BIP32)', function () {
it('can import a BIP32 testnet xpriv and export to WIF', function () {
describe('bitcoinjs-lib (BIP32)', () => {
it('can import a BIP32 testnet xpriv and export to WIF', () => {
const xpriv = 'tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK'
const node = bip32.fromBase58(xpriv, bitcoin.networks.testnet)
assert.strictEqual(node.toWIF(), 'cQfoY67cetFNunmBUX5wJiw3VNoYx3gG9U9CAofKE6BfiV1fSRw7')
})
it('can export a BIP32 xpriv, then import it', function () {
it('can export a BIP32 xpriv, then import it', () => {
const mnemonic = 'praise you muffin lion enable neck grocery crumble super myself license ghost'
const seed = bip39.mnemonicToSeed(mnemonic)
const node = bip32.fromSeed(seed)
@ -27,7 +27,7 @@ describe('bitcoinjs-lib (BIP32)', function () {
assert.strictEqual(node.toWIF(), restored.toWIF()) // same private key
})
it('can export a BIP32 xpub', function () {
it('can export a BIP32 xpub', () => {
const mnemonic = 'praise you muffin lion enable neck grocery crumble super myself license ghost'
const seed = bip39.mnemonicToSeed(mnemonic)
const node = bip32.fromSeed(seed)
@ -36,7 +36,7 @@ describe('bitcoinjs-lib (BIP32)', function () {
assert.strictEqual(string, 'xpub661MyMwAqRbcGhVeaVfEBA25e3cP9DsJQZoE8iep5fZSxy3TnPBNBgWnMZx56oreNc48ZoTkQfatNJ9VWnQ7ZcLZcVStpaXLTeG8bGrzX3n')
})
it('can create a BIP32, bitcoin, account 0, external address', function () {
it('can create a BIP32, bitcoin, account 0, external address', () => {
const path = "m/0'/0/0"
const root = bip32.fromSeed(Buffer.from('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', 'hex'))
@ -51,7 +51,7 @@ describe('bitcoinjs-lib (BIP32)', function () {
assert.strictEqual(getAddress(child1b), '1JHyB1oPXufr4FXkfitsjgNB5yRY9jAaa7')
})
it('can create a BIP44, bitcoin, account 0, external address', function () {
it('can create a BIP44, bitcoin, account 0, external address', () => {
const root = bip32.fromSeed(Buffer.from('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', 'hex'))
const child1 = root.derivePath("m/44'/0'/0'/0/0")
@ -67,7 +67,7 @@ describe('bitcoinjs-lib (BIP32)', function () {
assert.strictEqual(getAddress(child1b), '12Tyvr1U8A3ped6zwMEU5M8cx3G38sP5Au')
})
it('can create a BIP49, bitcoin testnet, account 0, external address', function () {
it('can create a BIP49, bitcoin testnet, account 0, external address', () => {
const mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'
const seed = bip39.mnemonicToSeed(mnemonic)
const root = bip32.fromSeed(seed)
@ -82,7 +82,7 @@ describe('bitcoinjs-lib (BIP32)', function () {
assert.strictEqual(address, '2Mww8dCYPUpKHofjgcXcBCEGmniw9CoaiD2')
})
it('can use BIP39 to generate BIP32 addresses', function () {
it('can use BIP39 to generate BIP32 addresses', () => {
// var mnemonic = bip39.generateMnemonic()
const mnemonic = 'praise you muffin lion enable neck grocery crumble super myself license ghost'
assert(bip39.validateMnemonic(mnemonic))

View file

@ -4,8 +4,8 @@ const { describe, it } = require('mocha')
const assert = require('assert')
const bitcoin = require('../../')
describe('bitcoinjs-lib (blocks)', function () {
it('can extract a height from a CoinBase transaction', function () {
describe('bitcoinjs-lib (blocks)', () => {
it('can extract a height from a CoinBase transaction', () => {
// from 00000000000000000097669cdca131f24d40c4cc7d80eaa65967a2d09acf6ce6
const txHex = '010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff50037f9a07174d696e656420627920416e74506f6f6c685b205a2b1f7bfabe6d6d36afe1910eca9405b66f97750940a656e38e2c0312958190ff8e98fd16761d220400000000000000aa340000d49f0000ffffffff02b07fc366000000001976a9148349212dc27ce3ab4c5b29b85c4dec643d764b1788ac0000000000000000266a24aa21a9ed72d9432948505e3d3062f1307a3f027a5dea846ff85e47159680919c12bf1e400120000000000000000000000000000000000000000000000000000000000000000000000000'
const tx = bitcoin.Transaction.fromHex(txHex)

View file

@ -8,9 +8,9 @@ const bip65 = require('bip65')
const alice = bitcoin.ECPair.fromWIF('cScfkGjbzzoeewVWmU2hYPUHeVGJRDdFt7WhmrVVGkxpmPP8BHWe', regtest)
const bob = bitcoin.ECPair.fromWIF('cMkopUXKWsEzAjfa1zApksGRwjVpJRB3831qM9W4gKZsLwjHXA9x', regtest)
describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
describe('bitcoinjs-lib (transactions w/ CLTV)', () => {
// force update MTP
before(async function () {
before(async () => {
await regtestUtils.mine(11)
})
@ -38,7 +38,7 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
}
// expiry past, {Alice's signature} OP_TRUE
it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the past)', async function () {
it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the past)', async () => {
// 3 hours ago
const lockTime = bip65.encode({ utc: utcNow() - (3600 * 3) })
const redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
@ -77,7 +77,7 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
})
// expiry will pass, {Alice's signature} OP_TRUE
it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)', async function () {
it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)', async () => {
const height = await regtestUtils.height()
// 5 blocks from now
const lockTime = bip65.encode({ blocks: height + 5 })
@ -120,7 +120,7 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
})
// expiry ignored, {Bob's signature} {Alice's signature} OP_FALSE
it('can create (and broadcast via 3PBP) a Transaction where Alice and Bob can redeem the output at any time', async function () {
it('can create (and broadcast via 3PBP) a Transaction where Alice and Bob can redeem the output at any time', async () => {
// two hours ago
const lockTime = bip65.encode({ utc: utcNow() - (3600 * 2) })
const redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
@ -159,7 +159,7 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
})
// expiry in the future, {Alice's signature} OP_TRUE
it('can create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry', async function () {
it('can create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry', async () => {
// two hours from now
const lockTime = bip65.encode({ utc: utcNow() + (3600 * 2) })
const redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
@ -189,7 +189,7 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
tx.setInputScript(0, redeemScriptSig)
await regtestUtils.broadcast(tx.toHex()).catch(err => {
assert.throws(function () {
assert.throws(() => {
if (err) throw err
}, /Error: non-final \(code 64\)/)
})

View file

@ -8,9 +8,9 @@ const bip68 = require('bip68')
const alice = bitcoin.ECPair.fromWIF('cScfkGjbzzoeewVWmU2hYPUHeVGJRDdFt7WhmrVVGkxpmPP8BHWe', regtest)
const bob = bitcoin.ECPair.fromWIF('cMkopUXKWsEzAjfa1zApksGRwjVpJRB3831qM9W4gKZsLwjHXA9x', regtest)
describe('bitcoinjs-lib (transactions w/ CSV)', function () {
describe('bitcoinjs-lib (transactions w/ CSV)', () => {
// force update MTP
before(async function () {
before(async () => {
await regtestUtils.mine(11)
})
@ -35,7 +35,7 @@ describe('bitcoinjs-lib (transactions w/ CSV)', function () {
}
// expiry will pass, {Alice's signature} OP_TRUE
it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)', async function () {
it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)', async () => {
// 5 blocks from now
const sequence = bip68.encode({ blocks: 5 })
const p2sh = bitcoin.payments.p2sh({
@ -84,7 +84,7 @@ describe('bitcoinjs-lib (transactions w/ CSV)', function () {
})
// expiry in the future, {Alice's signature} OP_TRUE
it('can create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry', async function () {
it('can create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry', async () => {
// two hours after confirmation
const sequence = bip68.encode({ seconds: 7168 })
const p2sh = bitcoin.payments.p2sh({
@ -119,7 +119,7 @@ describe('bitcoinjs-lib (transactions w/ CSV)', function () {
tx.setInputScript(0, redeemScriptSig)
await regtestUtils.broadcast(tx.toHex()).catch(err => {
assert.throws(function () {
assert.throws(() => {
if (err) throw err
}, /Error: non-BIP68-final \(code 64\)/)
})

View file

@ -16,7 +16,7 @@ async function buildAndSign (depends, prevOutput, redeemScript, witnessScript) {
txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
if (depends.signatures) {
keyPairs.forEach((keyPair) => {
keyPairs.forEach(keyPair => {
txb.sign(0, keyPair, redeemScript, null, unspent.value, witnessScript)
})
} else if (depends.signature) {
@ -26,7 +26,7 @@ async function buildAndSign (depends, prevOutput, redeemScript, witnessScript) {
return regtestUtils.broadcast(txb.build().toHex())
}
;['p2ms', 'p2pk', 'p2pkh', 'p2wpkh'].forEach((k) => {
;['p2ms', 'p2pk', 'p2pkh', 'p2wpkh'].forEach(k => {
const fixtures = require('../fixtures/' + k)
const { depends } = fixtures.dynamic
const fn = bitcoin.payments[k]
@ -39,7 +39,7 @@ async function buildAndSign (depends, prevOutput, redeemScript, witnessScript) {
const { output } = fn(base)
if (!output) throw new TypeError('Missing output')
describe('bitcoinjs-lib (payments - ' + k + ')', function () {
describe('bitcoinjs-lib (payments - ' + k + ')', () => {
it('can broadcast as an output, and be spent as an input', async () => {
await buildAndSign(depends, output, null, null)
})

View file

@ -8,8 +8,8 @@ function rng () {
return Buffer.from('YT8dAtK4d16A3P1z+TpwB2jJ4aFH3g9M1EioIBkLEV4=', 'base64')
}
describe('bitcoinjs-lib (transactions)', function () {
it('can create a 1-to-1 Transaction', function () {
describe('bitcoinjs-lib (transactions)', () => {
it('can create a 1-to-1 Transaction', () => {
const alice = bitcoin.ECPair.fromWIF('L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy')
const txb = new bitcoin.TransactionBuilder()
@ -24,7 +24,7 @@ describe('bitcoinjs-lib (transactions)', function () {
assert.strictEqual(txb.build().toHex(), '01000000019d344070eac3fe6e394a16d06d7704a7d5c0a10eb2a2c16bc98842b7cc20d561000000006b48304502210088828c0bdfcdca68d8ae0caeb6ec62cd3fd5f9b2191848edae33feb533df35d302202e0beadd35e17e7f83a733f5277028a9b453d525553e3f5d2d7a7aa8010a81d60121029f50f51d63b345039a290c94bffd3180c99ed659ff6ea6b1242bca47eb93b59fffffffff01e02e0000000000001976a91406afd46bcdfd22ef94ac122aa11f241244a37ecc88ac00000000')
})
it('can create a 2-to-2 Transaction', function () {
it('can create a 2-to-2 Transaction', () => {
const alice = bitcoin.ECPair.fromWIF('L1Knwj9W3qK3qMKdTvmg3VfzUs3ij2LETTFhxza9LfD5dngnoLG1')
const bob = bitcoin.ECPair.fromWIF('KwcN2pT3wnRAurhy7qMczzbkpY5nXMW2ubh696UBc1bcwctTx26z')
@ -232,17 +232,17 @@ describe('bitcoinjs-lib (transactions)', function () {
})
})
it('can verify Transaction (P2PKH) signatures', function () {
it('can verify Transaction (P2PKH) signatures', () => {
const txHex = '010000000321c5f7e7bc98b3feda84aad36a5c99a02bcb8823a2f3eccbcd5da209698b5c20000000006b48304502210099e021772830207cf7c55b69948d3b16b4dcbf1f55a9cd80ebf8221a169735f9022064d33f11d62cd28240b3862afc0b901adc9f231c7124dd19bdb30367b61964c50121032b4c06c06c3ec0b7fa29519dfa5aae193ee2cc35ca127f29f14ec605d62fb63dffffffff8a75ce85441ddb3f342708ee33cc8ed418b07d9ba9e0e7c4e1cccfe9f52d8a88000000006946304302207916c23dae212c95a920423902fa44e939fb3d542f4478a7b46e9cde53705800021f0d74e9504146e404c1b8f9cba4dff2d4782e3075491c9ed07ce4a7d1c4461a01210216c92abe433106491bdeb4a261226f20f5a4ac86220cc6e37655aac6bf3c1f2affffffffdfef93f69fe32e944fad79fa8f882b3a155d80383252348caba1a77a5abbf7ef000000006b483045022100faa6e9ca289b46c64764a624c59ac30d9abcf1d4a04c4de9089e67cbe0d300a502206930afa683f6807502de5c2431bf9a1fd333c8a2910a76304df0f3d23d83443f0121039e05da8b8ea4f9868ecebb25998c7701542986233f4401799551fbecf316b18fffffffff01ff4b0000000000001976a9146c86476d1d85cd60116cd122a274e6a570a5a35c88acc96d0700'
const keyPairs = [
'032b4c06c06c3ec0b7fa29519dfa5aae193ee2cc35ca127f29f14ec605d62fb63d',
'0216c92abe433106491bdeb4a261226f20f5a4ac86220cc6e37655aac6bf3c1f2a',
'039e05da8b8ea4f9868ecebb25998c7701542986233f4401799551fbecf316b18f'
].map(function (q) { return bitcoin.ECPair.fromPublicKey(Buffer.from(q, 'hex')) })
].map(q => { return bitcoin.ECPair.fromPublicKey(Buffer.from(q, 'hex')) })
const tx = bitcoin.Transaction.fromHex(txHex)
tx.ins.forEach(function (input, i) {
tx.ins.forEach((input, i) => {
const keyPair = keyPairs[i]
const p2pkh = bitcoin.payments.p2pkh({
pubkey: keyPair.publicKey,
@ -256,7 +256,7 @@ describe('bitcoinjs-lib (transactions)', function () {
})
})
it('can verify Transaction (P2SH(P2WPKH)) signatures', function () {
it('can verify Transaction (P2SH(P2WPKH)) signatures', () => {
const utxos = {
'f72d1d83ac40fcedd01415751556a905844ab5f44bbb7728565ebb91b1590109:0': {
value: 50000
@ -266,7 +266,7 @@ describe('bitcoinjs-lib (transactions)', function () {
const txHex = '02000000000101090159b191bb5e562877bb4bf4b54a8405a95615751514d0edfc40ac831d2df7000000001716001435a179e5516947a39ae9c8a25e9fe62c0fc598edffffffff01204e0000000000001976a91431d43308d3c886d53e9ae8a45728370571ff456988ac0247304402206ec41f685b997a51f325b07ee852e82a535f6b52ef54485cc133e05168aa052a022070bafa86108acb51c77b2b259ae8fb7fd1efa10fef804fcfe9b13c2db719acf5012103fb03e9d0a9af86cbed94225dbb8bb70f6b82109bce0a61ddcf41dab6cbb4871100000000'
const tx = bitcoin.Transaction.fromHex(txHex)
tx.ins.forEach(function (input, i) {
tx.ins.forEach((input, i) => {
const txId = Buffer.from(input.hash).reverse().toString('hex')
const utxo = utxos[`${txId}:${i}`]
if (!utxo) throw new Error('Missing utxo')

View file

@ -2,8 +2,8 @@ const { describe, it } = require('mocha')
const assert = require('assert')
const u = require('./payments.utils')
;['embed', 'p2ms', 'p2pk', 'p2pkh', 'p2sh', 'p2wpkh', 'p2wsh'].forEach(function (p) {
describe(p, function () {
;['embed', 'p2ms', 'p2pk', 'p2pkh', 'p2sh', 'p2wpkh', 'p2wsh'].forEach(p => {
describe(p, () => {
let fn
let payment = require('../src/payments/' + p)
if (p === 'embed') {
@ -13,15 +13,15 @@ const u = require('./payments.utils')
}
const fixtures = require('./fixtures/' + p)
fixtures.valid.forEach(function (f, i) {
it(f.description + ' as expected', function () {
fixtures.valid.forEach((f, i) => {
it(f.description + ' as expected', () => {
const args = u.preform(f.arguments)
const actual = fn(args, f.options)
u.equate(actual, f.expected, f.arguments)
})
it(f.description + ' as expected (no validation)', function () {
it(f.description + ' as expected (no validation)', () => {
const args = u.preform(f.arguments)
const actual = fn(args, Object.assign({}, f.options, {
validate: false
@ -31,11 +31,11 @@ const u = require('./payments.utils')
})
})
fixtures.invalid.forEach(function (f) {
it('throws ' + f.exception + (f.description ? ('for ' + f.description) : ''), function () {
fixtures.invalid.forEach(f => {
it('throws ' + f.exception + (f.description ? ('for ' + f.description) : ''), () => {
const args = u.preform(f.arguments)
assert.throws(function () {
assert.throws(() => {
fn(args, f.options)
}, new RegExp(f.exception))
})
@ -45,23 +45,23 @@ const u = require('./payments.utils')
if (!fixtures.dynamic) return
const { depends, details } = fixtures.dynamic
details.forEach(function (f) {
details.forEach(f => {
const detail = u.preform(f)
const disabled = {}
if (f.disabled) f.disabled.forEach(function (k) { disabled[k] = true })
if (f.disabled) f.disabled.forEach(k => { disabled[k] = true })
for (let key in depends) {
if (key in disabled) continue
const dependencies = depends[key]
dependencies.forEach(function (dependency) {
dependencies.forEach(dependency => {
if (!Array.isArray(dependency)) dependency = [dependency]
const args = {}
dependency.forEach(function (d) { u.from(d, detail, args) })
dependency.forEach(d => { u.from(d, detail, args) })
const expected = u.from(key, detail)
it(f.description + ', ' + key + ' derives from ' + JSON.stringify(dependency), function () {
it(f.description + ', ' + key + ' derives from ' + JSON.stringify(dependency), () => {
u.equate(fn(args), expected)
})
})

View file

@ -39,7 +39,7 @@ function carryOver (a, b) {
function equateBase (a, b, context) {
if ('output' in b) t.strictEqual(tryASM(a.output), tryASM(b.output), `Inequal ${context}output`)
if ('input' in b) t.strictEqual(tryASM(a.input), tryASM(b.input), `Inequal ${context}input`)
if ('witness' in b) t.deepEqual(tryHex(a.witness), tryHex(b.witness), `Inequal ${context}witness`)
if ('witness' in b) t.deepStrictEqual(tryHex(a.witness), tryHex(b.witness), `Inequal ${context}witness`)
}
function equate (a, b, args) {
@ -58,19 +58,20 @@ function equate (a, b, args) {
equateBase(a, b, '')
if (b.redeem) equateBase(a.redeem, b.redeem, 'redeem.')
if (b.network) t.deepEqual(a.network, BNETWORKS[b.network], 'Inequal *.network')
if (b.network) t.deepStrictEqual(a.network, BNETWORKS[b.network], 'Inequal *.network')
// contextual
if (b.signature === null) b.signature = undefined
if (b.signatures === null) b.signatures = undefined
if ('address' in b) t.strictEqual(a.address, b.address, 'Inequal *.address')
if ('hash' in b) t.strictEqual(tryHex(a.hash), tryHex(b.hash), 'Inequal *.hash')
if ('pubkey' in b) t.strictEqual(tryHex(a.pubkey), tryHex(b.pubkey), 'Inequal *.pubkey')
if ('signature' in b) t.strictEqual(tryHex(a.signature), tryHex(b.signature), 'Inequal signature')
if ('m' in b) t.strictEqual(a.m, b.m, 'Inequal *.m')
if ('n' in b) t.strictEqual(a.n, b.n, 'Inequal *.n')
if ('pubkeys' in b) t.deepEqual(tryHex(a.pubkeys), tryHex(b.pubkeys), 'Inequal *.pubkeys')
if ('signatures' in b) t.deepEqual(tryHex(a.signatures), tryHex(b.signatures), 'Inequal *.signatures')
if ('data' in b) t.deepEqual(tryHex(a.data), tryHex(b.data), 'Inequal *.data')
if ('pubkeys' in b) t.deepStrictEqual(tryHex(a.pubkeys), tryHex(b.pubkeys), 'Inequal *.pubkeys')
if ('signatures' in b) t.deepStrictEqual(tryHex(a.signatures), tryHex(b.signatures), 'Inequal *.signatures')
if ('data' in b) t.deepStrictEqual(tryHex(a.data), tryHex(b.data), 'Inequal *.data')
}
function preform (x) {
@ -94,7 +95,7 @@ function preform (x) {
if (x.pubkey) x.pubkey = Buffer.from(x.pubkey, 'hex')
if (x.signature) x.signature = Buffer.from(x.signature, 'hex')
if (x.pubkeys) x.pubkeys = x.pubkeys.map(fromHex)
if (x.signatures) x.signatures = x.signatures.map(function (y) { return Number.isFinite(y) ? y : Buffer.from(y, 'hex') })
if (x.signatures) x.signatures = x.signatures.map(y => { return Number.isFinite(y) ? y : Buffer.from(y, 'hex') })
if (x.redeem) {
x.redeem = Object.assign({}, x.redeem)
if (typeof x.redeem.input === 'string') x.redeem.input = asmToBuffer(x.redeem.input)

View file

@ -6,44 +6,44 @@ const minimalData = require('minimaldata')
const fixtures = require('./fixtures/script.json')
const fixtures2 = require('./fixtures/templates.json')
describe('script', function () {
describe('script', () => {
// TODO
describe('isCanonicalPubKey', function () {
it('rejects if not provided a Buffer', function () {
describe('isCanonicalPubKey', () => {
it('rejects if not provided a Buffer', () => {
assert.strictEqual(false, bscript.isCanonicalPubKey(0))
})
it('rejects smaller than 33', function () {
it('rejects smaller than 33', () => {
for (var i = 0; i < 33; i++) {
assert.strictEqual(false, bscript.isCanonicalPubKey(Buffer.from('', i)))
}
})
})
describe.skip('isCanonicalScriptSignature', function () {
describe.skip('isCanonicalScriptSignature', () => {
})
describe('fromASM/toASM', function () {
fixtures.valid.forEach(function (f) {
it('encodes/decodes ' + f.asm, function () {
describe('fromASM/toASM', () => {
fixtures.valid.forEach(f => {
it('encodes/decodes ' + f.asm, () => {
const script = bscript.fromASM(f.asm)
assert.strictEqual(bscript.toASM(script), f.asm)
})
})
fixtures.invalid.fromASM.forEach(function (f) {
it('throws ' + f.description, function () {
assert.throws(function () {
fixtures.invalid.fromASM.forEach(f => {
it('throws ' + f.description, () => {
assert.throws(() => {
bscript.fromASM(f.script)
}, new RegExp(f.description))
})
})
})
describe('fromASM/toASM (templates)', function () {
fixtures2.valid.forEach(function (f) {
describe('fromASM/toASM (templates)', () => {
fixtures2.valid.forEach(f => {
if (f.inputHex) {
const ih = bscript.toASM(Buffer.from(f.inputHex, 'hex'))
it('encodes/decodes ' + ih, function () {
it('encodes/decodes ' + ih, () => {
const script = bscript.fromASM(f.input)
assert.strictEqual(script.toString('hex'), f.inputHex)
assert.strictEqual(bscript.toASM(script), f.input)
@ -51,7 +51,7 @@ describe('script', function () {
}
if (f.outputHex) {
it('encodes/decodes ' + f.output, function () {
it('encodes/decodes ' + f.output, () => {
const script = bscript.fromASM(f.output)
assert.strictEqual(script.toString('hex'), f.outputHex)
assert.strictEqual(bscript.toASM(script), f.output)
@ -60,9 +60,9 @@ describe('script', function () {
})
})
describe('isPushOnly', function () {
fixtures.valid.forEach(function (f) {
it('returns ' + !!f.stack + ' for ' + f.asm, function () {
describe('isPushOnly', () => {
fixtures.valid.forEach(f => {
it('returns ' + !!f.stack + ' for ' + f.asm, () => {
const script = bscript.fromASM(f.asm)
const chunks = bscript.decompile(script)
@ -71,26 +71,26 @@ describe('script', function () {
})
})
describe('toStack', function () {
fixtures.valid.forEach(function (f) {
it('returns ' + !!f.stack + ' for ' + f.asm, function () {
describe('toStack', () => {
fixtures.valid.forEach(f => {
it('returns ' + !!f.stack + ' for ' + f.asm, () => {
if (!f.stack || !f.asm) return
const script = bscript.fromASM(f.asm)
const stack = bscript.toStack(script)
assert.deepEqual(stack.map(function (x) {
assert.deepStrictEqual(stack.map(x => {
return x.toString('hex')
}), f.stack)
assert.equal(bscript.toASM(bscript.compile(stack)), f.asm, 'should rebuild same script from stack')
assert.strictEqual(bscript.toASM(bscript.compile(stack)), f.asm, 'should rebuild same script from stack')
})
})
})
describe('compile (via fromASM)', function () {
fixtures.valid.forEach(function (f) {
it('(' + f.type + ') compiles ' + f.asm, function () {
describe('compile (via fromASM)', () => {
fixtures.valid.forEach(f => {
it('(' + f.type + ') compiles ' + f.asm, () => {
const scriptSig = bscript.fromASM(f.asm)
assert.strictEqual(scriptSig.toString('hex'), f.script)
@ -104,9 +104,9 @@ describe('script', function () {
})
})
describe('decompile', function () {
fixtures.valid.forEach(function (f) {
it('decompiles ' + f.asm, function () {
describe('decompile', () => {
fixtures.valid.forEach(f => {
it('decompiles ' + f.asm, () => {
const chunks = bscript.decompile(Buffer.from(f.script, 'hex'))
assert.strictEqual(bscript.compile(chunks).toString('hex'), f.script)
@ -123,8 +123,8 @@ describe('script', function () {
})
})
fixtures.invalid.decompile.forEach(function (f) {
it('fails to decompile ' + f.script + ', because "' + f.description + '"', function () {
fixtures.invalid.decompile.forEach(f => {
it('fails to decompile ' + f.script + ', because "' + f.description + '"', () => {
const chunks = bscript.decompile(Buffer.from(f.script, 'hex'))
assert.strictEqual(chunks, null)
@ -132,9 +132,9 @@ describe('script', function () {
})
})
describe('SCRIPT_VERIFY_MINIMALDATA policy', function () {
fixtures.valid.forEach(function (f) {
it('compliant for ' + f.type + ' scriptSig ' + f.asm, function () {
describe('SCRIPT_VERIFY_MINIMALDATA policy', () => {
fixtures.valid.forEach(f => {
it('compliant for ' + f.type + ' scriptSig ' + f.asm, () => {
const script = Buffer.from(f.script, 'hex')
assert(minimalData(script))
@ -142,7 +142,7 @@ describe('script', function () {
})
function testEncodingForSize (i) {
it('compliant for data PUSH of length ' + i, function () {
it('compliant for data PUSH of length ' + i, () => {
const buffer = Buffer.alloc(i)
const script = bscript.compile([buffer])

View file

@ -3,10 +3,10 @@ const assert = require('assert')
const scriptNumber = require('../src/script_number')
const fixtures = require('./fixtures/script_number.json')
describe('script-number', function () {
describe('decode', function () {
fixtures.forEach(function (f) {
it(f.hex + ' returns ' + f.number, function () {
describe('script-number', () => {
describe('decode', () => {
fixtures.forEach(f => {
it(f.hex + ' returns ' + f.number, () => {
const actual = scriptNumber.decode(Buffer.from(f.hex, 'hex'), f.bytes)
assert.strictEqual(actual, f.number)
@ -14,9 +14,9 @@ describe('script-number', function () {
})
})
describe('encode', function () {
fixtures.forEach(function (f) {
it(f.number + ' returns ' + f.hex, function () {
describe('encode', () => {
fixtures.forEach(f => {
it(f.number + ' returns ' + f.hex, () => {
const actual = scriptNumber.encode(f.number)
assert.strictEqual(actual.toString('hex'), f.hex)

View file

@ -4,7 +4,7 @@ const bscriptSig = require('../src/script').signature
const Buffer = require('safe-buffer').Buffer
const fixtures = require('./fixtures/signature.json')
describe('Script Signatures', function () {
describe('Script Signatures', () => {
function fromRaw (signature) {
return Buffer.concat([
Buffer.from(signature.r, 'hex'),
@ -19,43 +19,43 @@ describe('Script Signatures', function () {
}
}
describe('encode', function () {
fixtures.valid.forEach(function (f) {
it('encodes ' + f.hex, function () {
describe('encode', () => {
fixtures.valid.forEach(f => {
it('encodes ' + f.hex, () => {
const buffer = bscriptSig.encode(fromRaw(f.raw), f.hashType)
assert.strictEqual(buffer.toString('hex'), f.hex)
})
})
fixtures.invalid.forEach(function (f) {
fixtures.invalid.forEach(f => {
if (!f.raw) return
it('throws ' + f.exception, function () {
it('throws ' + f.exception, () => {
const signature = fromRaw(f.raw)
assert.throws(function () {
assert.throws(() => {
bscriptSig.encode(signature, f.hashType)
}, new RegExp(f.exception))
})
})
})
describe('decode', function () {
fixtures.valid.forEach(function (f) {
it('decodes ' + f.hex, function () {
describe('decode', () => {
fixtures.valid.forEach(f => {
it('decodes ' + f.hex, () => {
const decode = bscriptSig.decode(Buffer.from(f.hex, 'hex'))
assert.deepEqual(toRaw(decode.signature), f.raw)
assert.deepStrictEqual(toRaw(decode.signature), f.raw)
assert.strictEqual(decode.hashType, f.hashType)
})
})
fixtures.invalid.forEach(function (f) {
it('throws on ' + f.hex, function () {
fixtures.invalid.forEach(f => {
it('throws on ' + f.hex, () => {
const buffer = Buffer.from(f.hex, 'hex')
assert.throws(function () {
assert.throws(() => {
bscriptSig.decode(buffer)
}, new RegExp(f.exception))
})

View file

@ -4,13 +4,13 @@ const bscript = require('../src/script')
const fixtures = require('./fixtures/transaction')
const Transaction = require('..').Transaction
describe('Transaction', function () {
describe('Transaction', () => {
function fromRaw (raw, noWitness) {
const tx = new Transaction()
tx.version = raw.version
tx.locktime = raw.locktime
raw.ins.forEach(function (txIn, i) {
raw.ins.forEach((txIn, i) => {
const txHash = Buffer.from(txIn.hash, 'hex')
let scriptSig
@ -23,7 +23,7 @@ describe('Transaction', function () {
tx.addInput(txHash, txIn.index, txIn.sequence, scriptSig)
if (!noWitness && txIn.witness) {
const witness = txIn.witness.map(function (x) {
const witness = txIn.witness.map(x => {
return Buffer.from(x, 'hex')
})
@ -31,7 +31,7 @@ describe('Transaction', function () {
}
})
raw.outs.forEach(function (txOut) {
raw.outs.forEach(txOut => {
let script
if (txOut.data) {
@ -46,19 +46,19 @@ describe('Transaction', function () {
return tx
}
describe('fromBuffer/fromHex', function () {
describe('fromBuffer/fromHex', () => {
function importExport (f) {
const id = f.id || f.hash
const txHex = f.hex || f.txHex
it('imports ' + f.description + ' (' + id + ')', function () {
it('imports ' + f.description + ' (' + id + ')', () => {
const actual = Transaction.fromHex(txHex)
assert.strictEqual(actual.toHex(), txHex)
})
if (f.whex) {
it('imports ' + f.description + ' (' + id + ') as witness', function () {
it('imports ' + f.description + ' (' + id + ') as witness', () => {
const actual = Transaction.fromHex(f.whex)
assert.strictEqual(actual.toHex(), f.whex)
@ -70,38 +70,38 @@ describe('Transaction', function () {
fixtures.hashForSignature.forEach(importExport)
fixtures.hashForWitnessV0.forEach(importExport)
fixtures.invalid.fromBuffer.forEach(function (f) {
it('throws on ' + f.exception, function () {
assert.throws(function () {
fixtures.invalid.fromBuffer.forEach(f => {
it('throws on ' + f.exception, () => {
assert.throws(() => {
Transaction.fromHex(f.hex)
}, new RegExp(f.exception))
})
})
it('.version should be interpreted as an int32le', function () {
it('.version should be interpreted as an int32le', () => {
const txHex = 'ffffffff0000ffffffff'
const tx = Transaction.fromHex(txHex)
assert.equal(-1, tx.version)
assert.equal(0xffffffff, tx.locktime)
assert.strictEqual(-1, tx.version)
assert.strictEqual(0xffffffff, tx.locktime)
})
})
describe('toBuffer/toHex', function () {
fixtures.valid.forEach(function (f) {
it('exports ' + f.description + ' (' + f.id + ')', function () {
describe('toBuffer/toHex', () => {
fixtures.valid.forEach(f => {
it('exports ' + f.description + ' (' + f.id + ')', () => {
const actual = fromRaw(f.raw, true)
assert.strictEqual(actual.toHex(), f.hex)
})
if (f.whex) {
it('exports ' + f.description + ' (' + f.id + ') as witness', function () {
it('exports ' + f.description + ' (' + f.id + ') as witness', () => {
const wactual = fromRaw(f.raw)
assert.strictEqual(wactual.toHex(), f.whex)
})
}
})
it('accepts target Buffer and offset parameters', function () {
it('accepts target Buffer and offset parameters', () => {
const f = fixtures.valid[0]
const actual = fromRaw(f.raw)
const byteLength = actual.byteLength()
@ -114,31 +114,31 @@ describe('Transaction', function () {
assert.strictEqual(b.length, byteLength)
assert.strictEqual(a.toString('hex'), f.hex)
assert.strictEqual(b.toString('hex'), f.hex)
assert.deepEqual(a, b)
assert.deepEqual(a, target.slice(0, byteLength))
assert.deepEqual(b, target.slice(byteLength))
assert.deepStrictEqual(a, b)
assert.deepStrictEqual(a, target.slice(0, byteLength))
assert.deepStrictEqual(b, target.slice(byteLength))
})
})
describe('hasWitnesses', function () {
fixtures.valid.forEach(function (f) {
it('detects if the transaction has witnesses: ' + (f.whex ? 'true' : 'false'), function () {
describe('hasWitnesses', () => {
fixtures.valid.forEach(f => {
it('detects if the transaction has witnesses: ' + (f.whex ? 'true' : 'false'), () => {
assert.strictEqual(Transaction.fromHex(f.whex ? f.whex : f.hex).hasWitnesses(), !!f.whex)
})
})
})
describe('weight/virtualSize', function () {
it('computes virtual size', function () {
fixtures.valid.forEach(function (f) {
describe('weight/virtualSize', () => {
it('computes virtual size', () => {
fixtures.valid.forEach(f => {
const transaction = Transaction.fromHex(f.whex ? f.whex : f.hex)
assert.strictEqual(transaction.virtualSize(), f.virtualSize)
})
})
it('computes weight', function () {
fixtures.valid.forEach(function (f) {
it('computes weight', () => {
fixtures.valid.forEach(f => {
const transaction = Transaction.fromHex(f.whex ? f.whex : f.hex)
assert.strictEqual(transaction.weight(), f.weight)
@ -146,19 +146,19 @@ describe('Transaction', function () {
})
})
describe('addInput', function () {
describe('addInput', () => {
let prevTxHash
beforeEach(function () {
beforeEach(() => {
prevTxHash = Buffer.from('ffffffff00ffff000000000000000000000000000000000000000000101010ff', 'hex')
})
it('returns an index', function () {
it('returns an index', () => {
const tx = new Transaction()
assert.strictEqual(tx.addInput(prevTxHash, 0), 0)
assert.strictEqual(tx.addInput(prevTxHash, 0), 1)
})
it('defaults to empty script, witness and 0xffffffff SEQUENCE number', function () {
it('defaults to empty script, witness and 0xffffffff SEQUENCE number', () => {
const tx = new Transaction()
tx.addInput(prevTxHash, 0)
@ -167,49 +167,49 @@ describe('Transaction', function () {
assert.strictEqual(tx.ins[0].sequence, 0xffffffff)
})
fixtures.invalid.addInput.forEach(function (f) {
it('throws on ' + f.exception, function () {
fixtures.invalid.addInput.forEach(f => {
it('throws on ' + f.exception, () => {
const tx = new Transaction()
const hash = Buffer.from(f.hash, 'hex')
assert.throws(function () {
assert.throws(() => {
tx.addInput(hash, f.index)
}, new RegExp(f.exception))
})
})
})
describe('addOutput', function () {
it('returns an index', function () {
describe('addOutput', () => {
it('returns an index', () => {
const tx = new Transaction()
assert.strictEqual(tx.addOutput(Buffer.alloc(0), 0), 0)
assert.strictEqual(tx.addOutput(Buffer.alloc(0), 0), 1)
})
})
describe('clone', function () {
fixtures.valid.forEach(function (f) {
describe('clone', () => {
fixtures.valid.forEach(f => {
let actual
let expected
beforeEach(function () {
beforeEach(() => {
expected = Transaction.fromHex(f.hex)
actual = expected.clone()
})
it('should have value equality', function () {
assert.deepEqual(actual, expected)
it('should have value equality', () => {
assert.deepStrictEqual(actual, expected)
})
it('should not have reference equality', function () {
assert.notEqual(actual, expected)
it('should not have reference equality', () => {
assert.notStrictEqual(actual, expected)
})
})
})
describe('getHash/getId', function () {
describe('getHash/getId', () => {
function verify (f) {
it('should return the id for ' + f.id + '(' + f.description + ')', function () {
it('should return the id for ' + f.id + '(' + f.description + ')', () => {
const tx = Transaction.fromHex(f.whex || f.hex)
assert.strictEqual(tx.getHash().toString('hex'), f.hash)
@ -220,9 +220,9 @@ describe('Transaction', function () {
fixtures.valid.forEach(verify)
})
describe('isCoinbase', function () {
describe('isCoinbase', () => {
function verify (f) {
it('should return ' + f.coinbase + ' for ' + f.id + '(' + f.description + ')', function () {
it('should return ' + f.coinbase + ' for ' + f.id + '(' + f.description + ')', () => {
const tx = Transaction.fromHex(f.hex)
assert.strictEqual(tx.isCoinbase(), f.coinbase)
@ -232,8 +232,8 @@ describe('Transaction', function () {
fixtures.valid.forEach(verify)
})
describe('hashForSignature', function () {
it('does not use Witness serialization', function () {
describe('hashForSignature', () => {
it('does not use Witness serialization', () => {
const randScript = Buffer.from('6a', 'hex')
const tx = new Transaction()
@ -241,24 +241,24 @@ describe('Transaction', function () {
tx.addOutput(randScript, 5000000000)
const original = tx.__toBuffer
tx.__toBuffer = function (a, b, c) {
tx.__toBuffer = (a, b, c) => {
if (c !== false) throw new Error('hashForSignature MUST pass false')
return original.call(this, a, b, c)
}
assert.throws(function () {
assert.throws(() => {
tx.__toBuffer(undefined, undefined, true)
}, /hashForSignature MUST pass false/)
// assert hashForSignature does not pass false
assert.doesNotThrow(function () {
assert.doesNotThrow(() => {
tx.hashForSignature(0, randScript, 1)
})
})
fixtures.hashForSignature.forEach(function (f) {
it('should return ' + f.hash + ' for ' + (f.description ? ('case "' + f.description + '"') : f.script), function () {
fixtures.hashForSignature.forEach(f => {
it('should return ' + f.hash + ' for ' + (f.description ? ('case "' + f.description + '"') : f.script), () => {
const tx = Transaction.fromHex(f.txHex)
const script = bscript.fromASM(f.script)
@ -267,9 +267,9 @@ describe('Transaction', function () {
})
})
describe('hashForWitnessV0', function () {
fixtures.hashForWitnessV0.forEach(function (f) {
it('should return ' + f.hash + ' for ' + (f.description ? ('case "' + f.description + '"') : ''), function () {
describe('hashForWitnessV0', () => {
fixtures.hashForWitnessV0.forEach(f => {
it('should return ' + f.hash + ' for ' + (f.description ? ('case "' + f.description + '"') : ''), () => {
const tx = Transaction.fromHex(f.txHex)
const script = bscript.fromASM(f.script)
@ -278,9 +278,9 @@ describe('Transaction', function () {
})
})
describe('setWitness', function () {
it('only accepts a a witness stack (Array of Buffers)', function () {
assert.throws(function () {
describe('setWitness', () => {
it('only accepts a a witness stack (Array of Buffers)', () => {
assert.throws(() => {
(new Transaction()).setWitness(0, 'foobar')
}, /Expected property "1" of type \[Buffer], got String "foobar"/)
})

View file

@ -15,9 +15,9 @@ function constructSign (f, txb) {
const network = NETWORKS[f.network]
const stages = f.stages && f.stages.concat()
f.inputs.forEach(function (input, index) {
f.inputs.forEach((input, index) => {
if (!input.signs) return
input.signs.forEach(function (sign) {
input.signs.forEach(sign => {
const keyPair = ECPair.fromWIF(sign.keyPair, network)
let redeemScript
let witnessScript
@ -55,7 +55,7 @@ function construct (f, dontSign) {
if (Number.isFinite(f.version)) txb.setVersion(f.version)
if (f.locktime !== undefined) txb.setLockTime(f.locktime)
f.inputs.forEach(function (input) {
f.inputs.forEach(input => {
let prevTx
if (input.txRaw) {
const constructed = construct(input.txRaw)
@ -75,7 +75,7 @@ function construct (f, dontSign) {
txb.addInput(prevTx, input.vout, input.sequence, prevTxScript)
})
f.outputs.forEach(function (output) {
f.outputs.forEach(output => {
if (output.address) {
txb.addOutput(output.address, output.value)
} else {
@ -87,20 +87,20 @@ function construct (f, dontSign) {
return constructSign(f, txb)
}
describe('TransactionBuilder', function () {
describe('TransactionBuilder', () => {
// constants
const keyPair = ECPair.fromPrivateKey(Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex'))
const scripts = [
'1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH',
'1cMh228HTCiwS8ZsaakH8A8wze1JR5ZsP'
].map(function (x) {
].map(x => {
return baddress.toOutputScript(x)
})
const txHash = Buffer.from('0e7cea811c0be9f73c0aca591034396e7264473fc25c1ca45195d7417b36cbe2', 'hex')
describe('fromTransaction', function () {
fixtures.valid.build.forEach(function (f) {
it('returns TransactionBuilder, with ' + f.description, function () {
describe('fromTransaction', () => {
fixtures.valid.build.forEach(f => {
it('returns TransactionBuilder, with ' + f.description, () => {
const network = NETWORKS[f.network || 'bitcoin']
const tx = Transaction.fromHex(f.txHex)
@ -112,82 +112,82 @@ describe('TransactionBuilder', function () {
})
})
fixtures.valid.fromTransaction.forEach(function (f) {
it('returns TransactionBuilder, with ' + f.description, function () {
fixtures.valid.fromTransaction.forEach(f => {
it('returns TransactionBuilder, with ' + f.description, () => {
const tx = new Transaction()
f.inputs.forEach(function (input) {
f.inputs.forEach(input => {
const txHash2 = Buffer.from(input.txId, 'hex').reverse()
tx.addInput(txHash2, input.vout, undefined, bscript.fromASM(input.scriptSig))
})
f.outputs.forEach(function (output) {
f.outputs.forEach(output => {
tx.addOutput(bscript.fromASM(output.script), output.value)
})
const txb = TransactionBuilder.fromTransaction(tx)
const txAfter = f.incomplete ? txb.buildIncomplete() : txb.build()
txAfter.ins.forEach(function (input, i) {
assert.equal(bscript.toASM(input.script), f.inputs[i].scriptSigAfter)
txAfter.ins.forEach((input, i) => {
assert.strictEqual(bscript.toASM(input.script), f.inputs[i].scriptSigAfter)
})
txAfter.outs.forEach(function (output, i) {
assert.equal(bscript.toASM(output.script), f.outputs[i].script)
txAfter.outs.forEach((output, i) => {
assert.strictEqual(bscript.toASM(output.script), f.outputs[i].script)
})
})
})
fixtures.valid.fromTransactionSequential.forEach(function (f) {
it('with ' + f.description, function () {
fixtures.valid.fromTransactionSequential.forEach(f => {
it('with ' + f.description, () => {
const network = NETWORKS[f.network]
const tx = Transaction.fromHex(f.txHex)
const txb = TransactionBuilder.fromTransaction(tx, network)
tx.ins.forEach(function (input, i) {
assert.equal(bscript.toASM(input.script), f.inputs[i].scriptSig)
tx.ins.forEach((input, i) => {
assert.strictEqual(bscript.toASM(input.script), f.inputs[i].scriptSig)
})
constructSign(f, txb)
const txAfter = f.incomplete ? txb.buildIncomplete() : txb.build()
txAfter.ins.forEach(function (input, i) {
assert.equal(bscript.toASM(input.script), f.inputs[i].scriptSigAfter)
txAfter.ins.forEach((input, i) => {
assert.strictEqual(bscript.toASM(input.script), f.inputs[i].scriptSigAfter)
})
assert.equal(txAfter.toHex(), f.txHexAfter)
assert.strictEqual(txAfter.toHex(), f.txHexAfter)
})
})
it('classifies transaction inputs', function () {
it('classifies transaction inputs', () => {
const tx = Transaction.fromHex(fixtures.valid.classification.hex)
const txb = TransactionBuilder.fromTransaction(tx)
txb.__INPUTS.forEach(function (i) {
txb.__INPUTS.forEach(i => {
assert.strictEqual(i.prevOutType, 'scripthash')
assert.strictEqual(i.redeemScriptType, 'multisig')
})
})
fixtures.invalid.fromTransaction.forEach(function (f) {
it('throws ' + f.exception, function () {
fixtures.invalid.fromTransaction.forEach(f => {
it('throws ' + f.exception, () => {
const tx = Transaction.fromHex(f.txHex)
assert.throws(function () {
assert.throws(() => {
TransactionBuilder.fromTransaction(tx)
}, new RegExp(f.exception))
})
})
})
describe('addInput', function () {
describe('addInput', () => {
let txb
beforeEach(function () {
beforeEach(() => {
txb = new TransactionBuilder()
})
it('accepts a txHash, index [and sequence number]', function () {
it('accepts a txHash, index [and sequence number]', () => {
const vin = txb.addInput(txHash, 1, 54)
assert.strictEqual(vin, 0)
@ -198,7 +198,7 @@ describe('TransactionBuilder', function () {
assert.strictEqual(txb.__INPUTS[0].prevOutScript, undefined)
})
it('accepts a txHash, index [, sequence number and scriptPubKey]', function () {
it('accepts a txHash, index [, sequence number and scriptPubKey]', () => {
const vin = txb.addInput(txHash, 1, 54, scripts[1])
assert.strictEqual(vin, 0)
@ -209,7 +209,7 @@ describe('TransactionBuilder', function () {
assert.strictEqual(txb.__INPUTS[0].prevOutScript, scripts[1])
})
it('accepts a prevTx, index [and sequence number]', function () {
it('accepts a prevTx, index [and sequence number]', () => {
const prevTx = new Transaction()
prevTx.addOutput(scripts[0], 0)
prevTx.addOutput(scripts[1], 1)
@ -218,116 +218,116 @@ describe('TransactionBuilder', function () {
assert.strictEqual(vin, 0)
const txIn = txb.__TX.ins[0]
assert.deepEqual(txIn.hash, prevTx.getHash())
assert.deepStrictEqual(txIn.hash, prevTx.getHash())
assert.strictEqual(txIn.index, 1)
assert.strictEqual(txIn.sequence, 54)
assert.strictEqual(txb.__INPUTS[0].prevOutScript, scripts[1])
})
it('returns the input index', function () {
it('returns the input index', () => {
assert.strictEqual(txb.addInput(txHash, 0), 0)
assert.strictEqual(txb.addInput(txHash, 1), 1)
})
it('throws if SIGHASH_ALL has been used to sign any existing scriptSigs', function () {
it('throws if SIGHASH_ALL has been used to sign any existing scriptSigs', () => {
txb.addInput(txHash, 0)
txb.addOutput(scripts[0], 1000)
txb.sign(0, keyPair)
assert.throws(function () {
assert.throws(() => {
txb.addInput(txHash, 0)
}, /No, this would invalidate signatures/)
})
})
describe('addOutput', function () {
describe('addOutput', () => {
let txb
beforeEach(function () {
beforeEach(() => {
txb = new TransactionBuilder()
})
it('accepts an address string and value', function () {
it('accepts an address string and value', () => {
const { address } = payments.p2pkh({ pubkey: keyPair.publicKey })
const vout = txb.addOutput(address, 1000)
assert.strictEqual(vout, 0)
const txout = txb.__TX.outs[0]
assert.deepEqual(txout.script, scripts[0])
assert.deepStrictEqual(txout.script, scripts[0])
assert.strictEqual(txout.value, 1000)
})
it('accepts a ScriptPubKey and value', function () {
it('accepts a ScriptPubKey and value', () => {
const vout = txb.addOutput(scripts[0], 1000)
assert.strictEqual(vout, 0)
const txout = txb.__TX.outs[0]
assert.deepEqual(txout.script, scripts[0])
assert.deepStrictEqual(txout.script, scripts[0])
assert.strictEqual(txout.value, 1000)
})
it('throws if address is of the wrong network', function () {
assert.throws(function () {
it('throws if address is of the wrong network', () => {
assert.throws(() => {
txb.addOutput('2NGHjvjw83pcVFgMcA7QvSMh2c246rxLVz9', 1000)
}, /2NGHjvjw83pcVFgMcA7QvSMh2c246rxLVz9 has no matching Script/)
})
it('add second output after signed first input with SIGHASH_NONE', function () {
it('add second output after signed first input with SIGHASH_NONE', () => {
txb.addInput(txHash, 0)
txb.addOutput(scripts[0], 2000)
txb.sign(0, keyPair, undefined, Transaction.SIGHASH_NONE)
assert.equal(txb.addOutput(scripts[1], 9000), 1)
assert.strictEqual(txb.addOutput(scripts[1], 9000), 1)
})
it('add first output after signed first input with SIGHASH_NONE', function () {
it('add first output after signed first input with SIGHASH_NONE', () => {
txb.addInput(txHash, 0)
txb.sign(0, keyPair, undefined, Transaction.SIGHASH_NONE)
assert.equal(txb.addOutput(scripts[0], 2000), 0)
assert.strictEqual(txb.addOutput(scripts[0], 2000), 0)
})
it('add second output after signed first input with SIGHASH_SINGLE', function () {
it('add second output after signed first input with SIGHASH_SINGLE', () => {
txb.addInput(txHash, 0)
txb.addOutput(scripts[0], 2000)
txb.sign(0, keyPair, undefined, Transaction.SIGHASH_SINGLE)
assert.equal(txb.addOutput(scripts[1], 9000), 1)
assert.strictEqual(txb.addOutput(scripts[1], 9000), 1)
})
it('add first output after signed first input with SIGHASH_SINGLE', function () {
it('add first output after signed first input with SIGHASH_SINGLE', () => {
txb.addInput(txHash, 0)
txb.sign(0, keyPair, undefined, Transaction.SIGHASH_SINGLE)
assert.throws(function () {
assert.throws(() => {
txb.addOutput(scripts[0], 2000)
}, /No, this would invalidate signatures/)
})
it('throws if SIGHASH_ALL has been used to sign any existing scriptSigs', function () {
it('throws if SIGHASH_ALL has been used to sign any existing scriptSigs', () => {
txb.addInput(txHash, 0)
txb.addOutput(scripts[0], 2000)
txb.sign(0, keyPair)
assert.throws(function () {
assert.throws(() => {
txb.addOutput(scripts[1], 9000)
}, /No, this would invalidate signatures/)
})
})
describe('setLockTime', function () {
it('throws if if there exist any scriptSigs', function () {
describe('setLockTime', () => {
it('throws if if there exist any scriptSigs', () => {
const txb = new TransactionBuilder()
txb.addInput(txHash, 0)
txb.addOutput(scripts[0], 100)
txb.sign(0, keyPair)
assert.throws(function () {
assert.throws(() => {
txb.setLockTime(65535)
}, /No, this would invalidate signatures/)
})
})
describe('sign', function () {
it('supports the alternative abstract interface { publicKey, sign }', function () {
describe('sign', () => {
it('supports the alternative abstract interface { publicKey, sign }', () => {
const keyPair = {
publicKey: ECPair.makeRandom({ rng: function () { return Buffer.alloc(32, 1) } }).publicKey,
sign: function (hash) { return Buffer.alloc(64, 0x5f) }
publicKey: ECPair.makeRandom({ rng: () => { return Buffer.alloc(32, 1) } }).publicKey,
sign: hash => { return Buffer.alloc(64, 0x5f) }
}
const txb = new TransactionBuilder()
@ -335,16 +335,16 @@ describe('TransactionBuilder', function () {
txb.addInput('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 1)
txb.addOutput('1111111111111111111114oLvT2', 100000)
txb.sign(0, keyPair)
assert.equal(txb.build().toHex(), '0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000006a47304402205f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f02205f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f0121031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078fffffffff01a0860100000000001976a914000000000000000000000000000000000000000088ac00000000')
assert.strictEqual(txb.build().toHex(), '0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000006a47304402205f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f02205f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f0121031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078fffffffff01a0860100000000001976a914000000000000000000000000000000000000000088ac00000000')
})
fixtures.invalid.sign.forEach(function (f) {
it('throws ' + f.exception + (f.description ? ' (' + f.description + ')' : ''), function () {
fixtures.invalid.sign.forEach(f => {
it('throws ' + f.exception + (f.description ? ' (' + f.description + ')' : ''), () => {
const txb = construct(f, true)
let threw = false
f.inputs.forEach(function (input, index) {
input.signs.forEach(function (sign) {
f.inputs.forEach((input, index) => {
input.signs.forEach(sign => {
const keyPairNetwork = NETWORKS[sign.network || f.network]
const keyPair2 = ECPair.fromWIF(sign.keyPair, keyPairNetwork)
let redeemScript
@ -359,7 +359,7 @@ describe('TransactionBuilder', function () {
}
if (sign.throws) {
assert.throws(function () {
assert.throws(() => {
txb.sign(index, keyPair2, redeemScript, sign.hashType, sign.value, witnessScript)
}, new RegExp(f.exception))
threw = true
@ -369,14 +369,14 @@ describe('TransactionBuilder', function () {
})
})
assert.equal(threw, true)
assert.strictEqual(threw, true)
})
})
})
describe('build', function () {
fixtures.valid.build.forEach(function (f) {
it('builds "' + f.description + '"', function () {
describe('build', () => {
fixtures.valid.build.forEach(f => {
it('builds "' + f.description + '"', () => {
const txb = construct(f)
const tx = f.incomplete ? txb.buildIncomplete() : txb.build()
@ -385,10 +385,10 @@ describe('TransactionBuilder', function () {
})
// TODO: remove duplicate test code
fixtures.invalid.build.forEach(function (f) {
describe('for ' + (f.description || f.exception), function () {
it('throws ' + f.exception, function () {
assert.throws(function () {
fixtures.invalid.build.forEach(f => {
describe('for ' + (f.description || f.exception), () => {
it('throws ' + f.exception, () => {
assert.throws(() => {
let txb
if (f.txHex) {
txb = TransactionBuilder.fromTransaction(Transaction.fromHex(f.txHex))
@ -402,8 +402,8 @@ describe('TransactionBuilder', function () {
// if throws on incomplete too, enforce that
if (f.incomplete) {
it('throws ' + f.exception, function () {
assert.throws(function () {
it('throws ' + f.exception, () => {
assert.throws(() => {
let txb
if (f.txHex) {
txb = TransactionBuilder.fromTransaction(Transaction.fromHex(f.txHex))
@ -415,7 +415,7 @@ describe('TransactionBuilder', function () {
}, new RegExp(f.exception))
})
} else {
it('does not throw if buildIncomplete', function () {
it('does not throw if buildIncomplete', () => {
let txb
if (f.txHex) {
txb = TransactionBuilder.fromTransaction(Transaction.fromHex(f.txHex))
@ -429,7 +429,7 @@ describe('TransactionBuilder', function () {
})
})
it('for incomplete with 0 signatures', function () {
it('for incomplete with 0 signatures', () => {
const randomTxData = '0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb022022dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01232103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ac00000000'
const randomAddress = '1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH'
@ -441,7 +441,7 @@ describe('TransactionBuilder', function () {
assert(tx)
})
it('for incomplete P2SH with 0 signatures', function () {
it('for incomplete P2SH with 0 signatures', () => {
const inp = Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a80400000017a91471a8ec07ff69c6c4fee489184c462a9b1b9237488700000000', 'hex') // arbitrary P2SH input
const inpTx = Transaction.fromBuffer(inp)
@ -452,7 +452,7 @@ describe('TransactionBuilder', function () {
txb.buildIncomplete()
})
it('for incomplete P2WPKH with 0 signatures', function () {
it('for incomplete P2WPKH with 0 signatures', () => {
const inp = Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a8040000001600141a15805e1f4040c9f68ccc887fca2e63547d794b00000000', 'hex')
const inpTx = Transaction.fromBuffer(inp)
@ -463,7 +463,7 @@ describe('TransactionBuilder', function () {
txb.buildIncomplete()
})
it('for incomplete P2WSH with 0 signatures', function () {
it('for incomplete P2WSH with 0 signatures', () => {
const inpTx = Transaction.fromBuffer(Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a80400000022002072df76fcc0b231b94bdf7d8c25d7eef4716597818d211e19ade7813bff7a250200000000', 'hex'))
const txb = new TransactionBuilder(NETWORKS.testnet)
@ -474,17 +474,17 @@ describe('TransactionBuilder', function () {
})
})
describe('multisig', function () {
fixtures.valid.multisig.forEach(function (f) {
it(f.description, function () {
describe('multisig', () => {
fixtures.valid.multisig.forEach(f => {
it(f.description, () => {
const network = NETWORKS[f.network]
let txb = construct(f, true)
let tx
f.inputs.forEach(function (input, i) {
f.inputs.forEach((input, i) => {
const redeemScript = bscript.fromASM(input.redeemScript)
input.signs.forEach(function (sign) {
input.signs.forEach(sign => {
// rebuild the transaction each-time after the first
if (tx) {
// manually override the scriptSig?
@ -513,10 +513,10 @@ describe('TransactionBuilder', function () {
})
})
describe('various edge case', function () {
describe('various edge case', () => {
const network = NETWORKS.testnet
it('should warn of high fee for segwit transaction based on VSize, not Size', function () {
it('should warn of high fee for segwit transaction based on VSize, not Size', () => {
const rawtx = '01000000000104fdaac89627208b4733484ca56bc291f4cf4fa8d7c5f29893c52b46788a0a' +
'1df90000000000fffffffffdaac89627208b4733484ca56bc291f4cf4fa8d7c5f29893c52b46788a0a1df9' +
'0100000000ffffffffa2ef7aaab316a3e5b5b0a78d1d35c774b95a079f9f0c762277a49caf1f26bca40000' +
@ -538,12 +538,12 @@ describe('TransactionBuilder', function () {
txb.__INPUTS[2].value = 248920
txb.__INPUTS[3].value = 248920
assert.throws(function () {
assert.throws(() => {
txb.build()
}, new RegExp('Transaction has absurd fees'))
})
it('should classify witness inputs with witness = true during multisigning', function () {
it('should classify witness inputs with witness = true during multisigning', () => {
const keyPair = ECPair.fromWIF('cRAwuVuVSBZMPu7hdrYvMCZ8eevzmkExjFbaBLhqnDdrezxN3nTS', network)
const witnessScript = Buffer.from('522102bbbd6eb01efcbe4bd9664b886f26f69de5afcb2e479d72596c8bf21929e352e22102d9c3f7180ef13ec5267723c9c2ffab56a4215241f837502ea8977c8532b9ea1952ae', 'hex')
const redeemScript = Buffer.from('002024376a0a9abab599d0e028248d48ebe817bc899efcffa1cd2984d67289daf5af', 'hex')
@ -558,13 +558,13 @@ describe('TransactionBuilder', function () {
const tx = txb.buildIncomplete()
// Only input is segwit, so txid should be accurate with the final tx
assert.equal(tx.getId(), 'f15d0a65b21b4471405b21a099f8b18e1ae4d46d55efbd0f4766cf11ad6cb821')
assert.strictEqual(tx.getId(), 'f15d0a65b21b4471405b21a099f8b18e1ae4d46d55efbd0f4766cf11ad6cb821')
const txHex = tx.toHex()
TransactionBuilder.fromTransaction(Transaction.fromHex(txHex))
})
it('should handle badly pre-filled OP_0s', function () {
it('should handle badly pre-filled OP_0s', () => {
// OP_0 is used where a signature is missing
const redeemScripSig = bscript.fromASM('OP_0 OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae')
const redeemScript = bscript.fromASM('OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG')
@ -580,11 +580,11 @@ describe('TransactionBuilder', function () {
txb.sign(0, keyPair2, redeemScript)
const tx2 = txb.build()
assert.equal(tx2.getId(), 'eab59618a564e361adef6d918bd792903c3d41bcf1220137364fb847880467f9')
assert.equal(bscript.toASM(tx2.ins[0].script), 'OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae')
assert.strictEqual(tx2.getId(), 'eab59618a564e361adef6d918bd792903c3d41bcf1220137364fb847880467f9')
assert.strictEqual(bscript.toASM(tx2.ins[0].script), 'OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae')
})
it('should not classify blank scripts as nonstandard', function () {
it('should not classify blank scripts as nonstandard', () => {
let txb = new TransactionBuilder()
txb.setVersion(1)
txb.addInput('aa94ab02c182214f090e99a0d57021caffd0f195a81c24602b1028b130b63e31', 0)
@ -596,14 +596,14 @@ describe('TransactionBuilder', function () {
txb.addOutput('1Gokm82v6DmtwKEB8AiVhm82hyFSsEvBDK', 15000)
txb.sign(0, keyPair)
const txId = txb.build().getId()
assert.equal(txId, '54f097315acbaedb92a95455da3368eb45981cdae5ffbc387a9afc872c0f29b3')
assert.strictEqual(txId, '54f097315acbaedb92a95455da3368eb45981cdae5ffbc387a9afc872c0f29b3')
// and, repeat
txb = TransactionBuilder.fromTransaction(Transaction.fromHex(incomplete))
txb.addOutput('1Gokm82v6DmtwKEB8AiVhm82hyFSsEvBDK', 15000)
txb.sign(0, keyPair)
const txId2 = txb.build().getId()
assert.equal(txId, txId2)
assert.strictEqual(txId, txId2)
})
})
})

View file

@ -3,38 +3,38 @@ const assert = require('assert')
const types = require('../src/types')
const typeforce = require('typeforce')
describe('types', function () {
describe('Buffer Hash160/Hash256', function () {
describe('types', () => {
describe('Buffer Hash160/Hash256', () => {
const buffer20byte = Buffer.alloc(20)
const buffer32byte = Buffer.alloc(32)
it('return true for valid size', function () {
it('return true for valid size', () => {
assert(types.Hash160bit(buffer20byte))
assert(types.Hash256bit(buffer32byte))
})
it('return true for oneOf', function () {
assert.doesNotThrow(function () {
it('return true for oneOf', () => {
assert.doesNotThrow(() => {
typeforce(types.oneOf(types.Hash160bit, types.Hash256bit), buffer32byte)
})
assert.doesNotThrow(function () {
assert.doesNotThrow(() => {
typeforce(types.oneOf(types.Hash256bit, types.Hash160bit), buffer32byte)
})
})
it('throws for invalid size', function () {
assert.throws(function () {
it('throws for invalid size', () => {
assert.throws(() => {
types.Hash160bit(buffer32byte)
}, /Expected Buffer\(Length: 20\), got Buffer\(Length: 32\)/)
assert.throws(function () {
assert.throws(() => {
types.Hash256bit(buffer20byte)
}, /Expected Buffer\(Length: 32\), got Buffer\(Length: 20\)/)
})
})
describe('Satoshi', function () {
describe('Satoshi', () => {
[
{ value: -1, result: false },
{ value: 0, result: true },
@ -42,8 +42,8 @@ describe('types', function () {
{ value: 20999999 * 1e8, result: true },
{ value: 21000000 * 1e8, result: true },
{ value: 21000001 * 1e8, result: false }
].forEach(function (f) {
it('returns ' + f.result + ' for valid for ' + f.value, function () {
].forEach(f => {
it('returns ' + f.result + ' for valid for ' + f.value, () => {
assert.strictEqual(types.Satoshi(f.value), f.result)
})
})