Merge branch 'master' into bnjs

This commit is contained in:
Daniel Cousens 2018-06-26 13:15:07 +10:00 committed by GitHub
commit 8220e33d76
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 1050 additions and 1042 deletions

View file

@ -1,10 +1,10 @@
/* global describe, it */
let assert = require('assert')
let baddress = require('../src/address')
let bscript = require('../src/script')
let fixtures = require('./fixtures/address.json')
let NETWORKS = Object.assign({
const assert = require('assert')
const baddress = require('../src/address')
const bscript = require('../src/script')
const fixtures = require('./fixtures/address.json')
const NETWORKS = Object.assign({
litecoin: {
messagePrefix: '\x19Litecoin Signed Message:\n',
bip32: {
@ -23,7 +23,7 @@ describe('address', function () {
if (!f.base58check) return
it('decodes ' + f.base58check, function () {
var decode = baddress.fromBase58Check(f.base58check)
const decode = baddress.fromBase58Check(f.base58check)
assert.strictEqual(decode.version, f.version)
assert.strictEqual(decode.hash.toString('hex'), f.hash)
@ -44,7 +44,7 @@ describe('address', function () {
if (!f.bech32) return
it('decodes ' + f.bech32, function () {
var actual = baddress.fromBech32(f.bech32)
const actual = baddress.fromBech32(f.bech32)
assert.strictEqual(actual.version, f.version)
assert.strictEqual(actual.prefix, NETWORKS[f.network].bech32)
@ -64,8 +64,8 @@ describe('address', function () {
describe('fromOutputScript', function () {
fixtures.standard.forEach(function (f) {
it('encodes ' + f.script.slice(0, 30) + '... (' + f.network + ')', function () {
var script = bscript.fromASM(f.script)
var address = baddress.fromOutputScript(script, NETWORKS[f.network])
const script = bscript.fromASM(f.script)
const address = baddress.fromOutputScript(script, NETWORKS[f.network])
assert.strictEqual(address, f.base58check || f.bech32.toLowerCase())
})
@ -73,7 +73,7 @@ describe('address', function () {
fixtures.invalid.fromOutputScript.forEach(function (f) {
it('throws when ' + f.script.slice(0, 30) + '... ' + f.exception, function () {
var script = bscript.fromASM(f.script)
const script = bscript.fromASM(f.script)
assert.throws(function () {
baddress.fromOutputScript(script)
@ -87,7 +87,7 @@ describe('address', function () {
if (!f.base58check) return
it('encodes ' + f.hash + ' (' + f.network + ')', function () {
var address = baddress.toBase58Check(Buffer.from(f.hash, 'hex'), f.version)
const address = baddress.toBase58Check(Buffer.from(f.hash, 'hex'), f.version)
assert.strictEqual(address, f.base58check)
})
@ -97,7 +97,7 @@ describe('address', function () {
describe('toBech32', function () {
fixtures.bech32.forEach((f, i) => {
if (!f.bech32) return
var data = Buffer.from(f.data, 'hex')
const data = Buffer.from(f.data, 'hex')
it('encode ' + f.address, function () {
assert.deepEqual(baddress.toBech32(data, f.version, f.prefix), f.address)
@ -118,7 +118,7 @@ describe('address', function () {
describe('toOutputScript', function () {
fixtures.standard.forEach(function (f) {
it('decodes ' + f.script.slice(0, 30) + '... (' + f.network + ')', function () {
var script = baddress.toOutputScript(f.base58check || f.bech32, NETWORKS[f.network])
const script = baddress.toOutputScript(f.base58check || f.bech32, NETWORKS[f.network])
assert.strictEqual(bscript.toASM(script), f.script)
})

View file

@ -1,35 +1,35 @@
/* global describe, it */
var assert = require('assert')
var base58 = require('bs58')
var bitcoin = require('../')
const assert = require('assert')
const base58 = require('bs58')
const bitcoin = require('../')
var base58EncodeDecode = require('./fixtures/core/base58_encode_decode.json')
var base58KeysInvalid = require('./fixtures/core/base58_keys_invalid.json')
var base58KeysValid = require('./fixtures/core/base58_keys_valid.json')
var blocksValid = require('./fixtures/core/blocks.json')
var sigCanonical = require('./fixtures/core/sig_canonical.json')
var sigHash = require('./fixtures/core/sighash.json')
var sigNoncanonical = require('./fixtures/core/sig_noncanonical.json')
var txValid = require('./fixtures/core/tx_valid.json')
const base58EncodeDecode = require('./fixtures/core/base58_encode_decode.json')
const base58KeysInvalid = require('./fixtures/core/base58_keys_invalid.json')
const base58KeysValid = require('./fixtures/core/base58_keys_valid.json')
const blocksValid = require('./fixtures/core/blocks.json')
const sigCanonical = require('./fixtures/core/sig_canonical.json')
const sigHash = require('./fixtures/core/sighash.json')
const sigNoncanonical = require('./fixtures/core/sig_noncanonical.json')
const txValid = require('./fixtures/core/tx_valid.json')
describe('Bitcoin-core', function () {
// base58EncodeDecode
describe('base58', function () {
base58EncodeDecode.forEach(function (f) {
var fhex = f[0]
var fb58 = f[1]
const fhex = f[0]
const fb58 = f[1]
it('can decode ' + fb58, function () {
var buffer = base58.decode(fb58)
var actual = buffer.toString('hex')
const buffer = base58.decode(fb58)
const actual = buffer.toString('hex')
assert.strictEqual(actual, fhex)
})
it('can encode ' + fhex, function () {
var buffer = Buffer.from(fhex, 'hex')
var actual = base58.encode(buffer)
const buffer = Buffer.from(fhex, 'hex')
const actual = base58.encode(buffer)
assert.strictEqual(actual, fb58)
})
@ -38,20 +38,20 @@ describe('Bitcoin-core', function () {
// base58KeysValid
describe('address.toBase58Check', function () {
var typeMap = {
const typeMap = {
'pubkey': 'pubKeyHash',
'script': 'scriptHash'
}
base58KeysValid.forEach(function (f) {
var expected = f[0]
var hash = Buffer.from(f[1], 'hex')
var params = f[2]
const expected = f[0]
const hash = Buffer.from(f[1], 'hex')
const params = f[2]
if (params.isPrivkey) return
var network = params.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin
var version = network[typeMap[params.addrType]]
const network = params.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin
const version = network[typeMap[params.addrType]]
it('can export ' + expected, function () {
assert.strictEqual(bitcoin.address.toBase58Check(hash, version), expected)
@ -61,7 +61,7 @@ describe('Bitcoin-core', function () {
// base58KeysInvalid
describe('address.fromBase58Check', function () {
var allowedNetworks = [
const allowedNetworks = [
bitcoin.networks.bitcoin.pubkeyhash,
bitcoin.networks.bitcoin.scripthash,
bitcoin.networks.testnet.pubkeyhash,
@ -69,11 +69,11 @@ describe('Bitcoin-core', function () {
]
base58KeysInvalid.forEach(function (f) {
var string = f[0]
const string = f[0]
it('throws on ' + string, function () {
assert.throws(function () {
var address = bitcoin.address.fromBase58Check(string)
const address = bitcoin.address.fromBase58Check(string)
assert.notEqual(allowedNetworks.indexOf(address.version), -1, 'Invalid network')
}, /(Invalid (checksum|network))|(too (short|long))/)
@ -84,14 +84,14 @@ describe('Bitcoin-core', function () {
// base58KeysValid
describe('ECPair', function () {
base58KeysValid.forEach(function (f) {
var string = f[0]
var hex = f[1]
var params = f[2]
const string = f[0]
const hex = f[1]
const params = f[2]
if (!params.isPrivkey) return
var network = params.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin
var keyPair = bitcoin.ECPair.fromWIF(string, network)
const network = params.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin
const keyPair = bitcoin.ECPair.fromWIF(string, network)
it('fromWIF imports ' + string, function () {
assert.strictEqual(keyPair.privateKey.toString('hex'), hex)
@ -106,13 +106,13 @@ describe('Bitcoin-core', function () {
// base58KeysInvalid
describe('ECPair.fromWIF', function () {
var allowedNetworks = [
const allowedNetworks = [
bitcoin.networks.bitcoin,
bitcoin.networks.testnet
]
base58KeysInvalid.forEach(function (f) {
var string = f[0]
const string = f[0]
it('throws on ' + string, function () {
assert.throws(function () {
@ -125,7 +125,7 @@ describe('Bitcoin-core', function () {
describe('Block.fromHex', function () {
blocksValid.forEach(function (f) {
it('can parse ' + f.id, function () {
var block = bitcoin.Block.fromHex(f.hex)
const block = bitcoin.Block.fromHex(f.hex)
assert.strictEqual(block.getId(), f.id)
assert.strictEqual(block.transactions.length, f.transactions)
@ -139,19 +139,19 @@ describe('Bitcoin-core', function () {
// 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?
const inputs = f[0]
const fhex = f[1]
// const verifyFlags = f[2] // TODO: do we need to test this?
it('can decode ' + fhex, function () {
var transaction = bitcoin.Transaction.fromHex(fhex)
const transaction = bitcoin.Transaction.fromHex(fhex)
transaction.ins.forEach(function (txIn, i) {
var input = inputs[i]
const input = inputs[i]
// reverse because test data is reversed
var prevOutHash = Buffer.from(input[0], 'hex').reverse()
var prevOutIndex = input[1]
const prevOutHash = Buffer.from(input[0], 'hex').reverse()
const prevOutIndex = input[1]
assert.deepEqual(txIn.hash, prevOutHash)
@ -168,29 +168,29 @@ describe('Bitcoin-core', function () {
// Objects that are only a single string are ignored
if (f.length === 1) return
var txHex = f[0]
var scriptHex = f[1]
var inIndex = f[2]
var hashType = f[3]
var expectedHash = f[4]
const txHex = f[0]
const scriptHex = f[1]
const inIndex = f[2]
const hashType = f[3]
const expectedHash = f[4]
var hashTypes = []
const hashTypes = []
if ((hashType & 0x1f) === bitcoin.Transaction.SIGHASH_NONE) hashTypes.push('SIGHASH_NONE')
else if ((hashType & 0x1f) === bitcoin.Transaction.SIGHASH_SINGLE) hashTypes.push('SIGHASH_SINGLE')
else hashTypes.push('SIGHASH_ALL')
if (hashType & bitcoin.Transaction.SIGHASH_ANYONECANPAY) hashTypes.push('SIGHASH_ANYONECANPAY')
var hashTypeName = hashTypes.join(' | ')
const hashTypeName = hashTypes.join(' | ')
it('should hash ' + txHex.slice(0, 40) + '... (' + hashTypeName + ')', function () {
var transaction = bitcoin.Transaction.fromHex(txHex)
const transaction = bitcoin.Transaction.fromHex(txHex)
assert.strictEqual(transaction.toHex(), txHex)
var script = Buffer.from(scriptHex, 'hex')
var scriptChunks = bitcoin.script.decompile(script)
const script = Buffer.from(scriptHex, 'hex')
const scriptChunks = bitcoin.script.decompile(script)
assert.strictEqual(bitcoin.script.compile(scriptChunks).toString('hex'), scriptHex)
var hash = transaction.hashForSignature(inIndex, script, hashType)
const hash = transaction.hashForSignature(inIndex, script, hashType)
// reverse because test data is reversed
assert.equal(hash.reverse().toString('hex'), expectedHash)
@ -200,11 +200,11 @@ describe('Bitcoin-core', function () {
describe('script.signature.decode', function () {
sigCanonical.forEach(function (hex) {
var buffer = Buffer.from(hex, 'hex')
const buffer = Buffer.from(hex, 'hex')
it('can parse ' + hex, function () {
var parsed = bitcoin.script.signature.decode(buffer)
var actual = bitcoin.script.signature.encode(parsed.signature, parsed.hashType)
const parsed = bitcoin.script.signature.decode(buffer)
const actual = bitcoin.script.signature.encode(parsed.signature, parsed.hashType)
assert.strictEqual(actual.toString('hex'), hex)
})
@ -214,8 +214,8 @@ describe('Bitcoin-core', function () {
if (i === 0) return
if (i % 2 !== 0) return
var description = sigNoncanonical[i - 1].slice(0, -1)
var buffer = Buffer.from(hex, 'hex')
const description = sigNoncanonical[i - 1].slice(0, -1)
const buffer = Buffer.from(hex, 'hex')
it('throws on ' + description, function () {
assert.throws(function () {

View file

@ -1,15 +1,15 @@
/* global describe, it, beforeEach */
var assert = require('assert')
var Block = require('../src/block')
const assert = require('assert')
const Block = require('../src/block')
var fixtures = require('./fixtures/block')
const fixtures = require('./fixtures/block')
describe('Block', function () {
describe('version', function () {
it('should be interpreted as an int32le', function () {
var blockHex = 'ffffffff0000000000000000000000000000000000000000000000000000000000000000414141414141414141414141414141414141414141414141414141414141414101000000020000000300000000'
var block = Block.fromHex(blockHex)
const blockHex = 'ffffffff0000000000000000000000000000000000000000000000000000000000000000414141414141414141414141414141414141414141414141414141414141414101000000020000000300000000'
const block = Block.fromHex(blockHex)
assert.equal(-1, block.version)
assert.equal(1, block.timestamp)
})
@ -18,7 +18,7 @@ describe('Block', function () {
describe('calculateTarget', function () {
fixtures.targets.forEach(function (f) {
it('returns ' + f.expected + ' for 0x' + f.bits, function () {
var bits = parseInt(f.bits, 16)
const bits = parseInt(f.bits, 16)
assert.equal(Block.calculateTarget(bits).toString('hex'), f.expected)
})
@ -28,7 +28,7 @@ describe('Block', function () {
describe('fromBuffer/fromHex', function () {
fixtures.valid.forEach(function (f) {
it('imports ' + f.description, function () {
var block = Block.fromHex(f.hex)
const block = Block.fromHex(f.hex)
assert.strictEqual(block.version, f.version)
assert.strictEqual(block.prevHash.toString('hex'), f.prevHash)
@ -51,7 +51,7 @@ describe('Block', function () {
describe('toBuffer/toHex', function () {
fixtures.valid.forEach(function (f) {
var block
let block
beforeEach(function () {
block = Block.fromHex(f.hex)
@ -66,7 +66,7 @@ describe('Block', function () {
describe('getHash/getId', function () {
fixtures.valid.forEach(function (f) {
var block
let block
beforeEach(function () {
block = Block.fromHex(f.hex)
@ -81,14 +81,14 @@ describe('Block', function () {
describe('getUTCDate', function () {
fixtures.valid.forEach(function (f) {
var block
let block
beforeEach(function () {
block = Block.fromHex(f.hex)
})
it('returns UTC date of ' + f.id, function () {
var utcDate = block.getUTCDate().getTime()
const utcDate = block.getUTCDate().getTime()
assert.strictEqual(utcDate, f.timestamp * 1e3)
})
@ -105,7 +105,7 @@ describe('Block', function () {
fixtures.valid.forEach(function (f) {
if (f.hex.length === 160) return
var block
let block
beforeEach(function () {
block = Block.fromHex(f.hex)
@ -121,7 +121,7 @@ describe('Block', function () {
fixtures.valid.forEach(function (f) {
if (f.hex.length === 160) return
var block
let block
beforeEach(function () {
block = Block.fromHex(f.hex)
@ -135,7 +135,7 @@ describe('Block', function () {
describe('checkProofOfWork', function () {
fixtures.valid.forEach(function (f) {
var block
let block
beforeEach(function () {
block = Block.fromHex(f.hex)

View file

@ -1,16 +1,16 @@
/* global describe, it */
var assert = require('assert')
var bufferutils = require('../src/bufferutils')
const assert = require('assert')
const bufferutils = require('../src/bufferutils')
var fixtures = require('./fixtures/bufferutils.json')
const fixtures = require('./fixtures/bufferutils.json')
describe('bufferutils', function () {
describe('readUInt64LE', function () {
fixtures.valid.forEach(function (f) {
it('decodes ' + f.hex, function () {
var buffer = Buffer.from(f.hex, 'hex')
var number = bufferutils.readUInt64LE(buffer, 0)
const buffer = Buffer.from(f.hex, 'hex')
const number = bufferutils.readUInt64LE(buffer, 0)
assert.strictEqual(number, f.dec)
})
@ -18,7 +18,7 @@ describe('bufferutils', function () {
fixtures.invalid.readUInt64LE.forEach(function (f) {
it('throws on ' + f.description, function () {
var buffer = Buffer.from(f.hex, 'hex')
const buffer = Buffer.from(f.hex, 'hex')
assert.throws(function () {
bufferutils.readUInt64LE(buffer, 0)
@ -30,7 +30,7 @@ describe('bufferutils', function () {
describe('writeUInt64LE', function () {
fixtures.valid.forEach(function (f) {
it('encodes ' + f.dec, function () {
var buffer = Buffer.alloc(8, 0)
const buffer = Buffer.alloc(8, 0)
bufferutils.writeUInt64LE(buffer, f.dec, 0)
assert.strictEqual(buffer.toString('hex'), f.hex)
@ -39,7 +39,7 @@ describe('bufferutils', function () {
fixtures.invalid.readUInt64LE.forEach(function (f) {
it('throws on ' + f.description, function () {
var buffer = Buffer.alloc(8, 0)
const buffer = Buffer.alloc(8, 0)
assert.throws(function () {
bufferutils.writeUInt64LE(buffer, f.dec, 0)

View file

@ -1,20 +1,20 @@
/* global describe, it */
var assert = require('assert')
var bcrypto = require('../src/crypto')
const assert = require('assert')
const bcrypto = require('../src/crypto')
var fixtures = require('./fixtures/crypto')
const fixtures = require('./fixtures/crypto')
describe('crypto', function () {
['hash160', 'hash256', 'ripemd160', 'sha1', 'sha256'].forEach(function (algorithm) {
describe(algorithm, function () {
fixtures.forEach(function (f) {
var fn = bcrypto[algorithm]
var expected = f[algorithm]
const fn = bcrypto[algorithm]
const expected = f[algorithm]
it('returns ' + expected + ' for ' + f.hex, function () {
var data = Buffer.from(f.hex, 'hex')
var actual = fn(data).toString('hex')
const data = Buffer.from(f.hex, 'hex')
const actual = fn(data).toString('hex')
assert.strictEqual(actual, expected)
})

View file

@ -1,36 +1,36 @@
/* global describe, it, beforeEach */
/* eslint-disable no-new */
let assert = require('assert')
let proxyquire = require('proxyquire')
let hoodwink = require('hoodwink')
const assert = require('assert')
const proxyquire = require('proxyquire')
const hoodwink = require('hoodwink')
let ECPair = require('../src/ecpair')
let tinysecp = require('tiny-secp256k1')
const ECPair = require('../src/ecpair')
const tinysecp = require('tiny-secp256k1')
let fixtures = require('./fixtures/ecpair.json')
const fixtures = require('./fixtures/ecpair.json')
let NETWORKS = require('../src/networks')
let NETWORKS_LIST = [] // Object.values(NETWORKS)
const NETWORKS = require('../src/networks')
const NETWORKS_LIST = [] // Object.values(NETWORKS)
for (let networkName in NETWORKS) {
NETWORKS_LIST.push(NETWORKS[networkName])
}
let ZERO = Buffer.alloc(32, 0)
let ONE = Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex')
let GROUP_ORDER = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 'hex')
let GROUP_ORDER_LESS_1 = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140', 'hex')
const ZERO = Buffer.alloc(32, 0)
const ONE = Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex')
const GROUP_ORDER = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 'hex')
const GROUP_ORDER_LESS_1 = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140', 'hex')
describe('ECPair', function () {
describe('constructor', function () {
it('defaults to compressed', function () {
let keyPair = ECPair.fromPrivateKey(ONE)
const keyPair = ECPair.fromPrivateKey(ONE)
assert.strictEqual(keyPair.compressed, true)
})
it('supports the uncompressed option', function () {
let keyPair = ECPair.fromPrivateKey(ONE, {
const keyPair = ECPair.fromPrivateKey(ONE, {
compressed: false
})
@ -38,7 +38,7 @@ describe('ECPair', function () {
})
it('supports the network option', function () {
let keyPair = ECPair.fromPrivateKey(ONE, {
const keyPair = ECPair.fromPrivateKey(ONE, {
compressed: false,
network: NETWORKS.testnet
})
@ -48,10 +48,10 @@ describe('ECPair', function () {
fixtures.valid.forEach(function (f) {
it('derives public key for ' + f.WIF, function () {
let d = Buffer.from(f.d, 'hex')
const d = Buffer.from(f.d, 'hex')
console.log(d)
let keyPair = ECPair.fromPrivateKey(d, {
const keyPair = ECPair.fromPrivateKey(d, {
compressed: f.compressed
})
@ -62,12 +62,12 @@ describe('ECPair', function () {
fixtures.invalid.constructor.forEach(function (f) {
it('throws ' + f.exception, function () {
if (f.d) {
let d = Buffer.from(f.d, 'hex')
const d = Buffer.from(f.d, 'hex')
assert.throws(function () {
ECPair.fromPrivateKey(d, f.options)
}, new RegExp(f.exception))
} else {
let Q = Buffer.from(f.Q, 'hex')
const Q = Buffer.from(f.Q, 'hex')
assert.throws(function () {
ECPair.fromPublicKey(Q, f.options)
}, new RegExp(f.exception))
@ -95,8 +95,8 @@ describe('ECPair', function () {
describe('fromWIF', function () {
fixtures.valid.forEach(function (f) {
it('imports ' + f.WIF + ' (' + f.network + ')', function () {
let network = NETWORKS[f.network]
let keyPair = ECPair.fromWIF(f.WIF, network)
const network = NETWORKS[f.network]
const keyPair = ECPair.fromWIF(f.WIF, network)
assert.strictEqual(keyPair.privateKey.toString('hex'), f.d)
assert.strictEqual(keyPair.compressed, f.compressed)
@ -106,7 +106,7 @@ describe('ECPair', function () {
fixtures.valid.forEach(function (f) {
it('imports ' + f.WIF + ' (via list of networks)', function () {
let keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST)
const keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST)
assert.strictEqual(keyPair.privateKey.toString('hex'), f.d)
assert.strictEqual(keyPair.compressed, f.compressed)
@ -117,7 +117,7 @@ describe('ECPair', function () {
fixtures.invalid.fromWIF.forEach(function (f) {
it('throws on ' + f.WIF, function () {
assert.throws(function () {
let networks = f.network ? NETWORKS[f.network] : NETWORKS_LIST
const networks = f.network ? NETWORKS[f.network] : NETWORKS_LIST
ECPair.fromWIF(f.WIF, networks)
}, new RegExp(f.exception))
@ -128,29 +128,29 @@ describe('ECPair', function () {
describe('toWIF', function () {
fixtures.valid.forEach(function (f) {
it('exports ' + f.WIF, function () {
let keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST)
let result = keyPair.toWIF()
const keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST)
const result = keyPair.toWIF()
assert.strictEqual(result, f.WIF)
})
})
})
describe('makeRandom', function () {
let d = Buffer.alloc(32, 4)
let exWIF = 'KwMWvwRJeFqxYyhZgNwYuYjbQENDAPAudQx5VEmKJrUZcq6aL2pv'
const d = Buffer.alloc(32, 4)
const exWIF = 'KwMWvwRJeFqxYyhZgNwYuYjbQENDAPAudQx5VEmKJrUZcq6aL2pv'
describe('uses randombytes RNG', function () {
it('generates a ECPair', function () {
let stub = { randombytes: function () { return d } }
let ProxiedECPair = proxyquire('../src/ecpair', stub)
const stub = { randombytes: function () { return d } }
const ProxiedECPair = proxyquire('../src/ecpair', stub)
let keyPair = ProxiedECPair.makeRandom()
const keyPair = ProxiedECPair.makeRandom()
assert.strictEqual(keyPair.toWIF(), exWIF)
})
})
it('allows a custom RNG to be used', function () {
let keyPair = ECPair.makeRandom({
const keyPair = ECPair.makeRandom({
rng: function (size) { return d.slice(0, size) }
})
@ -158,14 +158,14 @@ describe('ECPair', function () {
})
it('retains the same defaults as ECPair constructor', function () {
let keyPair = ECPair.makeRandom()
const keyPair = ECPair.makeRandom()
assert.strictEqual(keyPair.compressed, true)
assert.strictEqual(keyPair.network, NETWORKS.bitcoin)
})
it('supports the options parameter', function () {
let keyPair = ECPair.makeRandom({
const keyPair = ECPair.makeRandom({
compressed: false,
network: NETWORKS.testnet
})
@ -185,7 +185,7 @@ describe('ECPair', function () {
})
it('loops until d is within interval [1, n) : 1', hoodwink(function () {
let rng = this.stub(function f () {
const rng = this.stub(function f () {
if (f.calls === 0) return ZERO // 0
return ONE // >0
}, 2)
@ -194,7 +194,7 @@ describe('ECPair', function () {
}))
it('loops until d is within interval [1, n) : n - 1', hoodwink(function () {
let rng = this.stub(function f () {
const rng = this.stub(function f () {
if (f.calls === 0) return ZERO // <1
if (f.calls === 1) return GROUP_ORDER // >n-1
return GROUP_ORDER_LESS_1 // n-1
@ -207,8 +207,8 @@ describe('ECPair', function () {
describe('.network', function () {
fixtures.valid.forEach(function (f) {
it('returns ' + f.network + ' for ' + f.WIF, function () {
let network = NETWORKS[f.network]
let keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST)
const network = NETWORKS[f.network]
const keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST)
assert.strictEqual(keyPair.network, network)
})
@ -216,7 +216,9 @@ describe('ECPair', function () {
})
describe('tinysecp wrappers', function () {
let keyPair, hash, signature
let keyPair
let hash
let signature
beforeEach(function () {
keyPair = ECPair.makeRandom()

View file

@ -1,9 +1,9 @@
var assert = require('assert')
var bitcoin = require('../../')
var dhttp = require('dhttp/200')
const assert = require('assert')
const bitcoin = require('../../')
const dhttp = require('dhttp/200')
var APIPASS = process.env.APIPASS || 'satoshi'
var APIURL = 'https://api.dcousens.cloud/1'
const APIPASS = process.env.APIPASS || 'satoshi'
const APIURL = 'https://api.dcousens.cloud/1'
function broadcast (txHex, callback) {
dhttp({
@ -60,7 +60,7 @@ function verify (txo, callback) {
fetch(txo.txId, function (err, tx) {
if (err) return callback(err)
var txoActual = tx.outs[txo.vout]
const txoActual = tx.outs[txo.vout]
if (txo.address) assert.strictEqual(txoActual.address, txo.address)
if (txo.value) assert.strictEqual(txoActual.value, txo.value)
callback()
@ -68,8 +68,8 @@ function verify (txo, callback) {
}
// TODO: remove
let baddress = bitcoin.address
let bcrypto = bitcoin.crypto
const baddress = bitcoin.address
const bcrypto = bitcoin.crypto
function getAddress (node, network) {
network = network || bitcoin.networks.bitcoin
return baddress.toBase58Check(bcrypto.hash160(node.publicKey), network.pubKeyHash)

View file

@ -1,10 +1,10 @@
/* global describe, it */
let assert = require('assert')
let bitcoin = require('../../')
let dhttp = require('dhttp/200')
const assert = require('assert')
const bitcoin = require('../../')
const dhttp = require('dhttp/200')
let LITECOIN = {
const LITECOIN = {
messagePrefix: '\x19Litecoin Signed Message:\n',
bip32: {
public: 0x019da462,
@ -19,8 +19,8 @@ let LITECOIN = {
function rng () { return Buffer.from('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz') }
// TODO: remove
let baddress = bitcoin.address
let bcrypto = bitcoin.crypto
const baddress = bitcoin.address
const bcrypto = bitcoin.crypto
function getAddress (node, network) {
network = network || bitcoin.networks.bitcoin
return baddress.toBase58Check(bcrypto.hash160(node.publicKey), network.pubKeyHash)
@ -28,17 +28,17 @@ function getAddress (node, network) {
describe('bitcoinjs-lib (addresses)', function () {
it('can generate a random address', function () {
var keyPair = bitcoin.ECPair.makeRandom({ rng: rng })
var address = getAddress(keyPair)
const keyPair = bitcoin.ECPair.makeRandom({ rng: rng })
const address = getAddress(keyPair)
assert.strictEqual(address, '1F5VhMHukdnUES9kfXqzPzMeF1GPHKiF64')
})
it('can generate an address from a SHA256 hash', function () {
var hash = bitcoin.crypto.sha256(Buffer.from('correct horse battery staple'))
const hash = bitcoin.crypto.sha256(Buffer.from('correct horse battery staple'))
var keyPair = bitcoin.ECPair.fromPrivateKey(hash)
var address = getAddress(keyPair)
const keyPair = bitcoin.ECPair.fromPrivateKey(hash)
const address = getAddress(keyPair)
// Generating addresses from SHA256 hashes is not secure if the input to the hash function is predictable
// Do not use with predictable inputs
@ -46,70 +46,70 @@ describe('bitcoinjs-lib (addresses)', function () {
})
it('can import an address via WIF', function () {
var keyPair = bitcoin.ECPair.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct')
var address = getAddress(keyPair)
const keyPair = bitcoin.ECPair.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct')
const address = getAddress(keyPair)
assert.strictEqual(address, '19AAjaTUbRjQCMuVczepkoPswiZRhjtg31')
})
it('can generate a 2-of-3 multisig P2SH address', function () {
var pubKeys = [
const pubKeys = [
'026477115981fe981a6918a6297d9803c4dc04f328f22041bedff886bbc2962e01',
'02c96db2302d19b43d4c69368babace7854cc84eb9e061cde51cfa77ca4a22b8b9',
'03c6103b3b83e4a24a0e33a4df246ef11772f9992663db0c35759a5e2ebf68d8e9'
].map(function (hex) { return Buffer.from(hex, 'hex') })
var redeemScript = bitcoin.script.multisig.output.encode(2, pubKeys) // 2 of 3
var scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
var address = bitcoin.address.fromOutputScript(scriptPubKey)
const redeemScript = bitcoin.script.multisig.output.encode(2, pubKeys) // 2 of 3
const scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
const address = bitcoin.address.fromOutputScript(scriptPubKey)
assert.strictEqual(address, '36NUkt6FWUi3LAWBqWRdDmdTWbt91Yvfu7')
})
it('can generate a SegWit address', function () {
var keyPair = bitcoin.ECPair.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct')
const keyPair = bitcoin.ECPair.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct')
var scriptPubKey = bitcoin.script.witnessPubKeyHash.output.encode(bitcoin.crypto.hash160(keyPair.publicKey))
var address = bitcoin.address.fromOutputScript(scriptPubKey)
const scriptPubKey = bitcoin.script.witnessPubKeyHash.output.encode(bitcoin.crypto.hash160(keyPair.publicKey))
const address = bitcoin.address.fromOutputScript(scriptPubKey)
assert.strictEqual(address, 'bc1qt97wqg464zrhnx23upykca5annqvwkwujjglky')
})
it('can generate a SegWit address (via P2SH)', function () {
var keyPair = bitcoin.ECPair.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct')
const keyPair = bitcoin.ECPair.fromWIF('Kxr9tQED9H44gCmp6HAdmemAzU3n84H3dGkuWTKvE23JgHMW8gct')
var redeemScript = bitcoin.script.witnessPubKeyHash.output.encode(bitcoin.crypto.hash160(keyPair.publicKey))
var scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
var address = bitcoin.address.fromOutputScript(scriptPubKey)
const redeemScript = bitcoin.script.witnessPubKeyHash.output.encode(bitcoin.crypto.hash160(keyPair.publicKey))
const scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
const address = bitcoin.address.fromOutputScript(scriptPubKey)
assert.strictEqual(address, '34AgLJhwXrvmkZS1o5TrcdeevMt22Nar53')
})
it('can generate a SegWit 3-of-4 multisig address', function () {
var pubKeys = [
const pubKeys = [
'026477115981fe981a6918a6297d9803c4dc04f328f22041bedff886bbc2962e01',
'02c96db2302d19b43d4c69368babace7854cc84eb9e061cde51cfa77ca4a22b8b9',
'023e4740d0ba639e28963f3476157b7cf2fb7c6fdf4254f97099cf8670b505ea59',
'03c6103b3b83e4a24a0e33a4df246ef11772f9992663db0c35759a5e2ebf68d8e9'
].map(function (hex) { return Buffer.from(hex, 'hex') })
var witnessScript = bitcoin.script.multisig.output.encode(3, pubKeys) // 3 of 4
var scriptPubKey = bitcoin.script.witnessScriptHash.output.encode(bitcoin.crypto.sha256(witnessScript))
var address = bitcoin.address.fromOutputScript(scriptPubKey)
const witnessScript = bitcoin.script.multisig.output.encode(3, pubKeys) // 3 of 4
const scriptPubKey = bitcoin.script.witnessScriptHash.output.encode(bitcoin.crypto.sha256(witnessScript))
const address = bitcoin.address.fromOutputScript(scriptPubKey)
assert.strictEqual(address, 'bc1q75f6dv4q8ug7zhujrsp5t0hzf33lllnr3fe7e2pra3v24mzl8rrqtp3qul')
})
it('can generate a SegWit 2-of-2 multisig address (via P2SH)', function () {
var pubKeys = [
const pubKeys = [
'026477115981fe981a6918a6297d9803c4dc04f328f22041bedff886bbc2962e01',
'02c96db2302d19b43d4c69368babace7854cc84eb9e061cde51cfa77ca4a22b8b9'
].map(function (hex) { return Buffer.from(hex, 'hex') })
var witnessScript = bitcoin.script.multisig.output.encode(2, pubKeys) // 2 of 2
var redeemScript = bitcoin.script.witnessScriptHash.output.encode(bitcoin.crypto.sha256(witnessScript))
var scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
var address = bitcoin.address.fromOutputScript(scriptPubKey)
const witnessScript = bitcoin.script.multisig.output.encode(2, pubKeys) // 2 of 2
const redeemScript = bitcoin.script.witnessScriptHash.output.encode(bitcoin.crypto.sha256(witnessScript))
const scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
const address = bitcoin.address.fromOutputScript(scriptPubKey)
assert.strictEqual(address, '3P4mrxQfmExfhxqjLnR2Ah4WES5EB1KBrN')
})
@ -134,19 +134,19 @@ describe('bitcoinjs-lib (addresses)', function () {
// other networks
it('can generate a Testnet address', function () {
let testnet = bitcoin.networks.testnet
let keyPair = bitcoin.ECPair.makeRandom({ network: testnet, rng: rng })
let wif = keyPair.toWIF()
let address = getAddress(keyPair, testnet)
const testnet = bitcoin.networks.testnet
const keyPair = bitcoin.ECPair.makeRandom({ network: testnet, rng: rng })
const wif = keyPair.toWIF()
const address = getAddress(keyPair, testnet)
assert.strictEqual(address, 'mubSzQNtZfDj1YdNP6pNDuZy6zs6GDn61L')
assert.strictEqual(wif, 'cRgnQe9MUu1JznntrLaoQpB476M8PURvXVQB5R2eqms5tXnzNsrr')
})
it('can generate a Litecoin address', function () {
let keyPair = bitcoin.ECPair.makeRandom({ network: LITECOIN, rng: rng })
let wif = keyPair.toWIF()
let address = getAddress(keyPair, LITECOIN)
const keyPair = bitcoin.ECPair.makeRandom({ network: LITECOIN, rng: rng })
const wif = keyPair.toWIF()
const address = getAddress(keyPair, LITECOIN)
assert.strictEqual(address, 'LZJSxZbjqJ2XVEquqfqHg1RQTDdfST5PTn')
assert.strictEqual(wif, 'T7A4PUSgTDHecBxW1ZiYFrDNRih2o7M8Gf9xpoCgudPF9gDiNvuS')

View file

@ -1,13 +1,13 @@
/* global describe, it */
let assert = require('assert')
let bip32 = require('bip32')
let bip39 = require('bip39')
let bitcoin = require('../../')
const assert = require('assert')
const bip32 = require('bip32')
const bip39 = require('bip39')
const bitcoin = require('../../')
// TODO: remove
let baddress = bitcoin.address
let bcrypto = bitcoin.crypto
const baddress = bitcoin.address
const bcrypto = bitcoin.crypto
function getAddress (node, network) {
network = network || bitcoin.networks.bitcoin
return baddress.toBase58Check(bcrypto.hash160(node.publicKey), network.pubKeyHash)
@ -15,40 +15,40 @@ function getAddress (node, network) {
describe('bitcoinjs-lib (BIP32)', function () {
it('can import a BIP32 testnet xpriv and export to WIF', function () {
var xpriv = 'tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK'
var node = bip32.fromBase58(xpriv, bitcoin.networks.testnet)
const xpriv = 'tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK'
const node = bip32.fromBase58(xpriv, bitcoin.networks.testnet)
assert.equal(node.toWIF(), 'cQfoY67cetFNunmBUX5wJiw3VNoYx3gG9U9CAofKE6BfiV1fSRw7')
})
it('can export a BIP32 xpriv, then import it', function () {
var mnemonic = 'praise you muffin lion enable neck grocery crumble super myself license ghost'
var seed = bip39.mnemonicToSeed(mnemonic)
var node = bip32.fromSeed(seed)
var string = node.toBase58()
var restored = bip32.fromBase58(string)
const mnemonic = 'praise you muffin lion enable neck grocery crumble super myself license ghost'
const seed = bip39.mnemonicToSeed(mnemonic)
const node = bip32.fromSeed(seed)
const string = node.toBase58()
const restored = bip32.fromBase58(string)
assert.equal(getAddress(node), getAddress(restored)) // same public key
assert.equal(node.toWIF(), restored.toWIF()) // same private key
})
it('can export a BIP32 xpub', function () {
var mnemonic = 'praise you muffin lion enable neck grocery crumble super myself license ghost'
var seed = bip39.mnemonicToSeed(mnemonic)
var node = bip32.fromSeed(seed)
var string = node.neutered().toBase58()
const mnemonic = 'praise you muffin lion enable neck grocery crumble super myself license ghost'
const seed = bip39.mnemonicToSeed(mnemonic)
const node = bip32.fromSeed(seed)
const string = node.neutered().toBase58()
assert.equal(string, 'xpub661MyMwAqRbcGhVeaVfEBA25e3cP9DsJQZoE8iep5fZSxy3TnPBNBgWnMZx56oreNc48ZoTkQfatNJ9VWnQ7ZcLZcVStpaXLTeG8bGrzX3n')
})
it('can create a BIP32, bitcoin, account 0, external address', function () {
var path = "m/0'/0/0"
var root = bip32.fromSeed(Buffer.from('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', 'hex'))
const path = "m/0'/0/0"
const root = bip32.fromSeed(Buffer.from('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', 'hex'))
var child1 = root.derivePath(path)
const child1 = root.derivePath(path)
// option 2, manually
var child1b = root.deriveHardened(0)
const child1b = root.deriveHardened(0)
.derive(0)
.derive(0)
@ -57,12 +57,12 @@ describe('bitcoinjs-lib (BIP32)', function () {
})
it('can create a BIP44, bitcoin, account 0, external address', function () {
var root = bip32.fromSeed(Buffer.from('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', 'hex'))
const root = bip32.fromSeed(Buffer.from('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', 'hex'))
var child1 = root.derivePath("m/44'/0'/0'/0/0")
const child1 = root.derivePath("m/44'/0'/0'/0/0")
// option 2, manually
var child1b = root.deriveHardened(44)
const child1b = root.deriveHardened(44)
.deriveHardened(0)
.deriveHardened(0)
.derive(0)
@ -73,29 +73,29 @@ describe('bitcoinjs-lib (BIP32)', function () {
})
it('can create a BIP49, bitcoin testnet, account 0, external address', function () {
var mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'
var seed = bip39.mnemonicToSeed(mnemonic)
var root = bip32.fromSeed(seed)
const mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'
const seed = bip39.mnemonicToSeed(mnemonic)
const root = bip32.fromSeed(seed)
var path = "m/49'/1'/0'/0/0"
var child = root.derivePath(path)
const path = "m/49'/1'/0'/0/0"
const child = root.derivePath(path)
var keyhash = bitcoin.crypto.hash160(child.publicKey)
var scriptSig = bitcoin.script.witnessPubKeyHash.output.encode(keyhash)
var addressBytes = bitcoin.crypto.hash160(scriptSig)
var outputScript = bitcoin.script.scriptHash.output.encode(addressBytes)
var address = bitcoin.address.fromOutputScript(outputScript, bitcoin.networks.testnet)
const keyhash = bitcoin.crypto.hash160(child.publicKey)
const scriptSig = bitcoin.script.witnessPubKeyHash.output.encode(keyhash)
const addressBytes = bitcoin.crypto.hash160(scriptSig)
const outputScript = bitcoin.script.scriptHash.output.encode(addressBytes)
const address = bitcoin.address.fromOutputScript(outputScript, bitcoin.networks.testnet)
assert.equal(address, '2Mww8dCYPUpKHofjgcXcBCEGmniw9CoaiD2')
})
it('can use BIP39 to generate BIP32 addresses', function () {
// var mnemonic = bip39.generateMnemonic()
var mnemonic = 'praise you muffin lion enable neck grocery crumble super myself license ghost'
const mnemonic = 'praise you muffin lion enable neck grocery crumble super myself license ghost'
assert(bip39.validateMnemonic(mnemonic))
var seed = bip39.mnemonicToSeed(mnemonic)
var root = bip32.fromSeed(seed)
const seed = bip39.mnemonicToSeed(mnemonic)
const root = bip32.fromSeed(seed)
// receive addresses
assert.strictEqual(getAddress(root.derivePath("m/0'/0/0")), '1AVQHbGuES57wD68AJi7Gcobc3RZrfYWTC')

View file

@ -1,22 +1,22 @@
/* global describe, it */
'use strict'
var assert = require('assert')
var bitcoin = require('../../')
const assert = require('assert')
const bitcoin = require('../../')
describe('bitcoinjs-lib (blocks)', function () {
it('can extract a height from a CoinBase transaction', function () {
// from 00000000000000000097669cdca131f24d40c4cc7d80eaa65967a2d09acf6ce6
let txHex = '010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff50037f9a07174d696e656420627920416e74506f6f6c685b205a2b1f7bfabe6d6d36afe1910eca9405b66f97750940a656e38e2c0312958190ff8e98fd16761d220400000000000000aa340000d49f0000ffffffff02b07fc366000000001976a9148349212dc27ce3ab4c5b29b85c4dec643d764b1788ac0000000000000000266a24aa21a9ed72d9432948505e3d3062f1307a3f027a5dea846ff85e47159680919c12bf1e400120000000000000000000000000000000000000000000000000000000000000000000000000'
let tx = bitcoin.Transaction.fromHex(txHex)
const txHex = '010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff50037f9a07174d696e656420627920416e74506f6f6c685b205a2b1f7bfabe6d6d36afe1910eca9405b66f97750940a656e38e2c0312958190ff8e98fd16761d220400000000000000aa340000d49f0000ffffffff02b07fc366000000001976a9148349212dc27ce3ab4c5b29b85c4dec643d764b1788ac0000000000000000266a24aa21a9ed72d9432948505e3d3062f1307a3f027a5dea846ff85e47159680919c12bf1e400120000000000000000000000000000000000000000000000000000000000000000000000000'
const tx = bitcoin.Transaction.fromHex(txHex)
assert.strictEqual(tx.ins.length, 1)
let script = tx.ins[0].script
const script = tx.ins[0].script
// bitcoin.script.decompile(script) // returns [] :(
assert.strictEqual(script[0], 0x03)
let heightBuffer = script.slice(1, 4)
let height = bitcoin.script.number.decode(heightBuffer)
const heightBuffer = script.slice(1, 4)
const height = bitcoin.script.number.decode(heightBuffer)
assert.strictEqual(height, 498303)
})
})

View file

@ -1,13 +1,13 @@
/* global describe, it, before */
var assert = require('assert')
var bitcoin = require('../../')
var regtestUtils = require('./_regtest')
var regtest = regtestUtils.network
var bip65 = require('bip65')
const assert = require('assert')
const bitcoin = require('../../')
const regtestUtils = require('./_regtest')
const regtest = regtestUtils.network
const bip65 = require('bip65')
var alice = bitcoin.ECPair.fromWIF('cScfkGjbzzoeewVWmU2hYPUHeVGJRDdFt7WhmrVVGkxpmPP8BHWe', regtest)
var bob = bitcoin.ECPair.fromWIF('cMkopUXKWsEzAjfa1zApksGRwjVpJRB3831qM9W4gKZsLwjHXA9x', regtest)
const alice = bitcoin.ECPair.fromWIF('cScfkGjbzzoeewVWmU2hYPUHeVGJRDdFt7WhmrVVGkxpmPP8BHWe', regtest)
const bob = bitcoin.ECPair.fromWIF('cMkopUXKWsEzAjfa1zApksGRwjVpJRB3831qM9W4gKZsLwjHXA9x', regtest)
describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
// force update MTP
@ -15,7 +15,7 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
regtestUtils.mine(11, done)
})
let hashType = bitcoin.Transaction.SIGHASH_ALL
const hashType = bitcoin.Transaction.SIGHASH_ALL
function cltvCheckSigOutput (aQ, bQ, lockTime) {
return bitcoin.script.compile([
@ -43,24 +43,24 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
this.timeout(30000)
// 3 hours ago
let lockTime = bip65.encode({ utc: utcNow() - (3600 * 3) })
let redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
let scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
let address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
const lockTime = bip65.encode({ utc: utcNow() - (3600 * 3) })
const redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
const scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
const address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
// fund the P2SH(CLTV) address
regtestUtils.faucet(address, 1e5, function (err, unspent) {
if (err) return done(err)
var txb = new bitcoin.TransactionBuilder(regtest)
const txb = new bitcoin.TransactionBuilder(regtest)
txb.setLockTime(lockTime)
txb.addInput(unspent.txId, unspent.vout, 0xfffffffe)
txb.addOutput(regtestUtils.RANDOM_ADDRESS, 7e4)
// {Alice's signature} OP_TRUE
var tx = txb.buildIncomplete()
var signatureHash = tx.hashForSignature(0, redeemScript, hashType)
var redeemScriptSig = bitcoin.script.scriptHash.input.encode([
const tx = txb.buildIncomplete()
const signatureHash = tx.hashForSignature(0, redeemScript, hashType)
const redeemScriptSig = bitcoin.script.scriptHash.input.encode([
bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
bitcoin.opcodes.OP_TRUE
], redeemScript)
@ -87,24 +87,24 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
if (err) return done(err)
// 5 blocks from now
var lockTime = bip65.encode({ blocks: height + 5 })
var redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
var scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
var address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
const lockTime = bip65.encode({ blocks: height + 5 })
const redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
const scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
const address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
// fund the P2SH(CLTV) address
regtestUtils.faucet(address, 1e5, function (err, unspent) {
if (err) return done(err)
var txb = new bitcoin.TransactionBuilder(regtest)
const txb = new bitcoin.TransactionBuilder(regtest)
txb.setLockTime(lockTime)
txb.addInput(unspent.txId, unspent.vout, 0xfffffffe)
txb.addOutput(regtestUtils.RANDOM_ADDRESS, 7e4)
// {Alice's signature} OP_TRUE
var tx = txb.buildIncomplete()
var signatureHash = tx.hashForSignature(0, redeemScript, hashType)
var redeemScriptSig = bitcoin.script.scriptHash.input.encode([
const tx = txb.buildIncomplete()
const signatureHash = tx.hashForSignature(0, redeemScript, hashType)
const redeemScriptSig = bitcoin.script.scriptHash.input.encode([
bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
bitcoin.opcodes.OP_TRUE
], redeemScript)
@ -136,24 +136,24 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
this.timeout(30000)
// two hours ago
var lockTime = bip65.encode({ utc: utcNow() - (3600 * 2) })
var redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
var scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
var address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
const lockTime = bip65.encode({ utc: utcNow() - (3600 * 2) })
const redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
const scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
const address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
// fund the P2SH(CLTV) address
regtestUtils.faucet(address, 2e5, function (err, unspent) {
if (err) return done(err)
var txb = new bitcoin.TransactionBuilder(regtest)
const txb = new bitcoin.TransactionBuilder(regtest)
txb.setLockTime(lockTime)
txb.addInput(unspent.txId, unspent.vout, 0xfffffffe)
txb.addOutput(regtestUtils.RANDOM_ADDRESS, 8e4)
// {Alice's signature} {Bob's signature} OP_FALSE
var tx = txb.buildIncomplete()
var signatureHash = tx.hashForSignature(0, redeemScript, hashType)
var redeemScriptSig = bitcoin.script.scriptHash.input.encode([
const tx = txb.buildIncomplete()
const signatureHash = tx.hashForSignature(0, redeemScript, hashType)
const redeemScriptSig = bitcoin.script.scriptHash.input.encode([
bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
bitcoin.script.signature.encode(bob.sign(signatureHash), hashType),
bitcoin.opcodes.OP_FALSE
@ -178,24 +178,24 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
this.timeout(30000)
// two hours from now
var lockTime = bip65.encode({ utc: utcNow() + (3600 * 2) })
var redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
var scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
var address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
const lockTime = bip65.encode({ utc: utcNow() + (3600 * 2) })
const redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
const scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
const address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
// fund the P2SH(CLTV) address
regtestUtils.faucet(address, 2e4, function (err, unspent) {
if (err) return done(err)
var txb = new bitcoin.TransactionBuilder(regtest)
const txb = new bitcoin.TransactionBuilder(regtest)
txb.setLockTime(lockTime)
txb.addInput(unspent.txId, unspent.vout, 0xfffffffe)
txb.addOutput(regtestUtils.RANDOM_ADDRESS, 1e4)
// {Alice's signature} OP_TRUE
var tx = txb.buildIncomplete()
var signatureHash = tx.hashForSignature(0, redeemScript, hashType)
var redeemScriptSig = bitcoin.script.scriptHash.input.encode([
const tx = txb.buildIncomplete()
const signatureHash = tx.hashForSignature(0, redeemScript, hashType)
const redeemScriptSig = bitcoin.script.scriptHash.input.encode([
bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
bitcoin.script.signature.encode(bob.sign(signatureHash), hashType),
bitcoin.opcodes.OP_TRUE

View file

@ -1,32 +1,33 @@
/* global describe, it */
var assert = require('assert')
var BN = require('bn.js')
var bitcoin = require('../../')
var bip32 = require('bip32')
var crypto = require('crypto')
var tinysecp = require('tiny-secp256k1')
var ecurve = require('ecurve')
var secp256k1 = ecurve.getCurveByName('secp256k1')
const assert = require('assert')
const bigi = require('bigi')
const bitcoin = require('../../')
const bip32 = require('bip32')
const crypto = require('crypto')
const tinysecp = require('tiny-secp256k1')
const ecurve = require('ecurve')
const secp256k1 = ecurve.getCurveByName('secp256k1')
describe('bitcoinjs-lib (crypto)', function () {
it('can recover a private key from duplicate R values', function () {
this.timeout(30000)
// https://blockchain.info/tx/f4c16475f2a6e9c602e4a287f9db3040e319eb9ece74761a4b84bc820fbeef50
var tx = bitcoin.Transaction.fromHex('01000000020b668015b32a6178d8524cfef6dc6fc0a4751915c2e9b2ed2d2eab02424341c8000000006a47304402205e00298dc5265b7a914974c9d0298aa0e69a0ca932cb52a360436d6a622e5cd7022024bf5f506968f5f23f1835574d5afe0e9021b4a5b65cf9742332d5e4acb68f41012103fd089f73735129f3d798a657aaaa4aa62a00fa15c76b61fc7f1b27ed1d0f35b8ffffffffa95fa69f11dc1cbb77ef64f25a95d4b12ebda57d19d843333819d95c9172ff89000000006b48304502205e00298dc5265b7a914974c9d0298aa0e69a0ca932cb52a360436d6a622e5cd7022100832176b59e8f50c56631acbc824bcba936c9476c559c42a4468be98975d07562012103fd089f73735129f3d798a657aaaa4aa62a00fa15c76b61fc7f1b27ed1d0f35b8ffffffff02b000eb04000000001976a91472956eed9a8ecb19ae7e3ebd7b06cae4668696a788ac303db000000000001976a9146c0bd55dd2592287cd9992ce3ba3fc1208fb76da88ac00000000')
const tx = bitcoin.Transaction.fromHex('01000000020b668015b32a6178d8524cfef6dc6fc0a4751915c2e9b2ed2d2eab02424341c8000000006a47304402205e00298dc5265b7a914974c9d0298aa0e69a0ca932cb52a360436d6a622e5cd7022024bf5f506968f5f23f1835574d5afe0e9021b4a5b65cf9742332d5e4acb68f41012103fd089f73735129f3d798a657aaaa4aa62a00fa15c76b61fc7f1b27ed1d0f35b8ffffffffa95fa69f11dc1cbb77ef64f25a95d4b12ebda57d19d843333819d95c9172ff89000000006b48304502205e00298dc5265b7a914974c9d0298aa0e69a0ca932cb52a360436d6a622e5cd7022100832176b59e8f50c56631acbc824bcba936c9476c559c42a4468be98975d07562012103fd089f73735129f3d798a657aaaa4aa62a00fa15c76b61fc7f1b27ed1d0f35b8ffffffff02b000eb04000000001976a91472956eed9a8ecb19ae7e3ebd7b06cae4668696a788ac303db000000000001976a9146c0bd55dd2592287cd9992ce3ba3fc1208fb76da88ac00000000')
tx.ins.forEach(function (input, vin) {
var script = input.script
var scriptChunks = bitcoin.script.decompile(script)
const script = input.script
const scriptChunks = bitcoin.script.decompile(script)
assert(bitcoin.script.pubKeyHash.input.check(scriptChunks), 'Expected pubKeyHash script')
var prevOutScript = bitcoin.address.toOutputScript('1ArJ9vRaQcoQ29mTWZH768AmRwzb6Zif1z')
var scriptSignature = bitcoin.script.signature.decode(scriptChunks[0])
var publicKey = bitcoin.ECPair.fromPublicKey(scriptChunks[1])
const prevOutScript = bitcoin.address.toOutputScript('1ArJ9vRaQcoQ29mTWZH768AmRwzb6Zif1z')
const scriptSignature = bitcoin.script.signature.decode(scriptChunks[0])
const publicKey = bitcoin.ECPair.fromPublicKey(scriptChunks[1])
var m = tx.hashForSignature(vin, prevOutScript, scriptSignature.hashType)
const m = tx.hashForSignature(vin, prevOutScript, scriptSignature.hashType)
assert(publicKey.verify(m, scriptSignature.signature), 'Invalid m')
// store the required information
@ -34,35 +35,35 @@ describe('bitcoinjs-lib (crypto)', function () {
input.z = new BN(m)
})
// finally, run the tasks, then on to the mathmod
var n = new BN(secp256k1.n.toString())
// finally, run the tasks, then on to the math
const n = new BN(secp256k1.n.toString())
for (var i = 0; i < tx.ins.length; ++i) {
for (var j = i + 1; j < tx.ins.length; ++j) {
var inputA = tx.ins[i]
var inputB = tx.ins[j]
const inputA = tx.ins[i]
const inputB = tx.ins[j]
// enforce matching r values
let r = inputA.signature.slice(0, 32)
let rB = inputB.signature.slice(0, 32)
const r = inputA.signature.slice(0, 32)
const rB = inputB.signature.slice(0, 32)
assert.strictEqual(r.toString('hex'), rB.toString('hex'))
var rInv = new BN(r).invm(n)
const rInv = new BN(r).invm(n)
var s1 = new BN(inputA.signature.slice(32, 64))
var s2 = new BN(inputB.signature.slice(32, 64))
var z1 = inputA.z
var z2 = inputB.z
const s1 = new BN(inputA.signature.slice(32, 64))
const s2 = new BN(inputB.signature.slice(32, 64))
const z1 = inputA.z
const z2 = inputB.z
var zz = z1.sub(z2).mod(n)
var ss = s1.sub(s2).mod(n)
const zz = z1.sub(z2).mod(n)
const ss = s1.sub(s2).mod(n)
// k = (z1 - z2) / (s1 - s2)
// d1 = (s1 * k - z1) / r
// d2 = (s2 * k - z2) / r
var k = zz.mul(ss.invm(n)).mod(n)
var d1 = ((s1.mul(k).mod(n)).sub(z1).mod(n)).mul(rInv).mod(n)
var d2 = ((s2.mul(k).mod(n)).sub(z2).mod(n)).mul(rInv).mod(n)
const k = zz.mul(ss.invm(n)).mod(n)
const d1 = ((s1.mul(k).mod(n)).sub(z1).mod(n)).mul(rInv).mod(n)
const d2 = ((s2.mul(k).mod(n)).sub(z2).mod(n)).mul(rInv).mod(n)
// enforce matching private keys
assert.strictEqual(d1.toString(), d2.toString())
@ -75,41 +76,41 @@ describe('bitcoinjs-lib (crypto)', function () {
assert(master.isNeutered(), 'You already have the parent private key')
assert(!child.isNeutered(), 'Missing child private key')
var serQP = master.publicKey
var d1 = child.privateKey
var d2
var data = Buffer.alloc(37)
const serQP = master.publicKey
const d1 = child.privateKey
const data = Buffer.alloc(37)
serQP.copy(data, 0)
// search index space until we find it
let d2
for (var i = 0; i < 0x80000000; ++i) {
data.writeUInt32BE(i, 33)
// calculate I
var I = crypto.createHmac('sha512', master.chainCode).update(data).digest()
var IL = I.slice(0, 32)
const I = crypto.createHmac('sha512', master.chainCode).update(data).digest()
const IL = I.slice(0, 32)
// See bip32.js:273 to understand
d2 = tinysecp.privateSub(d1, IL)
var Qp = bip32.fromPrivateKey(d2, Buffer.alloc(32, 0)).publicKey
const Qp = bip32.fromPrivateKey(d2, Buffer.alloc(32, 0)).publicKey
if (Qp.equals(serQP)) break
}
var node = bip32.fromPrivateKey(d2, master.chainCode, master.network)
const node = bip32.fromPrivateKey(d2, master.chainCode, master.network)
node.depth = master.depth
node.index = master.index
node.masterFingerprint = master.masterFingerprint
return node
}
var seed = crypto.randomBytes(32)
var master = bip32.fromSeed(seed)
var child = master.derive(6) // m/6
const seed = crypto.randomBytes(32)
const master = bip32.fromSeed(seed)
const child = master.derive(6) // m/6
// now for the recovery
var neuteredMaster = master.neutered()
var recovered = recoverParent(neuteredMaster, child)
const neuteredMaster = master.neutered()
const recovered = recoverParent(neuteredMaster, child)
assert.strictEqual(recovered.toBase58(), master.toBase58())
})
})

View file

@ -1,13 +1,13 @@
/* global describe, it, before */
let assert = require('assert')
let bitcoin = require('../../')
let regtestUtils = require('./_regtest')
let regtest = regtestUtils.network
let bip68 = require('bip68')
const assert = require('assert')
const bitcoin = require('../../')
const regtestUtils = require('./_regtest')
const regtest = regtestUtils.network
const bip68 = require('bip68')
let alice = bitcoin.ECPair.fromWIF('cScfkGjbzzoeewVWmU2hYPUHeVGJRDdFt7WhmrVVGkxpmPP8BHWe', regtest)
let bob = bitcoin.ECPair.fromWIF('cMkopUXKWsEzAjfa1zApksGRwjVpJRB3831qM9W4gKZsLwjHXA9x', regtest)
const alice = bitcoin.ECPair.fromWIF('cScfkGjbzzoeewVWmU2hYPUHeVGJRDdFt7WhmrVVGkxpmPP8BHWe', regtest)
const bob = bitcoin.ECPair.fromWIF('cMkopUXKWsEzAjfa1zApksGRwjVpJRB3831qM9W4gKZsLwjHXA9x', regtest)
describe('bitcoinjs-lib (transactions w/ CSV)', function () {
// force update MTP
@ -15,7 +15,7 @@ describe('bitcoinjs-lib (transactions w/ CSV)', function () {
regtestUtils.mine(11, done)
})
let hashType = bitcoin.Transaction.SIGHASH_ALL
const hashType = bitcoin.Transaction.SIGHASH_ALL
// IF MTP (from when confirmed) > seconds, aQ can redeem
function csvCheckSigOutput (aQ, bQ, sequence) {
@ -43,23 +43,23 @@ describe('bitcoinjs-lib (transactions w/ CSV)', function () {
if (err) return done(err)
// 5 blocks from now
let sequence = bip68.encode({ blocks: 5 })
let redeemScript = csvCheckSigOutput(alice, bob, sequence)
let scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
let address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
const sequence = bip68.encode({ blocks: 5 })
const redeemScript = csvCheckSigOutput(alice, bob, sequence)
const scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
const address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
// fund the P2SH(CSV) address
regtestUtils.faucet(address, 1e5, function (err, unspent) {
if (err) return done(err)
let txb = new bitcoin.TransactionBuilder(regtest)
const txb = new bitcoin.TransactionBuilder(regtest)
txb.addInput(unspent.txId, unspent.vout, sequence)
txb.addOutput(regtestUtils.RANDOM_ADDRESS, 7e4)
// {Alice's signature} OP_TRUE
let tx = txb.buildIncomplete()
let signatureHash = tx.hashForSignature(0, redeemScript, hashType)
let redeemScriptSig = bitcoin.script.scriptHash.input.encode([
const tx = txb.buildIncomplete()
const signatureHash = tx.hashForSignature(0, redeemScript, hashType)
const redeemScriptSig = bitcoin.script.scriptHash.input.encode([
bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
bitcoin.opcodes.OP_TRUE
], redeemScript)
@ -91,23 +91,23 @@ describe('bitcoinjs-lib (transactions w/ CSV)', function () {
this.timeout(30000)
// two hours after confirmation
let sequence = bip68.encode({ seconds: 7168 })
let redeemScript = csvCheckSigOutput(alice, bob, sequence)
let scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
let address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
const sequence = bip68.encode({ seconds: 7168 })
const redeemScript = csvCheckSigOutput(alice, bob, sequence)
const scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
const address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
// fund the P2SH(CSV) address
regtestUtils.faucet(address, 2e4, function (err, unspent) {
if (err) return done(err)
let txb = new bitcoin.TransactionBuilder(regtest)
const txb = new bitcoin.TransactionBuilder(regtest)
txb.addInput(unspent.txId, unspent.vout, sequence)
txb.addOutput(regtestUtils.RANDOM_ADDRESS, 1e4)
// {Alice's signature} OP_TRUE
let tx = txb.buildIncomplete()
let signatureHash = tx.hashForSignature(0, redeemScript, hashType)
let redeemScriptSig = bitcoin.script.scriptHash.input.encode([
const tx = txb.buildIncomplete()
const signatureHash = tx.hashForSignature(0, redeemScript, hashType)
const redeemScriptSig = bitcoin.script.scriptHash.input.encode([
bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
bitcoin.script.signature.encode(bob.sign(signatureHash), hashType),
bitcoin.opcodes.OP_TRUE

View file

@ -1,72 +1,72 @@
/* global describe, it */
let assert = require('assert')
let bitcoin = require('../../')
let ecc = require('tiny-secp256k1')
const assert = require('assert')
const bitcoin = require('../../')
const ecc = require('tiny-secp256k1')
// TODO: remove
let baddress = bitcoin.address
let bcrypto = bitcoin.crypto
const baddress = bitcoin.address
const bcrypto = bitcoin.crypto
function getAddress (node) {
return baddress.toBase58Check(bcrypto.hash160(node.publicKey), bitcoin.networks.bitcoin.pubKeyHash)
}
// vG = (dG \+ sha256(e * dG)G)
function stealthSend (e, Q) {
var eQ = ecc.pointMultiply(Q, e, true) // shared secret
var c = bitcoin.crypto.sha256(eQ)
var Qc = ecc.pointAddScalar(Q, c)
var vG = bitcoin.ECPair.fromPublicKey(Qc)
const eQ = ecc.pointMultiply(Q, e, true) // shared secret
const c = bitcoin.crypto.sha256(eQ)
const Qc = ecc.pointAddScalar(Q, c)
const vG = bitcoin.ECPair.fromPublicKey(Qc)
return vG
}
// v = (d + sha256(eG * d))
function stealthReceive (d, eG) {
var eQ = ecc.pointMultiply(eG, d) // shared secret
var c = bitcoin.crypto.sha256(eQ)
var dc = ecc.privateAdd(d, c)
var v = bitcoin.ECPair.fromPrivateKey(dc)
const eQ = ecc.pointMultiply(eG, d) // shared secret
const c = bitcoin.crypto.sha256(eQ)
const dc = ecc.privateAdd(d, c)
const v = bitcoin.ECPair.fromPrivateKey(dc)
return v
}
// d = (v - sha256(e * dG))
function stealthRecoverLeaked (v, e, Q) {
var eQ = ecc.pointMultiply(Q, e) // shared secret
var c = bitcoin.crypto.sha256(eQ)
var vc = ecc.privateSub(v, c)
var d = bitcoin.ECPair.fromPrivateKey(vc)
const eQ = ecc.pointMultiply(Q, e) // shared secret
const c = bitcoin.crypto.sha256(eQ)
const vc = ecc.privateSub(v, c)
const d = bitcoin.ECPair.fromPrivateKey(vc)
return d
}
// vG = (rG \+ sha256(e * dG)G)
function stealthDualSend (e, R, Q) {
var eQ = ecc.pointMultiply(Q, e) // shared secret
var c = bitcoin.crypto.sha256(eQ)
var Rc = ecc.pointAddScalar(R, c)
var vG = bitcoin.ECPair.fromPublicKey(Rc)
const eQ = ecc.pointMultiply(Q, e) // shared secret
const c = bitcoin.crypto.sha256(eQ)
const Rc = ecc.pointAddScalar(R, c)
const vG = bitcoin.ECPair.fromPublicKey(Rc)
return vG
}
// vG = (rG \+ sha256(eG * d)G)
function stealthDualScan (d, R, eG) {
var eQ = ecc.pointMultiply(eG, d) // shared secret
var c = bitcoin.crypto.sha256(eQ)
var Rc = ecc.pointAddScalar(R, c)
var vG = bitcoin.ECPair.fromPublicKey(Rc)
const eQ = ecc.pointMultiply(eG, d) // shared secret
const c = bitcoin.crypto.sha256(eQ)
const Rc = ecc.pointAddScalar(R, c)
const vG = bitcoin.ECPair.fromPublicKey(Rc)
return vG
}
// v = (r + sha256(eG * d))
function stealthDualReceive (d, r, eG) {
var eQ = ecc.pointMultiply(eG, d) // shared secret
var c = bitcoin.crypto.sha256(eQ)
var rc = ecc.privateAdd(r, c)
var v = bitcoin.ECPair.fromPrivateKey(rc)
const eQ = ecc.pointMultiply(eG, d) // shared secret
const c = bitcoin.crypto.sha256(eQ)
const rc = ecc.privateAdd(r, c)
const v = bitcoin.ECPair.fromPrivateKey(rc)
return v
}
@ -74,16 +74,16 @@ function stealthDualReceive (d, r, eG) {
describe('bitcoinjs-lib (crypto)', function () {
it('can generate a single-key stealth address', function () {
// XXX: should be randomly generated, see next test for example
var recipient = bitcoin.ECPair.fromWIF('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss') // private to recipient
var nonce = bitcoin.ECPair.fromWIF('KxVqB96pxbw1pokzQrZkQbLfVBjjHFfp2mFfEp8wuEyGenLFJhM9') // private to sender
const recipient = bitcoin.ECPair.fromWIF('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss') // private to recipient
const nonce = bitcoin.ECPair.fromWIF('KxVqB96pxbw1pokzQrZkQbLfVBjjHFfp2mFfEp8wuEyGenLFJhM9') // private to sender
// ... recipient reveals public key (recipient.Q) to sender
var forSender = stealthSend(nonce.privateKey, recipient.publicKey)
const forSender = stealthSend(nonce.privateKey, recipient.publicKey)
assert.equal(getAddress(forSender), '1CcZWwCpACJL3AxqoDbwEt4JgDFuTHUspE')
assert.throws(function () { forSender.toWIF() }, /Error: Missing private key/)
// ... sender reveals nonce public key (nonce.Q) to recipient
var forRecipient = stealthReceive(recipient.privateKey, nonce.publicKey)
const forRecipient = stealthReceive(recipient.privateKey, nonce.publicKey)
assert.equal(getAddress(forRecipient), '1CcZWwCpACJL3AxqoDbwEt4JgDFuTHUspE')
assert.equal(forRecipient.toWIF(), 'L1yjUN3oYyCXV3LcsBrmxCNTa62bZKWCybxVJMvqjMmmfDE8yk7n')
@ -92,15 +92,15 @@ describe('bitcoinjs-lib (crypto)', function () {
})
it('can generate a single-key stealth address (randomly)', function () {
var recipient = bitcoin.ECPair.makeRandom() // private to recipient
var nonce = bitcoin.ECPair.makeRandom() // private to sender
const recipient = bitcoin.ECPair.makeRandom() // private to recipient
const nonce = bitcoin.ECPair.makeRandom() // private to sender
// ... recipient reveals public key (recipient.Q) to sender
var forSender = stealthSend(nonce.privateKey, recipient.publicKey)
const forSender = stealthSend(nonce.privateKey, recipient.publicKey)
assert.throws(function () { forSender.toWIF() }, /Error: Missing private key/)
// ... sender reveals nonce public key (nonce.Q) to recipient
var forRecipient = stealthReceive(recipient.privateKey, nonce.publicKey)
const forRecipient = stealthReceive(recipient.privateKey, nonce.publicKey)
assert.doesNotThrow(function () { forRecipient.toWIF() })
// sender and recipient, both derived same address
@ -108,38 +108,38 @@ describe('bitcoinjs-lib (crypto)', function () {
})
it('can recover parent recipient.d, if a derived private key is leaked [and nonce was revealed]', function () {
var recipient = bitcoin.ECPair.makeRandom() // private to recipient
var nonce = bitcoin.ECPair.makeRandom() // private to sender
const recipient = bitcoin.ECPair.makeRandom() // private to recipient
const nonce = bitcoin.ECPair.makeRandom() // private to sender
// ... recipient reveals public key (recipient.Q) to sender
var forSender = stealthSend(nonce.privateKey, recipient.publicKey)
const forSender = stealthSend(nonce.privateKey, recipient.publicKey)
assert.throws(function () { forSender.toWIF() }, /Error: Missing private key/)
// ... sender reveals nonce public key (nonce.Q) to recipient
var forRecipient = stealthReceive(recipient.privateKey, nonce.publicKey)
const forRecipient = stealthReceive(recipient.privateKey, nonce.publicKey)
assert.doesNotThrow(function () { forRecipient.toWIF() })
// ... recipient accidentally leaks forRecipient.d on the blockchain
var leaked = stealthRecoverLeaked(forRecipient.privateKey, nonce.privateKey, recipient.publicKey)
const leaked = stealthRecoverLeaked(forRecipient.privateKey, nonce.privateKey, recipient.publicKey)
assert.equal(leaked.toWIF(), recipient.toWIF())
})
it('can generate a dual-key stealth address', function () {
// XXX: should be randomly generated, see next test for example
var recipient = bitcoin.ECPair.fromWIF('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss') // private to recipient
var scan = bitcoin.ECPair.fromWIF('L5DkCk3xLLoGKncqKsWQTdaPSR4V8gzc14WVghysQGkdryRudjBM') // private to scanner/recipient
var nonce = bitcoin.ECPair.fromWIF('KxVqB96pxbw1pokzQrZkQbLfVBjjHFfp2mFfEp8wuEyGenLFJhM9') // private to sender
const recipient = bitcoin.ECPair.fromWIF('5KYZdUEo39z3FPrtuX2QbbwGnNP5zTd7yyr2SC1j299sBCnWjss') // private to recipient
const scan = bitcoin.ECPair.fromWIF('L5DkCk3xLLoGKncqKsWQTdaPSR4V8gzc14WVghysQGkdryRudjBM') // private to scanner/recipient
const nonce = bitcoin.ECPair.fromWIF('KxVqB96pxbw1pokzQrZkQbLfVBjjHFfp2mFfEp8wuEyGenLFJhM9') // private to sender
// ... recipient reveals public key(s) (recipient.Q, scan.Q) to sender
var forSender = stealthDualSend(nonce.privateKey, recipient.publicKey, scan.publicKey)
const forSender = stealthDualSend(nonce.privateKey, recipient.publicKey, scan.publicKey)
assert.throws(function () { forSender.toWIF() }, /Error: Missing private key/)
// ... sender reveals nonce public key (nonce.Q) to scanner
var forScanner = stealthDualScan(scan.privateKey, recipient.publicKey, nonce.publicKey)
const forScanner = stealthDualScan(scan.privateKey, recipient.publicKey, nonce.publicKey)
assert.throws(function () { forScanner.toWIF() }, /Error: Missing private key/)
// ... scanner reveals relevant transaction + nonce public key (nonce.Q) to recipient
var forRecipient = stealthDualReceive(scan.privateKey, recipient.privateKey, nonce.publicKey)
const forRecipient = stealthDualReceive(scan.privateKey, recipient.privateKey, nonce.publicKey)
assert.doesNotThrow(function () { forRecipient.toWIF() })
// scanner, sender and recipient, all derived same address
@ -148,20 +148,20 @@ describe('bitcoinjs-lib (crypto)', function () {
})
it('can generate a dual-key stealth address (randomly)', function () {
var recipient = bitcoin.ECPair.makeRandom() // private to recipient
var scan = bitcoin.ECPair.makeRandom() // private to scanner/recipient
var nonce = bitcoin.ECPair.makeRandom() // private to sender
const recipient = bitcoin.ECPair.makeRandom() // private to recipient
const scan = bitcoin.ECPair.makeRandom() // private to scanner/recipient
const nonce = bitcoin.ECPair.makeRandom() // private to sender
// ... recipient reveals public key(s) (recipient.Q, scan.Q) to sender
var forSender = stealthDualSend(nonce.privateKey, recipient.publicKey, scan.publicKey)
const forSender = stealthDualSend(nonce.privateKey, recipient.publicKey, scan.publicKey)
assert.throws(function () { forSender.toWIF() }, /Error: Missing private key/)
// ... sender reveals nonce public key (nonce.Q) to scanner
var forScanner = stealthDualScan(scan.privateKey, recipient.publicKey, nonce.publicKey)
const forScanner = stealthDualScan(scan.privateKey, recipient.publicKey, nonce.publicKey)
assert.throws(function () { forScanner.toWIF() }, /Error: Missing private key/)
// ... scanner reveals relevant transaction + nonce public key (nonce.Q) to recipient
var forRecipient = stealthDualReceive(scan.privateKey, recipient.privateKey, nonce.publicKey)
const forRecipient = stealthDualReceive(scan.privateKey, recipient.privateKey, nonce.publicKey)
assert.doesNotThrow(function () { forRecipient.toWIF() })
// scanner, sender and recipient, all derived same address

View file

@ -1,13 +1,13 @@
/* global describe, it */
let assert = require('assert')
let bitcoin = require('../../')
let regtestUtils = require('./_regtest')
let regtest = regtestUtils.network
const assert = require('assert')
const bitcoin = require('../../')
const regtestUtils = require('./_regtest')
const regtest = regtestUtils.network
// TODO: remove
let baddress = bitcoin.address
let bcrypto = bitcoin.crypto
const baddress = bitcoin.address
const bcrypto = bitcoin.crypto
function getAddress (node, network) {
network = network || bitcoin.networks.bitcoin
return baddress.toBase58Check(bcrypto.hash160(node.publicKey), network.pubKeyHash)
@ -19,8 +19,8 @@ function rng () {
describe('bitcoinjs-lib (transactions)', function () {
it('can create a 1-to-1 Transaction', function () {
var alice = bitcoin.ECPair.fromWIF('L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy')
var txb = new bitcoin.TransactionBuilder()
const alice = bitcoin.ECPair.fromWIF('L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy')
const txb = new bitcoin.TransactionBuilder()
txb.setVersion(1)
txb.addInput('61d520ccb74288c96bc1a2b20ea1c0d5a704776dd0164a396efec3ea7040349d', 0) // Alice's previous transaction output, has 15000 satoshis
@ -34,10 +34,10 @@ describe('bitcoinjs-lib (transactions)', function () {
})
it('can create a 2-to-2 Transaction', function () {
var alice = bitcoin.ECPair.fromWIF('L1Knwj9W3qK3qMKdTvmg3VfzUs3ij2LETTFhxza9LfD5dngnoLG1')
var bob = bitcoin.ECPair.fromWIF('KwcN2pT3wnRAurhy7qMczzbkpY5nXMW2ubh696UBc1bcwctTx26z')
const alice = bitcoin.ECPair.fromWIF('L1Knwj9W3qK3qMKdTvmg3VfzUs3ij2LETTFhxza9LfD5dngnoLG1')
const bob = bitcoin.ECPair.fromWIF('KwcN2pT3wnRAurhy7qMczzbkpY5nXMW2ubh696UBc1bcwctTx26z')
var txb = new bitcoin.TransactionBuilder()
const txb = new bitcoin.TransactionBuilder()
txb.setVersion(1)
txb.addInput('b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c', 6) // Alice's previous transaction output, has 200000 satoshis
txb.addInput('7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730', 0) // Bob's previous transaction output, has 300000 satoshis
@ -55,9 +55,9 @@ describe('bitcoinjs-lib (transactions)', function () {
it('can create (and broadcast via 3PBP) a typical Transaction', function (done) {
this.timeout(30000)
var alice1 = bitcoin.ECPair.makeRandom({ network: regtest })
var alice2 = bitcoin.ECPair.makeRandom({ network: regtest })
var aliceChange = bitcoin.ECPair.makeRandom({ network: regtest, rng: rng })
const alice1 = bitcoin.ECPair.makeRandom({ network: regtest })
const alice2 = bitcoin.ECPair.makeRandom({ network: regtest })
const aliceChange = bitcoin.ECPair.makeRandom({ network: regtest, rng: rng })
// give Alice 2 unspent outputs
regtestUtils.faucet(getAddress(alice1, regtest), 5e4, function (err, unspent0) {
@ -66,7 +66,7 @@ describe('bitcoinjs-lib (transactions)', function () {
regtestUtils.faucet(getAddress(alice2, regtest), 7e4, function (err, unspent1) {
if (err) return done(err)
var txb = new bitcoin.TransactionBuilder(regtest)
const txb = new bitcoin.TransactionBuilder(regtest)
txb.addInput(unspent0.txId, unspent0.vout) // alice1 unspent
txb.addInput(unspent1.txId, unspent1.vout) // alice2 unspent
txb.addOutput('mwCwTceJvYV27KXBc3NJZys6CjsgsoeHmf', 8e4) // the actual "spend"
@ -87,14 +87,14 @@ describe('bitcoinjs-lib (transactions)', function () {
it('can create (and broadcast via 3PBP) a Transaction with an OP_RETURN output', function (done) {
this.timeout(30000)
var keyPair = bitcoin.ECPair.makeRandom({ network: regtest })
const keyPair = bitcoin.ECPair.makeRandom({ network: regtest })
regtestUtils.faucet(getAddress(keyPair, regtest), 2e5, function (err, unspent) {
if (err) return done(err)
var txb = new bitcoin.TransactionBuilder(regtest)
var data = Buffer.from('bitcoinjs-lib', 'utf8')
var dataScript = bitcoin.script.nullData.output.encode([data])
const txb = new bitcoin.TransactionBuilder(regtest)
const data = Buffer.from('bitcoinjs-lib', 'utf8')
const dataScript = bitcoin.script.nullData.output.encode([data])
txb.addInput(unspent.txId, unspent.vout)
txb.addOutput(dataScript, 1000)
@ -117,20 +117,20 @@ describe('bitcoinjs-lib (transactions)', function () {
]
const pubKeys = keyPairs.map(function (x) { return x.publicKey })
var redeemScript = bitcoin.script.multisig.output.encode(2, pubKeys)
var scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
var address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
const redeemScript = bitcoin.script.multisig.output.encode(2, pubKeys)
const scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
const address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
regtestUtils.faucet(address, 2e4, function (err, unspent) {
if (err) return done(err)
var txb = new bitcoin.TransactionBuilder(regtest)
const txb = new bitcoin.TransactionBuilder(regtest)
txb.addInput(unspent.txId, unspent.vout)
txb.addOutput(regtestUtils.RANDOM_ADDRESS, 1e4)
txb.sign(0, keyPairs[0], redeemScript)
txb.sign(0, keyPairs[2], redeemScript)
var tx = txb.build()
const tx = txb.build()
// build and broadcast to the Bitcoin RegTest network
regtestUtils.broadcast(tx.toHex(), function (err) {
@ -152,20 +152,20 @@ describe('bitcoinjs-lib (transactions)', function () {
const keyPair = bitcoin.ECPair.makeRandom({ network: regtest })
const pubKeyHash = bitcoin.crypto.hash160(keyPair.publicKey)
var redeemScript = bitcoin.script.witnessPubKeyHash.output.encode(pubKeyHash)
var redeemScriptHash = bitcoin.crypto.hash160(redeemScript)
var scriptPubKey = bitcoin.script.scriptHash.output.encode(redeemScriptHash)
var address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
const redeemScript = bitcoin.script.witnessPubKeyHash.output.encode(pubKeyHash)
const redeemScriptHash = bitcoin.crypto.hash160(redeemScript)
const scriptPubKey = bitcoin.script.scriptHash.output.encode(redeemScriptHash)
const address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
regtestUtils.faucet(address, 5e4, function (err, unspent) {
if (err) return done(err)
var txb = new bitcoin.TransactionBuilder(regtest)
const txb = new bitcoin.TransactionBuilder(regtest)
txb.addInput(unspent.txId, unspent.vout)
txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
txb.sign(0, keyPair, redeemScript, null, unspent.value)
var tx = txb.build()
const tx = txb.build()
// build and broadcast to the Bitcoin RegTest network
regtestUtils.broadcast(tx.toHex(), function (err) {
@ -192,22 +192,22 @@ describe('bitcoinjs-lib (transactions)', function () {
]
const pubKeys = keyPairs.map(function (x) { return x.publicKey })
var witnessScript = bitcoin.script.multisig.output.encode(3, pubKeys)
var redeemScript = bitcoin.script.witnessScriptHash.output.encode(bitcoin.crypto.sha256(witnessScript))
var scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
var address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
const witnessScript = bitcoin.script.multisig.output.encode(3, pubKeys)
const redeemScript = bitcoin.script.witnessScriptHash.output.encode(bitcoin.crypto.sha256(witnessScript))
const scriptPubKey = bitcoin.script.scriptHash.output.encode(bitcoin.crypto.hash160(redeemScript))
const address = bitcoin.address.fromOutputScript(scriptPubKey, regtest)
regtestUtils.faucet(address, 6e4, function (err, unspent) {
if (err) return done(err)
var txb = new bitcoin.TransactionBuilder(regtest)
const txb = new bitcoin.TransactionBuilder(regtest)
txb.addInput(unspent.txId, unspent.vout)
txb.addOutput(regtestUtils.RANDOM_ADDRESS, 3e4)
txb.sign(0, keyPairs[0], redeemScript, null, unspent.value, witnessScript)
txb.sign(0, keyPairs[2], redeemScript, null, unspent.value, witnessScript)
txb.sign(0, keyPairs[3], redeemScript, null, unspent.value, witnessScript)
var tx = txb.build()
const tx = txb.build()
// build and broadcast to the Bitcoin RegTest network
regtestUtils.broadcast(tx.toHex(), function (err) {
@ -224,21 +224,21 @@ describe('bitcoinjs-lib (transactions)', function () {
})
it('can verify Transaction signatures', function () {
var txHex = '010000000321c5f7e7bc98b3feda84aad36a5c99a02bcb8823a2f3eccbcd5da209698b5c20000000006b48304502210099e021772830207cf7c55b69948d3b16b4dcbf1f55a9cd80ebf8221a169735f9022064d33f11d62cd28240b3862afc0b901adc9f231c7124dd19bdb30367b61964c50121032b4c06c06c3ec0b7fa29519dfa5aae193ee2cc35ca127f29f14ec605d62fb63dffffffff8a75ce85441ddb3f342708ee33cc8ed418b07d9ba9e0e7c4e1cccfe9f52d8a88000000006946304302207916c23dae212c95a920423902fa44e939fb3d542f4478a7b46e9cde53705800021f0d74e9504146e404c1b8f9cba4dff2d4782e3075491c9ed07ce4a7d1c4461a01210216c92abe433106491bdeb4a261226f20f5a4ac86220cc6e37655aac6bf3c1f2affffffffdfef93f69fe32e944fad79fa8f882b3a155d80383252348caba1a77a5abbf7ef000000006b483045022100faa6e9ca289b46c64764a624c59ac30d9abcf1d4a04c4de9089e67cbe0d300a502206930afa683f6807502de5c2431bf9a1fd333c8a2910a76304df0f3d23d83443f0121039e05da8b8ea4f9868ecebb25998c7701542986233f4401799551fbecf316b18fffffffff01ff4b0000000000001976a9146c86476d1d85cd60116cd122a274e6a570a5a35c88acc96d0700'
var keyPairs = [
const txHex = '010000000321c5f7e7bc98b3feda84aad36a5c99a02bcb8823a2f3eccbcd5da209698b5c20000000006b48304502210099e021772830207cf7c55b69948d3b16b4dcbf1f55a9cd80ebf8221a169735f9022064d33f11d62cd28240b3862afc0b901adc9f231c7124dd19bdb30367b61964c50121032b4c06c06c3ec0b7fa29519dfa5aae193ee2cc35ca127f29f14ec605d62fb63dffffffff8a75ce85441ddb3f342708ee33cc8ed418b07d9ba9e0e7c4e1cccfe9f52d8a88000000006946304302207916c23dae212c95a920423902fa44e939fb3d542f4478a7b46e9cde53705800021f0d74e9504146e404c1b8f9cba4dff2d4782e3075491c9ed07ce4a7d1c4461a01210216c92abe433106491bdeb4a261226f20f5a4ac86220cc6e37655aac6bf3c1f2affffffffdfef93f69fe32e944fad79fa8f882b3a155d80383252348caba1a77a5abbf7ef000000006b483045022100faa6e9ca289b46c64764a624c59ac30d9abcf1d4a04c4de9089e67cbe0d300a502206930afa683f6807502de5c2431bf9a1fd333c8a2910a76304df0f3d23d83443f0121039e05da8b8ea4f9868ecebb25998c7701542986233f4401799551fbecf316b18fffffffff01ff4b0000000000001976a9146c86476d1d85cd60116cd122a274e6a570a5a35c88acc96d0700'
const keyPairs = [
'032b4c06c06c3ec0b7fa29519dfa5aae193ee2cc35ca127f29f14ec605d62fb63d',
'0216c92abe433106491bdeb4a261226f20f5a4ac86220cc6e37655aac6bf3c1f2a',
'039e05da8b8ea4f9868ecebb25998c7701542986233f4401799551fbecf316b18f'
].map(function (q) { return bitcoin.ECPair.fromPublicKey(Buffer.from(q, 'hex')) })
var tx = bitcoin.Transaction.fromHex(txHex)
const tx = bitcoin.Transaction.fromHex(txHex)
tx.ins.forEach(function (input, i) {
var keyPair = keyPairs[i]
var prevOutScript = bitcoin.address.toOutputScript(getAddress(keyPair))
var scriptSig = bitcoin.script.pubKeyHash.input.decode(input.script)
var ss = bitcoin.script.signature.decode(scriptSig.signature)
var hash = tx.hashForSignature(i, prevOutScript, ss.hashType)
const keyPair = keyPairs[i]
const prevOutScript = bitcoin.address.toOutputScript(getAddress(keyPair))
const scriptSig = bitcoin.script.pubKeyHash.input.decode(input.script)
const ss = bitcoin.script.signature.decode(scriptSig.signature)
const hash = tx.hashForSignature(i, prevOutScript, ss.hashType)
assert.strictEqual(scriptSig.pubKey.toString('hex'), keyPair.publicKey.toString('hex'))
assert.strictEqual(keyPair.verify(hash, ss.signature), true)

View file

@ -1,11 +1,11 @@
/* global describe, it */
var assert = require('assert')
var bscript = require('../src/script')
var minimalData = require('minimaldata')
const assert = require('assert')
const bscript = require('../src/script')
const minimalData = require('minimaldata')
var fixtures = require('./fixtures/script.json')
var fixtures2 = require('./fixtures/templates.json')
const fixtures = require('./fixtures/script.json')
const fixtures2 = require('./fixtures/templates.json')
describe('script', function () {
// TODO
@ -25,7 +25,7 @@ describe('script', function () {
describe('fromASM/toASM', function () {
fixtures.valid.forEach(function (f) {
it('encodes/decodes ' + f.asm, function () {
var script = bscript.fromASM(f.asm)
const script = bscript.fromASM(f.asm)
assert.strictEqual(bscript.toASM(script), f.asm)
})
})
@ -42,10 +42,10 @@ describe('script', function () {
describe('fromASM/toASM (templates)', function () {
fixtures2.valid.forEach(function (f) {
if (f.inputHex) {
var ih = bscript.toASM(Buffer.from(f.inputHex, 'hex'))
const ih = bscript.toASM(Buffer.from(f.inputHex, 'hex'))
it('encodes/decodes ' + ih, function () {
var script = bscript.fromASM(f.input)
const script = bscript.fromASM(f.input)
assert.strictEqual(script.toString('hex'), f.inputHex)
assert.strictEqual(bscript.toASM(script), f.input)
})
@ -53,7 +53,7 @@ describe('script', function () {
if (f.outputHex) {
it('encodes/decodes ' + f.output, function () {
var script = bscript.fromASM(f.output)
const script = bscript.fromASM(f.output)
assert.strictEqual(script.toString('hex'), f.outputHex)
assert.strictEqual(bscript.toASM(script), f.output)
})
@ -64,8 +64,8 @@ describe('script', function () {
describe('isPushOnly', function () {
fixtures.valid.forEach(function (f) {
it('returns ' + !!f.stack + ' for ' + f.asm, function () {
var script = bscript.fromASM(f.asm)
var chunks = bscript.decompile(script)
const script = bscript.fromASM(f.asm)
const chunks = bscript.decompile(script)
assert.strictEqual(bscript.isPushOnly(chunks), !!f.stack)
})
@ -77,9 +77,9 @@ describe('script', function () {
it('returns ' + !!f.stack + ' for ' + f.asm, function () {
if (!f.stack || !f.asm) return
var script = bscript.fromASM(f.asm)
const script = bscript.fromASM(f.asm)
var stack = bscript.toStack(script)
const stack = bscript.toStack(script)
assert.deepEqual(stack.map(function (x) {
return x.toString('hex')
}), f.stack)
@ -92,12 +92,12 @@ describe('script', function () {
describe('compile (via fromASM)', function () {
fixtures.valid.forEach(function (f) {
it('(' + f.type + ') compiles ' + f.asm, function () {
var scriptSig = bscript.fromASM(f.asm)
const scriptSig = bscript.fromASM(f.asm)
assert.strictEqual(scriptSig.toString('hex'), f.script)
if (f.nonstandard) {
var scriptSigNS = bscript.fromASM(f.nonstandard.scriptSig)
const scriptSigNS = bscript.fromASM(f.nonstandard.scriptSig)
assert.strictEqual(scriptSigNS.toString('hex'), f.script)
}
@ -108,13 +108,13 @@ describe('script', function () {
describe('decompile', function () {
fixtures.valid.forEach(function (f) {
it('decompiles ' + f.asm, function () {
var chunks = bscript.decompile(Buffer.from(f.script, 'hex'))
const chunks = bscript.decompile(Buffer.from(f.script, 'hex'))
assert.strictEqual(bscript.compile(chunks).toString('hex'), f.script)
assert.strictEqual(bscript.toASM(chunks), f.asm)
if (f.nonstandard) {
var chunksNS = bscript.decompile(Buffer.from(f.nonstandard.scriptSigHex, 'hex'))
const chunksNS = bscript.decompile(Buffer.from(f.nonstandard.scriptSigHex, 'hex'))
assert.strictEqual(bscript.compile(chunksNS).toString('hex'), f.script)
@ -126,7 +126,7 @@ describe('script', function () {
fixtures.invalid.decompile.forEach(function (f) {
it('fails to decompile ' + f.script + ', because "' + f.description + '"', function () {
var chunks = bscript.decompile(Buffer.from(f.script, 'hex'))
const chunks = bscript.decompile(Buffer.from(f.script, 'hex'))
assert.strictEqual(chunks, null)
})
@ -136,7 +136,7 @@ describe('script', function () {
describe('SCRIPT_VERIFY_MINIMALDATA policy', function () {
fixtures.valid.forEach(function (f) {
it('compliant for ' + f.type + ' scriptSig ' + f.asm, function () {
var script = Buffer.from(f.script, 'hex')
const script = Buffer.from(f.script, 'hex')
assert(minimalData(script))
})
@ -144,8 +144,8 @@ describe('script', function () {
function testEncodingForSize (i) {
it('compliant for data PUSH of length ' + i, function () {
var buffer = Buffer.alloc(i)
var script = bscript.compile([buffer])
const buffer = Buffer.alloc(i)
const script = bscript.compile([buffer])
assert(minimalData(script), 'Failed for ' + i + ' length script: ' + script.toString('hex'))
})

View file

@ -1,14 +1,14 @@
/* global describe, it */
var assert = require('assert')
var scriptNumber = require('../src/script_number')
var fixtures = require('./fixtures/script_number.json')
const assert = require('assert')
const scriptNumber = require('../src/script_number')
const fixtures = require('./fixtures/script_number.json')
describe('script-number', function () {
describe('decode', function () {
fixtures.forEach(function (f) {
it(f.hex + ' returns ' + f.number, function () {
var actual = scriptNumber.decode(Buffer.from(f.hex, 'hex'), f.bytes)
const actual = scriptNumber.decode(Buffer.from(f.hex, 'hex'), f.bytes)
assert.strictEqual(actual, f.number)
})
@ -18,7 +18,7 @@ describe('script-number', function () {
describe('encode', function () {
fixtures.forEach(function (f) {
it(f.number + ' returns ' + f.hex, function () {
var actual = scriptNumber.encode(f.number)
const actual = scriptNumber.encode(f.number)
assert.strictEqual(actual.toString('hex'), f.hex)
})

View file

@ -1,9 +1,9 @@
/* global describe, it */
var assert = require('assert')
var bscriptSig = require('../src/script').signature
var Buffer = require('safe-buffer').Buffer
var fixtures = require('./fixtures/signature.json')
const assert = require('assert')
const bscriptSig = require('../src/script').signature
const Buffer = require('safe-buffer').Buffer
const fixtures = require('./fixtures/signature.json')
describe('Script Signatures', function () {
function fromRaw (signature) {
@ -23,7 +23,7 @@ describe('Script Signatures', function () {
describe('encode', function () {
fixtures.valid.forEach(function (f) {
it('encodes ' + f.hex, function () {
var buffer = bscriptSig.encode(fromRaw(f.raw), f.hashType)
const buffer = bscriptSig.encode(fromRaw(f.raw), f.hashType)
assert.strictEqual(buffer.toString('hex'), f.hex)
})
@ -33,7 +33,7 @@ describe('Script Signatures', function () {
if (!f.raw) return
it('throws ' + f.exception, function () {
var signature = fromRaw(f.raw)
const signature = fromRaw(f.raw)
assert.throws(function () {
bscriptSig.encode(signature, f.hashType)
@ -45,7 +45,7 @@ describe('Script Signatures', function () {
describe('decode', function () {
fixtures.valid.forEach(function (f) {
it('decodes ' + f.hex, function () {
var decode = bscriptSig.decode(Buffer.from(f.hex, 'hex'))
const decode = bscriptSig.decode(Buffer.from(f.hex, 'hex'))
assert.deepEqual(toRaw(decode.signature), f.raw)
assert.strictEqual(decode.hashType, f.hashType)
@ -54,7 +54,7 @@ describe('Script Signatures', function () {
fixtures.invalid.forEach(function (f) {
it('throws on ' + f.hex, function () {
var buffer = Buffer.from(f.hex, 'hex')
const buffer = Buffer.from(f.hex, 'hex')
assert.throws(function () {
bscriptSig.decode(buffer)

View file

@ -1,12 +1,12 @@
/* global describe, it */
var assert = require('assert')
var bcrypto = require('../src/crypto')
var bscript = require('../src/script')
var btemplates = require('../src/templates')
var ops = require('bitcoin-ops')
const assert = require('assert')
const bcrypto = require('../src/crypto')
const bscript = require('../src/script')
const btemplates = require('../src/templates')
const ops = require('bitcoin-ops')
var fixtures = require('./fixtures/templates.json')
const fixtures = require('./fixtures/templates.json')
function fromHex (x) { return Buffer.from(x, 'hex') }
function toHex (x) { return x.toString('hex') }
@ -17,8 +17,8 @@ describe('script-templates', function () {
if (!f.input) return
it('classifies ' + f.input + ' as ' + f.type, function () {
var input = bscript.fromASM(f.input)
var type = btemplates.classifyInput(input)
const input = bscript.fromASM(f.input)
const type = btemplates.classifyInput(input)
assert.strictEqual(type, f.type)
})
@ -29,8 +29,8 @@ describe('script-templates', function () {
if (!f.typeIncomplete) return
it('classifies incomplete ' + f.input + ' as ' + f.typeIncomplete, function () {
var input = bscript.fromASM(f.input)
var type = btemplates.classifyInput(input, true)
const input = bscript.fromASM(f.input)
const type = btemplates.classifyInput(input, true)
assert.strictEqual(type, f.typeIncomplete)
})
@ -42,8 +42,8 @@ describe('script-templates', function () {
if (!f.output) return
it('classifies ' + f.output + ' as ' + f.type, function () {
var output = bscript.fromASM(f.output)
var type = btemplates.classifyOutput(output)
const output = bscript.fromASM(f.output)
const type = btemplates.classifyOutput(output)
assert.strictEqual(type, f.type)
})
@ -60,24 +60,24 @@ describe('script-templates', function () {
'nullData',
'witnessCommitment'
].forEach(function (name) {
var inputType = btemplates[name].input
var outputType = btemplates[name].output
const inputType = btemplates[name].input
const outputType = btemplates[name].output
describe(name + '.input.check', function () {
fixtures.valid.forEach(function (f) {
if (name.toLowerCase() === btemplates.types.P2WPKH) return
if (name.toLowerCase() === btemplates.types.P2WSH) return
var expected = name.toLowerCase() === f.type.toLowerCase()
const expected = name.toLowerCase() === f.type.toLowerCase()
if (inputType && f.input) {
var input = bscript.fromASM(f.input)
const input = bscript.fromASM(f.input)
it('returns ' + expected + ' for ' + f.input, function () {
assert.strictEqual(inputType.check(input), expected)
})
if (f.typeIncomplete) {
var expectedIncomplete = name.toLowerCase() === f.typeIncomplete
const expectedIncomplete = name.toLowerCase() === f.typeIncomplete
it('returns ' + expected + ' for ' + f.input, function () {
assert.strictEqual(inputType.check(input, true), expectedIncomplete)
@ -92,7 +92,7 @@ describe('script-templates', function () {
if (!f.input && !f.inputHex) return
it('returns false for ' + f.description + ' (' + (f.input || f.inputHex) + ')', function () {
var input
let input
if (f.input) {
input = bscript.fromASM(f.input)
@ -107,11 +107,11 @@ describe('script-templates', function () {
describe(name + '.output.check', function () {
fixtures.valid.forEach(function (f) {
var expected = name.toLowerCase() === f.type
const expected = name.toLowerCase() === f.type
if (outputType && f.output) {
it('returns ' + expected + ' for ' + f.output, function () {
var output = bscript.fromASM(f.output)
const output = bscript.fromASM(f.output)
if (name.toLowerCase() === 'nulldata' && f.type === btemplates.types.WITNESS_COMMITMENT) return
if (name.toLowerCase() === 'witnesscommitment' && f.type === btemplates.types.NULLDATA) return
@ -126,7 +126,7 @@ describe('script-templates', function () {
if (!f.output && !f.outputHex) return
it('returns false for ' + f.description + ' (' + (f.output || f.outputHex) + ')', function () {
var output
let output
if (f.output) {
output = bscript.fromASM(f.output)
@ -144,8 +144,8 @@ describe('script-templates', function () {
fixtures.valid.forEach(function (f) {
if (f.type !== 'pubkey') return
var signature = Buffer.from(f.signature, 'hex')
var input = btemplates.pubKey.input.encode(signature)
const signature = Buffer.from(f.signature, 'hex')
const input = btemplates.pubKey.input.encode(signature)
it('encodes to ' + f.input, function () {
assert.strictEqual(bscript.toASM(input), f.input)
@ -161,8 +161,8 @@ describe('script-templates', function () {
fixtures.valid.forEach(function (f) {
if (f.type !== 'pubkey') return
var pubKey = Buffer.from(f.pubKey, 'hex')
var output = btemplates.pubKey.output.encode(pubKey)
const pubKey = Buffer.from(f.pubKey, 'hex')
const output = btemplates.pubKey.output.encode(pubKey)
it('encodes to ' + f.output, function () {
assert.strictEqual(bscript.toASM(output), f.output)
@ -178,9 +178,9 @@ describe('script-templates', function () {
fixtures.valid.forEach(function (f) {
if (f.type !== 'pubkeyhash') return
var pubKey = Buffer.from(f.pubKey, 'hex')
var signature = Buffer.from(f.signature, 'hex')
var input = btemplates.pubKeyHash.input.encode(signature, pubKey)
const pubKey = Buffer.from(f.pubKey, 'hex')
const signature = Buffer.from(f.signature, 'hex')
const input = btemplates.pubKeyHash.input.encode(signature, pubKey)
it('encodes to ' + f.input, function () {
assert.strictEqual(bscript.toASM(input), f.input)
@ -199,9 +199,9 @@ describe('script-templates', function () {
fixtures.valid.forEach(function (f) {
if (f.type !== 'pubkeyhash') return
var pubKey = Buffer.from(f.pubKey, 'hex')
var pubKeyHash = bcrypto.hash160(pubKey)
var output = btemplates.pubKeyHash.output.encode(pubKeyHash)
const pubKey = Buffer.from(f.pubKey, 'hex')
const pubKeyHash = bcrypto.hash160(pubKey)
const output = btemplates.pubKeyHash.output.encode(pubKeyHash)
it('encodes to ' + f.output, function () {
assert.strictEqual(bscript.toASM(output), f.output)
@ -214,7 +214,7 @@ describe('script-templates', function () {
fixtures.invalid.pubKeyHash.outputs.forEach(function (f) {
if (!f.hash) return
var hash = Buffer.from(f.hash, 'hex')
const hash = Buffer.from(f.hash, 'hex')
it('throws on ' + f.exception, function () {
assert.throws(function () {
@ -227,13 +227,13 @@ describe('script-templates', function () {
describe('multisig.input', function () {
fixtures.valid.forEach(function (f) {
if (f.type !== 'multisig' && f.typeIncomplete !== 'multisig') return
var allowIncomplete = f.typeIncomplete !== undefined
const allowIncomplete = f.typeIncomplete !== undefined
var signatures = f.signatures.map(function (signature) {
const signatures = f.signatures.map(function (signature) {
return signature ? Buffer.from(signature, 'hex') : ops.OP_0
})
var input = btemplates.multisig.input.encode(signatures)
const input = btemplates.multisig.input.encode(signatures)
it('encodes to ' + f.input, function () {
assert.strictEqual(bscript.toASM(input), f.input)
@ -246,10 +246,10 @@ describe('script-templates', function () {
fixtures.invalid.multisig.inputs.forEach(function (f) {
if (!f.output) return
var output = bscript.fromASM(f.output)
const output = bscript.fromASM(f.output)
it('throws on ' + f.exception, function () {
var signatures = f.signatures.map(function (signature) {
const signatures = f.signatures.map(function (signature) {
return signature ? Buffer.from(signature, 'hex') : ops.OP_0
})
@ -264,10 +264,10 @@ describe('script-templates', function () {
fixtures.valid.forEach(function (f) {
if (f.type !== 'multisig') return
var pubKeys = f.pubKeys.map(function (p) { return Buffer.from(p, 'hex') })
var m = pubKeys.length
const pubKeys = f.pubKeys.map(function (p) { return Buffer.from(p, 'hex') })
const m = pubKeys.length
var output = btemplates.multisig.output.encode(m, pubKeys)
const output = btemplates.multisig.output.encode(m, pubKeys)
it('encodes ' + f.output, function () {
assert.strictEqual(bscript.toASM(output), f.output)
@ -283,7 +283,7 @@ describe('script-templates', function () {
fixtures.invalid.multisig.outputs.forEach(function (f) {
if (!f.pubKeys) return
var pubKeys = f.pubKeys.map(function (p) {
const pubKeys = f.pubKeys.map(function (p) {
return Buffer.from(p, 'hex')
})
@ -299,9 +299,9 @@ describe('script-templates', function () {
fixtures.valid.forEach(function (f) {
if (f.type !== 'scripthash') return
var redeemScriptSig = bscript.fromASM(f.redeemScriptSig)
var redeemScript = bscript.fromASM(f.redeemScript)
var input = btemplates.scriptHash.input.encode(redeemScriptSig, redeemScript)
const redeemScriptSig = bscript.fromASM(f.redeemScriptSig)
const redeemScript = bscript.fromASM(f.redeemScript)
const input = btemplates.scriptHash.input.encode(redeemScriptSig, redeemScript)
it('encodes to ' + f.output, function () {
if (f.input) {
@ -325,9 +325,9 @@ describe('script-templates', function () {
if (f.type !== 'scripthash') return
if (!f.output) return
var redeemScript = bscript.fromASM(f.redeemScript)
var scriptHash = bcrypto.hash160(redeemScript)
var output = btemplates.scriptHash.output.encode(scriptHash)
const redeemScript = bscript.fromASM(f.redeemScript)
const scriptHash = bcrypto.hash160(redeemScript)
const output = btemplates.scriptHash.output.encode(scriptHash)
it('encodes to ' + f.output, function () {
assert.strictEqual(bscript.toASM(output), f.output)
@ -340,7 +340,7 @@ describe('script-templates', function () {
fixtures.invalid.scriptHash.outputs.forEach(function (f) {
if (!f.hash) return
var hash = Buffer.from(f.hash, 'hex')
const hash = Buffer.from(f.hash, 'hex')
it('throws on ' + f.exception, function () {
assert.throws(function () {
@ -355,17 +355,17 @@ describe('script-templates', function () {
if (f.type !== 'pubkeyhash' && f.type !== 'witnesspubkeyhash') return
if (!f.inputStack) return
var pubKey = Buffer.from(f.pubKey, 'hex')
var signature = Buffer.from(f.signature, 'hex')
const pubKey = Buffer.from(f.pubKey, 'hex')
const signature = Buffer.from(f.signature, 'hex')
it('encodes to ' + f.input, function () {
var inputStack = btemplates.witnessPubKeyHash.input.encodeStack(signature, pubKey)
const inputStack = btemplates.witnessPubKeyHash.input.encodeStack(signature, pubKey)
assert.deepEqual(inputStack.map(toHex), f.inputStack)
})
it('decodes to original arguments', function () {
var fInputStack = f.inputStack.map(fromHex)
const fInputStack = f.inputStack.map(fromHex)
assert.deepEqual(btemplates.witnessPubKeyHash.input.decodeStack(fInputStack), {
signature: signature,
@ -380,9 +380,9 @@ describe('script-templates', function () {
if (f.type !== 'witnesspubkeyhash') return
if (!f.output) return
var pubKey = Buffer.from(f.pubKey, 'hex')
var pubKeyHash = bcrypto.hash160(pubKey)
var output = btemplates.witnessPubKeyHash.output.encode(pubKeyHash)
const pubKey = Buffer.from(f.pubKey, 'hex')
const pubKeyHash = bcrypto.hash160(pubKey)
const output = btemplates.witnessPubKeyHash.output.encode(pubKeyHash)
it('encodes to ' + f.output, function () {
assert.strictEqual(bscript.toASM(output), f.output)
@ -395,7 +395,7 @@ describe('script-templates', function () {
fixtures.invalid.witnessPubKeyHash.outputs.forEach(function (f) {
if (!f.hash) return
var hash = Buffer.from(f.hash, 'hex')
const hash = Buffer.from(f.hash, 'hex')
it('throws on ' + f.exception, function () {
assert.throws(function () {
@ -410,17 +410,17 @@ describe('script-templates', function () {
if (f.type !== 'witnessscripthash') return
if (!f.inputStack || !f.witnessData) return
var witnessData = f.witnessData.map(fromHex)
var witnessScript = bscript.fromASM(f.witnessScript || f.redeemScript)
const witnessData = f.witnessData.map(fromHex)
const witnessScript = bscript.fromASM(f.witnessScript || f.redeemScript)
it('encodes to ' + f.input, function () {
var inputStack = btemplates.witnessScriptHash.input.encodeStack(witnessData, witnessScript)
const inputStack = btemplates.witnessScriptHash.input.encodeStack(witnessData, witnessScript)
assert.deepEqual(inputStack.map(toHex), f.inputStack)
})
it('decodes to original arguments', function () {
var result = btemplates.witnessScriptHash.input.decodeStack(f.inputStack.map(fromHex))
const result = btemplates.witnessScriptHash.input.decodeStack(f.inputStack.map(fromHex))
assert.deepEqual(result.witnessData.map(toHex), f.witnessData)
assert.strictEqual(bscript.toASM(result.witnessScript), f.witnessScript)
@ -433,9 +433,9 @@ describe('script-templates', function () {
if (f.type !== 'witnessscripthash') return
if (!f.output) return
var witnessScriptPubKey = bscript.fromASM(f.witnessScript)
var scriptHash = bcrypto.hash256(witnessScriptPubKey)
var output = btemplates.witnessScriptHash.output.encode(scriptHash)
const witnessScriptPubKey = bscript.fromASM(f.witnessScript)
const scriptHash = bcrypto.hash256(witnessScriptPubKey)
const output = btemplates.witnessScriptHash.output.encode(scriptHash)
it('encodes to ' + f.output, function () {
assert.strictEqual(bscript.toASM(output), f.output)
@ -448,7 +448,7 @@ describe('script-templates', function () {
fixtures.invalid.witnessScriptHash.outputs.forEach(function (f) {
if (!f.hash) return
var hash = Buffer.from(f.hash, 'hex')
const hash = Buffer.from(f.hash, 'hex')
it('throws on ' + f.exception, function () {
assert.throws(function () {
@ -463,8 +463,8 @@ describe('script-templates', function () {
if (f.type !== 'witnesscommitment') return
if (!f.scriptPubKey) return
var commitment = Buffer.from(f.witnessCommitment, 'hex')
var scriptPubKey = btemplates.witnessCommitment.output.encode(commitment)
const commitment = Buffer.from(f.witnessCommitment, 'hex')
const scriptPubKey = btemplates.witnessCommitment.output.encode(commitment)
it('encodes to ' + f.scriptPubKey, function () {
assert.strictEqual(bscript.toASM(scriptPubKey), f.scriptPubKey)
@ -477,7 +477,7 @@ describe('script-templates', function () {
fixtures.invalid.witnessCommitment.outputs.forEach(function (f) {
if (f.commitment) {
var hash = Buffer.from(f.commitment, 'hex')
const hash = Buffer.from(f.commitment, 'hex')
it('throws on bad encode data', function () {
assert.throws(function () {
btemplates.witnessCommitment.output.encode(hash)
@ -499,8 +499,8 @@ describe('script-templates', function () {
fixtures.valid.forEach(function (f) {
if (f.type !== 'nulldata') return
var data = f.data.map(function (x) { return Buffer.from(x, 'hex') })
var output = btemplates.nullData.output.encode(data)
const data = f.data.map(function (x) { return Buffer.from(x, 'hex') })
const output = btemplates.nullData.output.encode(data)
it('encodes to ' + f.output, function () {
assert.strictEqual(bscript.toASM(output), f.output)

View file

@ -1,19 +1,19 @@
/* global describe, it, beforeEach */
var assert = require('assert')
var bscript = require('../src/script')
var fixtures = require('./fixtures/transaction')
var Transaction = require('../src/transaction')
const assert = require('assert')
const bscript = require('../src/script')
const fixtures = require('./fixtures/transaction')
const Transaction = require('../src/transaction')
describe('Transaction', function () {
function fromRaw (raw, noWitness) {
var tx = new Transaction()
const tx = new Transaction()
tx.version = raw.version
tx.locktime = raw.locktime
raw.ins.forEach(function (txIn, i) {
var txHash = Buffer.from(txIn.hash, 'hex')
var scriptSig
const txHash = Buffer.from(txIn.hash, 'hex')
let scriptSig
if (txIn.data) {
scriptSig = Buffer.from(txIn.data, 'hex')
@ -24,7 +24,7 @@ describe('Transaction', function () {
tx.addInput(txHash, txIn.index, txIn.sequence, scriptSig)
if (!noWitness && txIn.witness) {
var witness = txIn.witness.map(function (x) {
const witness = txIn.witness.map(function (x) {
return Buffer.from(x, 'hex')
})
@ -33,7 +33,7 @@ describe('Transaction', function () {
})
raw.outs.forEach(function (txOut) {
var script
let script
if (txOut.data) {
script = Buffer.from(txOut.data, 'hex')
@ -49,18 +49,18 @@ describe('Transaction', function () {
describe('fromBuffer/fromHex', function () {
function importExport (f) {
var id = f.id || f.hash
var txHex = f.hex || f.txHex
const id = f.id || f.hash
const txHex = f.hex || f.txHex
it('imports ' + f.description + ' (' + id + ')', function () {
var actual = Transaction.fromHex(txHex)
const actual = Transaction.fromHex(txHex)
assert.strictEqual(actual.toHex(), txHex)
})
if (f.whex) {
it('imports ' + f.description + ' (' + id + ') as witness', function () {
var actual = Transaction.fromHex(f.whex)
const actual = Transaction.fromHex(f.whex)
assert.strictEqual(actual.toHex(), f.whex)
})
@ -80,8 +80,8 @@ describe('Transaction', function () {
})
it('.version should be interpreted as an int32le', function () {
var txHex = 'ffffffff0000ffffffff'
var tx = Transaction.fromHex(txHex)
const txHex = 'ffffffff0000ffffffff'
const tx = Transaction.fromHex(txHex)
assert.equal(-1, tx.version)
assert.equal(0xffffffff, tx.locktime)
})
@ -90,26 +90,26 @@ describe('Transaction', function () {
describe('toBuffer/toHex', function () {
fixtures.valid.forEach(function (f) {
it('exports ' + f.description + ' (' + f.id + ')', function () {
var actual = fromRaw(f.raw, true)
const actual = fromRaw(f.raw, true)
assert.strictEqual(actual.toHex(), f.hex)
})
if (f.whex) {
it('exports ' + f.description + ' (' + f.id + ') as witness', function () {
var wactual = fromRaw(f.raw)
const wactual = fromRaw(f.raw)
assert.strictEqual(wactual.toHex(), f.whex)
})
}
})
it('accepts target Buffer and offset parameters', function () {
var f = fixtures.valid[0]
var actual = fromRaw(f.raw)
var byteLength = actual.byteLength()
const f = fixtures.valid[0]
const actual = fromRaw(f.raw)
const byteLength = actual.byteLength()
var target = Buffer.alloc(byteLength * 2)
var a = actual.toBuffer(target, 0)
var b = actual.toBuffer(target, byteLength)
const target = Buffer.alloc(byteLength * 2)
const a = actual.toBuffer(target, 0)
const b = actual.toBuffer(target, byteLength)
assert.strictEqual(a.length, byteLength)
assert.strictEqual(b.length, byteLength)
@ -132,7 +132,7 @@ describe('Transaction', function () {
describe('weight/virtualSize', function () {
it('computes virtual size', function () {
fixtures.valid.forEach(function (f) {
var transaction = Transaction.fromHex(f.whex ? f.whex : f.hex)
const transaction = Transaction.fromHex(f.whex ? f.whex : f.hex)
assert.strictEqual(transaction.virtualSize(), f.virtualSize)
})
@ -140,7 +140,7 @@ describe('Transaction', function () {
it('computes weight', function () {
fixtures.valid.forEach(function (f) {
var transaction = Transaction.fromHex(f.whex ? f.whex : f.hex)
const transaction = Transaction.fromHex(f.whex ? f.whex : f.hex)
assert.strictEqual(transaction.weight(), f.weight)
})
@ -148,19 +148,19 @@ describe('Transaction', function () {
})
describe('addInput', function () {
var prevTxHash
let prevTxHash
beforeEach(function () {
prevTxHash = Buffer.from('ffffffff00ffff000000000000000000000000000000000000000000101010ff', 'hex')
})
it('returns an index', function () {
var tx = new Transaction()
const tx = new Transaction()
assert.strictEqual(tx.addInput(prevTxHash, 0), 0)
assert.strictEqual(tx.addInput(prevTxHash, 0), 1)
})
it('defaults to empty script, witness and 0xffffffff SEQUENCE number', function () {
var tx = new Transaction()
const tx = new Transaction()
tx.addInput(prevTxHash, 0)
assert.strictEqual(tx.ins[0].script.length, 0)
@ -170,8 +170,8 @@ describe('Transaction', function () {
fixtures.invalid.addInput.forEach(function (f) {
it('throws on ' + f.exception, function () {
var tx = new Transaction()
var hash = Buffer.from(f.hash, 'hex')
const tx = new Transaction()
const hash = Buffer.from(f.hash, 'hex')
assert.throws(function () {
tx.addInput(hash, f.index)
@ -182,7 +182,7 @@ describe('Transaction', function () {
describe('addOutput', function () {
it('returns an index', function () {
var tx = new Transaction()
const tx = new Transaction()
assert.strictEqual(tx.addOutput(Buffer.alloc(0), 0), 0)
assert.strictEqual(tx.addOutput(Buffer.alloc(0), 0), 1)
})
@ -190,7 +190,8 @@ describe('Transaction', function () {
describe('clone', function () {
fixtures.valid.forEach(function (f) {
var actual, expected
let actual
let expected
beforeEach(function () {
expected = Transaction.fromHex(f.hex)
@ -210,7 +211,7 @@ describe('Transaction', function () {
describe('getHash/getId', function () {
function verify (f) {
it('should return the id for ' + f.id + '(' + f.description + ')', function () {
var tx = Transaction.fromHex(f.whex || f.hex)
const tx = Transaction.fromHex(f.whex || f.hex)
assert.strictEqual(tx.getHash().toString('hex'), f.hash)
assert.strictEqual(tx.getId(), f.id)
@ -223,7 +224,7 @@ describe('Transaction', function () {
describe('isCoinbase', function () {
function verify (f) {
it('should return ' + f.coinbase + ' for ' + f.id + '(' + f.description + ')', function () {
var tx = Transaction.fromHex(f.hex)
const tx = Transaction.fromHex(f.hex)
assert.strictEqual(tx.isCoinbase(), f.coinbase)
})
@ -234,13 +235,13 @@ describe('Transaction', function () {
describe('hashForSignature', function () {
it('does not use Witness serialization', function () {
var randScript = Buffer.from('6a', 'hex')
const randScript = Buffer.from('6a', 'hex')
var tx = new Transaction()
const tx = new Transaction()
tx.addInput(Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex'), 0)
tx.addOutput(randScript, 5000000000)
var original = tx.__toBuffer
const original = tx.__toBuffer
tx.__toBuffer = function (a, b, c) {
if (c !== false) throw new Error('hashForSignature MUST pass false')
@ -259,8 +260,8 @@ describe('Transaction', function () {
fixtures.hashForSignature.forEach(function (f) {
it('should return ' + f.hash + ' for ' + (f.description ? ('case "' + f.description + '"') : f.script), function () {
var tx = Transaction.fromHex(f.txHex)
var script = bscript.fromASM(f.script)
const tx = Transaction.fromHex(f.txHex)
const script = bscript.fromASM(f.script)
assert.strictEqual(tx.hashForSignature(f.inIndex, script, f.type).toString('hex'), f.hash)
})
@ -270,8 +271,8 @@ describe('Transaction', function () {
describe('hashForWitnessV0', function () {
fixtures.hashForWitnessV0.forEach(function (f) {
it('should return ' + f.hash + ' for ' + (f.description ? ('case "' + f.description + '"') : ''), function () {
var tx = Transaction.fromHex(f.txHex)
var script = bscript.fromASM(f.script)
const tx = Transaction.fromHex(f.txHex)
const script = bscript.fromASM(f.script)
assert.strictEqual(tx.hashForWitnessV0(f.inIndex, script, f.value, f.type).toString('hex'), f.hash)
})

View file

@ -1,18 +1,18 @@
/* global describe, it, beforeEach */
let assert = require('assert')
let baddress = require('../src/address')
let bcrypto = require('../src/crypto')
let bscript = require('../src/script')
let btemplates = require('../src/templates')
let ops = require('bitcoin-ops')
const assert = require('assert')
const baddress = require('../src/address')
const bcrypto = require('../src/crypto')
const bscript = require('../src/script')
const btemplates = require('../src/templates')
const ops = require('bitcoin-ops')
let ECPair = require('../src/ecpair')
let Transaction = require('../src/transaction')
let TransactionBuilder = require('../src/transaction_builder')
let NETWORKS = require('../src/networks')
const ECPair = require('../src/ecpair')
const Transaction = require('../src/transaction')
const TransactionBuilder = require('../src/transaction_builder')
const NETWORKS = require('../src/networks')
let fixtures = require('./fixtures/transaction_builder')
const fixtures = require('./fixtures/transaction_builder')
// TODO: remove
function getAddress (node) {
@ -20,16 +20,16 @@ function getAddress (node) {
}
function construct (f, dontSign) {
var network = NETWORKS[f.network]
var txb = new TransactionBuilder(network)
const network = NETWORKS[f.network]
let txb = new TransactionBuilder(network)
if (Number.isFinite(f.version)) txb.setVersion(f.version)
if (f.locktime !== undefined) txb.setLockTime(f.locktime)
f.inputs.forEach(function (input) {
var prevTx
let prevTx
if (input.txRaw) {
var constructed = construct(input.txRaw)
const constructed = construct(input.txRaw)
if (input.txRaw.incomplete) prevTx = constructed.buildIncomplete()
else prevTx = constructed.build()
} else if (input.txHex) {
@ -38,7 +38,7 @@ function construct (f, dontSign) {
prevTx = input.txId
}
var prevTxScript
let prevTxScript
if (input.prevTxScript) {
prevTxScript = bscript.fromASM(input.prevTxScript)
}
@ -56,27 +56,31 @@ function construct (f, dontSign) {
if (dontSign) return txb
var stages = f.stages && f.stages.concat()
const stages = f.stages && f.stages.concat()
f.inputs.forEach(function (input, index) {
if (!input.signs) return
input.signs.forEach(function (sign) {
var keyPair = ECPair.fromWIF(sign.keyPair, network)
var redeemScript
var witnessScript
var value
const keyPair = ECPair.fromWIF(sign.keyPair, network)
let redeemScript
let witnessScript
let value
if (sign.redeemScript) {
redeemScript = bscript.fromASM(sign.redeemScript)
}
if (sign.value) {
value = sign.value
}
if (sign.witnessScript) {
witnessScript = bscript.fromASM(sign.witnessScript)
}
txb.sign(index, keyPair, redeemScript, sign.hashType, value, witnessScript)
if (sign.stage) {
var tx = txb.buildIncomplete()
const tx = txb.buildIncomplete()
assert.strictEqual(tx.toHex(), stages.shift())
txb = TransactionBuilder.fromTransaction(tx, network)
}
@ -88,23 +92,23 @@ function construct (f, dontSign) {
describe('TransactionBuilder', function () {
// constants
var keyPair = ECPair.fromPrivateKey(Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex'))
var scripts = [
const keyPair = ECPair.fromPrivateKey(Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex'))
const scripts = [
'1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH',
'1cMh228HTCiwS8ZsaakH8A8wze1JR5ZsP'
].map(function (x) {
return baddress.toOutputScript(x)
})
var txHash = Buffer.from('0e7cea811c0be9f73c0aca591034396e7264473fc25c1ca45195d7417b36cbe2', 'hex')
const txHash = Buffer.from('0e7cea811c0be9f73c0aca591034396e7264473fc25c1ca45195d7417b36cbe2', 'hex')
describe('fromTransaction', function () {
fixtures.valid.build.forEach(function (f) {
it('returns TransactionBuilder, with ' + f.description, function () {
var network = NETWORKS[f.network || 'bitcoin']
const network = NETWORKS[f.network || 'bitcoin']
var tx = Transaction.fromHex(f.txHex)
var txb = TransactionBuilder.fromTransaction(tx, network)
var txAfter = f.incomplete ? txb.buildIncomplete() : txb.build()
const tx = Transaction.fromHex(f.txHex)
const txb = TransactionBuilder.fromTransaction(tx, network)
const txAfter = f.incomplete ? txb.buildIncomplete() : txb.build()
assert.strictEqual(txAfter.toHex(), f.txHex)
assert.strictEqual(txb.network, network)
@ -113,10 +117,10 @@ describe('TransactionBuilder', function () {
fixtures.valid.fromTransaction.forEach(function (f) {
it('returns TransactionBuilder, with ' + f.description, function () {
var tx = new Transaction()
const tx = new Transaction()
f.inputs.forEach(function (input) {
var txHash2 = Buffer.from(input.txId, 'hex').reverse()
const txHash2 = Buffer.from(input.txId, 'hex').reverse()
tx.addInput(txHash2, input.vout, undefined, bscript.fromASM(input.scriptSig))
})
@ -125,8 +129,8 @@ describe('TransactionBuilder', function () {
tx.addOutput(bscript.fromASM(output.script), output.value)
})
var txb = TransactionBuilder.fromTransaction(tx)
var txAfter = f.incomplete ? txb.buildIncomplete() : txb.build()
const txb = TransactionBuilder.fromTransaction(tx)
const txAfter = f.incomplete ? txb.buildIncomplete() : txb.build()
txAfter.ins.forEach(function (input, i) {
assert.equal(bscript.toASM(input.script), f.inputs[i].scriptSigAfter)
@ -139,8 +143,8 @@ describe('TransactionBuilder', function () {
})
it('classifies transaction inputs', function () {
var tx = Transaction.fromHex(fixtures.valid.classification.hex)
var txb = TransactionBuilder.fromTransaction(tx)
const tx = Transaction.fromHex(fixtures.valid.classification.hex)
const txb = TransactionBuilder.fromTransaction(tx)
txb.__inputs.forEach(function (i) {
assert.strictEqual(i.prevOutType, 'scripthash')
@ -151,7 +155,7 @@ describe('TransactionBuilder', function () {
fixtures.invalid.fromTransaction.forEach(function (f) {
it('throws ' + f.exception, function () {
var tx = Transaction.fromHex(f.txHex)
const tx = Transaction.fromHex(f.txHex)
assert.throws(function () {
TransactionBuilder.fromTransaction(tx)
@ -161,16 +165,16 @@ describe('TransactionBuilder', function () {
})
describe('addInput', function () {
var txb
let txb
beforeEach(function () {
txb = new TransactionBuilder()
})
it('accepts a txHash, index [and sequence number]', function () {
var vin = txb.addInput(txHash, 1, 54)
const vin = txb.addInput(txHash, 1, 54)
assert.strictEqual(vin, 0)
var txIn = txb.__tx.ins[0]
const txIn = txb.__tx.ins[0]
assert.strictEqual(txIn.hash, txHash)
assert.strictEqual(txIn.index, 1)
assert.strictEqual(txIn.sequence, 54)
@ -178,10 +182,10 @@ describe('TransactionBuilder', function () {
})
it('accepts a txHash, index [, sequence number and scriptPubKey]', function () {
var vin = txb.addInput(txHash, 1, 54, scripts[1])
const vin = txb.addInput(txHash, 1, 54, scripts[1])
assert.strictEqual(vin, 0)
var txIn = txb.__tx.ins[0]
const txIn = txb.__tx.ins[0]
assert.strictEqual(txIn.hash, txHash)
assert.strictEqual(txIn.index, 1)
assert.strictEqual(txIn.sequence, 54)
@ -189,14 +193,14 @@ describe('TransactionBuilder', function () {
})
it('accepts a prevTx, index [and sequence number]', function () {
var prevTx = new Transaction()
const prevTx = new Transaction()
prevTx.addOutput(scripts[0], 0)
prevTx.addOutput(scripts[1], 1)
var vin = txb.addInput(prevTx, 1, 54)
const vin = txb.addInput(prevTx, 1, 54)
assert.strictEqual(vin, 0)
var txIn = txb.__tx.ins[0]
const txIn = txb.__tx.ins[0]
assert.deepEqual(txIn.hash, prevTx.getHash())
assert.strictEqual(txIn.index, 1)
assert.strictEqual(txIn.sequence, 54)
@ -219,26 +223,26 @@ describe('TransactionBuilder', function () {
})
describe('addOutput', function () {
var txb
let txb
beforeEach(function () {
txb = new TransactionBuilder()
})
it('accepts an address string and value', function () {
let address = getAddress(keyPair)
var vout = txb.addOutput(address, 1000)
const address = getAddress(keyPair)
const vout = txb.addOutput(address, 1000)
assert.strictEqual(vout, 0)
var txout = txb.__tx.outs[0]
const txout = txb.__tx.outs[0]
assert.deepEqual(txout.script, scripts[0])
assert.strictEqual(txout.value, 1000)
})
it('accepts a ScriptPubKey and value', function () {
var vout = txb.addOutput(scripts[0], 1000)
const vout = txb.addOutput(scripts[0], 1000)
assert.strictEqual(vout, 0)
var txout = txb.__tx.outs[0]
const txout = txb.__tx.outs[0]
assert.deepEqual(txout.script, scripts[0])
assert.strictEqual(txout.value, 1000)
})
@ -290,7 +294,7 @@ describe('TransactionBuilder', function () {
describe('setLockTime', function () {
it('throws if if there exist any scriptSigs', function () {
var txb = new TransactionBuilder()
const txb = new TransactionBuilder()
txb.addInput(txHash, 0)
txb.sign(0, keyPair)
@ -302,12 +306,12 @@ describe('TransactionBuilder', function () {
describe('sign', function () {
it('supports the alternative abstract interface { publicKey, sign }', function () {
var keyPair = {
const keyPair = {
publicKey: ECPair.makeRandom({ rng: function () { return Buffer.alloc(32, 1) } }).publicKey,
sign: function (hash) { return Buffer.alloc(64, 0x5f) }
}
var txb = new TransactionBuilder()
const txb = new TransactionBuilder()
txb.setVersion(1)
txb.addInput('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 1)
txb.addOutput('1111111111111111111114oLvT2', 100000)
@ -317,13 +321,14 @@ describe('TransactionBuilder', function () {
fixtures.invalid.sign.forEach(function (f) {
it('throws ' + f.exception + (f.description ? ' (' + f.description + ')' : ''), function () {
var txb = construct(f, true)
const txb = construct(f, true)
f.inputs.forEach(function (input, index) {
input.signs.forEach(function (sign) {
var keyPairNetwork = NETWORKS[sign.network || f.network]
var keyPair2 = ECPair.fromWIF(sign.keyPair, keyPairNetwork)
var redeemScript, witnessScript
const keyPairNetwork = NETWORKS[sign.network || f.network]
const keyPair2 = ECPair.fromWIF(sign.keyPair, keyPairNetwork)
let redeemScript
let witnessScript
if (sign.redeemScript) {
redeemScript = bscript.fromASM(sign.redeemScript)
@ -349,8 +354,8 @@ describe('TransactionBuilder', function () {
describe('build', function () {
fixtures.valid.build.forEach(function (f) {
it('builds "' + f.description + '"', function () {
var txb = construct(f)
var tx = f.incomplete ? txb.buildIncomplete() : txb.build()
const txb = construct(f)
const tx = f.incomplete ? txb.buildIncomplete() : txb.build()
assert.strictEqual(tx.toHex(), f.txHex)
})
@ -361,7 +366,7 @@ describe('TransactionBuilder', function () {
describe('for ' + (f.description || f.exception), function () {
it('throws ' + f.exception, function () {
assert.throws(function () {
var txb
let txb
if (f.txHex) {
txb = TransactionBuilder.fromTransaction(Transaction.fromHex(f.txHex))
} else {
@ -376,7 +381,7 @@ describe('TransactionBuilder', function () {
if (f.incomplete) {
it('throws ' + f.exception, function () {
assert.throws(function () {
var txb
let txb
if (f.txHex) {
txb = TransactionBuilder.fromTransaction(Transaction.fromHex(f.txHex))
} else {
@ -388,7 +393,7 @@ describe('TransactionBuilder', function () {
})
} else {
it('does not throw if buildIncomplete', function () {
var txb
let txb
if (f.txHex) {
txb = TransactionBuilder.fromTransaction(Transaction.fromHex(f.txHex))
} else {
@ -402,11 +407,11 @@ describe('TransactionBuilder', function () {
})
it('for incomplete with 0 signatures', function () {
var randomTxData = '0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb022022dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01232103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ac00000000'
var randomAddress = '1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH'
const randomTxData = '0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb022022dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01232103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ac00000000'
const randomAddress = '1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH'
var randomTx = Transaction.fromHex(randomTxData)
var tx = new TransactionBuilder()
const randomTx = Transaction.fromHex(randomTxData)
let tx = new TransactionBuilder()
tx.addInput(randomTx, 0)
tx.addOutput(randomAddress, 1000)
tx = tx.buildIncomplete()
@ -414,10 +419,10 @@ describe('TransactionBuilder', function () {
})
it('for incomplete P2SH with 0 signatures', function () {
var inp = Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a80400000017a91471a8ec07ff69c6c4fee489184c462a9b1b9237488700000000', 'hex') // arbitrary P2SH input
var inpTx = Transaction.fromBuffer(inp)
const inp = Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a80400000017a91471a8ec07ff69c6c4fee489184c462a9b1b9237488700000000', 'hex') // arbitrary P2SH input
const inpTx = Transaction.fromBuffer(inp)
var txb = new TransactionBuilder(NETWORKS.testnet)
const txb = new TransactionBuilder(NETWORKS.testnet)
txb.addInput(inpTx, 0)
txb.addOutput('2NAkqp5xffoomp5RLBcakuGpZ12GU4twdz4', 1e8) // arbitrary output
@ -425,10 +430,10 @@ describe('TransactionBuilder', function () {
})
it('for incomplete P2WPKH with 0 signatures', function () {
var inp = Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a8040000001600141a15805e1f4040c9f68ccc887fca2e63547d794b00000000', 'hex')
var inpTx = Transaction.fromBuffer(inp)
const inp = Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a8040000001600141a15805e1f4040c9f68ccc887fca2e63547d794b00000000', 'hex')
const inpTx = Transaction.fromBuffer(inp)
var txb = new TransactionBuilder(NETWORKS.testnet)
const txb = new TransactionBuilder(NETWORKS.testnet)
txb.addInput(inpTx, 0)
txb.addOutput('2NAkqp5xffoomp5RLBcakuGpZ12GU4twdz4', 1e8) // arbitrary output
@ -436,9 +441,9 @@ describe('TransactionBuilder', function () {
})
it('for incomplete P2WSH with 0 signatures', function () {
var inpTx = Transaction.fromBuffer(Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a80400000022002072df76fcc0b231b94bdf7d8c25d7eef4716597818d211e19ade7813bff7a250200000000', 'hex'))
const inpTx = Transaction.fromBuffer(Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a80400000022002072df76fcc0b231b94bdf7d8c25d7eef4716597818d211e19ade7813bff7a250200000000', 'hex'))
var txb = new TransactionBuilder(NETWORKS.testnet)
const txb = new TransactionBuilder(NETWORKS.testnet)
txb.addInput(inpTx, 0)
txb.addOutput('2NAkqp5xffoomp5RLBcakuGpZ12GU4twdz4', 1e8) // arbitrary output
@ -449,25 +454,25 @@ describe('TransactionBuilder', function () {
describe('multisig', function () {
fixtures.valid.multisig.forEach(function (f) {
it(f.description, function () {
var txb = construct(f, true)
var tx
var network = NETWORKS[f.network]
const network = NETWORKS[f.network]
let txb = construct(f, true)
let tx
f.inputs.forEach(function (input, i) {
var redeemScript = bscript.fromASM(input.redeemScript)
const redeemScript = bscript.fromASM(input.redeemScript)
input.signs.forEach(function (sign) {
// rebuild the transaction each-time after the first
if (tx) {
// do we filter OP_0's beforehand?
if (sign.filterOP_0) {
var scriptSig = tx.ins[i].script
const scriptSig = tx.ins[i].script
// ignore OP_0 on the front, ignore redeemScript
var signatures = bscript.decompile(scriptSig).slice(1, -1).filter(function (x) { return x !== ops.OP_0 })
const signatures = bscript.decompile(scriptSig).slice(1, -1).filter(function (x) { return x !== ops.OP_0 })
// rebuild/replace the scriptSig without them
var replacement = btemplates.scriptHash.input.encode(btemplates.multisig.input.encode(signatures), redeemScript)
const replacement = btemplates.scriptHash.input.encode(btemplates.multisig.input.encode(signatures), redeemScript)
assert.strictEqual(bscript.toASM(replacement), sign.scriptSigFiltered)
tx.ins[i].script = replacement
@ -476,7 +481,7 @@ describe('TransactionBuilder', function () {
txb = TransactionBuilder.fromTransaction(tx, network)
}
var keyPair2 = ECPair.fromWIF(sign.keyPair, network)
const keyPair2 = ECPair.fromWIF(sign.keyPair, network)
txb.sign(i, keyPair2, redeemScript, sign.hashType)
// update the tx
@ -493,10 +498,10 @@ describe('TransactionBuilder', function () {
})
describe('various edge case', function () {
var network = NETWORKS.testnet
const network = NETWORKS.testnet
it('should warn of high fee for segwit transaction based on VSize, not Size', function () {
var rawtx = '01000000000104fdaac89627208b4733484ca56bc291f4cf4fa8d7c5f29893c52b46788a0a' +
const rawtx = '01000000000104fdaac89627208b4733484ca56bc291f4cf4fa8d7c5f29893c52b46788a0a' +
'1df90000000000fffffffffdaac89627208b4733484ca56bc291f4cf4fa8d7c5f29893c52b46788a0a1df9' +
'0100000000ffffffffa2ef7aaab316a3e5b5b0a78d1d35c774b95a079f9f0c762277a49caf1f26bca40000' +
'000000ffffffffa2ef7aaab316a3e5b5b0a78d1d35c774b95a079f9f0c762277a49caf1f26bca401000000' +
@ -511,7 +516,7 @@ describe('TransactionBuilder', function () {
'd561abaac86c37a353b52895a5e6c196d6f44802473044022007be81ffd4297441ab10e740fc9bab9545a2' +
'194a565cd6aa4cc38b8eaffa343402201c5b4b61d73fa38e49c1ee68cc0e6dfd2f5dae453dd86eb142e87a' +
'0bafb1bc8401210283409659355b6d1cc3c32decd5d561abaac86c37a353b52895a5e6c196d6f44800000000'
var txb = TransactionBuilder.fromTransaction(Transaction.fromHex(rawtx))
const txb = TransactionBuilder.fromTransaction(Transaction.fromHex(rawtx))
txb.__inputs[0].value = 241530
txb.__inputs[1].value = 241530
txb.__inputs[2].value = 248920
@ -523,64 +528,64 @@ describe('TransactionBuilder', function () {
})
it('should classify witness inputs with witness = true during multisigning', function () {
var keyPair = ECPair.fromWIF('cRAwuVuVSBZMPu7hdrYvMCZ8eevzmkExjFbaBLhqnDdrezxN3nTS', network)
var witnessScript = Buffer.from('522102bbbd6eb01efcbe4bd9664b886f26f69de5afcb2e479d72596c8bf21929e352e22102d9c3f7180ef13ec5267723c9c2ffab56a4215241f837502ea8977c8532b9ea1952ae', 'hex')
var redeemScript = Buffer.from('002024376a0a9abab599d0e028248d48ebe817bc899efcffa1cd2984d67289daf5af', 'hex')
var scriptPubKey = Buffer.from('a914b64f1a3eacc1c8515592a6f10457e8ff90e4db6a87', 'hex')
var txb = new TransactionBuilder(network)
const keyPair = ECPair.fromWIF('cRAwuVuVSBZMPu7hdrYvMCZ8eevzmkExjFbaBLhqnDdrezxN3nTS', network)
const witnessScript = Buffer.from('522102bbbd6eb01efcbe4bd9664b886f26f69de5afcb2e479d72596c8bf21929e352e22102d9c3f7180ef13ec5267723c9c2ffab56a4215241f837502ea8977c8532b9ea1952ae', 'hex')
const redeemScript = Buffer.from('002024376a0a9abab599d0e028248d48ebe817bc899efcffa1cd2984d67289daf5af', 'hex')
const scriptPubKey = Buffer.from('a914b64f1a3eacc1c8515592a6f10457e8ff90e4db6a87', 'hex')
const txb = new TransactionBuilder(network)
txb.setVersion(1)
txb.addInput('a4696c4b0cd27ec2e173ab1fa7d1cc639a98ee237cec95a77ca7ff4145791529', 1, 0xffffffff, scriptPubKey)
txb.addOutput(scriptPubKey, 99000)
txb.sign(0, keyPair, redeemScript, null, 100000, witnessScript)
// 2-of-2 signed only once
var tx = txb.buildIncomplete()
const tx = txb.buildIncomplete()
// Only input is segwit, so txid should be accurate with the final tx
assert.equal(tx.getId(), 'f15d0a65b21b4471405b21a099f8b18e1ae4d46d55efbd0f4766cf11ad6cb821')
var txHex = tx.toHex()
var newTxb = TransactionBuilder.fromTransaction(Transaction.fromHex(txHex))
const txHex = tx.toHex()
const newTxb = TransactionBuilder.fromTransaction(Transaction.fromHex(txHex))
// input should have the key 'witness' set to true
assert.equal(newTxb.__inputs[0].witness, true)
})
it('should handle badly pre-filled OP_0s', function () {
// OP_0 is used where a signature is missing
var redeemScripSig = bscript.fromASM('OP_0 OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae')
var redeemScript = bscript.fromASM('OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG')
const redeemScripSig = bscript.fromASM('OP_0 OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae')
const redeemScript = bscript.fromASM('OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG')
var tx = new Transaction()
const tx = new Transaction()
tx.addInput(Buffer.from('cff58855426469d0ef16442ee9c644c4fb13832467bcbc3173168a7916f07149', 'hex'), 0, undefined, redeemScripSig)
tx.addOutput(Buffer.from('76a914aa4d7985c57e011a8b3dd8e0e5a73aaef41629c588ac', 'hex'), 1000)
// now import the Transaction
var txb = TransactionBuilder.fromTransaction(tx, NETWORKS.testnet)
const txb = TransactionBuilder.fromTransaction(tx, NETWORKS.testnet)
var keyPair2 = ECPair.fromWIF('91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx3cTMqe', network)
const keyPair2 = ECPair.fromWIF('91avARGdfge8E4tZfYLoxeJ5sGBdNJQH4kvjJoQFacbgx3cTMqe', network)
txb.sign(0, keyPair2, redeemScript)
var tx2 = txb.build()
const tx2 = txb.build()
assert.equal(tx2.getId(), 'eab59618a564e361adef6d918bd792903c3d41bcf1220137364fb847880467f9')
assert.equal(bscript.toASM(tx2.ins[0].script), 'OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae')
})
it('should not classify blank scripts as nonstandard', function () {
var txb = new TransactionBuilder()
let txb = new TransactionBuilder()
txb.setVersion(1)
txb.addInput('aa94ab02c182214f090e99a0d57021caffd0f195a81c24602b1028b130b63e31', 0)
var incomplete = txb.buildIncomplete().toHex()
var keyPair = ECPair.fromWIF('L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy')
const incomplete = txb.buildIncomplete().toHex()
const keyPair = ECPair.fromWIF('L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy')
// sign, as expected
txb.addOutput('1Gokm82v6DmtwKEB8AiVhm82hyFSsEvBDK', 15000)
txb.sign(0, keyPair)
var txId = txb.build().getId()
const txId = txb.build().getId()
assert.equal(txId, '54f097315acbaedb92a95455da3368eb45981cdae5ffbc387a9afc872c0f29b3')
// and, repeat
txb = TransactionBuilder.fromTransaction(Transaction.fromHex(incomplete))
txb.addOutput('1Gokm82v6DmtwKEB8AiVhm82hyFSsEvBDK', 15000)
txb.sign(0, keyPair)
var txId2 = txb.build().getId()
const txId2 = txb.build().getId()
assert.equal(txId, txId2)
})
})

View file

@ -1,13 +1,13 @@
/* global describe, it */
var assert = require('assert')
var types = require('../src/types')
var typeforce = require('typeforce')
const assert = require('assert')
const types = require('../src/types')
const typeforce = require('typeforce')
describe('types', function () {
describe('Buffer Hash160/Hash256', function () {
var buffer20byte = Buffer.alloc(20)
var buffer32byte = Buffer.alloc(32)
const buffer20byte = Buffer.alloc(20)
const buffer32byte = Buffer.alloc(32)
it('return true for valid size', function () {
assert(types.Hash160bit(buffer20byte))