bitcoinjs-lib/test/bitcoin.core.js

227 lines
7.1 KiB
JavaScript
Raw Permalink Normal View History

2018-07-23 09:45:01 +02:00
const { describe, it } = require('mocha')
2018-06-25 08:25:12 +02:00
const assert = require('assert')
const base58 = require('bs58')
const bitcoin = require('../')
2018-06-25 08:25:12 +02:00
const base58EncodeDecode = require('./fixtures/core/base58_encode_decode.json')
const base58KeysInvalid = require('./fixtures/core/base58_keys_invalid.json')
const base58KeysValid = require('./fixtures/core/base58_keys_valid.json')
const blocksValid = require('./fixtures/core/blocks.json')
const sigCanonical = require('./fixtures/core/sig_canonical.json')
const sigHash = require('./fixtures/core/sighash.json')
const sigNoncanonical = require('./fixtures/core/sig_noncanonical.json')
const txValid = require('./fixtures/core/tx_valid.json')
2015-02-23 00:36:57 +01:00
describe('Bitcoin-core', function () {
2016-09-14 14:29:12 +02:00
// base58EncodeDecode
2015-02-23 00:36:57 +01:00
describe('base58', function () {
2016-09-14 14:29:12 +02:00
base58EncodeDecode.forEach(function (f) {
const fhex = f[0]
const fb58 = f[1]
2015-02-23 00:36:57 +01:00
it('can decode ' + fb58, function () {
const buffer = base58.decode(fb58)
const actual = buffer.toString('hex')
2015-05-07 03:29:20 +02:00
assert.strictEqual(actual, fhex)
})
2015-02-23 00:36:57 +01:00
it('can encode ' + fhex, function () {
const buffer = Buffer.from(fhex, 'hex')
const actual = base58.encode(buffer)
2015-05-07 03:29:20 +02:00
assert.strictEqual(actual, fb58)
})
})
})
2016-09-14 14:29:12 +02:00
// base58KeysValid
2015-08-20 05:12:05 +02:00
describe('address.toBase58Check', function () {
const typeMap = {
2015-02-23 00:36:57 +01:00
'pubkey': 'pubKeyHash',
'script': 'scriptHash'
}
2016-09-14 14:29:12 +02:00
base58KeysValid.forEach(function (f) {
const expected = f[0]
const hash = Buffer.from(f[1], 'hex')
const params = f[2]
if (params.isPrivkey) return
const network = params.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin
const version = network[typeMap[params.addrType]]
it('can export ' + expected, function () {
2015-08-20 05:10:03 +02:00
assert.strictEqual(bitcoin.address.toBase58Check(hash, version), expected)
})
})
})
2016-09-14 14:29:12 +02:00
// base58KeysInvalid
2015-08-20 05:12:05 +02:00
describe('address.fromBase58Check', function () {
const allowedNetworks = [
2015-08-20 05:10:03 +02:00
bitcoin.networks.bitcoin.pubkeyhash,
bitcoin.networks.bitcoin.scripthash,
bitcoin.networks.testnet.pubkeyhash,
bitcoin.networks.testnet.scripthash
]
2016-09-14 14:29:12 +02:00
base58KeysInvalid.forEach(function (f) {
const string = f[0]
2015-02-23 00:36:57 +01:00
it('throws on ' + string, function () {
assert.throws(function () {
const address = bitcoin.address.fromBase58Check(string)
assert.notEqual(allowedNetworks.indexOf(address.version), -1, 'Invalid network')
2015-08-18 02:20:49 +02:00
}, /(Invalid (checksum|network))|(too (short|long))/)
})
})
})
2016-09-14 14:29:12 +02:00
// base58KeysValid
2015-03-02 06:48:36 +01:00
describe('ECPair', function () {
2016-09-14 14:29:12 +02:00
base58KeysValid.forEach(function (f) {
const string = f[0]
const hex = f[1]
const params = f[2]
if (!params.isPrivkey) return
2015-07-28 08:42:57 +02:00
const network = params.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin
const keyPair = bitcoin.ECPair.fromWIF(string, network)
2015-07-08 04:33:48 +02:00
it('fromWIF imports ' + string, function () {
assert.strictEqual(keyPair.privateKey.toString('hex'), hex)
2015-05-07 03:29:20 +02:00
assert.strictEqual(keyPair.compressed, params.isCompressed)
})
2015-07-08 04:33:48 +02:00
it('toWIF exports ' + hex + ' to ' + string, function () {
2015-05-07 03:29:20 +02:00
assert.strictEqual(keyPair.toWIF(), string)
})
})
})
2016-09-14 14:29:12 +02:00
// base58KeysInvalid
2015-07-08 04:33:48 +02:00
describe('ECPair.fromWIF', function () {
const allowedNetworks = [
2015-08-20 05:10:03 +02:00
bitcoin.networks.bitcoin,
bitcoin.networks.testnet
]
2016-09-14 14:29:12 +02:00
base58KeysInvalid.forEach(function (f) {
const string = f[0]
2015-02-23 00:36:57 +01:00
it('throws on ' + string, function () {
assert.throws(function () {
2015-08-20 05:10:03 +02:00
bitcoin.ECPair.fromWIF(string, allowedNetworks)
}, /(Invalid|Unknown) (checksum|compression flag|network version|WIF length)/)
})
})
})
2015-07-08 04:33:48 +02:00
describe('Block.fromHex', function () {
2016-09-14 14:29:12 +02:00
blocksValid.forEach(function (f) {
2015-07-08 04:33:48 +02:00
it('can parse ' + f.id, function () {
const block = bitcoin.Block.fromHex(f.hex)
2015-05-07 03:29:20 +02:00
assert.strictEqual(block.getId(), f.id)
assert.strictEqual(block.transactions.length, f.transactions)
})
})
})
2016-09-14 14:29:12 +02:00
// txValid
2015-07-08 04:33:48 +02:00
describe('Transaction.fromHex', function () {
2016-09-14 14:29:12 +02:00
txValid.forEach(function (f) {
// Objects that are only a single string are ignored
if (f.length === 1) return
const inputs = f[0]
const fhex = f[1]
// const verifyFlags = f[2] // TODO: do we need to test this?
2015-02-23 00:36:57 +01:00
it('can decode ' + fhex, function () {
const transaction = bitcoin.Transaction.fromHex(fhex)
transaction.ins.forEach(function (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)
// we read UInt32, not Int32
2015-05-07 03:29:20 +02:00
assert.strictEqual(txIn.index & 0xffffffff, prevOutIndex)
})
})
})
})
// sighash
2015-02-23 00:36:57 +01:00
describe('Transaction', function () {
2016-09-14 14:29:12 +02:00
sigHash.forEach(function (f) {
// Objects that are only a single string are ignored
if (f.length === 1) return
const txHex = f[0]
const scriptHex = f[1]
const inIndex = f[2]
const hashType = f[3]
const expectedHash = f[4]
const hashTypes = []
2015-08-20 05:10:03 +02:00
if ((hashType & 0x1f) === bitcoin.Transaction.SIGHASH_NONE) hashTypes.push('SIGHASH_NONE')
else if ((hashType & 0x1f) === bitcoin.Transaction.SIGHASH_SINGLE) hashTypes.push('SIGHASH_SINGLE')
2015-04-28 02:38:10 +02:00
else hashTypes.push('SIGHASH_ALL')
2015-08-20 05:10:03 +02:00
if (hashType & bitcoin.Transaction.SIGHASH_ANYONECANPAY) hashTypes.push('SIGHASH_ANYONECANPAY')
2015-04-28 02:38:10 +02:00
const hashTypeName = hashTypes.join(' | ')
2015-04-28 02:38:10 +02:00
it('should hash ' + txHex.slice(0, 40) + '... (' + hashTypeName + ')', function () {
const transaction = bitcoin.Transaction.fromHex(txHex)
2015-05-07 03:29:20 +02:00
assert.strictEqual(transaction.toHex(), txHex)
const script = Buffer.from(scriptHex, 'hex')
const scriptChunks = bitcoin.script.decompile(script)
2015-08-20 05:31:29 +02:00
assert.strictEqual(bitcoin.script.compile(scriptChunks).toString('hex'), scriptHex)
const hash = transaction.hashForSignature(inIndex, script, hashType)
// reverse because test data is reversed
assert.equal(hash.reverse().toString('hex'), expectedHash)
})
})
})
describe('script.signature.decode', function () {
2016-09-14 14:29:12 +02:00
sigCanonical.forEach(function (hex) {
const buffer = Buffer.from(hex, 'hex')
2015-02-23 00:36:57 +01:00
it('can parse ' + hex, function () {
const parsed = bitcoin.script.signature.decode(buffer)
const actual = bitcoin.script.signature.encode(parsed.signature, parsed.hashType)
2015-05-07 03:29:20 +02:00
assert.strictEqual(actual.toString('hex'), hex)
})
})
2016-09-14 14:29:12 +02:00
sigNoncanonical.forEach(function (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')
2015-02-23 00:36:57 +01:00
it('throws on ' + description, function () {
assert.throws(function () {
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/)
})
})
})
})