bitcoinjs-lib/test/bitcoin.core.js
2014-08-16 17:36:06 +10:00

229 lines
6.6 KiB
JavaScript

var assert = require('assert')
var base58 = require('bs58')
var base58check = require('bs58check')
var networks = require('../src/networks')
var Address = require('../src/address')
var BigInteger = require('bigi')
var ECKey = require('../src/eckey')
var ECSignature = require('../src/ecsignature')
var Transaction = require('../src/transaction')
var Script = require('../src/script')
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 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")
describe('Bitcoin-core', function() {
// base58_encode_decode
describe('base58', function() {
base58_encode_decode.forEach(function(f) {
var fhex = f[0]
var fb58 = f[1]
it('can decode ' + fb58, function() {
var buffer = base58.decode(fb58)
var actual = buffer.toString('hex')
assert.equal(actual, fhex)
})
it('can encode ' + fhex, function() {
var buffer = new Buffer(fhex, 'hex')
var actual = base58.encode(buffer)
assert.equal(actual, fb58)
})
})
})
// base58_keys_valid
describe('Address', function() {
base58_keys_valid.forEach(function(f) {
var string = f[0]
var hex = f[1]
var params = f[2]
var network = networks.bitcoin
if (params.isPrivkey) return
if (params.isTestnet) network = networks.testnet
it('can import ' + string, function() {
var address = Address.fromBase58Check(string)
assert.equal(address.hash.toString('hex'), hex)
if (params.addrType === 'pubkey') {
assert.equal(address.version, network.pubKeyHash)
} else if (params.addrType === 'script') {
assert.equal(address.version, network.scriptHash)
}
})
})
})
// base58_keys_invalid
describe('Address', function() {
var allowedNetworks = [
networks.bitcoin.pubkeyhash,
networks.bitcoin.scripthash,
networks.testnet.pubkeyhash,
networks.testnet.scripthash
]
base58_keys_invalid.forEach(function(f) {
var string = f[0]
it('throws on ' + string, function() {
assert.throws(function() {
var address = Address.fromBase58Check(string)
assert.notEqual(allowedNetworks.indexOf(address.version), -1, 'Invalid network')
}, /Invalid (checksum|hash length|network)/)
})
})
})
// base58_keys_valid
describe('ECKey', function() {
base58_keys_valid.forEach(function(f) {
var string = f[0]
var hex = f[1]
var params = f[2]
var network = networks.bitcoin
if (!params.isPrivkey) return
if (params.isTestnet) network = networks.testnet
it('imports ' + string + ' correctly', function() {
var privKey = ECKey.fromWIF(string)
assert.equal(privKey.d.toHex(), hex)
assert.equal(privKey.pub.compressed, params.isCompressed)
})
})
})
// base58_keys_invalid
describe('ECKey', function() {
var allowedNetworks = [
networks.bitcoin.wif,
networks.testnet.wif
]
base58_keys_invalid.forEach(function(f) {
var string = f[0]
it('throws on ' + string, function() {
assert.throws(function() {
var privKey = ECKey.fromWIF(string)
var version = base58check.decode(string).version
assert.notEqual(allowedNetworks.indexOf(version), -1, 'Invalid network')
}, /Invalid (checksum|compression flag|network|WIF payload)/)
})
})
})
// tx_valid
describe('Transaction', function() {
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]
// var verifyFlags = f[2] // TODO: do we need to test this?
it('can decode ' + fhex, function() {
var transaction = Transaction.fromHex(fhex)
transaction.ins.forEach(function(txin, i) {
var input = inputs[i]
var prevOutHash = input[0]
var prevOutIndex = input[1]
// var prevOutScriptPubKey = input[2] // TODO: we don't have a ASM parser
var actualHash = txin.hash
// Test data is big-endian
Array.prototype.reverse.call(actualHash)
assert.equal(actualHash.toString('hex'), prevOutHash)
// we read UInt32, not Int32
assert.equal(txin.index & 0xffffffff, prevOutIndex)
})
})
})
})
// sighash
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]
var expectedHash = f[4]
it('should hash ' + txHex + ' correctly', function() {
var transaction = Transaction.fromHex(txHex)
assert.equal(transaction.toHex(), txHex)
var script = Script.fromHex(scriptHex)
assert.equal(script.toHex(), scriptHex)
var actualHash
try {
actualHash = transaction.hashForSignature(inIndex, script, hashType)
} catch (e) {
// don't fail if we don't support it yet, TODO
if (!e.message.match(/not yet supported/)) throw e
}
if (actualHash != undefined) {
// Test data is big-endian
Array.prototype.reverse.call(actualHash)
assert.equal(actualHash.toString('hex'), expectedHash)
}
})
})
})
describe('ECSignature', function() {
sig_canonical.forEach(function(hex) {
var buffer = new Buffer(hex, 'hex')
it('can parse ' + hex, function() {
var parsed = ECSignature.parseScriptSignature(buffer)
var actual = parsed.signature.toScriptSignature(parsed.hashType)
assert.equal(actual.toString('hex'), hex)
})
})
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')
it('throws on ' + description, function() {
assert.throws(function() {
ECSignature.parseScriptSignature(buffer)
})
})
})
})
})