use standardjs formatting
This commit is contained in:
parent
09d8e440de
commit
399803affa
41 changed files with 1252 additions and 1177 deletions
|
@ -1,3 +1,5 @@
|
|||
/* global describe, it */
|
||||
|
||||
var assert = require('assert')
|
||||
var networks = require('../src/networks')
|
||||
|
||||
|
@ -6,10 +8,10 @@ var Script = require('../src/script')
|
|||
|
||||
var fixtures = require('./fixtures/address.json')
|
||||
|
||||
describe('Address', function() {
|
||||
describe('Constructor', function() {
|
||||
it('does not mutate the input', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('Address', function () {
|
||||
describe('Constructor', function () {
|
||||
it('does not mutate the input', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
var hash = new Buffer(f.hash, 'hex')
|
||||
var addr = new Address(hash, f.version)
|
||||
|
||||
|
@ -19,9 +21,9 @@ describe('Address', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('fromBase58Check', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('imports ' + f.script + ' (' + f.network + ') correctly', function() {
|
||||
describe('fromBase58Check', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('imports ' + f.script + ' (' + f.network + ') correctly', function () {
|
||||
var addr = Address.fromBase58Check(f.base58check)
|
||||
|
||||
assert.equal(addr.version, f.version)
|
||||
|
@ -29,18 +31,18 @@ describe('Address', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.fromBase58Check.forEach(function(f) {
|
||||
it('throws on ' + f.description, function() {
|
||||
assert.throws(function() {
|
||||
fixtures.invalid.fromBase58Check.forEach(function (f) {
|
||||
it('throws on ' + f.description, function () {
|
||||
assert.throws(function () {
|
||||
Address.fromBase58Check(f.base58check)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('fromOutputScript', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('imports ' + f.script + ' (' + f.network + ') correctly', function() {
|
||||
describe('fromOutputScript', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('imports ' + f.script + ' (' + f.network + ') correctly', function () {
|
||||
var script = Script.fromASM(f.script)
|
||||
var addr = Address.fromOutputScript(script, networks[f.network])
|
||||
|
||||
|
@ -49,20 +51,20 @@ describe('Address', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.fromOutputScript.forEach(function(f) {
|
||||
it('throws when ' + f.description, function() {
|
||||
fixtures.invalid.fromOutputScript.forEach(function (f) {
|
||||
it('throws when ' + f.description, function () {
|
||||
var script = Script.fromASM(f.script)
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
Address.fromOutputScript(script)
|
||||
}, new RegExp(f.description))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('toBase58Check', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('exports ' + f.script + ' (' + f.network + ') correctly', function() {
|
||||
describe('toBase58Check', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('exports ' + f.script + ' (' + f.network + ') correctly', function () {
|
||||
var addr = Address.fromBase58Check(f.base58check)
|
||||
var result = addr.toBase58Check()
|
||||
|
||||
|
@ -71,9 +73,9 @@ describe('Address', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('toOutputScript', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('imports ' + f.script + ' (' + f.network + ') correctly', function() {
|
||||
describe('toOutputScript', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('imports ' + f.script + ' (' + f.network + ') correctly', function () {
|
||||
var addr = Address.fromBase58Check(f.base58check)
|
||||
var script = addr.toOutputScript()
|
||||
|
||||
|
@ -81,11 +83,11 @@ describe('Address', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.toOutputScript.forEach(function(f) {
|
||||
it('throws when ' + f.description, function() {
|
||||
fixtures.invalid.toOutputScript.forEach(function (f) {
|
||||
it('throws when ' + f.description, function () {
|
||||
var addr = new Address(new Buffer(f.hash, 'hex'), f.version)
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
addr.toOutputScript()
|
||||
}, new RegExp(f.description))
|
||||
})
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
/* global describe, it, beforeEach */
|
||||
|
||||
var assert = require('assert')
|
||||
var base58check = require('../src/base58check')
|
||||
var bs58check = require('bs58check')
|
||||
var sinon = require('sinon')
|
||||
|
||||
describe('base58check', function() {
|
||||
describe('base58check', function () {
|
||||
var param
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
param = {}
|
||||
})
|
||||
|
||||
it('wraps bs58check.decode', sinon.test(function() {
|
||||
it('wraps bs58check.decode', sinon.test(function () {
|
||||
var expectation = this.mock(bs58check).expects('decode')
|
||||
expectation.once().calledWith(param)
|
||||
expectation.onCall(0).returns('foo')
|
||||
|
@ -18,7 +20,7 @@ describe('base58check', function() {
|
|||
assert.equal(base58check.decode(param), 'foo')
|
||||
}))
|
||||
|
||||
it('wraps bs58check.encode', sinon.test(function() {
|
||||
it('wraps bs58check.encode', sinon.test(function () {
|
||||
var expectation = this.mock(bs58check).expects('encode')
|
||||
expectation.once().calledWith(param)
|
||||
expectation.onCall(0).returns('foo')
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
var assert = require('assert')
|
||||
/* global describe, it */
|
||||
|
||||
var assert = require('assert')
|
||||
var base58 = require('bs58')
|
||||
//var base58check = require('bs58check')
|
||||
|
||||
var Bitcoin = require('../')
|
||||
var Address = Bitcoin.Address
|
||||
|
@ -12,29 +12,29 @@ var ECSignature = Bitcoin.ECSignature
|
|||
var Transaction = Bitcoin.Transaction
|
||||
var Script = Bitcoin.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")
|
||||
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() {
|
||||
describe('Bitcoin-core', function () {
|
||||
// base58_encode_decode
|
||||
describe('base58', function() {
|
||||
base58_encode_decode.forEach(function(f) {
|
||||
describe('base58', function () {
|
||||
base58_encode_decode.forEach(function (f) {
|
||||
var fhex = f[0]
|
||||
var fb58 = f[1]
|
||||
|
||||
it('can decode ' + fb58, function() {
|
||||
it('can decode ' + fb58, function () {
|
||||
var buffer = base58.decode(fb58)
|
||||
var actual = new Buffer(buffer).toString('hex')
|
||||
|
||||
assert.equal(actual, fhex)
|
||||
})
|
||||
|
||||
it('can encode ' + fhex, function() {
|
||||
it('can encode ' + fhex, function () {
|
||||
var buffer = new Buffer(fhex, 'hex')
|
||||
var actual = base58.encode(buffer)
|
||||
|
||||
|
@ -44,32 +44,33 @@ describe('Bitcoin-core', function() {
|
|||
})
|
||||
|
||||
// base58_keys_valid
|
||||
describe('Address', function() {
|
||||
base58_keys_valid.forEach(function(f) {
|
||||
describe('Address', function () {
|
||||
var typeMap = {
|
||||
'pubkey': 'pubKeyHash',
|
||||
'script': 'scriptHash'
|
||||
}
|
||||
|
||||
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
|
||||
if (params.isTestnet)
|
||||
network = networks.testnet
|
||||
|
||||
it('can import ' + string, function() {
|
||||
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)
|
||||
}
|
||||
assert.equal(address.version, network[typeMap[params.addrType]])
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// base58_keys_invalid
|
||||
describe('Address', function() {
|
||||
describe('Address', function () {
|
||||
var allowedNetworks = [
|
||||
networks.bitcoin.pubkeyhash,
|
||||
networks.bitcoin.scripthash,
|
||||
|
@ -77,11 +78,11 @@ describe('Bitcoin-core', function() {
|
|||
networks.testnet.scripthash
|
||||
]
|
||||
|
||||
base58_keys_invalid.forEach(function(f) {
|
||||
base58_keys_invalid.forEach(function (f) {
|
||||
var string = f[0]
|
||||
|
||||
it('throws on ' + string, function() {
|
||||
assert.throws(function() {
|
||||
it('throws on ' + string, function () {
|
||||
assert.throws(function () {
|
||||
var address = Address.fromBase58Check(string)
|
||||
|
||||
assert.notEqual(allowedNetworks.indexOf(address.version), -1, 'Invalid network')
|
||||
|
@ -91,8 +92,8 @@ describe('Bitcoin-core', function() {
|
|||
})
|
||||
|
||||
// base58_keys_valid
|
||||
describe('ECKey', function() {
|
||||
base58_keys_valid.forEach(function(f) {
|
||||
describe('ECKey', function () {
|
||||
base58_keys_valid.forEach(function (f) {
|
||||
var string = f[0]
|
||||
var hex = f[1]
|
||||
var params = f[2]
|
||||
|
@ -101,29 +102,29 @@ describe('Bitcoin-core', function() {
|
|||
if (!params.isPrivkey) return
|
||||
var privKey = ECKey.fromWIF(string)
|
||||
|
||||
it('imports ' + string + ' correctly', function() {
|
||||
it('imports ' + string + ' correctly', function () {
|
||||
assert.equal(privKey.d.toHex(), hex)
|
||||
assert.equal(privKey.pub.compressed, params.isCompressed)
|
||||
})
|
||||
|
||||
it('exports ' + hex + ' to ' + string, function() {
|
||||
it('exports ' + hex + ' to ' + string, function () {
|
||||
assert.equal(privKey.toWIF(network), string)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
// base58_keys_invalid
|
||||
describe('ECKey', function() {
|
||||
describe('ECKey', function () {
|
||||
var allowedNetworks = [
|
||||
networks.bitcoin.wif,
|
||||
networks.testnet.wif
|
||||
]
|
||||
|
||||
base58_keys_invalid.forEach(function(f) {
|
||||
base58_keys_invalid.forEach(function (f) {
|
||||
var string = f[0]
|
||||
|
||||
it('throws on ' + string, function() {
|
||||
assert.throws(function() {
|
||||
it('throws on ' + string, function () {
|
||||
assert.throws(function () {
|
||||
ECKey.fromWIF(string)
|
||||
var version = base58check.decode(string).readUInt8(0)
|
||||
|
||||
|
@ -134,23 +135,23 @@ describe('Bitcoin-core', function() {
|
|||
})
|
||||
|
||||
// tx_valid
|
||||
describe('Transaction', function() {
|
||||
tx_valid.forEach(function(f) {
|
||||
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?
|
||||
// var verifyFlags = f[2] // TODO: do we need to test this?
|
||||
|
||||
it('can decode ' + fhex, function() {
|
||||
it('can decode ' + fhex, function () {
|
||||
var transaction = Transaction.fromHex(fhex)
|
||||
|
||||
transaction.ins.forEach(function(txin, i) {
|
||||
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 prevOutScriptPubKey = input[2] // TODO: we don't have a ASM parser
|
||||
|
||||
var actualHash = txin.hash
|
||||
|
||||
|
@ -167,8 +168,8 @@ describe('Bitcoin-core', function() {
|
|||
})
|
||||
|
||||
// sighash
|
||||
describe('Transaction', function() {
|
||||
sighash.forEach(function(f) {
|
||||
describe('Transaction', function () {
|
||||
sighash.forEach(function (f) {
|
||||
// Objects that are only a single string are ignored
|
||||
if (f.length === 1) return
|
||||
|
||||
|
@ -178,7 +179,7 @@ describe('Bitcoin-core', function() {
|
|||
var hashType = f[3]
|
||||
var expectedHash = f[4]
|
||||
|
||||
it('should hash ' + txHex + ' correctly', function() {
|
||||
it('should hash ' + txHex + ' correctly', function () {
|
||||
var transaction = Transaction.fromHex(txHex)
|
||||
assert.equal(transaction.toHex(), txHex)
|
||||
|
||||
|
@ -190,7 +191,8 @@ describe('Bitcoin-core', function() {
|
|||
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 (!e.message.match(/not yet supported/))
|
||||
throw e
|
||||
}
|
||||
|
||||
if (actualHash !== undefined) {
|
||||
|
@ -203,18 +205,18 @@ describe('Bitcoin-core', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('ECSignature', function() {
|
||||
sig_canonical.forEach(function(hex) {
|
||||
describe('ECSignature', function () {
|
||||
sig_canonical.forEach(function (hex) {
|
||||
var buffer = new Buffer(hex, 'hex')
|
||||
|
||||
it('can parse ' + hex, function() {
|
||||
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) {
|
||||
sig_noncanonical.forEach(function (hex, i) {
|
||||
if (i === 0) return
|
||||
if (i % 2 !== 0) return
|
||||
|
||||
|
@ -223,8 +225,8 @@ describe('Bitcoin-core', function() {
|
|||
|
||||
var buffer = new Buffer(hex, 'hex')
|
||||
|
||||
it('throws on ' + description, function() {
|
||||
assert.throws(function() {
|
||||
it('throws on ' + description, function () {
|
||||
assert.throws(function () {
|
||||
ECSignature.parseScriptSignature(buffer)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,13 +1,15 @@
|
|||
/* global describe, it, beforeEach */
|
||||
|
||||
var assert = require('assert')
|
||||
|
||||
var Block = require('../src/block')
|
||||
|
||||
var fixtures = require('./fixtures/block')
|
||||
|
||||
describe('Block', function() {
|
||||
describe('fromBuffer/fromHex', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('imports the block: ' + f.description + ' correctly', function() {
|
||||
describe('Block', function () {
|
||||
describe('fromBuffer/fromHex', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('imports the block: ' + f.description + ' correctly', function () {
|
||||
var block = Block.fromHex(f.hex)
|
||||
|
||||
assert.equal(block.version, f.version)
|
||||
|
@ -19,66 +21,66 @@ describe('Block', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.forEach(function(f) {
|
||||
it('throws on ' + f.exception, function() {
|
||||
assert.throws(function() {
|
||||
fixtures.invalid.forEach(function (f) {
|
||||
it('throws on ' + f.exception, function () {
|
||||
assert.throws(function () {
|
||||
Block.fromHex(f.hex)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('toBuffer/toHex', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('toBuffer/toHex', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
var block
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
block = Block.fromHex(f.hex)
|
||||
})
|
||||
|
||||
it('exports the block: ' + f.description + ' correctly', function() {
|
||||
it('exports the block: ' + f.description + ' correctly', function () {
|
||||
assert.equal(block.toHex(), f.hex)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('getHash', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('getHash', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
var block
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
block = Block.fromHex(f.hex)
|
||||
})
|
||||
|
||||
it('calculates ' + f.hash + ' for the block: ' + f.description, function() {
|
||||
it('calculates ' + f.hash + ' for the block: ' + f.description, function () {
|
||||
assert.equal(block.getHash().toString('hex'), f.hash)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('getId', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('getId', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
var block
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
block = Block.fromHex(f.hex)
|
||||
})
|
||||
|
||||
it('calculates ' + f.id + ' for the block: ' + f.description, function() {
|
||||
it('calculates ' + f.id + ' for the block: ' + f.description, function () {
|
||||
assert.equal(block.getId(), f.id)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('getUTCDate', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('getUTCDate', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
var block
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
block = Block.fromHex(f.hex)
|
||||
})
|
||||
|
||||
it('returns UTC date of ' + f.id, function() {
|
||||
it('returns UTC date of ' + f.id, function () {
|
||||
var utcDate = block.getUTCDate().getTime()
|
||||
|
||||
assert.equal(utcDate, f.timestamp * 1e3)
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
/* global describe, it */
|
||||
|
||||
var assert = require('assert')
|
||||
var bufferutils = require('../src/bufferutils')
|
||||
|
||||
var fixtures = require('./fixtures/bufferutils.json')
|
||||
|
||||
describe('bufferutils', function() {
|
||||
describe('pushDataSize', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('determines the pushDataSize of ' + f.dec + ' correctly', function() {
|
||||
describe('bufferutils', function () {
|
||||
describe('pushDataSize', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('determines the pushDataSize of ' + f.dec + ' correctly', function () {
|
||||
if (!f.hexPD) return
|
||||
|
||||
var size = bufferutils.pushDataSize(f.dec)
|
||||
|
@ -16,11 +18,11 @@ describe('bufferutils', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('readPushDataInt', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('readPushDataInt', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
if (!f.hexPD) return
|
||||
|
||||
it('decodes ' + f.hexPD + ' correctly', function() {
|
||||
it('decodes ' + f.hexPD + ' correctly', function () {
|
||||
var buffer = new Buffer(f.hexPD, 'hex')
|
||||
var d = bufferutils.readPushDataInt(buffer, 0)
|
||||
var fopcode = parseInt(f.hexPD.substr(0, 2), 16)
|
||||
|
@ -32,9 +34,9 @@ describe('bufferutils', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('readUInt64LE', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('decodes ' + f.hex64 + ' correctly', function() {
|
||||
describe('readUInt64LE', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('decodes ' + f.hex64 + ' correctly', function () {
|
||||
var buffer = new Buffer(f.hex64, 'hex')
|
||||
var number = bufferutils.readUInt64LE(buffer, 0)
|
||||
|
||||
|
@ -42,20 +44,20 @@ describe('bufferutils', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.forEach(function(f) {
|
||||
it('throws on ' + f.description, function() {
|
||||
fixtures.invalid.forEach(function (f) {
|
||||
it('throws on ' + f.description, function () {
|
||||
var buffer = new Buffer(f.hex64, 'hex')
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
bufferutils.readUInt64LE(buffer, 0)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('readVarInt', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('decodes ' + f.hexVI + ' correctly', function() {
|
||||
describe('readVarInt', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('decodes ' + f.hexVI + ' correctly', function () {
|
||||
var buffer = new Buffer(f.hexVI, 'hex')
|
||||
var d = bufferutils.readVarInt(buffer, 0)
|
||||
|
||||
|
@ -64,20 +66,20 @@ describe('bufferutils', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.forEach(function(f) {
|
||||
it('throws on ' + f.description, function() {
|
||||
fixtures.invalid.forEach(function (f) {
|
||||
it('throws on ' + f.description, function () {
|
||||
var buffer = new Buffer(f.hexVI, 'hex')
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
bufferutils.readVarInt(buffer, 0)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('reverse', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('reverses ' + f.hex64 + ' correctly', function() {
|
||||
describe('reverse', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('reverses ' + f.hex64 + ' correctly', function () {
|
||||
var buffer = new Buffer(f.hex64, 'hex')
|
||||
var buffer2 = bufferutils.reverse(buffer)
|
||||
|
||||
|
@ -88,9 +90,9 @@ describe('bufferutils', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('varIntBuffer', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('encodes ' + f.dec + ' correctly', function() {
|
||||
describe('varIntBuffer', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('encodes ' + f.dec + ' correctly', function () {
|
||||
var buffer = bufferutils.varIntBuffer(f.dec)
|
||||
|
||||
assert.equal(buffer.toString('hex'), f.hexVI)
|
||||
|
@ -98,9 +100,9 @@ describe('bufferutils', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('varIntSize', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('determines the varIntSize of ' + f.dec + ' correctly', function() {
|
||||
describe('varIntSize', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('determines the varIntSize of ' + f.dec + ' correctly', function () {
|
||||
var size = bufferutils.varIntSize(f.dec)
|
||||
|
||||
assert.equal(size, f.hexVI.length / 2)
|
||||
|
@ -108,11 +110,11 @@ describe('bufferutils', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('writePushDataInt', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('writePushDataInt', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
if (!f.hexPD) return
|
||||
|
||||
it('encodes ' + f.dec + ' correctly', function() {
|
||||
it('encodes ' + f.dec + ' correctly', function () {
|
||||
var buffer = new Buffer(5)
|
||||
buffer.fill(0)
|
||||
|
||||
|
@ -122,9 +124,9 @@ describe('bufferutils', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('writeUInt64LE', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('encodes ' + f.dec + ' correctly', function() {
|
||||
describe('writeUInt64LE', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('encodes ' + f.dec + ' correctly', function () {
|
||||
var buffer = new Buffer(8)
|
||||
buffer.fill(0)
|
||||
|
||||
|
@ -133,21 +135,21 @@ describe('bufferutils', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.forEach(function(f) {
|
||||
it('throws on ' + f.description, function() {
|
||||
fixtures.invalid.forEach(function (f) {
|
||||
it('throws on ' + f.description, function () {
|
||||
var buffer = new Buffer(8)
|
||||
buffer.fill(0)
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
bufferutils.writeUInt64LE(buffer, f.dec, 0)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('writeVarInt', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('encodes ' + f.dec + ' correctly', function() {
|
||||
describe('writeVarInt', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('encodes ' + f.dec + ' correctly', function () {
|
||||
var buffer = new Buffer(9)
|
||||
buffer.fill(0)
|
||||
|
||||
|
@ -156,12 +158,12 @@ describe('bufferutils', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.forEach(function(f) {
|
||||
it('throws on ' + f.description, function() {
|
||||
fixtures.invalid.forEach(function (f) {
|
||||
it('throws on ' + f.description, function () {
|
||||
var buffer = new Buffer(9)
|
||||
buffer.fill(0)
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
bufferutils.writeVarInt(buffer, f.dec, 0)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
/* global describe, it */
|
||||
|
||||
var assert = require('assert')
|
||||
var crypto = require('../src/crypto')
|
||||
|
||||
var fixtures = require('./fixtures/crypto.json')
|
||||
|
||||
describe('Crypto', function() {
|
||||
describe('HASH160', function() {
|
||||
it('matches the test vectors', function() {
|
||||
fixtures.before.hex.forEach(function(hex, i) {
|
||||
describe('Crypto', function () {
|
||||
describe('HASH160', function () {
|
||||
it('matches the test vectors', function () {
|
||||
fixtures.before.hex.forEach(function (hex, i) {
|
||||
var data = new Buffer(hex, 'hex')
|
||||
var actual = crypto.hash160(data).toString('hex')
|
||||
|
||||
|
@ -15,9 +17,9 @@ describe('Crypto', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('HASH256', function() {
|
||||
it('matches the test vectors', function() {
|
||||
fixtures.before.hex.forEach(function(hex, i) {
|
||||
describe('HASH256', function () {
|
||||
it('matches the test vectors', function () {
|
||||
fixtures.before.hex.forEach(function (hex, i) {
|
||||
var data = new Buffer(hex, 'hex')
|
||||
var actual = crypto.hash256(data).toString('hex')
|
||||
|
||||
|
@ -26,9 +28,9 @@ describe('Crypto', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('RIPEMD160', function() {
|
||||
it('matches the test vectors', function() {
|
||||
fixtures.before.hex.forEach(function(hex, i) {
|
||||
describe('RIPEMD160', function () {
|
||||
it('matches the test vectors', function () {
|
||||
fixtures.before.hex.forEach(function (hex, i) {
|
||||
var data = new Buffer(hex, 'hex')
|
||||
var actual = crypto.ripemd160(data).toString('hex')
|
||||
|
||||
|
@ -37,9 +39,9 @@ describe('Crypto', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('SHA1', function() {
|
||||
it('matches the test vectors', function() {
|
||||
fixtures.before.hex.forEach(function(hex, i) {
|
||||
describe('SHA1', function () {
|
||||
it('matches the test vectors', function () {
|
||||
fixtures.before.hex.forEach(function (hex, i) {
|
||||
var data = new Buffer(hex, 'hex')
|
||||
var actual = crypto.sha1(data).toString('hex')
|
||||
|
||||
|
@ -48,9 +50,9 @@ describe('Crypto', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('SHA256', function() {
|
||||
it('matches the test vectors', function() {
|
||||
fixtures.before.hex.forEach(function(hex, i) {
|
||||
describe('SHA256', function () {
|
||||
it('matches the test vectors', function () {
|
||||
fixtures.before.hex.forEach(function (hex, i) {
|
||||
var data = new Buffer(hex, 'hex')
|
||||
var actual = crypto.sha256(data).toString('hex')
|
||||
|
||||
|
@ -59,9 +61,9 @@ describe('Crypto', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('HmacSHA256', function() {
|
||||
it('matches the test vectors', function() {
|
||||
fixtures.before.hex.forEach(function(hex, i) {
|
||||
describe('HmacSHA256', function () {
|
||||
it('matches the test vectors', function () {
|
||||
fixtures.before.hex.forEach(function (hex, i) {
|
||||
var data = new Buffer(hex, 'hex')
|
||||
var secret = new Buffer(fixtures.before.secret)
|
||||
var actual = crypto.HmacSHA256(data, secret).toString('hex')
|
||||
|
@ -71,9 +73,9 @@ describe('Crypto', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('HmacSHA512', function() {
|
||||
it('matches the test vectors', function() {
|
||||
fixtures.before.hex.forEach(function(hex, i) {
|
||||
describe('HmacSHA512', function () {
|
||||
it('matches the test vectors', function () {
|
||||
fixtures.before.hex.forEach(function (hex, i) {
|
||||
var data = new Buffer(hex, 'hex')
|
||||
var secret = new Buffer(fixtures.before.secret)
|
||||
var actual = crypto.HmacSHA512(data, secret).toString('hex')
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* global describe, it */
|
||||
|
||||
var assert = require('assert')
|
||||
var crypto = require('../src/crypto')
|
||||
var ecdsa = require('../src/ecdsa')
|
||||
|
@ -13,12 +15,14 @@ var curve = ecurve.getCurveByName('secp256k1')
|
|||
|
||||
var fixtures = require('./fixtures/ecdsa.json')
|
||||
|
||||
describe('ecdsa', function() {
|
||||
describe('deterministicGenerateK', function() {
|
||||
function checkSig() { return true }
|
||||
describe('ecdsa', function () {
|
||||
describe('deterministicGenerateK', function () {
|
||||
function checkSig () {
|
||||
return true
|
||||
}
|
||||
|
||||
fixtures.valid.ecdsa.forEach(function(f) {
|
||||
it('for \"' + f.message + '\"', function() {
|
||||
fixtures.valid.ecdsa.forEach(function (f) {
|
||||
it('for "' + f.message + '"', function () {
|
||||
var d = BigInteger.fromHex(f.d)
|
||||
var h1 = crypto.sha256(f.message)
|
||||
|
||||
|
@ -28,8 +32,8 @@ describe('ecdsa', function() {
|
|||
})
|
||||
|
||||
// FIXME: remove in 2.0.0
|
||||
fixtures.valid.ecdsa.forEach(function(f) {
|
||||
it('(deprecated) for \"' + f.message + '\"', function() {
|
||||
fixtures.valid.ecdsa.forEach(function (f) {
|
||||
it('(deprecated) for "' + f.message + '"', function () {
|
||||
var d = BigInteger.fromHex(f.d)
|
||||
var h1 = crypto.sha256(f.message)
|
||||
|
||||
|
@ -38,7 +42,7 @@ describe('ecdsa', function() {
|
|||
})
|
||||
})
|
||||
|
||||
it('loops until an appropriate k value is found', sinon.test(function() {
|
||||
it('loops until an appropriate k value is found', sinon.test(function () {
|
||||
this.mock(BigInteger).expects('fromBuffer')
|
||||
.exactly(3)
|
||||
.onCall(0).returns(new BigInteger('0')) // < 1
|
||||
|
@ -52,7 +56,7 @@ describe('ecdsa', function() {
|
|||
assert.equal(k.toString(), '42')
|
||||
}))
|
||||
|
||||
it('loops until a suitable signature is found', sinon.test(function() {
|
||||
it('loops until a suitable signature is found', sinon.test(function () {
|
||||
this.mock(BigInteger).expects('fromBuffer')
|
||||
.exactly(4)
|
||||
.onCall(0).returns(new BigInteger('0')) // < 1
|
||||
|
@ -72,13 +76,13 @@ describe('ecdsa', function() {
|
|||
assert.equal(k.toString(), '53')
|
||||
}))
|
||||
|
||||
fixtures.valid.rfc6979.forEach(function(f) {
|
||||
it('produces the expected k values for ' + f.message + ' if k wasn\'t suitable', function() {
|
||||
fixtures.valid.rfc6979.forEach(function (f) {
|
||||
it('produces the expected k values for ' + f.message + " if k wasn't suitable", function () {
|
||||
var d = BigInteger.fromHex(f.d)
|
||||
var h1 = crypto.sha256(f.message)
|
||||
|
||||
var results = []
|
||||
ecdsa.deterministicGenerateK(curve, h1, d, function(k) {
|
||||
ecdsa.deterministicGenerateK(curve, h1, d, function (k) {
|
||||
results.push(k)
|
||||
|
||||
return results.length === 16
|
||||
|
@ -91,9 +95,9 @@ describe('ecdsa', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('recoverPubKey', function() {
|
||||
fixtures.valid.ecdsa.forEach(function(f) {
|
||||
it('recovers the pubKey for ' + f.d, function() {
|
||||
describe('recoverPubKey', function () {
|
||||
fixtures.valid.ecdsa.forEach(function (f) {
|
||||
it('recovers the pubKey for ' + f.d, function () {
|
||||
var d = BigInteger.fromHex(f.d)
|
||||
var Q = curve.G.multiply(d)
|
||||
var signature = {
|
||||
|
@ -108,7 +112,7 @@ describe('ecdsa', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('with i ∈ {0,1,2,3}', function() {
|
||||
describe('with i ∈ {0,1,2,3}', function () {
|
||||
var hash = message.magicHash('1111', networks.bitcoin)
|
||||
var e = BigInteger.fromBuffer(hash)
|
||||
|
||||
|
@ -121,8 +125,8 @@ describe('ecdsa', function() {
|
|||
'027eea09d46ac7fb6aa2e96f9c576677214ffdc238eb167734a9b39d1eb4c3d30d'
|
||||
]
|
||||
|
||||
points.forEach(function(expectedHex, i) {
|
||||
it('recovers an expected point for i of ' + i, function() {
|
||||
points.forEach(function (expectedHex, i) {
|
||||
it('recovers an expected point for i of ' + i, function () {
|
||||
var Qprime = ecdsa.recoverPubKey(curve, e, signature, i)
|
||||
var QprimeHex = Qprime.getEncoded().toString('hex')
|
||||
|
||||
|
@ -131,21 +135,21 @@ describe('ecdsa', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.recoverPubKey.forEach(function(f) {
|
||||
it('throws on ' + f.description, function() {
|
||||
fixtures.invalid.recoverPubKey.forEach(function (f) {
|
||||
it('throws on ' + f.description, function () {
|
||||
var e = BigInteger.fromHex(f.e)
|
||||
var signature = new ECSignature(new BigInteger(f.signature.r), new BigInteger(f.signature.s))
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
ecdsa.recoverPubKey(curve, e, signature, f.i)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('sign', function() {
|
||||
fixtures.valid.ecdsa.forEach(function(f) {
|
||||
it('produces a deterministic signature for \"' + f.message + '\"', function() {
|
||||
describe('sign', function () {
|
||||
fixtures.valid.ecdsa.forEach(function (f) {
|
||||
it('produces a deterministic signature for "' + f.message + '"', function () {
|
||||
var d = BigInteger.fromHex(f.d)
|
||||
var hash = crypto.sha256(f.message)
|
||||
var signature = ecdsa.sign(curve, hash, d)
|
||||
|
@ -155,7 +159,7 @@ describe('ecdsa', function() {
|
|||
})
|
||||
})
|
||||
|
||||
it('should sign with low S value', function() {
|
||||
it('should sign with low S value', function () {
|
||||
var hash = crypto.sha256('Vires in numeris')
|
||||
var sig = ecdsa.sign(curve, hash, BigInteger.ONE)
|
||||
|
||||
|
@ -165,15 +169,15 @@ describe('ecdsa', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('verify/verifyRaw', function() {
|
||||
fixtures.valid.ecdsa.forEach(function(f) {
|
||||
it('verifies a valid signature for \"' + f.message + '\"', function() {
|
||||
describe('verify/verifyRaw', function () {
|
||||
fixtures.valid.ecdsa.forEach(function (f) {
|
||||
it('verifies a valid signature for "' + f.message + '"', function () {
|
||||
var d = BigInteger.fromHex(f.d)
|
||||
var H = crypto.sha256(f.message)
|
||||
var e = BigInteger.fromBuffer(H)
|
||||
var signature = new ECSignature(
|
||||
new BigInteger(f.signature.r),
|
||||
new BigInteger(f.signature.s)
|
||||
new BigInteger(f.signature.r),
|
||||
new BigInteger(f.signature.s)
|
||||
)
|
||||
var Q = curve.G.multiply(d)
|
||||
|
||||
|
@ -182,14 +186,14 @@ describe('ecdsa', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.verifyRaw.forEach(function(f) {
|
||||
it('fails to verify with ' + f.description, function() {
|
||||
fixtures.invalid.verifyRaw.forEach(function (f) {
|
||||
it('fails to verify with ' + f.description, function () {
|
||||
var H = crypto.sha256(f.message)
|
||||
var e = BigInteger.fromBuffer(H)
|
||||
var d = BigInteger.fromHex(f.d)
|
||||
var signature = new ECSignature(
|
||||
new BigInteger(f.signature.r),
|
||||
new BigInteger(f.signature.s)
|
||||
new BigInteger(f.signature.r),
|
||||
new BigInteger(f.signature.s)
|
||||
)
|
||||
var Q = curve.G.multiply(d)
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
/* global describe, it, beforeEach, afterEach */
|
||||
/* eslint-disable no-new */
|
||||
|
||||
var assert = require('assert')
|
||||
var crypto = require('crypto')
|
||||
var ecurve = require('ecurve')
|
||||
|
@ -9,22 +12,22 @@ var ECKey = require('../src/eckey')
|
|||
|
||||
var fixtures = require('./fixtures/eckey.json')
|
||||
|
||||
describe('ECKey', function() {
|
||||
describe('constructor', function() {
|
||||
it('defaults to compressed', function() {
|
||||
describe('ECKey', function () {
|
||||
describe('constructor', function () {
|
||||
it('defaults to compressed', function () {
|
||||
var privKey = new ECKey(BigInteger.ONE)
|
||||
|
||||
assert.equal(privKey.pub.compressed, true)
|
||||
})
|
||||
|
||||
it('supports the uncompressed flag', function() {
|
||||
it('supports the uncompressed flag', function () {
|
||||
var privKey = new ECKey(BigInteger.ONE, false)
|
||||
|
||||
assert.equal(privKey.pub.compressed, false)
|
||||
})
|
||||
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('calculates the matching pubKey for ' + f.d, function() {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('calculates the matching pubKey for ' + f.d, function () {
|
||||
var d = new BigInteger(f.d)
|
||||
var privKey = new ECKey(d)
|
||||
|
||||
|
@ -32,18 +35,18 @@ describe('ECKey', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.constructor.forEach(function(f) {
|
||||
it('throws on ' + f.d, function() {
|
||||
fixtures.invalid.constructor.forEach(function (f) {
|
||||
it('throws on ' + f.d, function () {
|
||||
var d = new BigInteger(f.d)
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
new ECKey(d)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('uses the secp256k1 curve by default', function() {
|
||||
it('uses the secp256k1 curve by default', function () {
|
||||
var secp256k1 = ecurve.getCurveByName('secp256k1')
|
||||
|
||||
for (var property in secp256k1) {
|
||||
|
@ -58,10 +61,10 @@ describe('ECKey', function() {
|
|||
}
|
||||
})
|
||||
|
||||
describe('fromWIF', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
f.WIFs.forEach(function(wif) {
|
||||
it('imports ' + wif.string + ' correctly', function() {
|
||||
describe('fromWIF', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
f.WIFs.forEach(function (wif) {
|
||||
it('imports ' + wif.string + ' correctly', function () {
|
||||
var privKey = ECKey.fromWIF(wif.string)
|
||||
|
||||
assert.equal(privKey.d.toString(), f.d)
|
||||
|
@ -70,19 +73,19 @@ describe('ECKey', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.WIF.forEach(function(f) {
|
||||
it('throws on ' + f.string, function() {
|
||||
assert.throws(function() {
|
||||
fixtures.invalid.WIF.forEach(function (f) {
|
||||
it('throws on ' + f.string, function () {
|
||||
assert.throws(function () {
|
||||
ECKey.fromWIF(f.string)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('toWIF', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
f.WIFs.forEach(function(wif) {
|
||||
it('exports ' + wif.string + ' correctly', function() {
|
||||
describe('toWIF', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
f.WIFs.forEach(function (wif) {
|
||||
it('exports ' + wif.string + ' correctly', function () {
|
||||
var privKey = ECKey.fromWIF(wif.string)
|
||||
var network = networks[wif.network]
|
||||
var result = privKey.toWIF(network)
|
||||
|
@ -93,34 +96,34 @@ describe('ECKey', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('makeRandom', function() {
|
||||
describe('makeRandom', function () {
|
||||
var exWIF = 'KwMWvwRJeFqxYyhZgNwYuYjbQENDAPAudQx5VEmKJrUZcq6aL2pv'
|
||||
var exPrivKey = ECKey.fromWIF(exWIF)
|
||||
var exBuffer = exPrivKey.d.toBuffer(32)
|
||||
|
||||
describe('uses default crypto RNG', function() {
|
||||
beforeEach(function() {
|
||||
describe('uses default crypto RNG', function () {
|
||||
beforeEach(function () {
|
||||
sinon.stub(crypto, 'randomBytes').returns(exBuffer)
|
||||
})
|
||||
|
||||
afterEach(function() {
|
||||
afterEach(function () {
|
||||
crypto.randomBytes.restore()
|
||||
})
|
||||
|
||||
it('generates a ECKey', function() {
|
||||
it('generates a ECKey', function () {
|
||||
var privKey = ECKey.makeRandom()
|
||||
|
||||
assert.equal(privKey.toWIF(), exWIF)
|
||||
})
|
||||
|
||||
it('supports compression', function() {
|
||||
it('supports compression', function () {
|
||||
assert.equal(ECKey.makeRandom(true).pub.compressed, true)
|
||||
assert.equal(ECKey.makeRandom(false).pub.compressed, false)
|
||||
})
|
||||
})
|
||||
|
||||
it('allows a custom RNG to be used', function() {
|
||||
function rng(size) {
|
||||
it('allows a custom RNG to be used', function () {
|
||||
function rng (size) {
|
||||
return exBuffer.slice(0, size)
|
||||
}
|
||||
|
||||
|
@ -129,16 +132,16 @@ describe('ECKey', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('signing', function() {
|
||||
describe('signing', function () {
|
||||
var hash = crypto.randomBytes(32)
|
||||
var priv = ECKey.makeRandom()
|
||||
var signature = priv.sign(hash)
|
||||
|
||||
it('should verify against the public key', function() {
|
||||
it('should verify against the public key', function () {
|
||||
assert(priv.pub.verify(hash, signature))
|
||||
})
|
||||
|
||||
it('should not verify against the wrong public key', function() {
|
||||
it('should not verify against the wrong public key', function () {
|
||||
var priv2 = ECKey.makeRandom()
|
||||
|
||||
assert(!priv2.pub.verify(hash, signature))
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* global describe, it, beforeEach */
|
||||
|
||||
var assert = require('assert')
|
||||
var crypto = require('../src/crypto')
|
||||
var networks = require('../src/networks')
|
||||
|
@ -10,10 +12,10 @@ var curve = ecurve.getCurveByName('secp256k1')
|
|||
|
||||
var fixtures = require('./fixtures/ecpubkey.json')
|
||||
|
||||
describe('ECPubKey', function() {
|
||||
describe('ECPubKey', function () {
|
||||
var Q
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
Q = ecurve.Point.fromAffine(
|
||||
curve,
|
||||
new BigInteger(fixtures.Q.x),
|
||||
|
@ -21,21 +23,21 @@ describe('ECPubKey', function() {
|
|||
)
|
||||
})
|
||||
|
||||
describe('constructor', function() {
|
||||
it('defaults to compressed', function() {
|
||||
describe('constructor', function () {
|
||||
it('defaults to compressed', function () {
|
||||
var pubKey = new ECPubKey(Q)
|
||||
|
||||
assert.equal(pubKey.compressed, true)
|
||||
})
|
||||
|
||||
it('supports the uncompressed flag', function() {
|
||||
it('supports the uncompressed flag', function () {
|
||||
var pubKey = new ECPubKey(Q, false)
|
||||
|
||||
assert.equal(pubKey.compressed, false)
|
||||
})
|
||||
})
|
||||
|
||||
it('uses the secp256k1 curve by default', function() {
|
||||
it('uses the secp256k1 curve by default', function () {
|
||||
var secp256k1 = ecurve.getCurveByName('secp256k1')
|
||||
|
||||
for (var property in secp256k1) {
|
||||
|
@ -50,8 +52,8 @@ describe('ECPubKey', function() {
|
|||
}
|
||||
})
|
||||
|
||||
describe('fromHex/toHex', function() {
|
||||
it('supports compressed points', function() {
|
||||
describe('fromHex/toHex', function () {
|
||||
it('supports compressed points', function () {
|
||||
var pubKey = ECPubKey.fromHex(fixtures.compressed.hex)
|
||||
|
||||
assert(pubKey.Q.equals(Q))
|
||||
|
@ -59,7 +61,7 @@ describe('ECPubKey', function() {
|
|||
assert.equal(pubKey.compressed, true)
|
||||
})
|
||||
|
||||
it('supports uncompressed points', function() {
|
||||
it('supports uncompressed points', function () {
|
||||
var pubKey = ECPubKey.fromHex(fixtures.uncompressed.hex)
|
||||
|
||||
assert(pubKey.Q.equals(Q))
|
||||
|
@ -68,22 +70,22 @@ describe('ECPubKey', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('getAddress', function() {
|
||||
it('calculates the expected hash (compressed)', function() {
|
||||
describe('getAddress', function () {
|
||||
it('calculates the expected hash (compressed)', function () {
|
||||
var pubKey = new ECPubKey(Q, true)
|
||||
var address = pubKey.getAddress()
|
||||
|
||||
assert.equal(address.hash.toString('hex'), fixtures.compressed.hash160)
|
||||
})
|
||||
|
||||
it('calculates the expected hash (uncompressed)', function() {
|
||||
it('calculates the expected hash (uncompressed)', function () {
|
||||
var pubKey = new ECPubKey(Q, false)
|
||||
var address = pubKey.getAddress()
|
||||
|
||||
assert.equal(address.hash.toString('hex'), fixtures.uncompressed.hash160)
|
||||
})
|
||||
|
||||
it('supports alternative networks', function() {
|
||||
it('supports alternative networks', function () {
|
||||
var pubKey = new ECPubKey(Q)
|
||||
var address = pubKey.getAddress(networks.testnet)
|
||||
|
||||
|
@ -92,9 +94,9 @@ describe('ECPubKey', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('verify', function() {
|
||||
describe('verify', function () {
|
||||
var pubKey, signature
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
pubKey = new ECPubKey(Q)
|
||||
|
||||
signature = {
|
||||
|
@ -103,13 +105,13 @@ describe('ECPubKey', function() {
|
|||
}
|
||||
})
|
||||
|
||||
it('verifies a valid signature', function() {
|
||||
it('verifies a valid signature', function () {
|
||||
var hash = crypto.sha256(fixtures.message)
|
||||
|
||||
assert(pubKey.verify(hash, signature))
|
||||
})
|
||||
|
||||
it('doesn\'t verify the wrong signature', function() {
|
||||
it("doesn't verify the wrong signature", function () {
|
||||
var hash = crypto.sha256('mushrooms')
|
||||
|
||||
assert(!pubKey.verify(hash, signature))
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* global describe, it */
|
||||
|
||||
var assert = require('assert')
|
||||
|
||||
var BigInteger = require('bigi')
|
||||
|
@ -5,13 +7,13 @@ var ECSignature = require('../src/ecsignature')
|
|||
|
||||
var fixtures = require('./fixtures/ecsignature.json')
|
||||
|
||||
describe('ECSignature', function() {
|
||||
describe('toCompact', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('exports ' + f.compact.hex + ' correctly', function() {
|
||||
describe('ECSignature', function () {
|
||||
describe('toCompact', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('exports ' + f.compact.hex + ' correctly', function () {
|
||||
var signature = new ECSignature(
|
||||
new BigInteger(f.signature.r),
|
||||
new BigInteger(f.signature.s)
|
||||
new BigInteger(f.signature.r),
|
||||
new BigInteger(f.signature.s)
|
||||
)
|
||||
|
||||
var buffer = signature.toCompact(f.compact.i, f.compact.compressed)
|
||||
|
@ -20,9 +22,9 @@ describe('ECSignature', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('parseCompact', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('imports ' + f.compact.hex + ' correctly', function() {
|
||||
describe('parseCompact', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('imports ' + f.compact.hex + ' correctly', function () {
|
||||
var buffer = new Buffer(f.compact.hex, 'hex')
|
||||
var parsed = ECSignature.parseCompact(buffer)
|
||||
|
||||
|
@ -33,23 +35,23 @@ describe('ECSignature', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.compact.forEach(function(f) {
|
||||
it('throws on ' + f.hex, function() {
|
||||
fixtures.invalid.compact.forEach(function (f) {
|
||||
it('throws on ' + f.hex, function () {
|
||||
var buffer = new Buffer(f.hex, 'hex')
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
ECSignature.parseCompact(buffer)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('toDER', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('exports ' + f.DER + ' correctly', function() {
|
||||
describe('toDER', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('exports ' + f.DER + ' correctly', function () {
|
||||
var signature = new ECSignature(
|
||||
new BigInteger(f.signature.r),
|
||||
new BigInteger(f.signature.s)
|
||||
new BigInteger(f.signature.r),
|
||||
new BigInteger(f.signature.s)
|
||||
)
|
||||
|
||||
var DER = signature.toDER()
|
||||
|
@ -58,9 +60,9 @@ describe('ECSignature', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('fromDER', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('imports ' + f.DER + ' correctly', function() {
|
||||
describe('fromDER', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('imports ' + f.DER + ' correctly', function () {
|
||||
var buffer = new Buffer(f.DER, 'hex')
|
||||
var signature = ECSignature.fromDER(buffer)
|
||||
|
||||
|
@ -69,23 +71,23 @@ describe('ECSignature', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.DER.forEach(function(f) {
|
||||
it('throws on ' + f.hex, function() {
|
||||
fixtures.invalid.DER.forEach(function (f) {
|
||||
it('throws on ' + f.hex, function () {
|
||||
var buffer = new Buffer(f.hex, 'hex')
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
ECSignature.fromDER(buffer)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('toScriptSignature', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('exports ' + f.scriptSignature.hex + ' correctly', function() {
|
||||
describe('toScriptSignature', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('exports ' + f.scriptSignature.hex + ' correctly', function () {
|
||||
var signature = new ECSignature(
|
||||
new BigInteger(f.signature.r),
|
||||
new BigInteger(f.signature.s)
|
||||
new BigInteger(f.signature.r),
|
||||
new BigInteger(f.signature.s)
|
||||
)
|
||||
|
||||
var scriptSignature = signature.toScriptSignature(f.scriptSignature.hashType)
|
||||
|
@ -93,23 +95,23 @@ describe('ECSignature', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.scriptSignature.forEach(function(f) {
|
||||
it('throws ' + f.exception, function() {
|
||||
fixtures.invalid.scriptSignature.forEach(function (f) {
|
||||
it('throws ' + f.exception, function () {
|
||||
var signature = new ECSignature(
|
||||
new BigInteger(f.signature.r),
|
||||
new BigInteger(f.signature.s)
|
||||
new BigInteger(f.signature.r),
|
||||
new BigInteger(f.signature.s)
|
||||
)
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
signature.toScriptSignature(f.hashType)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('parseScriptSignature', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('imports ' + f.scriptSignature.hex + ' correctly', function() {
|
||||
describe('parseScriptSignature', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('imports ' + f.scriptSignature.hex + ' correctly', function () {
|
||||
var buffer = new Buffer(f.scriptSignature.hex, 'hex')
|
||||
var parsed = ECSignature.parseScriptSignature(buffer)
|
||||
|
||||
|
@ -119,11 +121,11 @@ describe('ECSignature', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.scriptSignature.forEach(function(f) {
|
||||
it('throws on ' + f.hex, function() {
|
||||
fixtures.invalid.scriptSignature.forEach(function (f) {
|
||||
it('throws on ' + f.hex, function () {
|
||||
var buffer = new Buffer(f.hex, 'hex')
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
ECSignature.parseScriptSignature(buffer)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
|
|
150
test/hdnode.js
150
test/hdnode.js
|
@ -1,3 +1,6 @@
|
|||
/* global describe, it */
|
||||
/* eslint-disable no-new */
|
||||
|
||||
var assert = require('assert')
|
||||
var networks = require('../src/networks')
|
||||
|
||||
|
@ -11,50 +14,50 @@ var curve = ecurve.getCurveByName('secp256k1')
|
|||
|
||||
var fixtures = require('./fixtures/hdnode.json')
|
||||
|
||||
describe('HDNode', function() {
|
||||
describe('Constructor', function() {
|
||||
describe('HDNode', function () {
|
||||
describe('Constructor', function () {
|
||||
var d = BigInteger.ONE
|
||||
var Q = curve.G.multiply(d)
|
||||
var chainCode = new Buffer(32)
|
||||
chainCode.fill(1)
|
||||
|
||||
it('calculates the publicKey from a BigInteger', function() {
|
||||
it('calculates the publicKey from a BigInteger', function () {
|
||||
var hd = new HDNode(d, chainCode)
|
||||
|
||||
assert(hd.pubKey.Q.equals(Q))
|
||||
})
|
||||
|
||||
it('allows initialization directly from an ECKey', function() {
|
||||
it('allows initialization directly from an ECKey', function () {
|
||||
var ek = new ECKey(d)
|
||||
var hd = new HDNode(ek, chainCode)
|
||||
|
||||
assert.equal(hd.privKey, ek)
|
||||
})
|
||||
|
||||
it('allows initialization directly from an ECPubKey', function() {
|
||||
it('allows initialization directly from an ECPubKey', function () {
|
||||
var ek = new ECPubKey(Q)
|
||||
var hd = new HDNode(ek, chainCode)
|
||||
|
||||
assert.equal(hd.pubKey, ek)
|
||||
})
|
||||
|
||||
it('throws if ECKey is not compressed', function() {
|
||||
it('throws if ECKey is not compressed', function () {
|
||||
var ek = new ECKey(d, false)
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
new HDNode(ek, chainCode)
|
||||
}, /ECKey must be compressed/)
|
||||
})
|
||||
|
||||
it('throws if ECPubKey is not compressed', function() {
|
||||
it('throws if ECPubKey is not compressed', function () {
|
||||
var ek = new ECPubKey(Q, false)
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
new HDNode(ek, chainCode)
|
||||
}, /ECPubKey must be compressed/)
|
||||
})
|
||||
|
||||
it('only uses compressed points', function() {
|
||||
it('only uses compressed points', function () {
|
||||
var hd = new HDNode(Q, chainCode)
|
||||
var hdP = new HDNode(d, chainCode)
|
||||
|
||||
|
@ -62,41 +65,41 @@ describe('HDNode', function() {
|
|||
assert.strictEqual(hdP.pubKey.compressed, true)
|
||||
})
|
||||
|
||||
it('has a default depth/index of 0', function() {
|
||||
it('has a default depth/index of 0', function () {
|
||||
var hd = new HDNode(Q, chainCode)
|
||||
|
||||
assert.strictEqual(hd.depth, 0)
|
||||
assert.strictEqual(hd.index, 0)
|
||||
})
|
||||
|
||||
it('defaults to the bitcoin network', function() {
|
||||
it('defaults to the bitcoin network', function () {
|
||||
var hd = new HDNode(Q, chainCode)
|
||||
|
||||
assert.equal(hd.network, networks.bitcoin)
|
||||
})
|
||||
|
||||
it('supports alternative networks', function() {
|
||||
it('supports alternative networks', function () {
|
||||
var hd = new HDNode(Q, chainCode, networks.testnet)
|
||||
|
||||
assert.equal(hd.network, networks.testnet)
|
||||
})
|
||||
|
||||
it('throws when an invalid length chain code is given', function() {
|
||||
assert.throws(function() {
|
||||
it('throws when an invalid length chain code is given', function () {
|
||||
assert.throws(function () {
|
||||
new HDNode(d, chainCode.slice(0, 20), networks.testnet)
|
||||
}, /Expected chainCode length of 32, got 20/)
|
||||
})
|
||||
|
||||
it('throws when an unknown network is given', function() {
|
||||
assert.throws(function() {
|
||||
it('throws when an unknown network is given', function () {
|
||||
assert.throws(function () {
|
||||
new HDNode(d, chainCode, {})
|
||||
}, /Unknown BIP32 constants for network/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('fromSeed*', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('calculates privKey and chainCode for ' + f.master.fingerprint, function() {
|
||||
describe('fromSeed*', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('calculates privKey and chainCode for ' + f.master.fingerprint, function () {
|
||||
var network = networks[f.network]
|
||||
var hd = HDNode.fromSeedHex(f.master.seed, network)
|
||||
|
||||
|
@ -105,22 +108,22 @@ describe('HDNode', function() {
|
|||
})
|
||||
})
|
||||
|
||||
it('throws on low entropy seed', function() {
|
||||
assert.throws(function() {
|
||||
it('throws on low entropy seed', function () {
|
||||
assert.throws(function () {
|
||||
HDNode.fromSeedHex('ffffffffff')
|
||||
}, /Seed should be at least 128 bits/)
|
||||
})
|
||||
|
||||
it('throws on too high entropy seed', function() {
|
||||
assert.throws(function() {
|
||||
it('throws on too high entropy seed', function () {
|
||||
assert.throws(function () {
|
||||
HDNode.fromSeedHex('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff')
|
||||
}, /Seed should be at most 512 bits/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('toBase58', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('exports ' + f.master.base58 + ' (public) correctly', function() {
|
||||
describe('toBase58', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('exports ' + f.master.base58 + ' (public) correctly', function () {
|
||||
var network = networks[f.network]
|
||||
var hd = HDNode.fromSeedHex(f.master.seed, network).neutered()
|
||||
|
||||
|
@ -128,8 +131,8 @@ describe('HDNode', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('exports ' + f.master.base58Priv + ' (private) correctly', function() {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('exports ' + f.master.base58Priv + ' (private) correctly', function () {
|
||||
var network = networks[f.network]
|
||||
var hd = HDNode.fromSeedHex(f.master.seed, network)
|
||||
|
||||
|
@ -138,35 +141,35 @@ describe('HDNode', function() {
|
|||
})
|
||||
|
||||
// FIXME: remove in 2.x.y
|
||||
it('fails when there is no private key', function() {
|
||||
it('fails when there is no private key', function () {
|
||||
var hd = HDNode.fromBase58(fixtures.valid[0].master.base58)
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
hd.toBase58(true)
|
||||
}, /Missing private key/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('fromBase58', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('imports ' + f.master.base58 + ' (public) correctly', function() {
|
||||
describe('fromBase58', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('imports ' + f.master.base58 + ' (public) correctly', function () {
|
||||
var hd = HDNode.fromBase58(f.master.base58)
|
||||
|
||||
assert.equal(hd.toBase58(), f.master.base58)
|
||||
})
|
||||
})
|
||||
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('imports ' + f.master.base58Priv + ' (private) correctly', function() {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('imports ' + f.master.base58Priv + ' (private) correctly', function () {
|
||||
var hd = HDNode.fromBase58(f.master.base58Priv)
|
||||
|
||||
assert.equal(hd.toBase58(), f.master.base58Priv)
|
||||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.fromBase58.forEach(function(f) {
|
||||
it('throws on ' + f.string, function() {
|
||||
assert.throws(function() {
|
||||
fixtures.invalid.fromBase58.forEach(function (f) {
|
||||
it('throws on ' + f.string, function () {
|
||||
assert.throws(function () {
|
||||
var network = networks[f.network]
|
||||
|
||||
HDNode.fromBase58(f.string, network)
|
||||
|
@ -175,43 +178,43 @@ describe('HDNode', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('fromBuffer/fromHex', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('imports ' + f.master.hex + ' (public) correctly', function() {
|
||||
describe('fromBuffer/fromHex', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('imports ' + f.master.hex + ' (public) correctly', function () {
|
||||
var hd = HDNode.fromHex(f.master.hex)
|
||||
|
||||
assert.equal(hd.toBuffer().toString('hex'), f.master.hex)
|
||||
})
|
||||
})
|
||||
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('imports ' + f.master.hexPriv + ' (private) correctly', function() {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('imports ' + f.master.hexPriv + ' (private) correctly', function () {
|
||||
var hd = HDNode.fromHex(f.master.hexPriv)
|
||||
|
||||
assert.equal(hd.toBuffer().toString('hex'), f.master.hexPriv)
|
||||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.fromBuffer.forEach(function(f) {
|
||||
it('throws on ' + f.hex, function() {
|
||||
assert.throws(function() {
|
||||
fixtures.invalid.fromBuffer.forEach(function (f) {
|
||||
it('throws on ' + f.hex, function () {
|
||||
assert.throws(function () {
|
||||
HDNode.fromHex(f.hex)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('toBuffer/toHex', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('exports ' + f.master.hex + ' (public) correctly', function() {
|
||||
describe('toBuffer/toHex', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('exports ' + f.master.hex + ' (public) correctly', function () {
|
||||
var hd = HDNode.fromSeedHex(f.master.seed).neutered()
|
||||
|
||||
assert.equal(hd.toHex(), f.master.hex)
|
||||
})
|
||||
})
|
||||
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('exports ' + f.master.hexPriv + ' (private) correctly', function() {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('exports ' + f.master.hexPriv + ' (private) correctly', function () {
|
||||
var network = networks[f.network]
|
||||
var hd = HDNode.fromSeedHex(f.master.seed, network)
|
||||
|
||||
|
@ -220,38 +223,38 @@ describe('HDNode', function() {
|
|||
})
|
||||
|
||||
// FIXME: remove in 2.x.y
|
||||
it('fails when there is no private key', function() {
|
||||
it('fails when there is no private key', function () {
|
||||
var hd = HDNode.fromHex(fixtures.valid[0].master.hex)
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
hd.toHex(true)
|
||||
}, /Missing private key/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getIdentifier', function() {
|
||||
describe('getIdentifier', function () {
|
||||
var f = fixtures.valid[0]
|
||||
|
||||
it('returns the identifier for ' + f.master.fingerprint, function() {
|
||||
it('returns the identifier for ' + f.master.fingerprint, function () {
|
||||
var hd = HDNode.fromBase58(f.master.base58)
|
||||
|
||||
assert.equal(hd.getIdentifier().toString('hex'), f.master.identifier)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getFingerprint', function() {
|
||||
describe('getFingerprint', function () {
|
||||
var f = fixtures.valid[0]
|
||||
|
||||
it('returns the fingerprint for ' + f.master.fingerprint, function() {
|
||||
it('returns the fingerprint for ' + f.master.fingerprint, function () {
|
||||
var hd = HDNode.fromBase58(f.master.base58)
|
||||
|
||||
assert.equal(hd.getFingerprint().toString('hex'), f.master.fingerprint)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getAddress', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('returns ' + f.master.address + ' for ' + f.master.fingerprint, function() {
|
||||
describe('getAddress', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('returns ' + f.master.address + ' for ' + f.master.fingerprint, function () {
|
||||
var hd = HDNode.fromBase58(f.master.base58)
|
||||
|
||||
assert.equal(hd.getAddress().toString(), f.master.address)
|
||||
|
@ -259,10 +262,10 @@ describe('HDNode', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('neutered', function() {
|
||||
describe('neutered', function () {
|
||||
var f = fixtures.valid[0]
|
||||
|
||||
it('strips all private information', function() {
|
||||
it('strips all private information', function () {
|
||||
var hd = HDNode.fromBase58(f.master.base58)
|
||||
var hdn = hd.neutered()
|
||||
|
||||
|
@ -274,8 +277,8 @@ describe('HDNode', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('derive', function() {
|
||||
function verifyVector(hd, network, v, depth) {
|
||||
describe('derive', function () {
|
||||
function verifyVector (hd, network, v, depth) {
|
||||
assert.equal(hd.privKey.toWIF(network), v.wif)
|
||||
assert.equal(hd.pubKey.toHex(), v.pubKey)
|
||||
assert.equal(hd.chainCode.toString('hex'), v.chainCode)
|
||||
|
@ -288,16 +291,15 @@ describe('HDNode', function() {
|
|||
}
|
||||
}
|
||||
|
||||
fixtures.valid.forEach(function(f) {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
var network = networks[f.network]
|
||||
var hd = HDNode.fromSeedHex(f.master.seed, network)
|
||||
|
||||
// FIXME: test data is only testing Private -> private for now
|
||||
f.children.forEach(function(c, i) {
|
||||
it(c.description + ' from ' + f.master.fingerprint, function() {
|
||||
f.children.forEach(function (c, i) {
|
||||
it(c.description + ' from ' + f.master.fingerprint, function () {
|
||||
if (c.hardened) {
|
||||
hd = hd.deriveHardened(c.m)
|
||||
|
||||
} else {
|
||||
hd = hd.derive(c.m)
|
||||
}
|
||||
|
@ -307,7 +309,7 @@ describe('HDNode', function() {
|
|||
})
|
||||
})
|
||||
|
||||
it('works for Private -> public (neutered)', function() {
|
||||
it('works for Private -> public (neutered)', function () {
|
||||
var f = fixtures.valid[1]
|
||||
var c = f.children[0]
|
||||
|
||||
|
@ -317,7 +319,7 @@ describe('HDNode', function() {
|
|||
assert.equal(child.toBase58(), c.base58)
|
||||
})
|
||||
|
||||
it('works for Private -> public (neutered, hardened)', function() {
|
||||
it('works for Private -> public (neutered, hardened)', function () {
|
||||
var f = fixtures.valid[0]
|
||||
var c = f.children[0]
|
||||
|
||||
|
@ -327,7 +329,7 @@ describe('HDNode', function() {
|
|||
assert.equal(child.toBase58(), c.base58)
|
||||
})
|
||||
|
||||
it('works for Public -> public', function() {
|
||||
it('works for Public -> public', function () {
|
||||
var f = fixtures.valid[1]
|
||||
var c = f.children[0]
|
||||
|
||||
|
@ -337,13 +339,13 @@ describe('HDNode', function() {
|
|||
assert.equal(child.toBase58(), c.base58)
|
||||
})
|
||||
|
||||
it('throws on Public -> public (hardened)', function() {
|
||||
it('throws on Public -> public (hardened)', function () {
|
||||
var f = fixtures.valid[0]
|
||||
var c = f.children[0]
|
||||
|
||||
var master = HDNode.fromBase58(f.master.base58)
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
master.deriveHardened(c.m)
|
||||
}, /Could not derive hardened child key/)
|
||||
})
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
/* global describe, it */
|
||||
|
||||
var assert = require('assert')
|
||||
var bitcoin = require('../../')
|
||||
var blockchain = new (require('cb-helloblock'))('testnet')
|
||||
|
||||
describe('bitcoinjs-lib (advanced)', function() {
|
||||
it('can sign a Bitcoin message', function() {
|
||||
describe('bitcoinjs-lib (advanced)', function () {
|
||||
it('can sign a Bitcoin message', function () {
|
||||
var key = bitcoin.ECKey.fromWIF('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss')
|
||||
var message = 'This is an example of a signed message.'
|
||||
|
||||
|
@ -11,7 +13,7 @@ describe('bitcoinjs-lib (advanced)', function() {
|
|||
assert.equal(signature.toString('base64'), 'G9L5yLFjti0QTHhPyFrZCT1V/MMnBtXKmoiKDZ78NDBjERki6ZTQZdSMCtkgoNmp17By9ItJr8o7ChX0XxY91nk=')
|
||||
})
|
||||
|
||||
it('can verify a Bitcoin message', function() {
|
||||
it('can verify a Bitcoin message', function () {
|
||||
var address = '1HZwkjkeaoZfTSaJxDw6aKkxp45agDiEzN'
|
||||
var signature = 'HJLQlDWLyb1Ef8bQKEISzFbDAKctIlaqOpGbrk3YVtRsjmC61lpE5ErkPRUFtDKtx98vHFGUWlFhsh3DiW6N0rE'
|
||||
var message = 'This is an example of a signed message.'
|
||||
|
@ -19,16 +21,16 @@ describe('bitcoinjs-lib (advanced)', function() {
|
|||
assert(bitcoin.Message.verify(address, signature, message))
|
||||
})
|
||||
|
||||
it('can create an OP_RETURN transaction', function(done) {
|
||||
it('can create an OP_RETURN transaction', function (done) {
|
||||
this.timeout(20000)
|
||||
|
||||
var key = bitcoin.ECKey.fromWIF("L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy")
|
||||
var key = bitcoin.ECKey.fromWIF('L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy')
|
||||
var address = key.pub.getAddress(bitcoin.networks.testnet).toString()
|
||||
|
||||
blockchain.addresses.__faucetWithdraw(address, 2e4, function(err) {
|
||||
blockchain.addresses.__faucetWithdraw(address, 2e4, function (err) {
|
||||
if (err) return done(err)
|
||||
|
||||
blockchain.addresses.unspents(address, function(err, unspents) {
|
||||
blockchain.addresses.unspents(address, function (err, unspents) {
|
||||
if (err) return done(err)
|
||||
|
||||
var tx = new bitcoin.TransactionBuilder()
|
||||
|
@ -43,11 +45,11 @@ describe('bitcoinjs-lib (advanced)', function() {
|
|||
|
||||
var txBuilt = tx.build()
|
||||
|
||||
blockchain.transactions.propagate(txBuilt.toHex(), function(err) {
|
||||
blockchain.transactions.propagate(txBuilt.toHex(), function (err) {
|
||||
if (err) return done(err)
|
||||
|
||||
// check that the message was propagated
|
||||
blockchain.transactions.get(txBuilt.getId(), function(err, transaction) {
|
||||
// check that the message was propagated
|
||||
blockchain.transactions.get(txBuilt.getId(), function (err, transaction) {
|
||||
if (err) return done(err)
|
||||
|
||||
var actual = bitcoin.Transaction.fromHex(transaction.txHex)
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
/* global describe, it */
|
||||
|
||||
var assert = require('assert')
|
||||
var bigi = require('bigi')
|
||||
var bitcoin = require('../../')
|
||||
var crypto = require('crypto')
|
||||
var sinon = require('sinon')
|
||||
|
||||
describe('bitcoinjs-lib (basic)', function() {
|
||||
it('can generate a random bitcoin address', sinon.test(function() {
|
||||
describe('bitcoinjs-lib (basic)', function () {
|
||||
it('can generate a random bitcoin address', sinon.test(function () {
|
||||
// for testing only
|
||||
this.mock(crypto).expects('randomBytes')
|
||||
.onCall(0).returns(new Buffer('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'))
|
||||
|
@ -17,7 +19,7 @@ describe('bitcoinjs-lib (basic)', function() {
|
|||
assert.equal(address, '1F5VhMHukdnUES9kfXqzPzMeF1GPHKiF64')
|
||||
}))
|
||||
|
||||
it('can generate an address from a SHA256 hash', function() {
|
||||
it('can generate an address from a SHA256 hash', function () {
|
||||
var hash = bitcoin.crypto.sha256('correct horse battery staple')
|
||||
var d = bigi.fromBuffer(hash)
|
||||
|
||||
|
@ -26,19 +28,19 @@ describe('bitcoinjs-lib (basic)', function() {
|
|||
assert.equal(key.pub.getAddress().toString(), '1C7zdTfnkzmr13HfA2vNm5SJYRK6nEKyq8')
|
||||
})
|
||||
|
||||
it('can import an address via WIF', function() {
|
||||
it('can import an address via WIF', function () {
|
||||
var key = bitcoin.ECKey.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct')
|
||||
var address = key.pub.getAddress().toString()
|
||||
|
||||
assert.equal(address, '19AAjaTUbRjQCMuVczepkoPswiZRhjtg31')
|
||||
})
|
||||
|
||||
it('can create a Transaction', function() {
|
||||
var key = bitcoin.ECKey.fromWIF("L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy")
|
||||
it('can create a Transaction', function () {
|
||||
var key = bitcoin.ECKey.fromWIF('L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy')
|
||||
var tx = new bitcoin.TransactionBuilder()
|
||||
|
||||
tx.addInput("aa94ab02c182214f090e99a0d57021caffd0f195a81c24602b1028b130b63e31", 0)
|
||||
tx.addOutput("1Gokm82v6DmtwKEB8AiVhm82hyFSsEvBDK", 15000)
|
||||
tx.addInput('aa94ab02c182214f090e99a0d57021caffd0f195a81c24602b1028b130b63e31', 0)
|
||||
tx.addOutput('1Gokm82v6DmtwKEB8AiVhm82hyFSsEvBDK', 15000)
|
||||
tx.sign(0, key)
|
||||
|
||||
assert.equal(tx.build().toHex(), '0100000001313eb630b128102b60241ca895f1d0ffca2170d5a0990e094f2182c102ab94aa000000006b483045022100aefbcf847900b01dd3e3debe054d3b6d03d715d50aea8525f5ea3396f168a1fb022013d181d05b15b90111808b22ef4f9ebe701caf2ab48db269691fdf4e9048f4f60121029f50f51d63b345039a290c94bffd3180c99ed659ff6ea6b1242bca47eb93b59fffffffff01983a0000000000001976a914ad618cf4333b3b248f9744e8e81db2964d0ae39788ac00000000')
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* global describe, it */
|
||||
|
||||
var assert = require('assert')
|
||||
var async = require('async')
|
||||
var bigi = require('bigi')
|
||||
|
@ -5,8 +7,8 @@ var bitcoin = require('../../')
|
|||
var blockchain = new (require('cb-helloblock'))('bitcoin')
|
||||
var crypto = require('crypto')
|
||||
|
||||
describe('bitcoinjs-lib (crypto)', function() {
|
||||
it('can generate a single-key stealth address', function() {
|
||||
describe('bitcoinjs-lib (crypto)', function () {
|
||||
it('can generate a single-key stealth address', function () {
|
||||
var receiver = bitcoin.ECKey.fromWIF('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss')
|
||||
|
||||
// XXX: ephemeral, must be random (and secret to sender) to preserve privacy
|
||||
|
@ -39,10 +41,10 @@ describe('bitcoinjs-lib (crypto)', function() {
|
|||
})
|
||||
|
||||
// TODO
|
||||
it.skip('can generate a dual-key stealth address', function() {})
|
||||
it.skip('can generate a dual-key stealth address', function () {})
|
||||
|
||||
it('can recover a parent private key from the parent\'s public key and a derived non-hardened child private key', function() {
|
||||
function recoverParent(master, child) {
|
||||
it("can recover a parent private key from the parent's public key and a derived non-hardened child private key", function () {
|
||||
function recoverParent (master, child) {
|
||||
assert(!master.privKey, 'You already have the parent private key')
|
||||
assert(child.privKey, 'Missing child private key')
|
||||
|
||||
|
@ -87,33 +89,35 @@ describe('bitcoinjs-lib (crypto)', function() {
|
|||
assert.equal(recovered.toBase58(), master.toBase58())
|
||||
})
|
||||
|
||||
it('can recover a private key from duplicate R values', function() {
|
||||
it('can recover a private key from duplicate R values', function () {
|
||||
var inputs = [
|
||||
{
|
||||
txId: "f4c16475f2a6e9c602e4a287f9db3040e319eb9ece74761a4b84bc820fbeef50",
|
||||
txId: 'f4c16475f2a6e9c602e4a287f9db3040e319eb9ece74761a4b84bc820fbeef50',
|
||||
vout: 0
|
||||
},
|
||||
{
|
||||
txId: "f4c16475f2a6e9c602e4a287f9db3040e319eb9ece74761a4b84bc820fbeef50",
|
||||
txId: 'f4c16475f2a6e9c602e4a287f9db3040e319eb9ece74761a4b84bc820fbeef50',
|
||||
vout: 1
|
||||
}
|
||||
]
|
||||
|
||||
var txIds = inputs.map(function(x) { return x.txId })
|
||||
var txIds = inputs.map(function (x) {
|
||||
return x.txId
|
||||
})
|
||||
|
||||
// first retrieve the relevant transactions
|
||||
blockchain.transactions.get(txIds, function(err, results) {
|
||||
blockchain.transactions.get(txIds, function (err, results) {
|
||||
assert.ifError(err)
|
||||
|
||||
var transactions = {}
|
||||
results.forEach(function(tx) {
|
||||
results.forEach(function (tx) {
|
||||
transactions[tx.txId] = bitcoin.Transaction.fromHex(tx.txHex)
|
||||
})
|
||||
|
||||
var tasks = []
|
||||
|
||||
// now we need to collect/transform a bit of data from the selected inputs
|
||||
inputs.forEach(function(input) {
|
||||
inputs.forEach(function (input) {
|
||||
var transaction = transactions[input.txId]
|
||||
var script = transaction.ins[input.vout].script
|
||||
assert(bitcoin.scripts.isPubKeyHashInput(script), 'Expected pubKeyHash script')
|
||||
|
@ -121,8 +125,8 @@ describe('bitcoinjs-lib (crypto)', function() {
|
|||
var prevOutTxId = bitcoin.bufferutils.reverse(transaction.ins[input.vout].hash).toString('hex')
|
||||
var prevVout = transaction.ins[input.vout].index
|
||||
|
||||
tasks.push(function(callback) {
|
||||
blockchain.transactions.get(prevOutTxId, function(err, result) {
|
||||
tasks.push(function (callback) {
|
||||
blockchain.transactions.get(prevOutTxId, function (err, result) {
|
||||
if (err) return callback(err)
|
||||
|
||||
var prevOut = bitcoin.Transaction.fromHex(result.txHex)
|
||||
|
@ -144,8 +148,9 @@ describe('bitcoinjs-lib (crypto)', function() {
|
|||
})
|
||||
|
||||
// finally, run the tasks, then on to the math
|
||||
async.parallel(tasks, function(err) {
|
||||
if (err) throw err
|
||||
async.parallel(tasks, function (err) {
|
||||
if (err)
|
||||
throw err
|
||||
var n = bitcoin.ECKey.curve.n
|
||||
|
||||
for (var i = 0; i < inputs.length; ++i) {
|
||||
|
@ -170,8 +175,8 @@ describe('bitcoinjs-lib (crypto)', function() {
|
|||
// d1 = (s1 * k - z1) / r
|
||||
// d2 = (s2 * k - z2) / r
|
||||
var k = zz.multiply(ss.modInverse(n)).mod(n)
|
||||
var d1 = (( s1.multiply(k).mod(n) ).subtract(z1).mod(n) ).multiply(rInv).mod(n)
|
||||
var d2 = (( s2.multiply(k).mod(n) ).subtract(z2).mod(n) ).multiply(rInv).mod(n)
|
||||
var d1 = ((s1.multiply(k).mod(n)).subtract(z1).mod(n)).multiply(rInv).mod(n)
|
||||
var d2 = ((s2.multiply(k).mod(n)).subtract(z2).mod(n)).multiply(rInv).mod(n)
|
||||
|
||||
// enforce matching private keys
|
||||
assert.equal(d1.toString(), d2.toString())
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
/* global describe, it */
|
||||
|
||||
var assert = require('assert')
|
||||
var bitcoin = require('../../')
|
||||
var blockchain = new (require('cb-helloblock'))('testnet')
|
||||
|
||||
describe('bitcoinjs-lib (multisig)', function() {
|
||||
it('can create a 2-of-3 multisig P2SH address', function() {
|
||||
describe('bitcoinjs-lib (multisig)', function () {
|
||||
it('can create a 2-of-3 multisig P2SH address', function () {
|
||||
var pubKeys = [
|
||||
'026477115981fe981a6918a6297d9803c4dc04f328f22041bedff886bbc2962e01',
|
||||
'02c96db2302d19b43d4c69368babace7854cc84eb9e061cde51cfa77ca4a22b8b9',
|
||||
|
@ -17,29 +19,33 @@ describe('bitcoinjs-lib (multisig)', function() {
|
|||
assert.equal(address, '36NUkt6FWUi3LAWBqWRdDmdTWbt91Yvfu7')
|
||||
})
|
||||
|
||||
it('can spend from a 2-of-2 multsig P2SH address', function(done) {
|
||||
it('can spend from a 2-of-2 multsig P2SH address', function (done) {
|
||||
this.timeout(20000)
|
||||
|
||||
var privKeys = [
|
||||
'91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx',
|
||||
'91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgww7vXtT'
|
||||
].map(bitcoin.ECKey.fromWIF)
|
||||
var pubKeys = privKeys.map(function(x) { return x.pub })
|
||||
var pubKeys = privKeys.map(function (x) {
|
||||
return x.pub
|
||||
})
|
||||
|
||||
var redeemScript = bitcoin.scripts.multisigOutput(2, pubKeys) // 2 of 2
|
||||
var scriptPubKey = bitcoin.scripts.scriptHashOutput(redeemScript.getHash())
|
||||
var address = bitcoin.Address.fromOutputScript(scriptPubKey, bitcoin.networks.testnet).toString()
|
||||
|
||||
// Attempt to send funds to the source address
|
||||
blockchain.addresses.__faucetWithdraw(address, 2e4, function(err) {
|
||||
blockchain.addresses.__faucetWithdraw(address, 2e4, function (err) {
|
||||
if (err) return done(err)
|
||||
|
||||
// get latest unspents from the address
|
||||
blockchain.addresses.unspents(address, function(err, unspents) {
|
||||
// get latest unspents from the address
|
||||
blockchain.addresses.unspents(address, function (err, unspents) {
|
||||
if (err) return done(err)
|
||||
|
||||
// filter small unspents
|
||||
unspents = unspents.filter(function(unspent) { return unspent.value > 1e4 })
|
||||
// filter small unspents
|
||||
unspents = unspents.filter(function (unspent) {
|
||||
return unspent.value > 1e4
|
||||
})
|
||||
|
||||
// use the oldest unspent
|
||||
var unspent = unspents.pop()
|
||||
|
@ -52,16 +58,16 @@ describe('bitcoinjs-lib (multisig)', function() {
|
|||
txb.addOutput(targetAddress, 1e4)
|
||||
|
||||
// sign w/ each private key
|
||||
privKeys.forEach(function(privKey) {
|
||||
privKeys.forEach(function (privKey) {
|
||||
txb.sign(0, privKey, redeemScript)
|
||||
})
|
||||
|
||||
// broadcast our transaction
|
||||
blockchain.transactions.propagate(txb.build().toHex(), function(err) {
|
||||
blockchain.transactions.propagate(txb.build().toHex(), function (err) {
|
||||
if (err) return done(err)
|
||||
|
||||
// check that the funds (1e4 Satoshis) indeed arrived at the intended address
|
||||
blockchain.addresses.summary(targetAddress, function(err, result) {
|
||||
// check that the funds (1e4 Satoshis) indeed arrived at the intended address
|
||||
blockchain.addresses.summary(targetAddress, function (err, result) {
|
||||
if (err) return done(err)
|
||||
|
||||
assert.equal(result.balance, 1e4)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* global describe, it */
|
||||
|
||||
var assert = require('assert')
|
||||
var networks = require('../src/networks')
|
||||
|
||||
|
@ -8,10 +10,10 @@ var Message = require('../src/message')
|
|||
|
||||
var fixtures = require('./fixtures/message.json')
|
||||
|
||||
describe('Message', function() {
|
||||
describe('magicHash', function() {
|
||||
fixtures.valid.magicHash.forEach(function(f) {
|
||||
it('produces the correct magicHash for \"' + f.message + '\" (' + f.network + ')', function() {
|
||||
describe('Message', function () {
|
||||
describe('magicHash', function () {
|
||||
fixtures.valid.magicHash.forEach(function (f) {
|
||||
it('produces the correct magicHash for "' + f.message + '" (' + f.network + ')', function () {
|
||||
var network = networks[f.network]
|
||||
var actual = Message.magicHash(f.message, network)
|
||||
|
||||
|
@ -20,8 +22,8 @@ describe('Message', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('verify', function() {
|
||||
it('accepts an Address object', function() {
|
||||
describe('verify', function () {
|
||||
it('accepts an Address object', function () {
|
||||
var f = fixtures.valid.verify[0]
|
||||
var network = networks[f.network]
|
||||
|
||||
|
@ -29,8 +31,8 @@ describe('Message', function() {
|
|||
assert(Message.verify(address, f.signature, f.message, network))
|
||||
})
|
||||
|
||||
fixtures.valid.verify.forEach(function(f) {
|
||||
it('verifies a valid signature for \"' + f.message + '\" (' + f.network + ')', function() {
|
||||
fixtures.valid.verify.forEach(function (f) {
|
||||
it('verifies a valid signature for "' + f.message + '" (' + f.network + ')', function () {
|
||||
var network = networks[f.network]
|
||||
|
||||
assert(Message.verify(f.address, f.signature, f.message, network))
|
||||
|
@ -41,16 +43,16 @@ describe('Message', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.verify.forEach(function(f) {
|
||||
it(f.description, function() {
|
||||
fixtures.invalid.verify.forEach(function (f) {
|
||||
it(f.description, function () {
|
||||
assert(!Message.verify(f.address, f.signature, f.message))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('signing', function() {
|
||||
fixtures.valid.signing.forEach(function(f) {
|
||||
it(f.description, function() {
|
||||
describe('signing', function () {
|
||||
fixtures.valid.signing.forEach(function (f) {
|
||||
it(f.description, function () {
|
||||
var network = networks[f.network]
|
||||
|
||||
var privKey = new ECKey(new BigInteger(f.d), false)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* global describe, it, before, after */
|
||||
|
||||
var assert = require('assert')
|
||||
var networks = require('../src/networks')
|
||||
var sinon = require('sinon')
|
||||
|
@ -7,36 +9,36 @@ var Transaction = require('../src/transaction')
|
|||
|
||||
var fixtures = require('./fixtures/network')
|
||||
|
||||
describe('networks', function() {
|
||||
describe('networks', function () {
|
||||
var txToBuffer
|
||||
before(function(){
|
||||
txToBuffer = sinon.stub(Transaction.prototype, "toBuffer")
|
||||
before(function () {
|
||||
txToBuffer = sinon.stub(Transaction.prototype, 'toBuffer')
|
||||
})
|
||||
|
||||
after(function(){
|
||||
after(function () {
|
||||
Transaction.prototype.toBuffer.restore()
|
||||
})
|
||||
|
||||
describe('constants', function() {
|
||||
fixtures.valid.constants.forEach(function(f) {
|
||||
describe('constants', function () {
|
||||
fixtures.valid.constants.forEach(function (f) {
|
||||
var network = networks[f.network]
|
||||
|
||||
Object.keys(f.bip32).forEach(function(name) {
|
||||
Object.keys(f.bip32).forEach(function (name) {
|
||||
var extb58 = f.bip32[name]
|
||||
|
||||
it('resolves ' + extb58 + ' to ' + f.network, function() {
|
||||
it('resolves ' + extb58 + ' to ' + f.network, function () {
|
||||
assert.equal(HDNode.fromBase58(extb58, network).network, network)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('estimateFee', function() {
|
||||
fixtures.valid.estimateFee.forEach(function(f) {
|
||||
describe('(' + f.network + ')', function() {
|
||||
describe('estimateFee', function () {
|
||||
fixtures.valid.estimateFee.forEach(function (f) {
|
||||
describe('(' + f.network + ')', function () {
|
||||
var network = networks[f.network]
|
||||
|
||||
it('calculates the fee correctly for ' + f.description, function() {
|
||||
it('calculates the fee correctly for ' + f.description, function () {
|
||||
var buffer = new Buffer(f.txSize)
|
||||
txToBuffer.returns(buffer)
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
/* global describe, it */
|
||||
/* eslint-disable no-new */
|
||||
|
||||
var assert = require('assert')
|
||||
var opcodes = require('../src/opcodes')
|
||||
|
||||
|
@ -5,9 +8,9 @@ var Script = require('../src/script')
|
|||
|
||||
var fixtures = require('./fixtures/script.json')
|
||||
|
||||
describe('Script', function() {
|
||||
describe('constructor', function() {
|
||||
it('accepts valid parameters', function() {
|
||||
describe('Script', function () {
|
||||
describe('constructor', function () {
|
||||
it('accepts valid parameters', function () {
|
||||
var buffer = new Buffer([1])
|
||||
var chunks = [1]
|
||||
var script = new Script(buffer, chunks)
|
||||
|
@ -16,30 +19,32 @@ describe('Script', function() {
|
|||
assert.equal(script.chunks, chunks)
|
||||
})
|
||||
|
||||
it('throws an error when input is not an array', function() {
|
||||
assert.throws(function(){ new Script({}) }, /Expected Buffer, got/)
|
||||
it('throws an error when input is not an array', function () {
|
||||
assert.throws(function () {
|
||||
new Script({})
|
||||
}, /Expected Buffer, got/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('fromASM/toASM', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('decodes/encodes ' + f.description, function() {
|
||||
describe('fromASM/toASM', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('decodes/encodes ' + f.description, function () {
|
||||
assert.equal(Script.fromASM(f.asm).toASM(), f.asm)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('fromHex/toHex', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('decodes/encodes ' + f.description, function() {
|
||||
describe('fromHex/toHex', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('decodes/encodes ' + f.description, function () {
|
||||
assert.equal(Script.fromHex(f.hex).toHex(), f.hex)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('getHash', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('produces a HASH160 of \"' + f.asm + '\"', function() {
|
||||
describe('getHash', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('produces a HASH160 of "' + f.asm + '"', function () {
|
||||
var script = Script.fromHex(f.hex)
|
||||
|
||||
assert.equal(script.getHash().toString('hex'), f.hash)
|
||||
|
@ -47,8 +52,8 @@ describe('Script', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('fromChunks', function() {
|
||||
it('should match expected behaviour', function() {
|
||||
describe('fromChunks', function () {
|
||||
it('should match expected behaviour', function () {
|
||||
var hash = new Buffer(32)
|
||||
hash.fill(0)
|
||||
|
||||
|
@ -62,17 +67,17 @@ describe('Script', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('without', function() {
|
||||
describe('without', function () {
|
||||
var hex = 'a914e8c300c87986efa94c37c0519929019ef86eb5b487'
|
||||
var script = Script.fromHex(hex)
|
||||
|
||||
it('should return a script without the given value', function() {
|
||||
it('should return a script without the given value', function () {
|
||||
var subScript = script.without(opcodes.OP_HASH160)
|
||||
|
||||
assert.equal(subScript.toHex(), '14e8c300c87986efa94c37c0519929019ef86eb5b487')
|
||||
})
|
||||
|
||||
it('shouldnt mutate the original script', function() {
|
||||
it('shouldnt mutate the original script', function () {
|
||||
var subScript = script.without(opcodes.OP_EQUAL)
|
||||
|
||||
assert.notEqual(subScript.toHex(), hex)
|
||||
|
|
120
test/scripts.js
120
test/scripts.js
|
@ -1,3 +1,5 @@
|
|||
/* global describe, it */
|
||||
|
||||
var assert = require('assert')
|
||||
var ops = require('../src/opcodes')
|
||||
var scripts = require('../src/scripts')
|
||||
|
@ -7,16 +9,16 @@ var Script = require('../src/script')
|
|||
|
||||
var fixtures = require('./fixtures/scripts.json')
|
||||
|
||||
describe('Scripts', function() {
|
||||
describe('Scripts', function () {
|
||||
// TODO
|
||||
describe.skip('isCanonicalPubKey', function() {})
|
||||
describe.skip('isCanonicalSignature', function() {})
|
||||
describe.skip('isCanonicalPubKey', function () {})
|
||||
describe.skip('isCanonicalSignature', function () {})
|
||||
|
||||
describe('classifyInput', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('classifyInput', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
if (!f.scriptSig) return
|
||||
|
||||
it('classifies ' + f.scriptSig + ' as ' + f.type, function() {
|
||||
it('classifies ' + f.scriptSig + ' as ' + f.type, function () {
|
||||
var script = Script.fromASM(f.scriptSig)
|
||||
var type = scripts.classifyInput(script)
|
||||
|
||||
|
@ -24,11 +26,11 @@ describe('Scripts', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.valid.forEach(function(f) {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
if (!f.scriptSig) return
|
||||
if (!f.typeIncomplete) return
|
||||
|
||||
it('classifies incomplete ' + f.scriptSig + ' as ' + f.typeIncomplete, function() {
|
||||
it('classifies incomplete ' + f.scriptSig + ' as ' + f.typeIncomplete, function () {
|
||||
var script = Script.fromASM(f.scriptSig)
|
||||
var type = scripts.classifyInput(script, true)
|
||||
|
||||
|
@ -37,11 +39,11 @@ describe('Scripts', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('classifyOutput', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('classifyOutput', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
if (!f.scriptPubKey) return
|
||||
|
||||
it('classifies ' + f.scriptPubKey + ' as ' + f.type, function() {
|
||||
it('classifies ' + f.scriptPubKey + ' as ' + f.type, function () {
|
||||
var script = Script.fromASM(f.scriptPubKey)
|
||||
var type = scripts.classifyOutput(script)
|
||||
|
||||
|
@ -50,19 +52,19 @@ describe('Scripts', function() {
|
|||
})
|
||||
})
|
||||
|
||||
;['PubKey', 'PubKeyHash', 'ScriptHash', 'Multisig', 'NullData'].forEach(function(type) {
|
||||
;['PubKey', 'PubKeyHash', 'ScriptHash', 'Multisig', 'NullData'].forEach(function (type) {
|
||||
var inputFnName = 'is' + type + 'Input'
|
||||
var outputFnName = 'is' + type + 'Output'
|
||||
|
||||
var inputFn = scripts[inputFnName]
|
||||
var outputFn= scripts[outputFnName]
|
||||
var outputFn = scripts[outputFnName]
|
||||
|
||||
describe('is' + type + 'Input', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('is' + type + 'Input', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
var expected = type.toLowerCase() === f.type
|
||||
|
||||
if (inputFn && f.scriptSig) {
|
||||
it('returns ' + expected + ' for ' + f.scriptSig, function() {
|
||||
it('returns ' + expected + ' for ' + f.scriptSig, function () {
|
||||
var script = Script.fromASM(f.scriptSig)
|
||||
|
||||
assert.equal(inputFn(script), expected)
|
||||
|
@ -71,7 +73,7 @@ describe('Scripts', function() {
|
|||
if (f.typeIncomplete) {
|
||||
var expectedIncomplete = type.toLowerCase() === f.typeIncomplete
|
||||
|
||||
it('returns ' + expected + ' for ' + f.scriptSig, function() {
|
||||
it('returns ' + expected + ' for ' + f.scriptSig, function () {
|
||||
var script = Script.fromASM(f.scriptSig)
|
||||
|
||||
assert.equal(inputFn(script, true), expectedIncomplete)
|
||||
|
@ -82,9 +84,9 @@ describe('Scripts', function() {
|
|||
|
||||
if (!(inputFnName in fixtures.invalid)) return
|
||||
|
||||
fixtures.invalid[inputFnName].forEach(function(f) {
|
||||
fixtures.invalid[inputFnName].forEach(function (f) {
|
||||
if (inputFn && f.scriptSig) {
|
||||
it('returns false for ' + f.scriptSig, function() {
|
||||
it('returns false for ' + f.scriptSig, function () {
|
||||
var script = Script.fromASM(f.scriptSig)
|
||||
|
||||
assert.equal(inputFn(script), false)
|
||||
|
@ -93,12 +95,12 @@ describe('Scripts', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('is' + type + 'Output', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('is' + type + 'Output', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
var expected = type.toLowerCase() === f.type
|
||||
|
||||
if (outputFn && f.scriptPubKey) {
|
||||
it('returns ' + expected + ' for ' + f.scriptPubKey, function() {
|
||||
it('returns ' + expected + ' for ' + f.scriptPubKey, function () {
|
||||
var script = Script.fromASM(f.scriptPubKey)
|
||||
|
||||
assert.equal(outputFn(script), expected)
|
||||
|
@ -108,9 +110,9 @@ describe('Scripts', function() {
|
|||
|
||||
if (!(outputFnName in fixtures.invalid)) return
|
||||
|
||||
fixtures.invalid[outputFnName].forEach(function(f) {
|
||||
fixtures.invalid[outputFnName].forEach(function (f) {
|
||||
if (outputFn && f.scriptPubKey) {
|
||||
it('returns false for ' + f.scriptPubKey, function() {
|
||||
it('returns false for ' + f.scriptPubKey, function () {
|
||||
var script = Script.fromASM(f.scriptPubKey)
|
||||
|
||||
assert.equal(outputFn(script), false)
|
||||
|
@ -120,11 +122,11 @@ describe('Scripts', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('pubKeyInput', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('pubKeyInput', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
if (f.type !== 'pubkey') return
|
||||
|
||||
it('returns ' + f.scriptSig, function() {
|
||||
it('returns ' + f.scriptSig, function () {
|
||||
var signature = new Buffer(f.signature, 'hex')
|
||||
|
||||
var scriptSig = scripts.pubKeyInput(signature)
|
||||
|
@ -133,11 +135,11 @@ describe('Scripts', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('pubKeyOutput', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('pubKeyOutput', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
if (f.type !== 'pubkey') return
|
||||
|
||||
it('returns ' + f.scriptPubKey, function() {
|
||||
it('returns ' + f.scriptPubKey, function () {
|
||||
var pubKey = ECPubKey.fromHex(f.pubKey)
|
||||
|
||||
var scriptPubKey = scripts.pubKeyOutput(pubKey)
|
||||
|
@ -146,13 +148,13 @@ describe('Scripts', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('pubKeyHashInput', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('pubKeyHashInput', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
if (f.type !== 'pubkeyhash') return
|
||||
|
||||
var pubKey = ECPubKey.fromHex(f.pubKey)
|
||||
|
||||
it('returns ' + f.scriptSig, function() {
|
||||
it('returns ' + f.scriptSig, function () {
|
||||
var signature = new Buffer(f.signature, 'hex')
|
||||
|
||||
var scriptSig = scripts.pubKeyHashInput(signature, pubKey)
|
||||
|
@ -161,26 +163,26 @@ describe('Scripts', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('pubKeyHashOutput', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('pubKeyHashOutput', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
if (f.type !== 'pubkeyhash') return
|
||||
|
||||
var pubKey = ECPubKey.fromHex(f.pubKey)
|
||||
var address = pubKey.getAddress()
|
||||
|
||||
it('returns ' + f.scriptPubKey, function() {
|
||||
it('returns ' + f.scriptPubKey, function () {
|
||||
var scriptPubKey = scripts.pubKeyHashOutput(address.hash)
|
||||
assert.equal(scriptPubKey.toASM(), f.scriptPubKey)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('multisigInput', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('multisigInput', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
if (f.type !== 'multisig') return
|
||||
|
||||
it('returns ' + f.scriptSig, function() {
|
||||
var signatures = f.signatures.map(function(signature) {
|
||||
it('returns ' + f.scriptSig, function () {
|
||||
var signatures = f.signatures.map(function (signature) {
|
||||
return signature ? new Buffer(signature, 'hex') : ops.OP_0
|
||||
})
|
||||
|
||||
|
@ -189,53 +191,53 @@ describe('Scripts', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.multisigInput.forEach(function(f) {
|
||||
fixtures.invalid.multisigInput.forEach(function (f) {
|
||||
var pubKeys = f.pubKeys.map(ECPubKey.fromHex)
|
||||
var scriptPubKey = scripts.multisigOutput(pubKeys.length, pubKeys)
|
||||
|
||||
it('throws on ' + f.exception, function() {
|
||||
var signatures = f.signatures.map(function(signature) {
|
||||
it('throws on ' + f.exception, function () {
|
||||
var signatures = f.signatures.map(function (signature) {
|
||||
return signature ? new Buffer(signature, 'hex') : ops.OP_0
|
||||
})
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
scripts.multisigInput(signatures, scriptPubKey)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('multisigOutput', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('multisigOutput', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
if (f.type !== 'multisig') return
|
||||
|
||||
var pubKeys = f.pubKeys.map(ECPubKey.fromHex)
|
||||
var scriptPubKey = scripts.multisigOutput(pubKeys.length, pubKeys)
|
||||
|
||||
it('returns ' + f.scriptPubKey, function() {
|
||||
it('returns ' + f.scriptPubKey, function () {
|
||||
assert.equal(scriptPubKey.toASM(), f.scriptPubKey)
|
||||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.multisigOutput.forEach(function(f) {
|
||||
fixtures.invalid.multisigOutput.forEach(function (f) {
|
||||
var pubKeys = f.pubKeys.map(ECPubKey.fromHex)
|
||||
|
||||
it('throws on ' + f.exception, function() {
|
||||
assert.throws(function() {
|
||||
it('throws on ' + f.exception, function () {
|
||||
assert.throws(function () {
|
||||
scripts.multisigOutput(f.m, pubKeys)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('scriptHashInput', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('scriptHashInput', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
if (f.type !== 'scripthash') return
|
||||
|
||||
var redeemScript = Script.fromASM(f.redeemScript)
|
||||
var redeemScriptSig = Script.fromASM(f.redeemScriptSig)
|
||||
|
||||
it('returns ' + f.scriptSig, function() {
|
||||
it('returns ' + f.scriptSig, function () {
|
||||
var scriptSig = scripts.scriptHashInput(redeemScriptSig, redeemScript)
|
||||
|
||||
assert.equal(scriptSig.toASM(), f.scriptSig)
|
||||
|
@ -243,13 +245,13 @@ describe('Scripts', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('scriptHashOutput', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('scriptHashOutput', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
if (f.type !== 'scripthash') return
|
||||
|
||||
var redeemScript = Script.fromASM(f.redeemScript)
|
||||
|
||||
it('returns ' + f.scriptPubKey, function() {
|
||||
it('returns ' + f.scriptPubKey, function () {
|
||||
var scriptPubKey = scripts.scriptHashOutput(redeemScript.getHash())
|
||||
|
||||
assert.equal(scriptPubKey.toASM(), f.scriptPubKey)
|
||||
|
@ -257,14 +259,14 @@ describe('Scripts', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('nullDataOutput', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('nullDataOutput', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
if (f.type !== 'nulldata') return
|
||||
|
||||
var data = new Buffer(f.data, 'hex')
|
||||
var scriptPubKey = scripts.nullDataOutput(data)
|
||||
|
||||
it('returns ' + f.scriptPubKey, function() {
|
||||
it('returns ' + f.scriptPubKey, function () {
|
||||
assert.equal(scriptPubKey.toASM(), f.scriptPubKey)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* global describe, it, beforeEach */
|
||||
|
||||
var assert = require('assert')
|
||||
var scripts = require('../src/scripts')
|
||||
|
||||
|
@ -8,19 +10,18 @@ var Script = require('../src/script')
|
|||
|
||||
var fixtures = require('./fixtures/transaction')
|
||||
|
||||
describe('Transaction', function() {
|
||||
function fromRaw(raw) {
|
||||
describe('Transaction', function () {
|
||||
function fromRaw (raw) {
|
||||
var tx = new Transaction()
|
||||
tx.version = raw.version
|
||||
tx.locktime = raw.locktime
|
||||
|
||||
raw.ins.forEach(function(txIn) {
|
||||
raw.ins.forEach(function (txIn) {
|
||||
var txHash = new Buffer(txIn.hash, 'hex')
|
||||
var script
|
||||
|
||||
if (txIn.data) {
|
||||
script = new Script(new Buffer(txIn.data, 'hex'), [])
|
||||
|
||||
} else if (txIn.script) {
|
||||
script = Script.fromASM(txIn.script)
|
||||
}
|
||||
|
@ -28,34 +29,34 @@ describe('Transaction', function() {
|
|||
tx.addInput(txHash, txIn.index, txIn.sequence, script)
|
||||
})
|
||||
|
||||
raw.outs.forEach(function(txOut) {
|
||||
raw.outs.forEach(function (txOut) {
|
||||
tx.addOutput(Script.fromASM(txOut.script), txOut.value)
|
||||
})
|
||||
|
||||
return tx
|
||||
}
|
||||
|
||||
describe('fromBuffer/fromHex', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('imports ' + f.id + ' correctly', function() {
|
||||
describe('fromBuffer/fromHex', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('imports ' + f.id + ' correctly', function () {
|
||||
var actual = Transaction.fromHex(f.hex)
|
||||
|
||||
assert.deepEqual(actual.toHex(), f.hex)
|
||||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.fromBuffer.forEach(function(f) {
|
||||
it('throws on ' + f.exception, function() {
|
||||
assert.throws(function() {
|
||||
fixtures.invalid.fromBuffer.forEach(function (f) {
|
||||
it('throws on ' + f.exception, function () {
|
||||
assert.throws(function () {
|
||||
Transaction.fromHex(f.hex)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('toBuffer/toHex', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('exports ' + f.id + ' correctly', function() {
|
||||
describe('toBuffer/toHex', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('exports ' + f.id + ' correctly', function () {
|
||||
var actual = fromRaw(f.raw)
|
||||
|
||||
assert.deepEqual(actual.toHex(), f.hex)
|
||||
|
@ -63,81 +64,81 @@ describe('Transaction', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('addInput', function() {
|
||||
describe('addInput', function () {
|
||||
// FIXME: not as pretty as could be
|
||||
// Probably a bit representative of the API
|
||||
var prevTxHash, prevTxId, prevTx
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
var f = fixtures.valid[0]
|
||||
prevTx = Transaction.fromHex(f.hex)
|
||||
prevTxHash = prevTx.getHash()
|
||||
prevTxId = prevTx.getId()
|
||||
})
|
||||
|
||||
it('accepts a transaction id', function() {
|
||||
it('accepts a transaction id', function () {
|
||||
var tx = new Transaction()
|
||||
tx.addInput(prevTxId, 0)
|
||||
|
||||
assert.deepEqual(tx.ins[0].hash, prevTxHash)
|
||||
})
|
||||
|
||||
it('accepts a transaction hash', function() {
|
||||
it('accepts a transaction hash', function () {
|
||||
var tx = new Transaction()
|
||||
tx.addInput(prevTxHash, 0)
|
||||
|
||||
assert.deepEqual(tx.ins[0].hash, prevTxHash)
|
||||
})
|
||||
|
||||
it('accepts a Transaction object', function() {
|
||||
it('accepts a Transaction object', function () {
|
||||
var tx = new Transaction()
|
||||
tx.addInput(prevTx, 0)
|
||||
|
||||
assert.deepEqual(tx.ins[0].hash, prevTxHash)
|
||||
})
|
||||
|
||||
it('returns an index', function() {
|
||||
it('returns an index', function () {
|
||||
var tx = new Transaction()
|
||||
assert.equal(tx.addInput(prevTxHash, 0), 0)
|
||||
assert.equal(tx.addInput(prevTxHash, 0), 1)
|
||||
})
|
||||
|
||||
it('defaults to DEFAULT_SEQUENCE', function() {
|
||||
it('defaults to DEFAULT_SEQUENCE', function () {
|
||||
var tx = new Transaction()
|
||||
tx.addInput(prevTxHash, 0)
|
||||
|
||||
assert.equal(tx.ins[0].sequence, Transaction.DEFAULT_SEQUENCE)
|
||||
})
|
||||
|
||||
it('defaults to empty script', function() {
|
||||
it('defaults to empty script', function () {
|
||||
var tx = new Transaction()
|
||||
tx.addInput(prevTxHash, 0)
|
||||
|
||||
assert.equal(tx.ins[0].script, Script.EMPTY)
|
||||
})
|
||||
|
||||
fixtures.invalid.addInput.forEach(function(f) {
|
||||
it('throws on ' + f.exception, function() {
|
||||
fixtures.invalid.addInput.forEach(function (f) {
|
||||
it('throws on ' + f.exception, function () {
|
||||
var tx = new Transaction()
|
||||
var hash = new Buffer(f.hash, 'hex')
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
tx.addInput(hash, f.index)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('addOutput', function() {
|
||||
describe('addOutput', function () {
|
||||
// FIXME: not as pretty as could be
|
||||
// Probably a bit representative of the API
|
||||
var destAddressB58, destAddress, destScript
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
destAddressB58 = '15mMHKL96tWAUtqF3tbVf99Z8arcmnJrr3'
|
||||
destAddress = Address.fromBase58Check(destAddressB58)
|
||||
destScript = destAddress.toOutputScript()
|
||||
})
|
||||
|
||||
it('accepts an address string', function() {
|
||||
it('accepts an address string', function () {
|
||||
var tx = new Transaction()
|
||||
tx.addOutput(destAddressB58, 40000)
|
||||
|
||||
|
@ -145,7 +146,7 @@ describe('Transaction', function() {
|
|||
assert.equal(tx.outs[0].value, 40000)
|
||||
})
|
||||
|
||||
it('accepts an Address', function() {
|
||||
it('accepts an Address', function () {
|
||||
var tx = new Transaction()
|
||||
tx.addOutput(destAddress, 40000)
|
||||
|
||||
|
@ -153,7 +154,7 @@ describe('Transaction', function() {
|
|||
assert.equal(tx.outs[0].value, 40000)
|
||||
})
|
||||
|
||||
it('accepts a scriptPubKey', function() {
|
||||
it('accepts a scriptPubKey', function () {
|
||||
var tx = new Transaction()
|
||||
tx.addOutput(destScript, 40000)
|
||||
|
||||
|
@ -161,35 +162,35 @@ describe('Transaction', function() {
|
|||
assert.equal(tx.outs[0].value, 40000)
|
||||
})
|
||||
|
||||
it('returns an index', function() {
|
||||
it('returns an index', function () {
|
||||
var tx = new Transaction()
|
||||
assert.equal(tx.addOutput(destScript, 40000), 0)
|
||||
assert.equal(tx.addOutput(destScript, 40000), 1)
|
||||
})
|
||||
})
|
||||
|
||||
describe('clone', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
describe('clone', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
var actual, expected
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
expected = Transaction.fromHex(f.hex)
|
||||
actual = expected.clone()
|
||||
})
|
||||
|
||||
it('should have value equality', function() {
|
||||
it('should have value equality', function () {
|
||||
assert.deepEqual(actual, expected)
|
||||
})
|
||||
|
||||
it('should not have reference equality', function() {
|
||||
it('should not have reference equality', function () {
|
||||
assert.notEqual(actual, expected)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('getId', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('should return the id for ' + f.id, function() {
|
||||
describe('getId', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('should return the id for ' + f.id, function () {
|
||||
var tx = Transaction.fromHex(f.hex)
|
||||
var actual = tx.getId()
|
||||
|
||||
|
@ -198,9 +199,9 @@ describe('Transaction', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('getHash', function() {
|
||||
fixtures.valid.forEach(function(f) {
|
||||
it('should return the hash for ' + f.id, function() {
|
||||
describe('getHash', function () {
|
||||
fixtures.valid.forEach(function (f) {
|
||||
it('should return the hash for ' + f.id, function () {
|
||||
var tx = Transaction.fromHex(f.hex)
|
||||
var actual = tx.getHash().toString('hex')
|
||||
|
||||
|
@ -213,8 +214,8 @@ describe('Transaction', function() {
|
|||
// hashForSignature: [Function],
|
||||
|
||||
// FIXME: remove in 2.x.y
|
||||
describe('signInput/validateInput', function() {
|
||||
it('works for multi-sig redeem script', function() {
|
||||
describe('signInput/validateInput', function () {
|
||||
it('works for multi-sig redeem script', function () {
|
||||
var tx = new Transaction()
|
||||
tx.addInput('d6f72aab8ff86ff6289842a0424319bf2ddba85dc7c52757912297f948286389', 0)
|
||||
tx.addOutput('mrCDrCybB6J1vRfbwM5hemdJz73FwDBC8r', 1)
|
||||
|
@ -222,13 +223,15 @@ describe('Transaction', function() {
|
|||
var privKeys = [
|
||||
'5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf',
|
||||
'5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAvUcVfH'
|
||||
].map(function(wif) {
|
||||
].map(function (wif) {
|
||||
return ECKey.fromWIF(wif)
|
||||
})
|
||||
var pubKeys = privKeys.map(function(eck) { return eck.pub })
|
||||
var pubKeys = privKeys.map(function (eck) {
|
||||
return eck.pub
|
||||
})
|
||||
var redeemScript = scripts.multisigOutput(2, pubKeys)
|
||||
|
||||
var signatures = privKeys.map(function(privKey) {
|
||||
var signatures = privKeys.map(function (privKey) {
|
||||
return tx.signInput(0, redeemScript, privKey)
|
||||
})
|
||||
|
||||
|
@ -236,7 +239,7 @@ describe('Transaction', function() {
|
|||
var scriptSig = scripts.scriptHashInput(redeemScriptSig, redeemScript)
|
||||
tx.setInputScript(0, scriptSig)
|
||||
|
||||
signatures.forEach(function(sig, i){
|
||||
signatures.forEach(function (sig, i) {
|
||||
assert(tx.validateInput(0, redeemScript, privKeys[i].pub, sig))
|
||||
})
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* global describe, it, beforeEach */
|
||||
|
||||
var assert = require('assert')
|
||||
|
||||
var BigInteger = require('bigi')
|
||||
|
@ -8,8 +10,8 @@ var TransactionBuilder = require('../src/transaction_builder')
|
|||
|
||||
var fixtures = require('./fixtures/transaction_builder')
|
||||
|
||||
function construct(txb, f, sign) {
|
||||
f.inputs.forEach(function(input) {
|
||||
function construct (txb, f, sign) {
|
||||
f.inputs.forEach(function (input) {
|
||||
var prevTxScript
|
||||
|
||||
if (input.prevTxScript) {
|
||||
|
@ -19,15 +21,15 @@ function construct(txb, f, sign) {
|
|||
txb.addInput(input.txId, input.vout, input.sequence, prevTxScript)
|
||||
})
|
||||
|
||||
f.outputs.forEach(function(output) {
|
||||
f.outputs.forEach(function (output) {
|
||||
var script = Script.fromASM(output.script)
|
||||
|
||||
txb.addOutput(script, output.value)
|
||||
})
|
||||
|
||||
if (sign === undefined || sign) {
|
||||
f.inputs.forEach(function(input, index) {
|
||||
input.signs.forEach(function(sign) {
|
||||
f.inputs.forEach(function (input, index) {
|
||||
input.signs.forEach(function (sign) {
|
||||
var privKey = ECKey.fromWIF(sign.privKey)
|
||||
var redeemScript
|
||||
|
||||
|
@ -41,17 +43,19 @@ function construct(txb, f, sign) {
|
|||
}
|
||||
|
||||
// FIXME: add support for locktime/version in TransactionBuilder API
|
||||
if (f.version !== undefined) txb.tx.version = f.version
|
||||
if (f.locktime !== undefined) txb.tx.locktime = f.locktime
|
||||
if (f.version !== undefined)
|
||||
txb.tx.version = f.version
|
||||
if (f.locktime !== undefined)
|
||||
txb.tx.locktime = f.locktime
|
||||
}
|
||||
|
||||
describe('TransactionBuilder', function() {
|
||||
describe('TransactionBuilder', function () {
|
||||
var privAddress, privScript
|
||||
var prevTx, prevTxHash
|
||||
var privKey
|
||||
var txb
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
txb = new TransactionBuilder()
|
||||
|
||||
prevTx = new Transaction()
|
||||
|
@ -64,8 +68,8 @@ describe('TransactionBuilder', function() {
|
|||
privScript = privAddress.toOutputScript()
|
||||
})
|
||||
|
||||
describe('addInput', function() {
|
||||
it('accepts a txHash, index [and sequence number]', function() {
|
||||
describe('addInput', function () {
|
||||
it('accepts a txHash, index [and sequence number]', function () {
|
||||
var vin = txb.addInput(prevTxHash, 1, 54)
|
||||
assert.equal(vin, 0)
|
||||
|
||||
|
@ -76,7 +80,7 @@ describe('TransactionBuilder', function() {
|
|||
assert.equal(txb.inputs[0].prevOutScript, undefined)
|
||||
})
|
||||
|
||||
it('accepts a txHash, index [, sequence number and scriptPubKey]', function() {
|
||||
it('accepts a txHash, index [, sequence number and scriptPubKey]', function () {
|
||||
var vin = txb.addInput(prevTxHash, 1, 54, prevTx.outs[1].script)
|
||||
assert.equal(vin, 0)
|
||||
|
||||
|
@ -87,7 +91,7 @@ describe('TransactionBuilder', function() {
|
|||
assert.equal(txb.inputs[0].prevOutScript, prevTx.outs[1].script)
|
||||
})
|
||||
|
||||
it('accepts a prevTx, index [and sequence number]', function() {
|
||||
it('accepts a prevTx, index [and sequence number]', function () {
|
||||
var vin = txb.addInput(prevTx, 1, 54)
|
||||
assert.equal(vin, 0)
|
||||
|
||||
|
@ -98,40 +102,40 @@ describe('TransactionBuilder', function() {
|
|||
assert.equal(txb.inputs[0].prevOutScript, prevTx.outs[1].script)
|
||||
})
|
||||
|
||||
it('returns the input index', function() {
|
||||
it('returns the input index', function () {
|
||||
assert.equal(txb.addInput(prevTxHash, 0), 0)
|
||||
assert.equal(txb.addInput(prevTxHash, 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', function () {
|
||||
txb.addInput(prevTxHash, 0)
|
||||
txb.sign(0, privKey)
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
txb.addInput(prevTxHash, 0)
|
||||
}, /No, this would invalidate signatures/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('addOutput', function() {
|
||||
it('throws if SIGHASH_ALL has been used to sign any existing scriptSigs', function() {
|
||||
describe('addOutput', function () {
|
||||
it('throws if SIGHASH_ALL has been used to sign any existing scriptSigs', function () {
|
||||
txb.addInput(prevTxHash, 0)
|
||||
txb.addOutput(privScript, 2000)
|
||||
txb.sign(0, privKey)
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
txb.addOutput(privScript, 9000)
|
||||
}, /No, this would invalidate signatures/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('sign', function() {
|
||||
fixtures.invalid.sign.forEach(function(f) {
|
||||
it('throws on ' + f.exception + ' (' + f.description + ')', function() {
|
||||
describe('sign', function () {
|
||||
fixtures.invalid.sign.forEach(function (f) {
|
||||
it('throws on ' + f.exception + ' (' + f.description + ')', function () {
|
||||
construct(txb, f, false)
|
||||
|
||||
f.inputs.forEach(function(input, index) {
|
||||
input.signs.forEach(function(sign) {
|
||||
f.inputs.forEach(function (input, index) {
|
||||
input.signs.forEach(function (sign) {
|
||||
var privKey = ECKey.fromWIF(sign.privKey)
|
||||
var redeemScript
|
||||
|
||||
|
@ -141,9 +145,8 @@ describe('TransactionBuilder', function() {
|
|||
|
||||
if (!sign.throws) {
|
||||
txb.sign(index, privKey, redeemScript, sign.hashType)
|
||||
|
||||
} else {
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
txb.sign(index, privKey, redeemScript, sign.hashType)
|
||||
}, new RegExp(f.exception))
|
||||
}
|
||||
|
@ -153,9 +156,9 @@ describe('TransactionBuilder', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('build', function() {
|
||||
fixtures.valid.build.forEach(function(f) {
|
||||
it('builds \"' + f.description + '\"', function() {
|
||||
describe('build', function () {
|
||||
fixtures.valid.build.forEach(function (f) {
|
||||
it('builds "' + f.description + '"', function () {
|
||||
construct(txb, f)
|
||||
|
||||
var tx = txb.build()
|
||||
|
@ -163,35 +166,34 @@ describe('TransactionBuilder', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.build.forEach(function(f) {
|
||||
describe('for ' + (f.description || f.exception), function() {
|
||||
beforeEach(function() {
|
||||
fixtures.invalid.build.forEach(function (f) {
|
||||
describe('for ' + (f.description || f.exception), function () {
|
||||
beforeEach(function () {
|
||||
if (f.txHex) {
|
||||
var tx = Transaction.fromHex(f.txHex)
|
||||
txb = TransactionBuilder.fromTransaction(tx)
|
||||
|
||||
} else {
|
||||
construct(txb, f)
|
||||
}
|
||||
})
|
||||
|
||||
it('throws', function() {
|
||||
assert.throws(function() {
|
||||
it('throws', function () {
|
||||
assert.throws(function () {
|
||||
txb.build()
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
|
||||
if (f.alwaysThrows) return
|
||||
it('doesn\'t throw if building incomplete', function() {
|
||||
it("doesn't throw if building incomplete", function () {
|
||||
txb.buildIncomplete()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('fromTransaction', function() {
|
||||
fixtures.valid.build.forEach(function(f) {
|
||||
it('builds the correct TransactionBuilder for ' + f.description, function() {
|
||||
describe('fromTransaction', function () {
|
||||
fixtures.valid.build.forEach(function (f) {
|
||||
it('builds the correct TransactionBuilder for ' + f.description, function () {
|
||||
var tx = Transaction.fromHex(f.txHex)
|
||||
var txb = TransactionBuilder.fromTransaction(tx)
|
||||
|
||||
|
@ -199,25 +201,25 @@ describe('TransactionBuilder', function() {
|
|||
})
|
||||
})
|
||||
|
||||
fixtures.invalid.fromTransaction.forEach(function(f) {
|
||||
it('throws on ' + f.exception, function() {
|
||||
fixtures.invalid.fromTransaction.forEach(function (f) {
|
||||
it('throws on ' + f.exception, function () {
|
||||
var tx = Transaction.fromHex(f.txHex)
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
TransactionBuilder.fromTransaction(tx)
|
||||
}, new RegExp(f.exception))
|
||||
})
|
||||
})
|
||||
|
||||
it('works for the out-of-order P2SH multisig case', function() {
|
||||
it('works for the out-of-order P2SH multisig case', function () {
|
||||
var privKeys = [
|
||||
"91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgww7vXtT",
|
||||
"91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx"
|
||||
'91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgww7vXtT',
|
||||
'91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx'
|
||||
].map(ECKey.fromWIF)
|
||||
var redeemScript = Script.fromASM("OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a OP_2 OP_CHECKMULTISIG")
|
||||
var redeemScript = Script.fromASM('OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a OP_2 OP_CHECKMULTISIG')
|
||||
|
||||
txb.addInput("4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf", 0)
|
||||
txb.addOutput("1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH", 10000)
|
||||
txb.addInput('4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf', 0)
|
||||
txb.addOutput('1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH', 10000)
|
||||
txb.sign(0, privKeys[0], redeemScript)
|
||||
|
||||
var tx = txb.buildIncomplete()
|
||||
|
|
313
test/wallet.js
313
test/wallet.js
|
@ -1,3 +1,5 @@
|
|||
/* global describe, it, beforeEach, afterEach */
|
||||
|
||||
var assert = require('assert')
|
||||
var bufferutils = require('../src/bufferutils')
|
||||
var crypto = require('../src/crypto')
|
||||
|
@ -15,72 +17,72 @@ var fixtureTxes = require('./fixtures/mainnet_tx')
|
|||
var fixtureTx1Hex = fixtureTxes.prevTx
|
||||
var fixtureTx2Hex = fixtureTxes.tx
|
||||
|
||||
function fakeTxHash(i) {
|
||||
function fakeTxHash (i) {
|
||||
var hash = new Buffer(32)
|
||||
hash.fill(i)
|
||||
return hash
|
||||
}
|
||||
|
||||
function fakeTxId(i) {
|
||||
function fakeTxId (i) {
|
||||
var hash = fakeTxHash(i)
|
||||
Array.prototype.reverse.call(hash)
|
||||
return hash.toString('hex')
|
||||
}
|
||||
|
||||
describe('Wallet', function() {
|
||||
describe('Wallet', function () {
|
||||
var seed
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
seed = crypto.sha256("don't use a string seed like this in real life")
|
||||
})
|
||||
|
||||
describe('constructor', function() {
|
||||
describe('constructor', function () {
|
||||
var wallet
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
wallet = new Wallet(seed)
|
||||
})
|
||||
|
||||
it('defaults to Bitcoin network', function() {
|
||||
it('defaults to Bitcoin network', function () {
|
||||
assert.equal(wallet.getMasterKey().network, networks.bitcoin)
|
||||
})
|
||||
|
||||
it("generates m/0' as the main account", function() {
|
||||
it("generates m/0' as the main account", function () {
|
||||
var mainAccount = wallet.getAccountZero()
|
||||
assert.equal(mainAccount.index, 0 + HDNode.HIGHEST_BIT)
|
||||
assert.equal(mainAccount.depth, 1)
|
||||
})
|
||||
|
||||
it("generates m/0'/0 as the external account", function() {
|
||||
it("generates m/0'/0 as the external account", function () {
|
||||
var account = wallet.getExternalAccount()
|
||||
assert.equal(account.index, 0)
|
||||
assert.equal(account.depth, 2)
|
||||
})
|
||||
|
||||
it("generates m/0'/1 as the internal account", function() {
|
||||
it("generates m/0'/1 as the internal account", function () {
|
||||
var account = wallet.getInternalAccount()
|
||||
assert.equal(account.index, 1)
|
||||
assert.equal(account.depth, 2)
|
||||
})
|
||||
|
||||
describe('when seed is not specified', function() {
|
||||
it('generates a seed', function() {
|
||||
describe('when seed is not specified', function () {
|
||||
it('generates a seed', function () {
|
||||
var wallet = new Wallet()
|
||||
assert(wallet.getMasterKey())
|
||||
})
|
||||
})
|
||||
|
||||
describe('constructor options', function() {
|
||||
beforeEach(function() {
|
||||
describe('constructor options', function () {
|
||||
beforeEach(function () {
|
||||
wallet = new Wallet(seed, networks.testnet)
|
||||
})
|
||||
|
||||
it('uses the network if specified', function() {
|
||||
it('uses the network if specified', function () {
|
||||
assert.equal(wallet.getMasterKey().network, networks.testnet)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('newMasterKey', function() {
|
||||
it('resets accounts', function() {
|
||||
describe('newMasterKey', function () {
|
||||
it('resets accounts', function () {
|
||||
var wallet = new Wallet()
|
||||
var oldAccountZero = wallet.getAccountZero()
|
||||
var oldExternalAccount = wallet.getExternalAccount()
|
||||
|
@ -92,7 +94,7 @@ describe('Wallet', function() {
|
|||
assertNotEqual(wallet.getInternalAccount(), oldInternalAccount)
|
||||
})
|
||||
|
||||
it('resets addresses', function() {
|
||||
it('resets addresses', function () {
|
||||
var wallet = new Wallet()
|
||||
wallet.generateAddress()
|
||||
wallet.generateChangeAddress()
|
||||
|
@ -107,12 +109,12 @@ describe('Wallet', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('generateAddress', function() {
|
||||
it('generate receiving addresses', function() {
|
||||
describe('generateAddress', function () {
|
||||
it('generate receiving addresses', function () {
|
||||
var wallet = new Wallet(seed, networks.testnet)
|
||||
var expectedAddresses = [
|
||||
"n1GyUANZand9Kw6hGSV9837cCC9FFUQzQa",
|
||||
"n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X"
|
||||
'n1GyUANZand9Kw6hGSV9837cCC9FFUQzQa',
|
||||
'n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X'
|
||||
]
|
||||
|
||||
assert.equal(wallet.generateAddress(), expectedAddresses[0])
|
||||
|
@ -121,28 +123,18 @@ describe('Wallet', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('generateChangeAddress', function() {
|
||||
var wallet
|
||||
beforeEach(function() {
|
||||
wallet = new Wallet(seed)
|
||||
})
|
||||
|
||||
it('generates change addresses', function() {
|
||||
describe('generateChangeAddress', function () {
|
||||
it('generates change addresses', function () {
|
||||
var wallet = new Wallet(seed, networks.testnet)
|
||||
var expectedAddresses = ["mnXiDR4MKsFxcKJEZjx4353oXvo55iuptn"]
|
||||
var expectedAddresses = ['mnXiDR4MKsFxcKJEZjx4353oXvo55iuptn']
|
||||
|
||||
assert.equal(wallet.generateChangeAddress(), expectedAddresses[0])
|
||||
assert.deepEqual(wallet.changeAddresses, expectedAddresses)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getPrivateKey', function() {
|
||||
var wallet
|
||||
beforeEach(function() {
|
||||
wallet = new Wallet(seed)
|
||||
})
|
||||
|
||||
it('returns the private key at the given index of external account', function() {
|
||||
describe('getPrivateKey', function () {
|
||||
it('returns the private key at the given index of external account', function () {
|
||||
var wallet = new Wallet(seed, networks.testnet)
|
||||
|
||||
assertEqual(wallet.getPrivateKey(0), wallet.getExternalAccount().derive(0).privKey)
|
||||
|
@ -150,13 +142,8 @@ describe('Wallet', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('getInternalPrivateKey', function() {
|
||||
var wallet
|
||||
beforeEach(function() {
|
||||
wallet = new Wallet(seed)
|
||||
})
|
||||
|
||||
it('returns the private key at the given index of internal account', function() {
|
||||
describe('getInternalPrivateKey', function () {
|
||||
it('returns the private key at the given index of internal account', function () {
|
||||
var wallet = new Wallet(seed, networks.testnet)
|
||||
|
||||
assertEqual(wallet.getInternalPrivateKey(0), wallet.getInternalAccount().derive(0).privKey)
|
||||
|
@ -164,59 +151,54 @@ describe('Wallet', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('getPrivateKeyForAddress', function() {
|
||||
var wallet
|
||||
beforeEach(function() {
|
||||
wallet = new Wallet(seed)
|
||||
})
|
||||
|
||||
it('returns the private key for the given address', function() {
|
||||
describe('getPrivateKeyForAddress', function () {
|
||||
it('returns the private key for the given address', function () {
|
||||
var wallet = new Wallet(seed, networks.testnet)
|
||||
wallet.generateChangeAddress()
|
||||
wallet.generateAddress()
|
||||
wallet.generateAddress()
|
||||
|
||||
assertEqual(
|
||||
wallet.getPrivateKeyForAddress("n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X"),
|
||||
wallet.getPrivateKeyForAddress('n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X'),
|
||||
wallet.getExternalAccount().derive(1).privKey
|
||||
)
|
||||
assertEqual(
|
||||
wallet.getPrivateKeyForAddress("mnXiDR4MKsFxcKJEZjx4353oXvo55iuptn"),
|
||||
wallet.getPrivateKeyForAddress('mnXiDR4MKsFxcKJEZjx4353oXvo55iuptn'),
|
||||
wallet.getInternalAccount().derive(0).privKey
|
||||
)
|
||||
})
|
||||
|
||||
it('raises an error when address is not found', function() {
|
||||
it('raises an error when address is not found', function () {
|
||||
var wallet = new Wallet(seed, networks.testnet)
|
||||
|
||||
assert.throws(function() {
|
||||
wallet.getPrivateKeyForAddress("n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X")
|
||||
assert.throws(function () {
|
||||
wallet.getPrivateKeyForAddress('n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X')
|
||||
}, /Unknown address. Make sure the address is from the keychain and has been generated/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Unspent Outputs', function() {
|
||||
var utxo, expectedOutputKey
|
||||
describe('Unspent Outputs', function () {
|
||||
var utxo
|
||||
var wallet
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
utxo = {
|
||||
"address" : "1AZpKpcfCzKDUeTFBQUL4MokQai3m3HMXv",
|
||||
"confirmations": 1,
|
||||
"index": 0,
|
||||
"txId": fakeTxId(6),
|
||||
"value": 20000,
|
||||
"pending": false
|
||||
'address': '1AZpKpcfCzKDUeTFBQUL4MokQai3m3HMXv',
|
||||
'confirmations': 1,
|
||||
'index': 0,
|
||||
'txId': fakeTxId(6),
|
||||
'value': 20000,
|
||||
'pending': false
|
||||
}
|
||||
})
|
||||
|
||||
describe('on construction', function() {
|
||||
beforeEach(function() {
|
||||
describe('on construction', function () {
|
||||
beforeEach(function () {
|
||||
wallet = new Wallet(seed, networks.bitcoin)
|
||||
wallet.setUnspentOutputs([utxo])
|
||||
})
|
||||
|
||||
it('matches the expected behaviour', function() {
|
||||
it('matches the expected behaviour', function () {
|
||||
var output = wallet.unspents[0]
|
||||
|
||||
assert.equal(output.address, utxo.address)
|
||||
|
@ -224,8 +206,8 @@ describe('Wallet', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('getBalance', function() {
|
||||
beforeEach(function() {
|
||||
describe('getBalance', function () {
|
||||
beforeEach(function () {
|
||||
var utxo1 = cloneObject(utxo)
|
||||
utxo1.hash = fakeTxId(5)
|
||||
|
||||
|
@ -233,18 +215,18 @@ describe('Wallet', function() {
|
|||
wallet.setUnspentOutputs([utxo, utxo1])
|
||||
})
|
||||
|
||||
it('sums over utxo values', function() {
|
||||
it('sums over utxo values', function () {
|
||||
assert.equal(wallet.getBalance(), 40000)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getUnspentOutputs', function() {
|
||||
beforeEach(function() {
|
||||
describe('getUnspentOutputs', function () {
|
||||
beforeEach(function () {
|
||||
wallet = new Wallet(seed, networks.bitcoin)
|
||||
wallet.setUnspentOutputs([utxo])
|
||||
})
|
||||
|
||||
it('parses wallet unspents to the expected format', function() {
|
||||
it('parses wallet unspents to the expected format', function () {
|
||||
var outputs = wallet.getUnspentOutputs()
|
||||
var output = outputs[0]
|
||||
|
||||
|
@ -261,7 +243,7 @@ describe('Wallet', function() {
|
|||
assert.equal(utxo.confirmations, output.confirmations)
|
||||
})
|
||||
|
||||
it("ignores spent unspents (outputs with 'spent' property)", function() {
|
||||
it("ignores spent unspents (outputs with 'spent' property)", function () {
|
||||
var unspent = wallet.unspents[0]
|
||||
unspent.pending = true
|
||||
unspent.spent = true
|
||||
|
@ -270,12 +252,11 @@ describe('Wallet', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('setUnspentOutputs', function() {
|
||||
describe('setUnspentOutputs', function () {
|
||||
var utxo
|
||||
var expectedOutputKey
|
||||
var wallet
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
utxo = {
|
||||
hash: fakeTxId(0),
|
||||
index: 0,
|
||||
|
@ -286,7 +267,7 @@ describe('Wallet', function() {
|
|||
wallet = new Wallet(seed, networks.bitcoin)
|
||||
})
|
||||
|
||||
it('matches the expected behaviour', function() {
|
||||
it('matches the expected behaviour', function () {
|
||||
wallet.setUnspentOutputs([utxo])
|
||||
|
||||
var output = wallet.unspents[0]
|
||||
|
@ -294,12 +275,12 @@ describe('Wallet', function() {
|
|||
assert.equal(output.address, utxo.address)
|
||||
})
|
||||
|
||||
describe('required fields', function() {
|
||||
['index', 'address', 'hash', 'value'].forEach(function(field){
|
||||
it("throws an error when " + field + " is missing", function() {
|
||||
describe('required fields', function () {
|
||||
['index', 'address', 'hash', 'value'].forEach(function (field) {
|
||||
it('throws an error when ' + field + ' is missing', function () {
|
||||
delete utxo[field]
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
wallet.setUnspentOutputs([utxo])
|
||||
})
|
||||
})
|
||||
|
@ -307,16 +288,16 @@ describe('Wallet', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('Process transaction', function() {
|
||||
describe('Process transaction', function () {
|
||||
var wallet
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
wallet = new Wallet(seed)
|
||||
})
|
||||
|
||||
var addresses
|
||||
var tx
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
addresses = [
|
||||
'115qa7iPZqn6as57hxLL8E9VUnhmGQxKWi',
|
||||
'1Bu3bhwRmevHLAy1JrRB6AfcxfgDG2vXRd',
|
||||
|
@ -326,24 +307,24 @@ describe('Wallet', function() {
|
|||
tx = Transaction.fromHex(fixtureTx1Hex)
|
||||
})
|
||||
|
||||
describe("processPendingTx", function() {
|
||||
it("incoming: sets the pending flag on output", function() {
|
||||
describe('processPendingTx', function () {
|
||||
it('incoming: sets the pending flag on output', function () {
|
||||
wallet.addresses = [addresses[0]]
|
||||
wallet.processPendingTx(tx)
|
||||
|
||||
verifyOutputAdded(0, true)
|
||||
})
|
||||
|
||||
describe("when tx ins outpoint contains a known txhash:i", function() {
|
||||
describe('when tx ins outpoint contains a known txhash:i', function () {
|
||||
var spendTx
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
wallet.addresses = [addresses[0]]
|
||||
wallet.processConfirmedTx(tx)
|
||||
|
||||
spendTx = Transaction.fromHex(fixtureTx2Hex)
|
||||
})
|
||||
|
||||
it("outgoing: sets the pending flag and 'spent' on output", function() {
|
||||
it("outgoing: sets the pending flag and 'spent' on output", function () {
|
||||
var txIn = spendTx.ins[0]
|
||||
var txInId = new Buffer(txIn.hash)
|
||||
Array.prototype.reverse.call(txInId)
|
||||
|
@ -359,8 +340,8 @@ describe('Wallet', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('processConfirmedTx', function() {
|
||||
it('does not throw on scripts with no corresponding Address', function() {
|
||||
describe('processConfirmedTx', function () {
|
||||
it('does not throw on scripts with no corresponding Address', function () {
|
||||
var pubKey = wallet.getPrivateKey(0).pub
|
||||
var script = scripts.pubKeyOutput(pubKey)
|
||||
var tx2 = new Transaction()
|
||||
|
@ -371,8 +352,8 @@ describe('Wallet', function() {
|
|||
wallet.processConfirmedTx(tx2)
|
||||
})
|
||||
|
||||
describe("when tx outs contains an address owned by the wallet, an 'output' gets added to wallet.unspentMap", function() {
|
||||
it("works for receive address", function() {
|
||||
describe("when tx outs contains an address owned by the wallet, an 'output' gets added to wallet.unspentMap", function () {
|
||||
it('works for receive address', function () {
|
||||
var totalOuts = outputCount()
|
||||
|
||||
wallet.addresses = [addresses[0]]
|
||||
|
@ -382,7 +363,7 @@ describe('Wallet', function() {
|
|||
verifyOutputAdded(0, false)
|
||||
})
|
||||
|
||||
it("works for change address", function() {
|
||||
it('works for change address', function () {
|
||||
var totalOuts = outputCount()
|
||||
wallet.changeAddresses = [addresses[1]]
|
||||
|
||||
|
@ -392,26 +373,26 @@ describe('Wallet', function() {
|
|||
verifyOutputAdded(1, false)
|
||||
})
|
||||
|
||||
function outputCount() {
|
||||
function outputCount () {
|
||||
return Object.keys(wallet.unspentMap).length
|
||||
}
|
||||
})
|
||||
|
||||
describe("when tx ins contains a known txhash:i", function() {
|
||||
describe('when tx ins contains a known txhash:i', function () {
|
||||
var spendTx
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
wallet.addresses = [addresses[0]] // the address fixtureTx2 used as input
|
||||
wallet.processConfirmedTx(tx)
|
||||
|
||||
spendTx = Transaction.fromHex(fixtureTx2Hex)
|
||||
})
|
||||
|
||||
it("does not add to wallet.unspentMap", function() {
|
||||
it('does not add to wallet.unspentMap', function () {
|
||||
wallet.processConfirmedTx(spendTx)
|
||||
assert.deepEqual(wallet.unspentMap, {})
|
||||
})
|
||||
|
||||
it("deletes corresponding 'unspent'", function() {
|
||||
it("deletes corresponding 'unspent'", function () {
|
||||
var txIn = spendTx.ins[0]
|
||||
var txInId = bufferutils.reverse(txIn.hash).toString('hex')
|
||||
|
||||
|
@ -424,16 +405,15 @@ describe('Wallet', function() {
|
|||
})
|
||||
})
|
||||
|
||||
it("does nothing when none of the involved addresses belong to the wallet", function() {
|
||||
it('does nothing when none of the involved addresses belong to the wallet', function () {
|
||||
wallet.processConfirmedTx(tx)
|
||||
assert.deepEqual(wallet.unspentMap, {})
|
||||
})
|
||||
|
||||
|
||||
function verifyOutputAdded(index, pending) {
|
||||
function verifyOutputAdded (index, pending) {
|
||||
var txOut = tx.outs[index]
|
||||
|
||||
var key = tx.getId() + ":" + index
|
||||
var key = tx.getId() + ':' + index
|
||||
var output = wallet.unspentMap[key]
|
||||
assert.deepEqual(output.txHash, tx.getHash())
|
||||
assert.equal(output.value, txOut.value)
|
||||
|
@ -444,37 +424,37 @@ describe('Wallet', function() {
|
|||
}
|
||||
})
|
||||
|
||||
describe('createTx', function() {
|
||||
describe('createTx', function () {
|
||||
var wallet
|
||||
var address1, address2
|
||||
var to, value
|
||||
|
||||
beforeEach(function() {
|
||||
beforeEach(function () {
|
||||
to = 'mt7MyTVVEWnbwpF5hBn6fgnJcv95Syk2ue'
|
||||
value = 500000
|
||||
|
||||
address1 = "n1GyUANZand9Kw6hGSV9837cCC9FFUQzQa"
|
||||
address2 = "n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X"
|
||||
address1 = 'n1GyUANZand9Kw6hGSV9837cCC9FFUQzQa'
|
||||
address2 = 'n2fiWrHqD6GM5GiEqkbWAc6aaZQp3ba93X'
|
||||
|
||||
// set up 3 utxos
|
||||
var utxos = [
|
||||
{
|
||||
"txId": fakeTxId(1),
|
||||
"index": 0,
|
||||
"address": address1,
|
||||
"value": 400000 // not enough for value
|
||||
'txId': fakeTxId(1),
|
||||
'index': 0,
|
||||
'address': address1,
|
||||
'value': 400000 // not enough for value
|
||||
},
|
||||
{
|
||||
"txId": fakeTxId(2),
|
||||
"index": 1,
|
||||
"address": address1,
|
||||
"value": 500000 // enough for only value
|
||||
'txId': fakeTxId(2),
|
||||
'index': 1,
|
||||
'address': address1,
|
||||
'value': 500000 // enough for only value
|
||||
},
|
||||
{
|
||||
"txId": fakeTxId(3),
|
||||
"index": 0,
|
||||
"address" : address2,
|
||||
"value": 510000 // enough for value and fee
|
||||
'txId': fakeTxId(3),
|
||||
'index': 0,
|
||||
'address': address2,
|
||||
'value': 510000 // enough for value and fee
|
||||
}
|
||||
]
|
||||
|
||||
|
@ -484,27 +464,31 @@ describe('Wallet', function() {
|
|||
wallet.generateAddress()
|
||||
})
|
||||
|
||||
describe('transaction fee', function() {
|
||||
it('allows fee to be specified', function() {
|
||||
describe('transaction fee', function () {
|
||||
it('allows fee to be specified', function () {
|
||||
var fee = 30000
|
||||
var tx = wallet.createTx(to, value, { fixedFee: fee })
|
||||
var tx = wallet.createTx(to, value, {
|
||||
fixedFee: fee
|
||||
})
|
||||
|
||||
assert.equal(getFee(wallet, tx), fee)
|
||||
})
|
||||
|
||||
it('allows fee to be set to zero', function() {
|
||||
it('allows fee to be set to zero', function () {
|
||||
value = 510000
|
||||
var fee = 0
|
||||
var tx = wallet.createTx(to, value, { fixedFee: fee })
|
||||
var tx = wallet.createTx(to, value, {
|
||||
fixedFee: fee
|
||||
})
|
||||
|
||||
assert.equal(getFee(wallet, tx), fee)
|
||||
})
|
||||
|
||||
it('does not overestimate fees when network has dustSoftThreshold', function() {
|
||||
it('does not overestimate fees when network has dustSoftThreshold', function () {
|
||||
var utxo = {
|
||||
txId: fakeTxId(0),
|
||||
index: 0,
|
||||
address: "LeyySKbQrRRwodKEj1W4a8y3YQupPLw5os",
|
||||
address: 'LeyySKbQrRRwodKEj1W4a8y3YQupPLw5os',
|
||||
value: 500000
|
||||
}
|
||||
|
||||
|
@ -518,21 +502,21 @@ describe('Wallet', function() {
|
|||
assert.equal(getFee(wallet, tx), 100000)
|
||||
})
|
||||
|
||||
function getFee(wallet, tx) {
|
||||
var inputValue = tx.ins.reduce(function(accum, input) {
|
||||
function getFee (wallet, tx) {
|
||||
var inputValue = tx.ins.reduce(function (accum, input) {
|
||||
var txId = bufferutils.reverse(input.hash).toString('hex')
|
||||
|
||||
return accum + wallet.unspentMap[txId + ':' + input.index].value
|
||||
}, 0)
|
||||
|
||||
return tx.outs.reduce(function(accum, output) {
|
||||
return tx.outs.reduce(function (accum, output) {
|
||||
return accum - output.value
|
||||
}, inputValue)
|
||||
}
|
||||
})
|
||||
|
||||
describe('choosing utxo', function() {
|
||||
it('takes fees into account', function() {
|
||||
describe('choosing utxo', function () {
|
||||
it('takes fees into account', function () {
|
||||
var tx = wallet.createTx(to, value)
|
||||
|
||||
assert.equal(tx.ins.length, 1)
|
||||
|
@ -540,7 +524,7 @@ describe('Wallet', function() {
|
|||
assert.equal(tx.ins[0].index, 0)
|
||||
})
|
||||
|
||||
it('uses confirmed outputs', function() {
|
||||
it('uses confirmed outputs', function () {
|
||||
var tx2 = new Transaction()
|
||||
tx2.addInput(fakeTxId(4), 0)
|
||||
tx2.addOutput(address2, 530000)
|
||||
|
@ -553,7 +537,7 @@ describe('Wallet', function() {
|
|||
assert.equal(tx.ins[0].index, 0)
|
||||
})
|
||||
|
||||
it('ignores pending outputs', function() {
|
||||
it('ignores pending outputs', function () {
|
||||
var tx2 = new Transaction()
|
||||
tx2.addInput(fakeTxId(4), 0)
|
||||
tx2.addOutput(address2, 530000)
|
||||
|
@ -567,8 +551,8 @@ describe('Wallet', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('changeAddress', function() {
|
||||
it('should allow custom changeAddress', function() {
|
||||
describe('changeAddress', function () {
|
||||
it('should allow custom changeAddress', function () {
|
||||
var changeAddress = 'mfrFjnKZUvTcvdAK2fUX5D8v1Epu5H8JCk'
|
||||
var fromValue = 510000
|
||||
var toValue = fromValue / 2
|
||||
|
@ -591,8 +575,8 @@ describe('Wallet', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('transaction outputs', function() {
|
||||
it('includes the specified address and amount', function() {
|
||||
describe('transaction outputs', function () {
|
||||
it('includes the specified address and amount', function () {
|
||||
var tx = wallet.createTx(to, value)
|
||||
|
||||
assert.equal(tx.outs.length, 1)
|
||||
|
@ -603,12 +587,14 @@ describe('Wallet', function() {
|
|||
assert.equal(out.value, value)
|
||||
})
|
||||
|
||||
describe('change', function() {
|
||||
it('uses the last change address if there is any', function() {
|
||||
describe('change', function () {
|
||||
it('uses the last change address if there is any', function () {
|
||||
var fee = 0
|
||||
wallet.generateChangeAddress()
|
||||
wallet.generateChangeAddress()
|
||||
var tx = wallet.createTx(to, value, { fixedFee: fee })
|
||||
var tx = wallet.createTx(to, value, {
|
||||
fixedFee: fee
|
||||
})
|
||||
|
||||
assert.equal(tx.outs.length, 2)
|
||||
var out = tx.outs[1]
|
||||
|
@ -618,11 +604,13 @@ describe('Wallet', function() {
|
|||
assert.equal(out.value, 10000)
|
||||
})
|
||||
|
||||
it('generates a change address if there is not any', function() {
|
||||
it('generates a change address if there is not any', function () {
|
||||
var fee = 0
|
||||
assert.equal(wallet.changeAddresses.length, 0)
|
||||
|
||||
var tx = wallet.createTx(to, value, { fixedFee: fee })
|
||||
var tx = wallet.createTx(to, value, {
|
||||
fixedFee: fee
|
||||
})
|
||||
|
||||
assert.equal(wallet.changeAddresses.length, 1)
|
||||
var out = tx.outs[1]
|
||||
|
@ -632,7 +620,7 @@ describe('Wallet', function() {
|
|||
assert.equal(out.value, 10000)
|
||||
})
|
||||
|
||||
it('skips change if it is not above dust threshold', function() {
|
||||
it('skips change if it is not above dust threshold', function () {
|
||||
var tx1 = wallet.createTx(to, value - 546)
|
||||
assert.equal(tx1.outs.length, 1)
|
||||
|
||||
|
@ -642,59 +630,62 @@ describe('Wallet', function() {
|
|||
})
|
||||
})
|
||||
|
||||
describe('signing', function() {
|
||||
afterEach(function() {
|
||||
describe('signing', function () {
|
||||
afterEach(function () {
|
||||
TransactionBuilder.prototype.sign.restore()
|
||||
})
|
||||
|
||||
it('signs the inputs with respective keys', function() {
|
||||
it('signs the inputs with respective keys', function () {
|
||||
var fee = 30000
|
||||
sinon.spy(TransactionBuilder.prototype, "sign")
|
||||
sinon.spy(TransactionBuilder.prototype, 'sign')
|
||||
|
||||
wallet.createTx(to, value, { fixedFee: fee })
|
||||
wallet.createTx(to, value, {
|
||||
fixedFee: fee
|
||||
})
|
||||
|
||||
var priv1 = wallet.getPrivateKeyForAddress(address1)
|
||||
var priv2 = wallet.getPrivateKeyForAddress(address2)
|
||||
|
||||
// FIXME: boo (required) side effects
|
||||
priv1.pub.Q.affineX, priv2.pub.Q.affineX
|
||||
// FIXME: boo, toString invokes reqiuired affine coordinate side effects
|
||||
priv1.pub.Q.toString()
|
||||
priv2.pub.Q.toString()
|
||||
|
||||
assert(TransactionBuilder.prototype.sign.calledWith(0, priv2))
|
||||
assert(TransactionBuilder.prototype.sign.calledWith(1, priv1))
|
||||
})
|
||||
})
|
||||
|
||||
describe('when value is below dust threshold', function() {
|
||||
it('throws an error', function() {
|
||||
describe('when value is below dust threshold', function () {
|
||||
it('throws an error', function () {
|
||||
var value = 546
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
wallet.createTx(to, value)
|
||||
}, /546 must be above dust threshold \(546 Satoshis\)/)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when there is not enough money', function() {
|
||||
it('throws an error', function() {
|
||||
describe('when there is not enough money', function () {
|
||||
it('throws an error', function () {
|
||||
var value = 1400001
|
||||
|
||||
assert.throws(function() {
|
||||
assert.throws(function () {
|
||||
wallet.createTx(to, value)
|
||||
}, /Not enough funds \(incl. fee\): 1410000 < 1410001/)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
function assertEqual(obj1, obj2){
|
||||
function assertEqual (obj1, obj2) {
|
||||
assert.equal(obj1.toString(), obj2.toString())
|
||||
}
|
||||
|
||||
function assertNotEqual(obj1, obj2){
|
||||
function assertNotEqual (obj1, obj2) {
|
||||
assert.notEqual(obj1.toString(), obj2.toString())
|
||||
}
|
||||
|
||||
// quick and dirty: does not deal with functions on object
|
||||
function cloneObject(obj){
|
||||
function cloneObject (obj) {
|
||||
return JSON.parse(JSON.stringify(obj))
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue