Browse Source

Merge pull request #425 from bitcoinjs/nonetdetect

Remove network detection
hk-custom-address
Daniel Cousens 10 years ago
parent
commit
1eb98be6a5
  1. 18
      src/address.js
  2. 32
      src/ecpair.js
  3. 33
      src/hdnode.js
  4. 15
      src/transaction_builder.js
  5. 4
      test/address.js
  6. 13
      test/bitcoin.core.js
  7. 34
      test/ecpair.js
  8. 5
      test/fixtures/hdnode.json
  9. 54
      test/fixtures/transaction_builder.json
  10. 39
      test/hdnode.js
  11. 4
      test/integration/multisig.js
  12. 22
      test/networks.js
  13. 86
      test/transaction_builder.js

18
src/address.js

@ -3,15 +3,6 @@ var typeForce = require('typeforce')
var networks = require('./networks') var networks = require('./networks')
var scripts = require('./scripts') var scripts = require('./scripts')
function findScriptTypeByVersion (version) {
for (var networkName in networks) {
var network = networks[networkName]
if (version === network.pubKeyHash) return 'pubkeyhash'
if (version === network.scriptHash) return 'scripthash'
}
}
function fromBase58Check (string) { function fromBase58Check (string) {
var payload = base58check.decode(string) var payload = base58check.decode(string)
if (payload.length !== 21) throw new TypeError('Invalid address length') if (payload.length !== 21) throw new TypeError('Invalid address length')
@ -44,16 +35,17 @@ function toBase58Check (hash, version) {
return base58check.encode(payload) return base58check.encode(payload)
} }
function toOutputScript (address) { function toOutputScript (address, network) {
network = network || networks.bitcoin
var payload = base58check.decode(address) var payload = base58check.decode(address)
if (payload.length !== 21) throw new TypeError('Invalid hash length') if (payload.length !== 21) throw new TypeError('Invalid hash length')
var version = payload.readUInt8(0) var version = payload.readUInt8(0)
var hash = payload.slice(1) var hash = payload.slice(1)
var scriptType = findScriptTypeByVersion(version)
if (scriptType === 'pubkeyhash') return scripts.pubKeyHashOutput(hash) if (version === network.pubKeyHash) return scripts.pubKeyHashOutput(hash)
if (scriptType === 'scripthash') return scripts.scriptHashOutput(hash) if (version === network.scriptHash) return scripts.scriptHashOutput(hash)
throw new Error(address + ' has no matching Script') throw new Error(address + ' has no matching Script')
} }

32
src/ecpair.js

@ -3,27 +3,17 @@ var bs58check = require('bs58check')
var bcrypto = require('./crypto') var bcrypto = require('./crypto')
var ecdsa = require('./ecdsa') var ecdsa = require('./ecdsa')
var ecurve = require('ecurve') var ecurve = require('ecurve')
var networks = require('./networks') var NETWORKS = require('./networks')
var randomBytes = require('randombytes') var randomBytes = require('randombytes')
var typeForce = require('typeforce') var typeForce = require('typeforce')
var BigInteger = require('bigi') var BigInteger = require('bigi')
function findNetworkByWIFVersion (version) {
for (var networkName in networks) {
var network = networks[networkName]
if (network.wif === version) return network
}
throw new Error('Unknown network')
}
function ECPair (d, Q, options) { function ECPair (d, Q, options) {
options = options || {} options = options || {}
var compressed = options.compressed === undefined ? true : options.compressed var compressed = options.compressed === undefined ? true : options.compressed
var network = options.network === undefined ? networks.bitcoin : options.network var network = options.network === undefined ? NETWORKS.bitcoin : options.network
typeForce('Boolean', compressed) typeForce('Boolean', compressed)
assert('pubKeyHash' in network, 'Unknown pubKeyHash constants for network') assert('pubKeyHash' in network, 'Unknown pubKeyHash constants for network')
@ -67,7 +57,7 @@ ECPair.fromPublicKeyBuffer = function (buffer, network) {
}) })
} }
ECPair.fromWIF = function (string) { ECPair.fromWIF = function (string, networks) {
var payload = bs58check.decode(string) var payload = bs58check.decode(string)
var version = payload.readUInt8(0) var version = payload.readUInt8(0)
var compressed var compressed
@ -88,7 +78,21 @@ ECPair.fromWIF = function (string) {
compressed = false compressed = false
} }
var network = findNetworkByWIFVersion(version) var network
// list of networks?
if (Array.isArray(networks)) {
network = networks.filter(function (network) {
return version === network.wif
}).pop() || {}
// otherwise, assume a network object (or default to bitcoin)
} else {
network = networks || NETWORKS.bitcoin
}
if (version !== network.wif) throw new Error('Invalid network')
var d = BigInteger.fromBuffer(payload) var d = BigInteger.fromBuffer(payload)
return new ECPair(d, null, { return new ECPair(d, null, {

33
src/hdnode.js

@ -2,7 +2,7 @@ var base58check = require('bs58check')
var bcrypto = require('./crypto') var bcrypto = require('./crypto')
var createHmac = require('create-hmac') var createHmac = require('create-hmac')
var typeForce = require('typeforce') var typeForce = require('typeforce')
var networks = require('./networks') var NETWORKS = require('./networks')
var BigInteger = require('bigi') var BigInteger = require('bigi')
var ECPair = require('./ecpair') var ECPair = require('./ecpair')
@ -10,18 +10,6 @@ var ECPair = require('./ecpair')
var ecurve = require('ecurve') var ecurve = require('ecurve')
var curve = ecurve.getCurveByName('secp256k1') var curve = ecurve.getCurveByName('secp256k1')
function findBIP32NetworkByVersion (version) {
for (var name in networks) {
var network = networks[name]
if (version === network.bip32.private || version === network.bip32.public) {
return network
}
}
throw new Error('Could not find network for ' + version.toString(16))
}
function HDNode (keyPair, chainCode) { function HDNode (keyPair, chainCode) {
typeForce('ECPair', keyPair) typeForce('ECPair', keyPair)
typeForce('Buffer', chainCode) typeForce('Buffer', chainCode)
@ -65,22 +53,29 @@ HDNode.fromSeedHex = function (hex, network) {
return HDNode.fromSeedBuffer(new Buffer(hex, 'hex'), network) return HDNode.fromSeedBuffer(new Buffer(hex, 'hex'), network)
} }
HDNode.fromBase58 = function (string, network) { HDNode.fromBase58 = function (string, networks) {
var buffer = base58check.decode(string) var buffer = base58check.decode(string)
if (buffer.length !== HDNode.LENGTH) throw new Error('Invalid buffer length') if (buffer.length !== HDNode.LENGTH) throw new Error('Invalid buffer length')
// 4 byte: version bytes // 4 byte: version bytes
var version = buffer.readUInt32BE(0) var version = buffer.readUInt32BE(0)
var network
if (network) { // list of networks?
if (version !== network.bip32.private && if (Array.isArray(networks)) {
version !== network.bip32.public) throw new Error('Invalid network') network = networks.filter(function (network) {
return version === network.bip32.private ||
version === network.bip32.public
}).pop() || {}
// auto-detect // otherwise, assume a network object (or default to bitcoin)
} else { } else {
network = findBIP32NetworkByVersion(version) network = networks || NETWORKS.bitcoin
} }
if (version !== network.bip32.private &&
version !== network.bip32.public) throw new Error('Invalid network')
// 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ... // 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ...
var depth = buffer.readUInt8(4) var depth = buffer.readUInt8(4)

15
src/transaction_builder.js

@ -1,6 +1,7 @@
var assert = require('assert') var assert = require('assert')
var bcrypto = require('./crypto') var bcrypto = require('./crypto')
var bufferutils = require('./bufferutils') var bufferutils = require('./bufferutils')
var networks = require('./networks')
var ops = require('./opcodes') var ops = require('./opcodes')
var scripts = require('./scripts') var scripts = require('./scripts')
@ -37,7 +38,7 @@ function extractInput (txIn) {
hashType = parsed.hashType hashType = parsed.hashType
pubKeys = scriptSig.chunks.slice(1) pubKeys = scriptSig.chunks.slice(1)
signatures = [parsed.signature] signatures = [parsed.signature]
prevOutScript = Address.toOutputScript(ECPair.fromPublicKeyBuffer(pubKeys[0]).getAddress()) prevOutScript = scripts.pubKeyHashOutput(bcrypto.hash160(pubKeys[0]))
break break
} }
@ -83,17 +84,18 @@ function extractInput (txIn) {
} }
} }
function TransactionBuilder () { function TransactionBuilder (network) {
this.prevTxMap = {} this.prevTxMap = {}
this.prevOutScripts = {} this.prevOutScripts = {}
this.prevOutTypes = {} this.prevOutTypes = {}
this.network = network || networks.bitcoin
this.inputs = [] this.inputs = []
this.tx = new Transaction() this.tx = new Transaction()
} }
TransactionBuilder.fromTransaction = function (transaction) { TransactionBuilder.fromTransaction = function (transaction, network) {
var txb = new TransactionBuilder() var txb = new TransactionBuilder(network)
// Copy other transaction fields // Copy other transaction fields
txb.tx.version = transaction.version txb.tx.version = transaction.version
@ -188,7 +190,7 @@ TransactionBuilder.prototype.addOutput = function (scriptPubKey, value) {
// Attempt to get a valid address if it's a base58 address string // Attempt to get a valid address if it's a base58 address string
if (typeof scriptPubKey === 'string') { if (typeof scriptPubKey === 'string') {
scriptPubKey = Address.toOutputScript(scriptPubKey) scriptPubKey = Address.toOutputScript(scriptPubKey, this.network)
} }
return this.tx.addOutput(scriptPubKey, value) return this.tx.addOutput(scriptPubKey, value)
@ -280,6 +282,7 @@ TransactionBuilder.prototype.__build = function (allowIncomplete) {
} }
TransactionBuilder.prototype.sign = function (index, keyPair, redeemScript, hashType) { TransactionBuilder.prototype.sign = function (index, keyPair, redeemScript, hashType) {
assert.equal(keyPair.network, this.network, 'Inconsistent network')
assert(index in this.inputs, 'No input at index: ' + index) assert(index in this.inputs, 'No input at index: ' + index)
hashType = hashType || Transaction.SIGHASH_ALL hashType = hashType || Transaction.SIGHASH_ALL
@ -358,7 +361,7 @@ TransactionBuilder.prototype.sign = function (index, keyPair, redeemScript, hash
// we know nothin' Jon Snow, assume pubKeyHash // we know nothin' Jon Snow, assume pubKeyHash
} else { } else {
input.prevOutScript = Address.toOutputScript(keyPair.getAddress()) input.prevOutScript = scripts.pubKeyHashOutput(bcrypto.hash160(keyPair.getPublicKeyBuffer()))
input.prevOutType = 'pubkeyhash' input.prevOutType = 'pubkeyhash'
input.pubKeys = [kpPubKey] input.pubKeys = [kpPubKey]
input.scriptType = input.prevOutType input.scriptType = input.prevOutType

4
test/address.js

@ -61,8 +61,10 @@ describe('Address', function () {
describe('toOutputScript', function () { describe('toOutputScript', function () {
fixtures.valid.forEach(function (f) { fixtures.valid.forEach(function (f) {
var network = networks[f.network]
it('exports ' + f.script + '(' + f.network + ')', function () { it('exports ' + f.script + '(' + f.network + ')', function () {
var script = Address.toOutputScript(f.base58check) var script = Address.toOutputScript(f.base58check, network)
assert.strictEqual(script.toASM(), f.script) assert.strictEqual(script.toASM(), f.script)
}) })

13
test/bitcoin.core.js

@ -57,13 +57,10 @@ describe('Bitcoin-core', function () {
var expected = f[0] var expected = f[0]
var hash = new Buffer(f[1], 'hex') var hash = new Buffer(f[1], 'hex')
var params = f[2] var params = f[2]
var network = networks.bitcoin
if (params.isPrivkey) return if (params.isPrivkey) return
if (params.isTestnet) {
network = networks.testnet
}
var network = params.isTestnet ? networks.testnet : networks.bitcoin
var version = network[typeMap[params.addrType]] var version = network[typeMap[params.addrType]]
it('can export ' + expected, function () { it('can export ' + expected, function () {
@ -102,7 +99,9 @@ describe('Bitcoin-core', function () {
var params = f[2] var params = f[2]
if (!params.isPrivkey) return if (!params.isPrivkey) return
var keyPair = ECPair.fromWIF(string)
var network = params.isTestnet ? networks.testnet : networks.bitcoin
var keyPair = ECPair.fromWIF(string, network)
it('fromWIF imports ' + string, function () { it('fromWIF imports ' + string, function () {
assert.strictEqual(keyPair.d.toHex(), hex) assert.strictEqual(keyPair.d.toHex(), hex)
@ -127,9 +126,7 @@ describe('Bitcoin-core', function () {
it('throws on ' + string, function () { it('throws on ' + string, function () {
assert.throws(function () { assert.throws(function () {
var keyPair = ECPair.fromWIF(string) ECPair.fromWIF(string, allowedNetworks)
assert(allowedNetworks.indexOf(keyPair.network) > -1, 'Invalid network')
}, /(Invalid|Unknown) (checksum|compression flag|network|WIF payload)/) }, /(Invalid|Unknown) (checksum|compression flag|network|WIF payload)/)
}) })
}) })

34
test/ecpair.js

@ -4,7 +4,6 @@
var assert = require('assert') var assert = require('assert')
var ecdsa = require('../src/ecdsa') var ecdsa = require('../src/ecdsa')
var ecurve = require('ecurve') var ecurve = require('ecurve')
var networks = require('../src/networks')
var proxyquire = require('proxyquire') var proxyquire = require('proxyquire')
var sinon = require('sinon') var sinon = require('sinon')
@ -13,6 +12,12 @@ var ECPair = require('../src/ecpair')
var fixtures = require('./fixtures/ecpair.json') var fixtures = require('./fixtures/ecpair.json')
var NETWORKS = require('../src/networks')
var NETWORKS_LIST = [] // Object.values(NETWORKS)
for (var networkName in NETWORKS) {
NETWORKS_LIST.push(NETWORKS[networkName])
}
describe('ECPair', function () { describe('ECPair', function () {
describe('constructor', function () { describe('constructor', function () {
it('defaults to compressed', function () { it('defaults to compressed', function () {
@ -32,10 +37,10 @@ describe('ECPair', function () {
it('supports the network option', function () { it('supports the network option', function () {
var keyPair = new ECPair(BigInteger.ONE, null, { var keyPair = new ECPair(BigInteger.ONE, null, {
compressed: false, compressed: false,
network: networks.testnet network: NETWORKS.testnet
}) })
assert.strictEqual(keyPair.network, networks.testnet) assert.strictEqual(keyPair.network, NETWORKS.testnet)
}) })
it('throws if compressed option is not a bool', function () { it('throws if compressed option is not a bool', function () {
@ -102,12 +107,23 @@ describe('ECPair', function () {
describe('fromWIF', function () { describe('fromWIF', function () {
fixtures.valid.forEach(function (f) { fixtures.valid.forEach(function (f) {
it('imports ' + f.WIF + ' correctly', function () { it('imports ' + f.WIF + ' (' + f.network + ')', function () {
var keyPair = ECPair.fromWIF(f.WIF) var network = NETWORKS[f.network]
var keyPair = ECPair.fromWIF(f.WIF, network)
assert.strictEqual(keyPair.d.toString(), f.d)
assert.strictEqual(keyPair.compressed, f.compressed)
assert.strictEqual(keyPair.network, network)
})
})
fixtures.valid.forEach(function (f) {
it('imports ' + f.WIF + ' (via list of networks)', function () {
var keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST)
assert.strictEqual(keyPair.d.toString(), f.d) assert.strictEqual(keyPair.d.toString(), f.d)
assert.strictEqual(keyPair.compressed, f.compressed) assert.strictEqual(keyPair.compressed, f.compressed)
assert.strictEqual(keyPair.network, networks[f.network]) assert.strictEqual(keyPair.network, NETWORKS[f.network])
}) })
}) })
@ -122,8 +138,8 @@ describe('ECPair', function () {
describe('toWIF', function () { describe('toWIF', function () {
fixtures.valid.forEach(function (f) { fixtures.valid.forEach(function (f) {
it('exports ' + f.WIF + ' correctly', function () { it('exports ' + f.WIF, function () {
var keyPair = ECPair.fromWIF(f.WIF) var keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST)
var result = keyPair.toWIF() var result = keyPair.toWIF()
assert.strictEqual(result, f.WIF) assert.strictEqual(result, f.WIF)
@ -169,7 +185,7 @@ describe('ECPair', function () {
describe('getAddress', function () { describe('getAddress', function () {
fixtures.valid.forEach(function (f) { fixtures.valid.forEach(function (f) {
it('returns ' + f.address + ' for ' + f.WIF, function () { it('returns ' + f.address + ' for ' + f.WIF, function () {
var keyPair = ECPair.fromWIF(f.WIF) var keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST)
assert.strictEqual(keyPair.getAddress(), f.address) assert.strictEqual(keyPair.getAddress(), f.address)
}) })

5
test/fixtures/hdnode.json

@ -199,13 +199,12 @@
"string": "xprvQQQQQQQQQQQQQQQQCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334" "string": "xprvQQQQQQQQQQQQQQQQCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334"
}, },
{ {
"exception": "Could not find network for 0", "exception": "Invalid network",
"string": "1111111111111adADjFaSNPxwXqLjHLj4mBfYxuewDPbw9hEj1uaXCzMxRPXDFF3cUoezTFYom4sEmEVSQmENPPR315cFk9YUFVek73wE9" "string": "1111111111111adADjFaSNPxwXqLjHLj4mBfYxuewDPbw9hEj1uaXCzMxRPXDFF3cUoezTFYom4sEmEVSQmENPPR315cFk9YUFVek73wE9"
}, },
{ {
"exception": "Invalid network", "exception": "Invalid network",
"string": "Ltpv73XYpw28ZyVe2zEVyiFnxUZxoKLGQNdZ8NxUi1WcqjNmMBgtLbh3KimGSnPHCoLv1RmvxHs4dnKmo1oXQ8dXuDu8uroxrbVxZPA1gXboYvx", "string": "Ltpv73XYpw28ZyVe2zEVyiFnxUZxoKLGQNdZ8NxUi1WcqjNmMBgtLbh3KimGSnPHCoLv1RmvxHs4dnKmo1oXQ8dXuDu8uroxrbVxZPA1gXboYvx"
"network": "bitcoin"
} }
], ],
"fromBuffer": [ "fromBuffer": [

54
test/fixtures/transaction_builder.json

@ -68,6 +68,7 @@
}, },
{ {
"description": "Transaction w/ scriptHash(multisig 2-of-2) -> pubKeyHash", "description": "Transaction w/ scriptHash(multisig 2-of-2) -> pubKeyHash",
"network": "testnet",
"txHex": "0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000fd1b0100483045022100b7a9bab60c4307349de9571ce0bd26ebb9d68d4e9ab3f9173e1f736f1390a04a022020931ff70e87033cdd94bdf434e865993b2258065c5c222a53f29d077bcfa4480147304402206d79ad83f1ab12fc9feee9e66412de842fcbf8de0632beb4433d469f24f0fb4e022079e6df186582f2686a3292bde8e50dac36cb9bec3991995fe331e1daef7df8a4014c8752410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a52aeffffffff0110270000000000001976a914faf1d99bf040ea9c7f8cc9f14ac6733ad75ce24688ac00000000", "txHex": "0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000fd1b0100483045022100b7a9bab60c4307349de9571ce0bd26ebb9d68d4e9ab3f9173e1f736f1390a04a022020931ff70e87033cdd94bdf434e865993b2258065c5c222a53f29d077bcfa4480147304402206d79ad83f1ab12fc9feee9e66412de842fcbf8de0632beb4433d469f24f0fb4e022079e6df186582f2686a3292bde8e50dac36cb9bec3991995fe331e1daef7df8a4014c8752410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a52aeffffffff0110270000000000001976a914faf1d99bf040ea9c7f8cc9f14ac6733ad75ce24688ac00000000",
"inputs": [ "inputs": [
{ {
@ -93,6 +94,7 @@
}, },
{ {
"description": "Transaction w/ multisig 2-of-2 -> pubKeyHash", "description": "Transaction w/ multisig 2-of-2 -> pubKeyHash",
"network": "testnet",
"txHex": "0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009200483045022100b7a9bab60c4307349de9571ce0bd26ebb9d68d4e9ab3f9173e1f736f1390a04a022020931ff70e87033cdd94bdf434e865993b2258065c5c222a53f29d077bcfa4480147304402206d79ad83f1ab12fc9feee9e66412de842fcbf8de0632beb4433d469f24f0fb4e022079e6df186582f2686a3292bde8e50dac36cb9bec3991995fe331e1daef7df8a401ffffffff0110270000000000001976a914faf1d99bf040ea9c7f8cc9f14ac6733ad75ce24688ac00000000", "txHex": "0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009200483045022100b7a9bab60c4307349de9571ce0bd26ebb9d68d4e9ab3f9173e1f736f1390a04a022020931ff70e87033cdd94bdf434e865993b2258065c5c222a53f29d077bcfa4480147304402206d79ad83f1ab12fc9feee9e66412de842fcbf8de0632beb4433d469f24f0fb4e022079e6df186582f2686a3292bde8e50dac36cb9bec3991995fe331e1daef7df8a401ffffffff0110270000000000001976a914faf1d99bf040ea9c7f8cc9f14ac6733ad75ce24688ac00000000",
"inputs": [ "inputs": [
{ {
@ -118,6 +120,7 @@
}, },
{ {
"description": "Transaction w/ multisig 2-of-2 (reverse order) -> pubKeyHash", "description": "Transaction w/ multisig 2-of-2 (reverse order) -> pubKeyHash",
"network": "testnet",
"txHex": "0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009200483045022100b7a9bab60c4307349de9571ce0bd26ebb9d68d4e9ab3f9173e1f736f1390a04a022020931ff70e87033cdd94bdf434e865993b2258065c5c222a53f29d077bcfa4480147304402206d79ad83f1ab12fc9feee9e66412de842fcbf8de0632beb4433d469f24f0fb4e022079e6df186582f2686a3292bde8e50dac36cb9bec3991995fe331e1daef7df8a401ffffffff0110270000000000001976a914faf1d99bf040ea9c7f8cc9f14ac6733ad75ce24688ac00000000", "txHex": "0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009200483045022100b7a9bab60c4307349de9571ce0bd26ebb9d68d4e9ab3f9173e1f736f1390a04a022020931ff70e87033cdd94bdf434e865993b2258065c5c222a53f29d077bcfa4480147304402206d79ad83f1ab12fc9feee9e66412de842fcbf8de0632beb4433d469f24f0fb4e022079e6df186582f2686a3292bde8e50dac36cb9bec3991995fe331e1daef7df8a401ffffffff0110270000000000001976a914faf1d99bf040ea9c7f8cc9f14ac6733ad75ce24688ac00000000",
"inputs": [ "inputs": [
{ {
@ -143,6 +146,7 @@
}, },
{ {
"description": "Transaction w/ scriptHash(multisig 2-of-3)", "description": "Transaction w/ scriptHash(multisig 2-of-3)",
"network": "testnet",
"txHex": "0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000fd5e0100483045022100eec19e061cad41610f9b42d2b06638b6b0fec3da0de9c6858e7f8c06053979900220622936dd47e202b2ad17639cda680e52334d407149252959936bb1f38e4acc52014830450221009aac215157a74a18234fd06be27448dccee809986bbf93be457a9262f0c69a9402203ff41d7c757f0e8951e4471f205087ecff499f986400ab18210eaad9a628e33c014cc952410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000", "txHex": "0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000fd5e0100483045022100eec19e061cad41610f9b42d2b06638b6b0fec3da0de9c6858e7f8c06053979900220622936dd47e202b2ad17639cda680e52334d407149252959936bb1f38e4acc52014830450221009aac215157a74a18234fd06be27448dccee809986bbf93be457a9262f0c69a9402203ff41d7c757f0e8951e4471f205087ecff499f986400ab18210eaad9a628e33c014cc952410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000",
"inputs": [ "inputs": [
{ {
@ -237,7 +241,8 @@
], ],
"multisig": [ "multisig": [
{ {
"description": "P2SH 2of2 multisig, signed in correct order", "description": "P2SH 2-of-2 multisig, signed in correct order",
"network": "testnet",
"inputs": [ "inputs": [
{ {
"txId": "4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf", "txId": "4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf",
@ -266,7 +271,8 @@
"txHex": "0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd1c0100483045022100e37e33a4fe5fccfb87afb0e951e83fcea4820d73b327d21edc1adec3b916c437022061c5786908b674e323a1863cc2feeb60e1679f1892c10ee08ac21e51fd50ba9001483045022100aa0c323bc639d3d71591be98ccaf7b8cb8c86aa95f060aef5e36fc3f04c4d029022010e2b18de17e307a12ae7e0e88518fe814f18a0ca1ee4510ba23a65628b06576014c8752410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a52aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000" "txHex": "0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd1c0100483045022100e37e33a4fe5fccfb87afb0e951e83fcea4820d73b327d21edc1adec3b916c437022061c5786908b674e323a1863cc2feeb60e1679f1892c10ee08ac21e51fd50ba9001483045022100aa0c323bc639d3d71591be98ccaf7b8cb8c86aa95f060aef5e36fc3f04c4d029022010e2b18de17e307a12ae7e0e88518fe814f18a0ca1ee4510ba23a65628b06576014c8752410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a52aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000"
}, },
{ {
"description": "P2SH 2of2 multisig, signed in shuffled order", "description": "P2SH 2-of-2 multisig, signed in shuffled order",
"network": "testnet",
"inputs": [ "inputs": [
{ {
"txId": "4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf", "txId": "4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf",
@ -295,7 +301,8 @@
"txHex": "0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd1c0100483045022100e37e33a4fe5fccfb87afb0e951e83fcea4820d73b327d21edc1adec3b916c437022061c5786908b674e323a1863cc2feeb60e1679f1892c10ee08ac21e51fd50ba9001483045022100aa0c323bc639d3d71591be98ccaf7b8cb8c86aa95f060aef5e36fc3f04c4d029022010e2b18de17e307a12ae7e0e88518fe814f18a0ca1ee4510ba23a65628b06576014c8752410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a52aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000" "txHex": "0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd1c0100483045022100e37e33a4fe5fccfb87afb0e951e83fcea4820d73b327d21edc1adec3b916c437022061c5786908b674e323a1863cc2feeb60e1679f1892c10ee08ac21e51fd50ba9001483045022100aa0c323bc639d3d71591be98ccaf7b8cb8c86aa95f060aef5e36fc3f04c4d029022010e2b18de17e307a12ae7e0e88518fe814f18a0ca1ee4510ba23a65628b06576014c8752410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a52aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000"
}, },
{ {
"description": "P2SH 2of2 multisig, manually messed up order of signatures", "description": "P2SH 2-of-2 multisig, manually messed up order of signatures",
"network": "testnet",
"inputs": [ "inputs": [
{ {
"txId": "4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf", "txId": "4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf",
@ -324,7 +331,8 @@
"txHex": "0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd1c0100483045022100e37e33a4fe5fccfb87afb0e951e83fcea4820d73b327d21edc1adec3b916c437022061c5786908b674e323a1863cc2feeb60e1679f1892c10ee08ac21e51fd50ba9001483045022100aa0c323bc639d3d71591be98ccaf7b8cb8c86aa95f060aef5e36fc3f04c4d029022010e2b18de17e307a12ae7e0e88518fe814f18a0ca1ee4510ba23a65628b06576014c8752410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a52aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000" "txHex": "0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd1c0100483045022100e37e33a4fe5fccfb87afb0e951e83fcea4820d73b327d21edc1adec3b916c437022061c5786908b674e323a1863cc2feeb60e1679f1892c10ee08ac21e51fd50ba9001483045022100aa0c323bc639d3d71591be98ccaf7b8cb8c86aa95f060aef5e36fc3f04c4d029022010e2b18de17e307a12ae7e0e88518fe814f18a0ca1ee4510ba23a65628b06576014c8752410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a52aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000"
}, },
{ {
"description": "P2SH 2of3 multisig, signed by key 1 and 2", "description": "P2SH 2-of-3 multisig, signed by key 1 and 2",
"network": "testnet",
"inputs": [ "inputs": [
{ {
"txId": "4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf", "txId": "4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf",
@ -353,7 +361,8 @@
"txHex": "0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd5e0100483045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01483045022100ae06d8269b79b5cfa0297d1d88261b0061e52fc2814948c3aa05fa78ee76894302206e0c79a5c90569d8c72a542ef9a06471cbbcd2c651b312339983dfba4f8ff463014cc952410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000" "txHex": "0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd5e0100483045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01483045022100ae06d8269b79b5cfa0297d1d88261b0061e52fc2814948c3aa05fa78ee76894302206e0c79a5c90569d8c72a542ef9a06471cbbcd2c651b312339983dfba4f8ff463014cc952410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000"
}, },
{ {
"description": "P2SH 2of3 multisig, signed by key 1 and 3", "description": "P2SH 2-of-3 multisig, signed by key 1 and 3",
"network": "testnet",
"inputs": [ "inputs": [
{ {
"txId": "4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf", "txId": "4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf",
@ -382,7 +391,8 @@
"txHex": "0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd5e0100483045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01483045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af0014cc952410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000" "txHex": "0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd5e0100483045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01483045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af0014cc952410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000"
}, },
{ {
"description": "P2SH 2of3 multisig, signed by key 3 and 1", "description": "P2SH 2-of-3 multisig, signed by key 3 and 1",
"network": "testnet",
"inputs": [ "inputs": [
{ {
"txId": "4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf", "txId": "4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf",
@ -411,7 +421,8 @@
"txHex": "0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd5e0100483045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01483045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af0014cc952410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000" "txHex": "0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd5e0100483045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01483045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af0014cc952410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000"
}, },
{ {
"description": "P2SH 2of3 multisig, signed by key 1 and 3, manually messed up order of signatures", "description": "P2SH 2-of-3 multisig, signed by key 1 and 3, manually messed up order of signatures",
"network": "testnet",
"inputs": [ "inputs": [
{ {
"txId": "4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf", "txId": "4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf",
@ -440,7 +451,8 @@
"txHex": "0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd5e0100483045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01483045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af0014cc952410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000" "txHex": "0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd5e0100483045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01483045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af0014cc952410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000"
}, },
{ {
"description": "P2SH 2of3 multisig, signed by key 3 and 1, manually removing OP_0s", "description": "P2SH 2-of-3 multisig, signed by key 3 and 1, manually removing OP_0s",
"network": "testnet",
"inputs": [ "inputs": [
{ {
"txId": "4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf", "txId": "4971f016798a167331bcbc67248313fbc444c6e92e4416efd06964425588f5cf",
@ -618,6 +630,7 @@
}, },
{ {
"exception": "Inconsistent redeemScript", "exception": "Inconsistent redeemScript",
"network": "testnet",
"inputs": [ "inputs": [
{ {
"txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
@ -644,6 +657,7 @@
}, },
{ {
"exception": "Inconsistent hashType", "exception": "Inconsistent hashType",
"network": "testnet",
"inputs": [ "inputs": [
{ {
"txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
@ -740,6 +754,30 @@
} }
] ]
}, },
{
"description": "Wrong network for keyPair",
"exception": "Inconsistent network",
"network": "bitcoin",
"inputs": [
{
"txId": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
"vout": 0,
"signs": [
{
"keyPair": "91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgwmaKkrx",
"network": "testnet",
"throws": true
}
]
}
],
"outputs": [
{
"script": "OP_DUP OP_HASH160 aa4d7985c57e011a8b3dd8e0e5a73aaef41629c5 OP_EQUALVERIFY OP_CHECKSIG",
"value": 1000
}
]
},
{ {
"description": "Wrong key pair for multisig redeemScript", "description": "Wrong key pair for multisig redeemScript",
"exception": "key pair cannot sign for this input", "exception": "key pair cannot sign for this input",

39
test/hdnode.js

@ -2,7 +2,6 @@
/* eslint-disable no-new */ /* eslint-disable no-new */
var assert = require('assert') var assert = require('assert')
var networks = require('../src/networks')
var sinon = require('sinon') var sinon = require('sinon')
var BigInteger = require('bigi') var BigInteger = require('bigi')
@ -11,6 +10,12 @@ var HDNode = require('../src/hdnode')
var fixtures = require('./fixtures/hdnode.json') var fixtures = require('./fixtures/hdnode.json')
var NETWORKS = require('../src/networks')
var NETWORKS_LIST = [] // Object.values(NETWORKS)
for (var networkName in NETWORKS) {
NETWORKS_LIST.push(NETWORKS[networkName])
}
describe('HDNode', function () { describe('HDNode', function () {
describe('Constructor', function () { describe('Constructor', function () {
var keyPair, chainCode var keyPair, chainCode
@ -63,7 +68,7 @@ describe('HDNode', function () {
describe('fromSeed*', function () { describe('fromSeed*', function () {
fixtures.valid.forEach(function (f) { fixtures.valid.forEach(function (f) {
it('calculates privKey and chainCode for ' + f.master.fingerprint, function () { it('calculates privKey and chainCode for ' + f.master.fingerprint, function () {
var network = networks[f.network] var network = NETWORKS[f.network]
var hd = HDNode.fromSeedHex(f.master.seed, network) var hd = HDNode.fromSeedHex(f.master.seed, network)
assert.strictEqual(hd.keyPair.toWIF(), f.master.wif) assert.strictEqual(hd.keyPair.toWIF(), f.master.wif)
@ -87,7 +92,7 @@ describe('HDNode', function () {
describe('toBase58', function () { describe('toBase58', function () {
fixtures.valid.forEach(function (f) { fixtures.valid.forEach(function (f) {
it('exports ' + f.master.base58 + ' (public) correctly', function () { it('exports ' + f.master.base58 + ' (public) correctly', function () {
var network = networks[f.network] var network = NETWORKS[f.network]
var hd = HDNode.fromSeedHex(f.master.seed, network).neutered() var hd = HDNode.fromSeedHex(f.master.seed, network).neutered()
assert.strictEqual(hd.toBase58(), f.master.base58) assert.strictEqual(hd.toBase58(), f.master.base58)
@ -96,7 +101,7 @@ describe('HDNode', function () {
fixtures.valid.forEach(function (f) { fixtures.valid.forEach(function (f) {
it('exports ' + f.master.base58Priv + ' (private) correctly', function () { it('exports ' + f.master.base58Priv + ' (private) correctly', function () {
var network = networks[f.network] var network = NETWORKS[f.network]
var hd = HDNode.fromSeedHex(f.master.seed, network) var hd = HDNode.fromSeedHex(f.master.seed, network)
assert.strictEqual(hd.toBase58(), f.master.base58Priv) assert.strictEqual(hd.toBase58(), f.master.base58Priv)
@ -107,8 +112,8 @@ describe('HDNode', function () {
describe('fromBase58', function () { describe('fromBase58', function () {
fixtures.valid.forEach(function (f) { fixtures.valid.forEach(function (f) {
it('imports ' + f.master.base58 + ' (public) correctly', function () { it('imports ' + f.master.base58 + ' (public) correctly', function () {
var network = networks[f.network] var network = NETWORKS[f.network]
var hd = HDNode.fromBase58(f.master.base58) var hd = HDNode.fromBase58(f.master.base58, network)
assert.strictEqual(hd.toBase58(), f.master.base58) assert.strictEqual(hd.toBase58(), f.master.base58)
assert.strictEqual(hd.keyPair.network, network) assert.strictEqual(hd.keyPair.network, network)
@ -117,7 +122,7 @@ describe('HDNode', function () {
fixtures.valid.forEach(function (f) { fixtures.valid.forEach(function (f) {
it('imports ' + f.master.base58Priv + ' (private) correctly', function () { it('imports ' + f.master.base58Priv + ' (private) correctly', function () {
var network = networks[f.network] var network = NETWORKS[f.network]
var hd = HDNode.fromBase58(f.master.base58Priv, network) var hd = HDNode.fromBase58(f.master.base58Priv, network)
assert.strictEqual(hd.toBase58(), f.master.base58Priv) assert.strictEqual(hd.toBase58(), f.master.base58Priv)
@ -128,7 +133,7 @@ describe('HDNode', function () {
fixtures.invalid.fromBase58.forEach(function (f) { fixtures.invalid.fromBase58.forEach(function (f) {
it('throws on ' + f.string, function () { it('throws on ' + f.string, function () {
assert.throws(function () { assert.throws(function () {
var network = networks[f.network] var network = NETWORKS[f.network]
HDNode.fromBase58(f.string, network) HDNode.fromBase58(f.string, network)
}, new RegExp(f.exception)) }, new RegExp(f.exception))
@ -140,7 +145,7 @@ describe('HDNode', function () {
var f = fixtures.valid[0] 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) var hd = HDNode.fromBase58(f.master.base58, NETWORKS_LIST)
assert.strictEqual(hd.getIdentifier().toString('hex'), f.master.identifier) assert.strictEqual(hd.getIdentifier().toString('hex'), f.master.identifier)
}) })
@ -150,7 +155,7 @@ describe('HDNode', function () {
var f = fixtures.valid[0] 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) var hd = HDNode.fromBase58(f.master.base58, NETWORKS_LIST)
assert.strictEqual(hd.getFingerprint().toString('hex'), f.master.fingerprint) assert.strictEqual(hd.getFingerprint().toString('hex'), f.master.fingerprint)
}) })
@ -162,7 +167,7 @@ describe('HDNode', function () {
beforeEach(function () { beforeEach(function () {
var f = fixtures.valid[0] var f = fixtures.valid[0]
hd = HDNode.fromBase58(f.master.base58) hd = HDNode.fromBase58(f.master.base58, NETWORKS_LIST)
}) })
it('wraps ECPair.getAddress', sinon.test(function () { it('wraps ECPair.getAddress', sinon.test(function () {
@ -177,7 +182,7 @@ describe('HDNode', function () {
var f = fixtures.valid[0] 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 hd = HDNode.fromBase58(f.master.base58, NETWORKS_LIST)
var hdn = hd.neutered() var hdn = hd.neutered()
assert.strictEqual(hdn.keyPair.d, undefined) assert.strictEqual(hdn.keyPair.d, undefined)
@ -203,7 +208,7 @@ describe('HDNode', function () {
} }
fixtures.valid.forEach(function (f) { fixtures.valid.forEach(function (f) {
var network = networks[f.network] var network = NETWORKS[f.network]
var hd = HDNode.fromSeedHex(f.master.seed, network) var hd = HDNode.fromSeedHex(f.master.seed, network)
// FIXME: test data is only testing Private -> private for now // FIXME: test data is only testing Private -> private for now
@ -224,7 +229,7 @@ describe('HDNode', function () {
var f = fixtures.valid[1] var f = fixtures.valid[1]
var c = f.children[0] var c = f.children[0]
var master = HDNode.fromBase58(f.master.base58Priv) var master = HDNode.fromBase58(f.master.base58Priv, NETWORKS_LIST)
var child = master.derive(c.m).neutered() var child = master.derive(c.m).neutered()
assert.strictEqual(child.toBase58(), c.base58) assert.strictEqual(child.toBase58(), c.base58)
@ -234,7 +239,7 @@ describe('HDNode', function () {
var f = fixtures.valid[0] var f = fixtures.valid[0]
var c = f.children[0] var c = f.children[0]
var master = HDNode.fromBase58(f.master.base58Priv) var master = HDNode.fromBase58(f.master.base58Priv, NETWORKS_LIST)
var child = master.deriveHardened(c.m).neutered() var child = master.deriveHardened(c.m).neutered()
assert.strictEqual(child.toBase58(), c.base58) assert.strictEqual(child.toBase58(), c.base58)
@ -244,7 +249,7 @@ describe('HDNode', function () {
var f = fixtures.valid[1] var f = fixtures.valid[1]
var c = f.children[0] var c = f.children[0]
var master = HDNode.fromBase58(f.master.base58) var master = HDNode.fromBase58(f.master.base58, NETWORKS_LIST)
var child = master.derive(c.m) var child = master.derive(c.m)
assert.strictEqual(child.toBase58(), c.base58) assert.strictEqual(child.toBase58(), c.base58)
@ -254,7 +259,7 @@ describe('HDNode', function () {
var f = fixtures.valid[0] var f = fixtures.valid[0]
var c = f.children[0] var c = f.children[0]
var master = HDNode.fromBase58(f.master.base58) var master = HDNode.fromBase58(f.master.base58, NETWORKS_LIST)
assert.throws(function () { assert.throws(function () {
master.deriveHardened(c.m) master.deriveHardened(c.m)

4
test/integration/multisig.js

@ -32,7 +32,7 @@ describe('bitcoinjs-lib (multisig)', function () {
'91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgww7vXtT', '91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgww7vXtT',
'91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx3cTMqe', '91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx3cTMqe',
'91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx9rcrL7' '91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx9rcrL7'
].map(bitcoin.ECPair.fromWIF) ].map(function (wif) { return bitcoin.ECPair.fromWIF(wif, bitcoin.networks.testnet) })
var pubKeys = keyPairs.map(function (x) { return x.getPublicKeyBuffer() }) var pubKeys = keyPairs.map(function (x) { return x.getPublicKeyBuffer() })
var redeemScript = bitcoin.scripts.multisigOutput(2, pubKeys) // 2 of 4 var redeemScript = bitcoin.scripts.multisigOutput(2, pubKeys) // 2 of 4
@ -60,7 +60,7 @@ describe('bitcoinjs-lib (multisig)', function () {
network: bitcoin.networks.testnet network: bitcoin.networks.testnet
}).getAddress() }).getAddress()
var txb = new bitcoin.TransactionBuilder() var txb = new bitcoin.TransactionBuilder(bitcoin.networks.testnet)
txb.addInput(unspent.txId, unspent.vout) txb.addInput(unspent.txId, unspent.vout)
txb.addOutput(targetAddress, 1e4) txb.addOutput(targetAddress, 1e4)

22
test/networks.js

@ -1,22 +0,0 @@
/* global describe, it */
var assert = require('assert')
var networks = require('../src/networks')
var HDNode = require('../src/hdnode')
var fixtures = require('./fixtures/network')
describe('networks', function () {
fixtures.forEach(function (f) {
var network = networks[f.network]
Object.keys(f.bip32).forEach(function (name) {
var extb58 = f.bip32[name]
it(extb58 + ' auto-detects ' + f.network, function () {
assert.strictEqual(HDNode.fromBase58(extb58).keyPair.network, network)
})
})
})
})

86
test/transaction_builder.js

@ -10,10 +10,14 @@ var ECPair = require('../src/ecpair')
var Script = require('../src/script') var Script = require('../src/script')
var Transaction = require('../src/transaction') var Transaction = require('../src/transaction')
var TransactionBuilder = require('../src/transaction_builder') var TransactionBuilder = require('../src/transaction_builder')
var NETWORKS = require('../src/networks')
var fixtures = require('./fixtures/transaction_builder') var fixtures = require('./fixtures/transaction_builder')
function construct (txb, f, sign) { function construct (f, sign) {
var network = NETWORKS[f.network]
var txb = new TransactionBuilder(network)
f.inputs.forEach(function (input) { f.inputs.forEach(function (input) {
var prevTxScript var prevTxScript
@ -33,7 +37,7 @@ function construct (txb, f, sign) {
if (sign === undefined || sign) { if (sign === undefined || sign) {
f.inputs.forEach(function (input, index) { f.inputs.forEach(function (input, index) {
input.signs.forEach(function (sign) { input.signs.forEach(function (sign) {
var keyPair = ECPair.fromWIF(sign.keyPair) var keyPair = ECPair.fromWIF(sign.keyPair, network)
var redeemScript var redeemScript
if (sign.redeemScript) { if (sign.redeemScript) {
@ -53,6 +57,8 @@ function construct (txb, f, sign) {
if (f.locktime !== undefined) { if (f.locktime !== undefined) {
txb.tx.locktime = f.locktime txb.tx.locktime = f.locktime
} }
return txb
} }
describe('TransactionBuilder', function () { describe('TransactionBuilder', function () {
@ -74,6 +80,29 @@ describe('TransactionBuilder', function () {
privScript = Address.toOutputScript(privAddress) privScript = Address.toOutputScript(privAddress)
}) })
describe('fromTransaction', function () {
fixtures.valid.build.forEach(function (f) {
it('builds the correct TransactionBuilder for ' + f.description, function () {
var network = NETWORKS[f.network || 'bitcoin']
var tx = Transaction.fromHex(f.txHex)
var txb = TransactionBuilder.fromTransaction(tx, network)
assert.strictEqual(txb.build().toHex(), f.txHex)
assert.strictEqual(txb.network, network)
})
})
fixtures.invalid.fromTransaction.forEach(function (f) {
it('throws on ' + f.exception, function () {
var tx = Transaction.fromHex(f.txHex)
assert.throws(function () {
TransactionBuilder.fromTransaction(tx)
}, new RegExp(f.exception))
})
})
})
describe('addInput', function () { describe('addInput', function () {
it('accepts a txHash, index [and sequence number]', function () { it('accepts a txHash, index [and sequence number]', function () {
var vin = txb.addInput(prevTxHash, 1, 54) var vin = txb.addInput(prevTxHash, 1, 54)
@ -142,6 +171,12 @@ describe('TransactionBuilder', function () {
assert.strictEqual(txout.value, 1000) assert.strictEqual(txout.value, 1000)
}) })
it('throws if address is of the wrong network', function () {
assert.throws(function () {
txb.addOutput('2NGHjvjw83pcVFgMcA7QvSMh2c246rxLVz9', 1000)
}, /2NGHjvjw83pcVFgMcA7QvSMh2c246rxLVz9 has no matching Script/)
})
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.addInput(prevTxHash, 0)
txb.addOutput(privScript, 2000) txb.addOutput(privScript, 2000)
@ -155,12 +190,13 @@ describe('TransactionBuilder', function () {
describe('sign', function () { describe('sign', function () {
fixtures.invalid.sign.forEach(function (f) { fixtures.invalid.sign.forEach(function (f) {
it('throws on ' + f.exception + ' (' + f.description + ')', function () { it('throws on ' + f.exception + (f.description ? ' (' + f.description + ')' : ''), function () {
construct(txb, f, false) txb = construct(f, false)
f.inputs.forEach(function (input, index) { f.inputs.forEach(function (input, index) {
input.signs.forEach(function (sign) { input.signs.forEach(function (sign) {
var keyPair = ECPair.fromWIF(sign.keyPair) var keyPairNetwork = NETWORKS[sign.network || f.network]
var keyPair = ECPair.fromWIF(sign.keyPair, keyPairNetwork)
var redeemScript var redeemScript
if (sign.redeemScript) { if (sign.redeemScript) {
@ -184,7 +220,7 @@ describe('TransactionBuilder', function () {
describe('build', function () { describe('build', function () {
fixtures.valid.build.forEach(function (f) { fixtures.valid.build.forEach(function (f) {
it('builds "' + f.description + '"', function () { it('builds "' + f.description + '"', function () {
construct(txb, f) txb = construct(f)
var tx = txb.build() var tx = txb.build()
assert.strictEqual(tx.toHex(), f.txHex) assert.strictEqual(tx.toHex(), f.txHex)
@ -197,8 +233,9 @@ describe('TransactionBuilder', function () {
if (f.txHex) { if (f.txHex) {
var tx = Transaction.fromHex(f.txHex) var tx = Transaction.fromHex(f.txHex)
txb = TransactionBuilder.fromTransaction(tx) txb = TransactionBuilder.fromTransaction(tx)
} else { } else {
construct(txb, f) txb = construct(f)
} }
}) })
@ -219,9 +256,10 @@ describe('TransactionBuilder', function () {
describe('multisig', function () { describe('multisig', function () {
fixtures.valid.multisig.forEach(function (f) { fixtures.valid.multisig.forEach(function (f) {
it(f.description, function () { it(f.description, function () {
construct(txb, f, false) txb = construct(f, false)
var tx var tx
var network = NETWORKS[f.network]
f.inputs.forEach(function (input, i) { f.inputs.forEach(function (input, i) {
var redeemScript = Script.fromASM(input.redeemScript) var redeemScript = Script.fromASM(input.redeemScript)
@ -245,10 +283,10 @@ describe('TransactionBuilder', function () {
} }
// now import it // now import it
txb = TransactionBuilder.fromTransaction(tx) txb = TransactionBuilder.fromTransaction(tx, network)
} }
var keyPair = ECPair.fromWIF(sign.keyPair) var keyPair = ECPair.fromWIF(sign.keyPair, network)
txb.sign(i, keyPair, redeemScript, sign.hashType) txb.sign(i, keyPair, redeemScript, sign.hashType)
// update the tx // update the tx
@ -267,36 +305,18 @@ describe('TransactionBuilder', function () {
describe('multisig edge case', function () { describe('multisig edge case', function () {
it('should handle badly pre-filled OP_0s', function () { it('should handle badly pre-filled OP_0s', function () {
txb = TransactionBuilder.fromTransaction(Transaction.fromHex('0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd16010000483045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d014cc952410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000')) var lameTx = Transaction.fromHex('0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd16010000483045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d014cc952410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000')
var network = NETWORKS.testnet
txb = TransactionBuilder.fromTransaction(lameTx, network)
var redeemScript = Script.fromASM('OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG') var redeemScript = Script.fromASM('OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG')
var keyPair = ECPair.fromWIF('91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx3cTMqe') var keyPair = ECPair.fromWIF('91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx3cTMqe', network)
txb.sign(0, keyPair, redeemScript) txb.sign(0, keyPair, redeemScript)
var tx = txb.build() var tx = txb.build()
assert.equal(tx.toHex(), '0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd5e0100483045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01483045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af0014cc952410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000') assert.equal(tx.toHex(), '0100000001cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f0714900000000fd5e0100483045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01483045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af0014cc952410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253aeffffffff01e8030000000000001976a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac00000000')
}) })
}) })
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)
assert.strictEqual(txb.build().toHex(), f.txHex)
})
})
fixtures.invalid.fromTransaction.forEach(function (f) {
it('throws on ' + f.exception, function () {
var tx = Transaction.fromHex(f.txHex)
assert.throws(function () {
TransactionBuilder.fromTransaction(tx)
}, new RegExp(f.exception))
})
})
})
}) })

Loading…
Cancel
Save