bitcoinjs-lib/test/bitcoin.core.js

267 lines
7.9 KiB
JavaScript
Raw Normal View History

2015-02-23 00:36:57 +01:00
/* global describe, it */
2015-02-23 00:36:57 +01:00
var assert = require('assert')
2014-10-15 13:36:10 +02:00
var base58 = require('bs58')
var Bitcoin = require('../')
var Address = Bitcoin.Address
var Block = Bitcoin.Block
2015-03-02 06:48:36 +01:00
var ECPair = Bitcoin.ECPair
2014-10-15 13:36:10 +02:00
var ECSignature = Bitcoin.ECSignature
var Transaction = Bitcoin.Transaction
var Script = Bitcoin.Script
var bufferutils = Bitcoin.bufferutils
var networks = Bitcoin.networks
2015-02-23 00:36:57 +01:00
var base58_encode_decode = require('./fixtures/core/base58_encode_decode.json')
var base58_keys_invalid = require('./fixtures/core/base58_keys_invalid.json')
var base58_keys_valid = require('./fixtures/core/base58_keys_valid.json')
var blocks_valid = require('./fixtures/core/blocks.json')
2015-02-23 00:36:57 +01:00
var sig_canonical = require('./fixtures/core/sig_canonical.json')
var sig_noncanonical = require('./fixtures/core/sig_noncanonical.json')
var sighash = require('./fixtures/core/sighash.json')
var tx_valid = require('./fixtures/core/tx_valid.json')
2015-02-23 00:36:57 +01:00
describe('Bitcoin-core', function () {
// base58_encode_decode
2015-02-23 00:36:57 +01:00
describe('base58', function () {
base58_encode_decode.forEach(function (f) {
var fhex = f[0]
var fb58 = f[1]
2015-02-23 00:36:57 +01:00
it('can decode ' + fb58, function () {
var buffer = base58.decode(fb58)
2014-10-03 11:11:38 +02:00
var actual = new Buffer(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 () {
var buffer = new Buffer(fhex, 'hex')
var actual = base58.encode(buffer)
2015-05-07 03:29:20 +02:00
assert.strictEqual(actual, fb58)
})
})
})
// base58_keys_valid
describe('Address.toBase58Check', function () {
2015-02-23 00:36:57 +01:00
var typeMap = {
'pubkey': 'pubKeyHash',
'script': 'scriptHash'
}
base58_keys_valid.forEach(function (f) {
var expected = f[0]
var hash = new Buffer(f[1], 'hex')
var params = f[2]
if (params.isPrivkey) return
2015-07-28 08:42:57 +02:00
var network = params.isTestnet ? networks.testnet : networks.bitcoin
var version = network[typeMap[params.addrType]]
it('can export ' + expected, function () {
assert.strictEqual(Address.toBase58Check(hash, version), expected)
})
})
})
// base58_keys_invalid
2015-07-08 04:33:48 +02:00
describe('Address.fromBase58Check', function () {
var allowedNetworks = [
2014-06-13 16:30:13 +02:00
networks.bitcoin.pubkeyhash,
networks.bitcoin.scripthash,
networks.testnet.pubkeyhash,
networks.testnet.scripthash
]
2015-02-23 00:36:57 +01:00
base58_keys_invalid.forEach(function (f) {
var string = f[0]
2015-02-23 00:36:57 +01:00
it('throws on ' + string, function () {
assert.throws(function () {
var address = Address.fromBase58Check(string)
assert.notEqual(allowedNetworks.indexOf(address.version), -1, 'Invalid network')
}, /Invalid (checksum|address length|network)/)
})
})
})
// base58_keys_valid
2015-03-02 06:48:36 +01:00
describe('ECPair', function () {
2015-02-23 00:36:57 +01:00
base58_keys_valid.forEach(function (f) {
var string = f[0]
var hex = f[1]
var params = f[2]
if (!params.isPrivkey) return
2015-07-28 08:42:57 +02:00
var network = params.isTestnet ? networks.testnet : networks.bitcoin
var keyPair = ECPair.fromWIF(string, network)
2015-07-08 04:33:48 +02:00
it('fromWIF imports ' + string, function () {
2015-05-07 03:29:20 +02:00
assert.strictEqual(keyPair.d.toHex(), hex)
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)
})
})
})
// base58_keys_invalid
2015-07-08 04:33:48 +02:00
describe('ECPair.fromWIF', function () {
var allowedNetworks = [
2015-03-02 06:48:36 +01:00
networks.bitcoin,
networks.testnet
]
2015-02-23 00:36:57 +01:00
base58_keys_invalid.forEach(function (f) {
var string = f[0]
2015-02-23 00:36:57 +01:00
it('throws on ' + string, function () {
assert.throws(function () {
2015-07-28 08:42:57 +02:00
ECPair.fromWIF(string, allowedNetworks)
2015-03-02 06:48:36 +01:00
}, /(Invalid|Unknown) (checksum|compression flag|network|WIF payload)/)
})
})
})
2015-07-08 04:33:48 +02:00
describe('Block.fromHex', function () {
blocks_valid.forEach(function (f) {
2015-07-08 04:33:48 +02:00
it('can parse ' + f.id, function () {
var block = 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)
})
})
})
// tx_valid
2015-07-08 04:33:48 +02:00
describe('Transaction.fromHex', function () {
2015-02-23 00:36:57 +01:00
tx_valid.forEach(function (f) {
// Objects that are only a single string are ignored
if (f.length === 1) return
var inputs = f[0]
var fhex = f[1]
2015-02-23 00:36:57 +01:00
// var verifyFlags = f[2] // TODO: do we need to test this?
2015-02-23 00:36:57 +01:00
it('can decode ' + fhex, function () {
var transaction = Transaction.fromHex(fhex)
transaction.ins.forEach(function (txIn, i) {
var input = inputs[i]
// reverse because test data is big-endian
var prevOutHash = bufferutils.reverse(new Buffer(input[0], 'hex'))
var 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)
})
})
})
})
2015-07-08 04:33:48 +02:00
describe('Script.fromASM', function () {
2015-04-28 03:49:01 +02:00
tx_valid.forEach(function (f) {
// Objects that are only a single string are ignored
if (f.length === 1) return
var inputs = f[0]
inputs.forEach(function (input) {
var prevOutScriptPubKey = input[2]
2015-07-08 04:33:36 +02:00
.replace(/(^| )([0-9])( |$)/g, 'OP_$2 ')
2015-04-28 03:49:01 +02:00
.replace(/0x[a-f0-9]+ 0x([a-f0-9]+)/, '$1')
.replace(/DUP/g, 'OP_DUP')
.replace(/NOT/g, 'OP_NOT')
.replace(/HASH160/g, 'OP_HASH160')
.replace(/EQUALVERIFY/g, 'OP_EQUALVERIFY')
.replace(/EQUAL( |$)/g, 'OP_EQUAL ')
.replace(/CHECKSIG/g, 'OP_CHECKSIG')
.replace(/ CHECKMULTISIG/g, ' OP_CHECKMULTISIG')
.replace(/CODESEPARATOR/g, 'OP_CODESEPARATOR')
.replace(/CHECKSIGVERIFY/g, 'OP_CHECKSIGVERIFY')
2015-07-08 04:33:48 +02:00
it('can parse ' + prevOutScriptPubKey, function () {
2015-04-28 03:49:01 +02:00
// TODO: we can probably do better validation than this
Script.fromASM(prevOutScriptPubKey)
})
})
})
})
// sighash
2015-02-23 00:36:57 +01:00
describe('Transaction', function () {
sighash.forEach(function (f) {
// Objects that are only a single string are ignored
if (f.length === 1) return
var txHex = f[0]
var scriptHex = f[1]
var inIndex = f[2]
var hashType = f[3]
// reverse because test data is big-endian
var expectedHash = bufferutils.reverse(new Buffer(f[4], 'hex'))
2015-04-28 02:38:10 +02:00
var hashTypes = []
if ((hashType & 0x1f) === Transaction.SIGHASH_NONE) hashTypes.push('SIGHASH_NONE')
else if ((hashType & 0x1f) === Transaction.SIGHASH_SINGLE) hashTypes.push('SIGHASH_SINGLE')
else hashTypes.push('SIGHASH_ALL')
if (hashType & Transaction.SIGHASH_ANYONECANPAY) hashTypes.push('SIGHASH_ANYONECANPAY')
var hashTypeName = hashTypes.join(' | ')
it('should hash ' + txHex.slice(0, 40) + '... (' + hashTypeName + ')', function () {
var transaction = Transaction.fromHex(txHex)
2015-05-07 03:29:20 +02:00
assert.strictEqual(transaction.toHex(), txHex)
var script = Script.fromHex(scriptHex)
2015-05-07 03:29:20 +02:00
assert.strictEqual(script.toHex(), scriptHex)
2015-04-28 02:38:10 +02:00
var hash = transaction.hashForSignature(inIndex, script, hashType)
assert.deepEqual(hash, expectedHash)
})
})
})
2015-07-08 04:33:48 +02:00
describe('ECSignature.parseScriptSignature', function () {
2015-02-23 00:36:57 +01:00
sig_canonical.forEach(function (hex) {
var buffer = new Buffer(hex, 'hex')
2015-02-23 00:36:57 +01:00
it('can parse ' + hex, function () {
var parsed = ECSignature.parseScriptSignature(buffer)
var actual = parsed.signature.toScriptSignature(parsed.hashType)
2015-05-07 03:29:20 +02:00
assert.strictEqual(actual.toString('hex'), hex)
})
})
2015-02-23 00:36:57 +01:00
sig_noncanonical.forEach(function (hex, i) {
if (i === 0) return
if (i % 2 !== 0) return
var description = sig_noncanonical[i - 1].slice(0, -1)
if (description === 'too long') return // we support non secp256k1 signatures
var buffer = new Buffer(hex, 'hex')
2015-02-23 00:36:57 +01:00
it('throws on ' + description, function () {
assert.throws(function () {
ECSignature.parseScriptSignature(buffer)
})
})
})
})
})