From 8ec1911a269a5a3839fd51b45dec38b2df43b38f Mon Sep 17 00:00:00 2001
From: junderw <junderwood@bitcoinbank.co.jp>
Date: Sun, 7 Apr 2019 22:27:16 +0900
Subject: [PATCH 1/7] Fix tests Missing Input

---
 test/integration/_regtest.js     | 119 +++++++------
 test/integration/addresses.js    |  19 +--
 test/integration/bip32.js        |  18 +-
 test/integration/cltv.js         | 280 ++++++++++++++-----------------
 test/integration/csv.js          | 158 ++++++++---------
 test/integration/payments.js     |  44 +++--
 test/integration/transactions.js | 248 ++++++++++++---------------
 7 files changed, 412 insertions(+), 474 deletions(-)

diff --git a/test/integration/_regtest.js b/test/integration/_regtest.js
index f392a8a..650a79c 100644
--- a/test/integration/_regtest.js
+++ b/test/integration/_regtest.js
@@ -1,99 +1,109 @@
 const assert = require('assert')
 const bitcoin = require('../../')
-const dhttp = require('dhttp/200')
+const dhttpCallback = require('dhttp/200')
+// use Promises
+const dhttp = options => new Promise((resolve, reject) => {
+  return dhttpCallback(options, (err, data) => {
+    if (err) return reject(err)
+    else return resolve(data)
+  })
+})
 
 const APIPASS = process.env.APIPASS || 'satoshi'
 const APIURL = 'https://regtest.bitbank.cc/1'
 const NETWORK = bitcoin.networks.testnet
 
-function broadcast (txHex, callback) {
-  dhttp({
+function broadcast (txHex) {
+  return dhttp({
     method: 'POST',
     url: APIURL + '/t/push',
     body: txHex
-  }, callback)
+  })
 }
 
-function mine (count, callback) {
-  dhttp({
+function mine (count) {
+  return dhttp({
     method: 'POST',
     url: APIURL + '/r/generate?count=' + count + '&key=' + APIPASS
-  }, callback)
+  })
 }
 
-function height (callback) {
-  dhttp({
+function height () {
+  return dhttp({
     method: 'GET',
     url: APIURL + '/b/best/height'
-  }, callback)
+  })
 }
 
-function faucet (address, value, callback) {
-  dhttp({
-    method: 'POST',
-    url: APIURL + '/r/faucet?address=' + address + '&value=' + value + '&key=' + APIPASS
-  }, function (err, txId) {
-    if (err) return callback(err)
+async function faucet (address, value) {
+  let count = 0
+  let _unspents = []
+  const sleep = ms => new Promise(r => setTimeout(r, ms))
+  do {
+    if (count > 0) {
+      if (count >= 5) throw new Error('Missing Inputs')
+      console.log('Missing Inputs, retry #' + count)
+      await sleep(200)
+    }
+
+    const txId = await dhttp({
+      method: 'POST',
+      url: APIURL + '/r/faucet?address=' + address + '&value=' + value + '&key=' + APIPASS
+    })
 
-    unspents(address, function (err, results) {
-      if (err) return callback(err)
+    await sleep(100)
 
-      const unspents = results.filter(x => x.txId === txId)
-      if (unspents.length === 0) return callback(new Error('Missing unspent'))
+    const results = await unspents(address)
 
-      callback(null, unspents.pop())
-    })
-  })
+    _unspents = results.filter(x => x.txId === txId)
+
+    count++
+  } while (_unspents.length === 0)
+
+  return _unspents.pop()
 }
 
-function faucetComplex (output, value, callback) {
+async function faucetComplex (output, value) {
   const keyPair = bitcoin.ECPair.makeRandom({ network: NETWORK })
   const p2pkh = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: NETWORK })
 
-  faucet(p2pkh.address, value * 2, (err, unspent) => {
-    if (err) return callback(err)
+  const unspent = await faucet(p2pkh.address, value * 2)
 
-    const txvb = new bitcoin.TransactionBuilder(NETWORK)
-    txvb.addInput(unspent.txId, unspent.vout, null, p2pkh.output)
-    txvb.addOutput(output, value)
-    txvb.sign(0, keyPair)
-    const txv = txvb.build()
+  const txvb = new bitcoin.TransactionBuilder(NETWORK)
+  txvb.addInput(unspent.txId, unspent.vout, null, p2pkh.output)
+  txvb.addOutput(output, value)
+  txvb.sign(0, keyPair)
+  const txv = txvb.build()
 
-    broadcast(txv.toHex(), function (err) {
-      if (err) return callback(err)
+  await broadcast(txv.toHex())
 
-      return callback(null, {
-        txId: txv.getId(),
-        vout: 0,
-        value
-      })
-    })
-  })
+  return {
+    txId: txv.getId(),
+    vout: 0,
+    value
+  }
 }
 
-function fetch (txId, callback) {
-  dhttp({
+function fetch (txId) {
+  return dhttp({
     method: 'GET',
     url: APIURL + '/t/' + txId + '/json'
-  }, callback)
+  })
 }
 
-function unspents (address, callback) {
-  dhttp({
+function unspents (address) {
+  return dhttp({
     method: 'GET',
     url: APIURL + '/a/' + address + '/unspents'
-  }, callback)
+  })
 }
 
-function verify (txo, callback) {
-  fetch(txo.txId, function (err, tx) {
-    if (err) return callback(err)
+async function verify (txo) {
+  const tx = await fetch(txo.txId)
 
-    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()
-  })
+  const txoActual = tx.outs[txo.vout]
+  if (txo.address) assert.strictEqual(txoActual.address, txo.address)
+  if (txo.value) assert.strictEqual(txoActual.value, txo.value)
 }
 
 function getAddress (node, network) {
@@ -108,6 +118,7 @@ function randomAddress () {
 
 module.exports = {
   broadcast,
+  dhttp,
   faucet,
   faucetComplex,
   fetch,
diff --git a/test/integration/addresses.js b/test/integration/addresses.js
index 7cf2612..f37dbc7 100644
--- a/test/integration/addresses.js
+++ b/test/integration/addresses.js
@@ -1,29 +1,26 @@
 const { describe, it } = require('mocha')
 const assert = require('assert')
 const bitcoin = require('../../')
-const dhttp = require('dhttp/200')
+const dhttp = require('./_regtest').dhttp
 const TESTNET = bitcoin.networks.testnet
 
 describe('bitcoinjs-lib (addresses)', function () {
-  it('can generate a random address [and support the retrieval of transactions for that address (via 3PBP)', function (done) {
+  it('can generate a random address [and support the retrieval of transactions for that address (via 3PBP)', async function () {
     const keyPair = bitcoin.ECPair.makeRandom()
     const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey })
 
     // bitcoin P2PKH addresses start with a '1'
     assert.strictEqual(address.startsWith('1'), true)
 
-    dhttp({
+    const result = await dhttp({
       method: 'GET',
       url: 'https://blockchain.info/rawaddr/' + address
-    }, function (err, result) {
-      if (err) return done(err)
-
-      // random private keys [probably!] have no transactions
-      assert.strictEqual(result.n_tx, 0)
-      assert.strictEqual(result.total_received, 0)
-      assert.strictEqual(result.total_sent, 0)
-      done()
     })
+
+    // random private keys [probably!] have no transactions
+    assert.strictEqual(result.n_tx, 0)
+    assert.strictEqual(result.total_received, 0)
+    assert.strictEqual(result.total_sent, 0)
   })
 
   it('can import an address via WIF', function () {
diff --git a/test/integration/bip32.js b/test/integration/bip32.js
index 27a2da4..5f948fa 100644
--- a/test/integration/bip32.js
+++ b/test/integration/bip32.js
@@ -13,7 +13,7 @@ describe('bitcoinjs-lib (BIP32)', function () {
     const xpriv = 'tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK'
     const node = bip32.fromBase58(xpriv, bitcoin.networks.testnet)
 
-    assert.equal(node.toWIF(), 'cQfoY67cetFNunmBUX5wJiw3VNoYx3gG9U9CAofKE6BfiV1fSRw7')
+    assert.strictEqual(node.toWIF(), 'cQfoY67cetFNunmBUX5wJiw3VNoYx3gG9U9CAofKE6BfiV1fSRw7')
   })
 
   it('can export a BIP32 xpriv, then import it', function () {
@@ -23,8 +23,8 @@ describe('bitcoinjs-lib (BIP32)', function () {
     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
+    assert.strictEqual(getAddress(node), getAddress(restored)) // same public key
+    assert.strictEqual(node.toWIF(), restored.toWIF()) // same private key
   })
 
   it('can export a BIP32 xpub', function () {
@@ -33,7 +33,7 @@ describe('bitcoinjs-lib (BIP32)', function () {
     const node = bip32.fromSeed(seed)
     const string = node.neutered().toBase58()
 
-    assert.equal(string, 'xpub661MyMwAqRbcGhVeaVfEBA25e3cP9DsJQZoE8iep5fZSxy3TnPBNBgWnMZx56oreNc48ZoTkQfatNJ9VWnQ7ZcLZcVStpaXLTeG8bGrzX3n')
+    assert.strictEqual(string, 'xpub661MyMwAqRbcGhVeaVfEBA25e3cP9DsJQZoE8iep5fZSxy3TnPBNBgWnMZx56oreNc48ZoTkQfatNJ9VWnQ7ZcLZcVStpaXLTeG8bGrzX3n')
   })
 
   it('can create a BIP32, bitcoin, account 0, external address', function () {
@@ -47,8 +47,8 @@ describe('bitcoinjs-lib (BIP32)', function () {
       .derive(0)
       .derive(0)
 
-    assert.equal(getAddress(child1), '1JHyB1oPXufr4FXkfitsjgNB5yRY9jAaa7')
-    assert.equal(getAddress(child1b), '1JHyB1oPXufr4FXkfitsjgNB5yRY9jAaa7')
+    assert.strictEqual(getAddress(child1), '1JHyB1oPXufr4FXkfitsjgNB5yRY9jAaa7')
+    assert.strictEqual(getAddress(child1b), '1JHyB1oPXufr4FXkfitsjgNB5yRY9jAaa7')
   })
 
   it('can create a BIP44, bitcoin, account 0, external address', function () {
@@ -63,8 +63,8 @@ describe('bitcoinjs-lib (BIP32)', function () {
       .derive(0)
       .derive(0)
 
-    assert.equal(getAddress(child1), '12Tyvr1U8A3ped6zwMEU5M8cx3G38sP5Au')
-    assert.equal(getAddress(child1b), '12Tyvr1U8A3ped6zwMEU5M8cx3G38sP5Au')
+    assert.strictEqual(getAddress(child1), '12Tyvr1U8A3ped6zwMEU5M8cx3G38sP5Au')
+    assert.strictEqual(getAddress(child1b), '12Tyvr1U8A3ped6zwMEU5M8cx3G38sP5Au')
   })
 
   it('can create a BIP49, bitcoin testnet, account 0, external address', function () {
@@ -79,7 +79,7 @@ describe('bitcoinjs-lib (BIP32)', function () {
       redeem: bitcoin.payments.p2wpkh({ pubkey: child.publicKey, network: bitcoin.networks.testnet }),
       network: bitcoin.networks.testnet
     })
-    assert.equal(address, '2Mww8dCYPUpKHofjgcXcBCEGmniw9CoaiD2')
+    assert.strictEqual(address, '2Mww8dCYPUpKHofjgcXcBCEGmniw9CoaiD2')
   })
 
   it('can use BIP39 to generate BIP32 addresses', function () {
diff --git a/test/integration/cltv.js b/test/integration/cltv.js
index 8bf1c4a..66afb94 100644
--- a/test/integration/cltv.js
+++ b/test/integration/cltv.js
@@ -10,8 +10,8 @@ const bob = bitcoin.ECPair.fromWIF('cMkopUXKWsEzAjfa1zApksGRwjVpJRB3831qM9W4gKZs
 
 describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
   // force update MTP
-  before(function (done) {
-    regtestUtils.mine(11, done)
+  before(async function () {
+    await regtestUtils.mine(11)
   })
 
   const hashType = bitcoin.Transaction.SIGHASH_ALL
@@ -38,188 +38,160 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
   }
 
   // expiry past, {Alice's signature} OP_TRUE
-  it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the past)', function (done) {
+  it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the past)', async function () {
     // 3 hours ago
     const lockTime = bip65.encode({ utc: utcNow() - (3600 * 3) })
     const redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
     const { address } = bitcoin.payments.p2sh({ redeem: { output: redeemScript, network: regtest }, network: regtest })
 
     // fund the P2SH(CLTV) address
-    regtestUtils.faucet(address, 1e5, function (err, unspent) {
-      if (err) return done(err)
-
-      const txb = new bitcoin.TransactionBuilder(regtest)
-      txb.setLockTime(lockTime)
-      // Note: nSequence MUST be <= 0xfffffffe otherwise LockTime is ignored, and is immediately spendable.
-      txb.addInput(unspent.txId, unspent.vout, 0xfffffffe)
-      txb.addOutput(regtestUtils.RANDOM_ADDRESS, 7e4)
-
-      // {Alice's signature} OP_TRUE
-      const tx = txb.buildIncomplete()
-      const signatureHash = tx.hashForSignature(0, redeemScript, hashType)
-      const redeemScriptSig = bitcoin.payments.p2sh({
-        redeem: {
-          input: bitcoin.script.compile([
-            bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
-            bitcoin.opcodes.OP_TRUE
-          ]),
-          output: redeemScript
-        }
-      }).input
-      tx.setInputScript(0, redeemScriptSig)
-
-      regtestUtils.broadcast(tx.toHex(), function (err) {
-        if (err) return done(err)
-
-        regtestUtils.verify({
-          txId: tx.getId(),
-          address: regtestUtils.RANDOM_ADDRESS,
-          vout: 0,
-          value: 7e4
-        }, done)
-      })
+    const unspent = await regtestUtils.faucet(address, 1e5)
+    const txb = new bitcoin.TransactionBuilder(regtest)
+    txb.setLockTime(lockTime)
+    // Note: nSequence MUST be <= 0xfffffffe otherwise LockTime is ignored, and is immediately spendable.
+    txb.addInput(unspent.txId, unspent.vout, 0xfffffffe)
+    txb.addOutput(regtestUtils.RANDOM_ADDRESS, 7e4)
+
+    // {Alice's signature} OP_TRUE
+    const tx = txb.buildIncomplete()
+    const signatureHash = tx.hashForSignature(0, redeemScript, hashType)
+    const redeemScriptSig = bitcoin.payments.p2sh({
+      redeem: {
+        input: bitcoin.script.compile([
+          bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
+          bitcoin.opcodes.OP_TRUE
+        ]),
+        output: redeemScript
+      }
+    }).input
+    tx.setInputScript(0, redeemScriptSig)
+
+    await regtestUtils.broadcast(tx.toHex())
+
+    await regtestUtils.verify({
+      txId: tx.getId(),
+      address: regtestUtils.RANDOM_ADDRESS,
+      vout: 0,
+      value: 7e4
     })
   })
 
   // expiry will pass, {Alice's signature} OP_TRUE
-  it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)', function (done) {
-    regtestUtils.height(function (err, height) {
-      if (err) return done(err)
-
-      // 5 blocks from now
-      const lockTime = bip65.encode({ blocks: height + 5 })
-      const redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
-      const { address } = bitcoin.payments.p2sh({ redeem: { output: redeemScript, network: regtest }, network: regtest })
-
-      // fund the P2SH(CLTV) address
-      regtestUtils.faucet(address, 1e5, function (err, unspent) {
-        if (err) return done(err)
-
-        const txb = new bitcoin.TransactionBuilder(regtest)
-        txb.setLockTime(lockTime)
-        // Note: nSequence MUST be <= 0xfffffffe otherwise LockTime is ignored, and is immediately spendable.
-        txb.addInput(unspent.txId, unspent.vout, 0xfffffffe)
-        txb.addOutput(regtestUtils.RANDOM_ADDRESS, 7e4)
-
-        // {Alice's signature} OP_TRUE
-        const tx = txb.buildIncomplete()
-        const signatureHash = tx.hashForSignature(0, redeemScript, hashType)
-        const redeemScriptSig = bitcoin.payments.p2sh({
-          redeem: {
-            input: bitcoin.script.compile([
-              bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
-              bitcoin.opcodes.OP_TRUE
-            ]),
-            output: redeemScript
-          }
-        }).input
-        tx.setInputScript(0, redeemScriptSig)
-
-        // TODO: test that it failures _prior_ to expiry, unfortunately, race conditions when run concurrently
-        // ...
-        // into the future!
-        regtestUtils.mine(5, function (err) {
-          if (err) return done(err)
-
-          regtestUtils.broadcast(tx.toHex(), function (err) {
-            if (err) return done(err)
-
-            regtestUtils.verify({
-              txId: tx.getId(),
-              address: regtestUtils.RANDOM_ADDRESS,
-              vout: 0,
-              value: 7e4
-            }, done)
-          })
-        })
-      })
+  it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)', async function () {
+    const height = await regtestUtils.height()
+    // 5 blocks from now
+    const lockTime = bip65.encode({ blocks: height + 5 })
+    const redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
+    const { address } = bitcoin.payments.p2sh({ redeem: { output: redeemScript, network: regtest }, network: regtest })
+
+    // fund the P2SH(CLTV) address
+    const unspent = await regtestUtils.faucet(address, 1e5)
+    const txb = new bitcoin.TransactionBuilder(regtest)
+    txb.setLockTime(lockTime)
+    // Note: nSequence MUST be <= 0xfffffffe otherwise LockTime is ignored, and is immediately spendable.
+    txb.addInput(unspent.txId, unspent.vout, 0xfffffffe)
+    txb.addOutput(regtestUtils.RANDOM_ADDRESS, 7e4)
+
+    // {Alice's signature} OP_TRUE
+    const tx = txb.buildIncomplete()
+    const signatureHash = tx.hashForSignature(0, redeemScript, hashType)
+    const redeemScriptSig = bitcoin.payments.p2sh({
+      redeem: {
+        input: bitcoin.script.compile([
+          bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
+          bitcoin.opcodes.OP_TRUE
+        ]),
+        output: redeemScript
+      }
+    }).input
+    tx.setInputScript(0, redeemScriptSig)
+
+    // TODO: test that it failures _prior_ to expiry, unfortunately, race conditions when run concurrently
+    // ...
+    // into the future!
+    await regtestUtils.mine(5)
+    await regtestUtils.broadcast(tx.toHex())
+    await regtestUtils.verify({
+      txId: tx.getId(),
+      address: regtestUtils.RANDOM_ADDRESS,
+      vout: 0,
+      value: 7e4
     })
   })
 
   // expiry ignored, {Bob's signature} {Alice's signature} OP_FALSE
-  it('can create (and broadcast via 3PBP) a Transaction where Alice and Bob can redeem the output at any time', function (done) {
+  it('can create (and broadcast via 3PBP) a Transaction where Alice and Bob can redeem the output at any time', async function () {
     // two hours ago
     const lockTime = bip65.encode({ utc: utcNow() - (3600 * 2) })
     const redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
     const { address } = bitcoin.payments.p2sh({ redeem: { output: redeemScript, network: regtest }, network: regtest })
 
     // fund the P2SH(CLTV) address
-    regtestUtils.faucet(address, 2e5, function (err, unspent) {
-      if (err) return done(err)
-
-      const txb = new bitcoin.TransactionBuilder(regtest)
-      txb.setLockTime(lockTime)
-      // Note: nSequence MUST be <= 0xfffffffe otherwise LockTime is ignored, and is immediately spendable.
-      txb.addInput(unspent.txId, unspent.vout, 0xfffffffe)
-      txb.addOutput(regtestUtils.RANDOM_ADDRESS, 8e4)
-
-      // {Alice's signature} {Bob's signature} OP_FALSE
-      const tx = txb.buildIncomplete()
-      const signatureHash = tx.hashForSignature(0, redeemScript, hashType)
-      const redeemScriptSig = bitcoin.payments.p2sh({
-        redeem: {
-          input: bitcoin.script.compile([
-            bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
-            bitcoin.script.signature.encode(bob.sign(signatureHash), hashType),
-            bitcoin.opcodes.OP_FALSE
-          ]),
-          output: redeemScript
-        }
-      }).input
-      tx.setInputScript(0, redeemScriptSig)
-
-      regtestUtils.broadcast(tx.toHex(), function (err) {
-        if (err) return done(err)
-
-        regtestUtils.verify({
-          txId: tx.getId(),
-          address: regtestUtils.RANDOM_ADDRESS,
-          vout: 0,
-          value: 8e4
-        }, done)
-      })
+    const unspent = await regtestUtils.faucet(address, 2e5)
+    const txb = new bitcoin.TransactionBuilder(regtest)
+    txb.setLockTime(lockTime)
+    // Note: nSequence MUST be <= 0xfffffffe otherwise LockTime is ignored, and is immediately spendable.
+    txb.addInput(unspent.txId, unspent.vout, 0xfffffffe)
+    txb.addOutput(regtestUtils.RANDOM_ADDRESS, 8e4)
+
+    // {Alice's signature} {Bob's signature} OP_FALSE
+    const tx = txb.buildIncomplete()
+    const signatureHash = tx.hashForSignature(0, redeemScript, hashType)
+    const redeemScriptSig = bitcoin.payments.p2sh({
+      redeem: {
+        input: bitcoin.script.compile([
+          bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
+          bitcoin.script.signature.encode(bob.sign(signatureHash), hashType),
+          bitcoin.opcodes.OP_FALSE
+        ]),
+        output: redeemScript
+      }
+    }).input
+    tx.setInputScript(0, redeemScriptSig)
+
+    await regtestUtils.broadcast(tx.toHex())
+    await regtestUtils.verify({
+      txId: tx.getId(),
+      address: regtestUtils.RANDOM_ADDRESS,
+      vout: 0,
+      value: 8e4
     })
   })
 
   // expiry in the future, {Alice's signature} OP_TRUE
-  it('can create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry', function (done) {
+  it('can create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry', async function () {
     // two hours from now
     const lockTime = bip65.encode({ utc: utcNow() + (3600 * 2) })
     const redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
     const { address } = bitcoin.payments.p2sh({ redeem: { output: redeemScript, network: regtest }, network: regtest })
 
     // fund the P2SH(CLTV) address
-    regtestUtils.faucet(address, 2e4, function (err, unspent) {
-      if (err) return done(err)
-
-      const txb = new bitcoin.TransactionBuilder(regtest)
-      txb.setLockTime(lockTime)
-      // Note: nSequence MUST be <= 0xfffffffe otherwise LockTime is ignored, and is immediately spendable.
-      txb.addInput(unspent.txId, unspent.vout, 0xfffffffe)
-      txb.addOutput(regtestUtils.RANDOM_ADDRESS, 1e4)
-
-      // {Alice's signature} OP_TRUE
-      const tx = txb.buildIncomplete()
-      const signatureHash = tx.hashForSignature(0, redeemScript, hashType)
-      const redeemScriptSig = bitcoin.payments.p2sh({
-        redeem: {
-          input: bitcoin.script.compile([
-            bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
-            bitcoin.script.signature.encode(bob.sign(signatureHash), hashType),
-            bitcoin.opcodes.OP_TRUE
-          ]),
-          output: redeemScript
-        }
-      }).input
-      tx.setInputScript(0, redeemScriptSig)
-
-      regtestUtils.broadcast(tx.toHex(), function (err) {
-        assert.throws(function () {
-          if (err) throw err
-        }, /Error: non-final \(code 64\)/)
-
-        done()
-      })
+    const unspent = await regtestUtils.faucet(address, 2e4)
+    const txb = new bitcoin.TransactionBuilder(regtest)
+    txb.setLockTime(lockTime)
+    // Note: nSequence MUST be <= 0xfffffffe otherwise LockTime is ignored, and is immediately spendable.
+    txb.addInput(unspent.txId, unspent.vout, 0xfffffffe)
+    txb.addOutput(regtestUtils.RANDOM_ADDRESS, 1e4)
+
+    // {Alice's signature} OP_TRUE
+    const tx = txb.buildIncomplete()
+    const signatureHash = tx.hashForSignature(0, redeemScript, hashType)
+    const redeemScriptSig = bitcoin.payments.p2sh({
+      redeem: {
+        input: bitcoin.script.compile([
+          bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
+          bitcoin.script.signature.encode(bob.sign(signatureHash), hashType),
+          bitcoin.opcodes.OP_TRUE
+        ]),
+        output: redeemScript
+      }
+    }).input
+    tx.setInputScript(0, redeemScriptSig)
+
+    await regtestUtils.broadcast(tx.toHex()).catch(err => {
+      assert.throws(function () {
+        if (err) throw err
+      }, /Error: non-final \(code 64\)/)
     })
   })
 })
diff --git a/test/integration/csv.js b/test/integration/csv.js
index 5996634..1ad8c90 100644
--- a/test/integration/csv.js
+++ b/test/integration/csv.js
@@ -10,8 +10,8 @@ const bob = bitcoin.ECPair.fromWIF('cMkopUXKWsEzAjfa1zApksGRwjVpJRB3831qM9W4gKZs
 
 describe('bitcoinjs-lib (transactions w/ CSV)', function () {
   // force update MTP
-  before(function (done) {
-    regtestUtils.mine(11, done)
+  before(async function () {
+    await regtestUtils.mine(11)
   })
 
   const hashType = bitcoin.Transaction.SIGHASH_ALL
@@ -35,66 +35,56 @@ describe('bitcoinjs-lib (transactions w/ CSV)', function () {
   }
 
   // expiry will pass, {Alice's signature} OP_TRUE
-  it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)', function (done) {
-    regtestUtils.height(function (err, height) {
-      if (err) return done(err)
-
-      // 5 blocks from now
-      const sequence = bip68.encode({ blocks: 5 })
-      const p2sh = bitcoin.payments.p2sh({
-        redeem: {
-          output: csvCheckSigOutput(alice, bob, sequence)
-        },
-        network: regtest
-      })
-
-      // fund the P2SH(CSV) address
-      regtestUtils.faucet(p2sh.address, 1e5, function (err, unspent) {
-        if (err) return done(err)
-
-        const txb = new bitcoin.TransactionBuilder(regtest)
-        txb.addInput(unspent.txId, unspent.vout, sequence)
-        txb.addOutput(regtestUtils.RANDOM_ADDRESS, 7e4)
-
-        // {Alice's signature} OP_TRUE
-        const tx = txb.buildIncomplete()
-        const signatureHash = tx.hashForSignature(0, p2sh.redeem.output, hashType)
-        const redeemScriptSig = bitcoin.payments.p2sh({
-          network: regtest,
-          redeem: {
-            network: regtest,
-            output: p2sh.redeem.output,
-            input: bitcoin.script.compile([
-              bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
-              bitcoin.opcodes.OP_TRUE
-            ])
-          }
-        }).input
-        tx.setInputScript(0, redeemScriptSig)
-
-        // TODO: test that it failures _prior_ to expiry, unfortunately, race conditions when run concurrently
-        // ...
-        // into the future!
-        regtestUtils.mine(10, function (err) {
-          if (err) return done(err)
-
-          regtestUtils.broadcast(tx.toHex(), function (err) {
-            if (err) return done(err)
-
-            regtestUtils.verify({
-              txId: tx.getId(),
-              address: regtestUtils.RANDOM_ADDRESS,
-              vout: 0,
-              value: 7e4
-            }, done)
-          })
-        })
-      })
+  it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)', async function () {
+    // 5 blocks from now
+    const sequence = bip68.encode({ blocks: 5 })
+    const p2sh = bitcoin.payments.p2sh({
+      redeem: {
+        output: csvCheckSigOutput(alice, bob, sequence)
+      },
+      network: regtest
+    })
+
+    // fund the P2SH(CSV) address
+    const unspent = await regtestUtils.faucet(p2sh.address, 1e5)
+
+    const txb = new bitcoin.TransactionBuilder(regtest)
+    txb.addInput(unspent.txId, unspent.vout, sequence)
+    txb.addOutput(regtestUtils.RANDOM_ADDRESS, 7e4)
+
+    // {Alice's signature} OP_TRUE
+    const tx = txb.buildIncomplete()
+    const signatureHash = tx.hashForSignature(0, p2sh.redeem.output, hashType)
+    const redeemScriptSig = bitcoin.payments.p2sh({
+      network: regtest,
+      redeem: {
+        network: regtest,
+        output: p2sh.redeem.output,
+        input: bitcoin.script.compile([
+          bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
+          bitcoin.opcodes.OP_TRUE
+        ])
+      }
+    }).input
+    tx.setInputScript(0, redeemScriptSig)
+
+    // TODO: test that it failures _prior_ to expiry, unfortunately, race conditions when run concurrently
+    // ...
+    // into the future!
+    await regtestUtils.mine(10)
+
+    await regtestUtils.broadcast(tx.toHex())
+
+    await regtestUtils.verify({
+      txId: tx.getId(),
+      address: regtestUtils.RANDOM_ADDRESS,
+      vout: 0,
+      value: 7e4
     })
   })
 
   // expiry in the future, {Alice's signature} OP_TRUE
-  it('can create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry', function (done) {
+  it('can create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry', async function () {
     // two hours after confirmation
     const sequence = bip68.encode({ seconds: 7168 })
     const p2sh = bitcoin.payments.p2sh({
@@ -105,37 +95,33 @@ describe('bitcoinjs-lib (transactions w/ CSV)', function () {
     })
 
     // fund the P2SH(CSV) address
-    regtestUtils.faucet(p2sh.address, 2e4, function (err, unspent) {
-      if (err) return done(err)
+    const unspent = await regtestUtils.faucet(p2sh.address, 2e4)
 
-      const txb = new bitcoin.TransactionBuilder(regtest)
-      txb.addInput(unspent.txId, unspent.vout, sequence)
-      txb.addOutput(regtestUtils.RANDOM_ADDRESS, 1e4)
+    const txb = new bitcoin.TransactionBuilder(regtest)
+    txb.addInput(unspent.txId, unspent.vout, sequence)
+    txb.addOutput(regtestUtils.RANDOM_ADDRESS, 1e4)
 
-      // {Alice's signature} OP_TRUE
-      const tx = txb.buildIncomplete()
-      const signatureHash = tx.hashForSignature(0, p2sh.redeem.output, hashType)
-      const redeemScriptSig = bitcoin.payments.p2sh({
+    // {Alice's signature} OP_TRUE
+    const tx = txb.buildIncomplete()
+    const signatureHash = tx.hashForSignature(0, p2sh.redeem.output, hashType)
+    const redeemScriptSig = bitcoin.payments.p2sh({
+      network: regtest,
+      redeem: {
         network: regtest,
-        redeem: {
-          network: regtest,
-          output: p2sh.redeem.output,
-          input: bitcoin.script.compile([
-            bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
-            bitcoin.script.signature.encode(bob.sign(signatureHash), hashType),
-            bitcoin.opcodes.OP_TRUE
-          ])
-        }
-      }).input
-      tx.setInputScript(0, redeemScriptSig)
-
-      regtestUtils.broadcast(tx.toHex(), function (err) {
-        assert.throws(function () {
-          if (err) throw err
-        }, /Error: non-BIP68-final \(code 64\)/)
-
-        done()
-      })
+        output: p2sh.redeem.output,
+        input: bitcoin.script.compile([
+          bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
+          bitcoin.script.signature.encode(bob.sign(signatureHash), hashType),
+          bitcoin.opcodes.OP_TRUE
+        ])
+      }
+    }).input
+    tx.setInputScript(0, redeemScriptSig)
+
+    await regtestUtils.broadcast(tx.toHex()).catch(err => {
+      assert.throws(function () {
+        if (err) throw err
+      }, /Error: non-BIP68-final \(code 64\)/)
     })
   })
 })
diff --git a/test/integration/payments.js b/test/integration/payments.js
index a8fb84e..2fcdbda 100644
--- a/test/integration/payments.js
+++ b/test/integration/payments.js
@@ -8,24 +8,22 @@ const keyPairs = [
   bitcoin.ECPair.makeRandom({ network: NETWORK })
 ]
 
-function buildAndSign (depends, prevOutput, redeemScript, witnessScript, done) {
-  regtestUtils.faucetComplex(prevOutput, 5e4, (err, unspent) => {
-    if (err) return done(err)
+async function buildAndSign (depends, prevOutput, redeemScript, witnessScript) {
+  const unspent = await regtestUtils.faucetComplex(prevOutput, 5e4)
 
-    const txb = new bitcoin.TransactionBuilder(NETWORK)
-    txb.addInput(unspent.txId, unspent.vout, null, prevOutput)
-    txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
+  const txb = new bitcoin.TransactionBuilder(NETWORK)
+  txb.addInput(unspent.txId, unspent.vout, null, prevOutput)
+  txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
 
-    if (depends.signatures) {
-      keyPairs.forEach((keyPair) => {
-        txb.sign(0, keyPair, redeemScript, null, unspent.value, witnessScript)
-      })
-    } else if (depends.signature) {
-      txb.sign(0, keyPairs[0], redeemScript, null, unspent.value, witnessScript)
-    }
+  if (depends.signatures) {
+    keyPairs.forEach((keyPair) => {
+      txb.sign(0, keyPair, redeemScript, null, unspent.value, witnessScript)
+    })
+  } else if (depends.signature) {
+    txb.sign(0, keyPairs[0], redeemScript, null, unspent.value, witnessScript)
+  }
 
-    regtestUtils.broadcast(txb.build().toHex(), done)
-  })
+  return regtestUtils.broadcast(txb.build().toHex())
 }
 
 ;['p2ms', 'p2pk', 'p2pkh', 'p2wpkh'].forEach((k) => {
@@ -42,28 +40,28 @@ function buildAndSign (depends, prevOutput, redeemScript, witnessScript, done) {
   if (!output) throw new TypeError('Missing output')
 
   describe('bitcoinjs-lib (payments - ' + k + ')', function () {
-    it('can broadcast as an output, and be spent as an input', (done) => {
-      buildAndSign(depends, output, null, null, done)
+    it('can broadcast as an output, and be spent as an input', async () => {
+      await buildAndSign(depends, output, null, null)
     })
 
-    it('can (as P2SH(' + k + ')) broadcast as an output, and be spent as an input', (done) => {
+    it('can (as P2SH(' + k + ')) broadcast as an output, and be spent as an input', async () => {
       const p2sh = bitcoin.payments.p2sh({ redeem: { output }, network: NETWORK })
-      buildAndSign(depends, p2sh.output, p2sh.redeem.output, null, done)
+      await buildAndSign(depends, p2sh.output, p2sh.redeem.output, null)
     })
 
     // NOTE: P2WPKH cannot be wrapped in P2WSH, consensus fail
     if (k === 'p2wpkh') return
 
-    it('can (as P2WSH(' + k + ')) broadcast as an output, and be spent as an input', (done) => {
+    it('can (as P2WSH(' + k + ')) broadcast as an output, and be spent as an input', async () => {
       const p2wsh = bitcoin.payments.p2wsh({ redeem: { output }, network: NETWORK })
-      buildAndSign(depends, p2wsh.output, null, p2wsh.redeem.output, done)
+      await buildAndSign(depends, p2wsh.output, null, p2wsh.redeem.output)
     })
 
-    it('can (as P2SH(P2WSH(' + k + '))) broadcast as an output, and be spent as an input', (done) => {
+    it('can (as P2SH(P2WSH(' + k + '))) broadcast as an output, and be spent as an input', async () => {
       const p2wsh = bitcoin.payments.p2wsh({ redeem: { output }, network: NETWORK })
       const p2sh = bitcoin.payments.p2sh({ redeem: { output: p2wsh.output }, network: NETWORK })
 
-      buildAndSign(depends, p2sh.output, p2sh.redeem.output, p2wsh.redeem.output, done)
+      await buildAndSign(depends, p2sh.output, p2sh.redeem.output, p2wsh.redeem.output)
     })
   })
 })
diff --git a/test/integration/transactions.js b/test/integration/transactions.js
index f725241..a3836a7 100644
--- a/test/integration/transactions.js
+++ b/test/integration/transactions.js
@@ -43,7 +43,7 @@ describe('bitcoinjs-lib (transactions)', function () {
     assert.strictEqual(txb.build().toHex(), '01000000024c94e48a870b85f41228d33cf25213dfcc8dd796e7211ed6b1f9a014809dbbb5060000006a473044022041450c258ce7cac7da97316bf2ea1ce66d88967c4df94f3e91f4c2a30f5d08cb02203674d516e6bb2b0afd084c3551614bd9cec3c2945231245e891b145f2d6951f0012103e05ce435e462ec503143305feb6c00e06a3ad52fbf939e85c65f3a765bb7baacffffffff3077d9de049574c3af9bc9c09a7c9db80f2d94caaf63988c9166249b955e867d000000006b483045022100aeb5f1332c79c446d3f906e4499b2e678500580a3f90329edf1ba502eec9402e022072c8b863f8c8d6c26f4c691ac9a6610aa4200edc697306648ee844cfbc089d7a012103df7940ee7cddd2f97763f67e1fb13488da3fbdd7f9c68ec5ef0864074745a289ffffffff0220bf0200000000001976a9147dd65592d0ab2fe0d0257d571abf032cd9db93dc88ac10980200000000001976a914c42e7ef92fdb603af844d064faad95db9bcdfd3d88ac00000000')
   })
 
-  it('can create (and broadcast via 3PBP) a typical Transaction', function (done) {
+  it('can create (and broadcast via 3PBP) a typical Transaction', async () => {
     const alice1 = bitcoin.ECPair.makeRandom({ network: regtest })
     const alice2 = bitcoin.ECPair.makeRandom({ network: regtest })
     const aliceChange = bitcoin.ECPair.makeRandom({ network: regtest, rng: rng })
@@ -53,51 +53,45 @@ describe('bitcoinjs-lib (transactions)', function () {
     const aliceCpkh = bitcoin.payments.p2pkh({ pubkey: aliceChange.publicKey, network: regtest })
 
     // give Alice 2 unspent outputs
-    regtestUtils.faucet(alice1pkh.address, 5e4, function (err, unspent0) {
-      if (err) return done(err)
-
-      regtestUtils.faucet(alice2pkh.address, 7e4, function (err, unspent1) {
-        if (err) return done(err)
-
-        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"
-        txb.addOutput(aliceCpkh.address, 1e4) // Alice's change
-        // (in)(5e4 + 7e4) - (out)(8e4 + 1e4) = (fee)3e4 = 30000, this is the miner fee
-
-        // Alice signs each input with the respective private keys
-        txb.sign(0, alice1)
-        txb.sign(1, alice2)
-
-        // build and broadcast our RegTest network
-        regtestUtils.broadcast(txb.build().toHex(), done)
-        // to build and broadcast to the actual Bitcoin network, see https://github.com/bitcoinjs/bitcoinjs-lib/issues/839
-      })
-    })
+    const unspent0 = await regtestUtils.faucet(alice1pkh.address, 5e4)
+
+    const unspent1 = await regtestUtils.faucet(alice2pkh.address, 7e4)
+
+    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"
+    txb.addOutput(aliceCpkh.address, 1e4) // Alice's change
+    // (in)(5e4 + 7e4) - (out)(8e4 + 1e4) = (fee)3e4 = 30000, this is the miner fee
+
+    // Alice signs each input with the respective private keys
+    txb.sign(0, alice1)
+    txb.sign(1, alice2)
+
+    // build and broadcast our RegTest network
+    await regtestUtils.broadcast(txb.build().toHex())
+    // to build and broadcast to the actual Bitcoin network, see https://github.com/bitcoinjs/bitcoinjs-lib/issues/839
   })
 
-  it('can create (and broadcast via 3PBP) a Transaction with an OP_RETURN output', function (done) {
+  it('can create (and broadcast via 3PBP) a Transaction with an OP_RETURN output', async () => {
     const keyPair = bitcoin.ECPair.makeRandom({ network: regtest })
     const p2pkh = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: regtest })
 
-    regtestUtils.faucet(p2pkh.address, 2e5, function (err, unspent) {
-      if (err) return done(err)
+    const unspent = await regtestUtils.faucet(p2pkh.address, 2e5)
 
-      const txb = new bitcoin.TransactionBuilder(regtest)
-      const data = Buffer.from('bitcoinjs-lib', 'utf8')
-      const embed = bitcoin.payments.embed({ data: [data] })
-      txb.addInput(unspent.txId, unspent.vout)
-      txb.addOutput(embed.output, 1000)
-      txb.addOutput(regtestUtils.RANDOM_ADDRESS, 1e5)
-      txb.sign(0, keyPair)
+    const txb = new bitcoin.TransactionBuilder(regtest)
+    const data = Buffer.from('bitcoinjs-lib', 'utf8')
+    const embed = bitcoin.payments.embed({ data: [data] })
+    txb.addInput(unspent.txId, unspent.vout)
+    txb.addOutput(embed.output, 1000)
+    txb.addOutput(regtestUtils.RANDOM_ADDRESS, 1e5)
+    txb.sign(0, keyPair)
 
-      // build and broadcast to the RegTest network
-      regtestUtils.broadcast(txb.build().toHex(), done)
-    })
+    // build and broadcast to the RegTest network
+    await regtestUtils.broadcast(txb.build().toHex())
   })
 
-  it('can create (and broadcast via 3PBP) a Transaction, w/ a P2SH(P2MS(2 of 4)) (multisig) input', function (done) {
+  it('can create (and broadcast via 3PBP) a Transaction, w/ a P2SH(P2MS(2 of 4)) (multisig) input', async () => {
     const keyPairs = [
       bitcoin.ECPair.makeRandom({ network: regtest }),
       bitcoin.ECPair.makeRandom({ network: regtest }),
@@ -108,118 +102,102 @@ describe('bitcoinjs-lib (transactions)', function () {
     const p2ms = bitcoin.payments.p2ms({ m: 2, pubkeys: pubkeys, network: regtest })
     const p2sh = bitcoin.payments.p2sh({ redeem: p2ms, network: regtest })
 
-    regtestUtils.faucet(p2sh.address, 2e4, function (err, unspent) {
-      if (err) return done(err)
+    const unspent = await regtestUtils.faucet(p2sh.address, 2e4)
 
-      const txb = new bitcoin.TransactionBuilder(regtest)
-      txb.addInput(unspent.txId, unspent.vout)
-      txb.addOutput(regtestUtils.RANDOM_ADDRESS, 1e4)
+    const txb = new bitcoin.TransactionBuilder(regtest)
+    txb.addInput(unspent.txId, unspent.vout)
+    txb.addOutput(regtestUtils.RANDOM_ADDRESS, 1e4)
 
-      txb.sign(0, keyPairs[0], p2sh.redeem.output)
-      txb.sign(0, keyPairs[2], p2sh.redeem.output)
-      const tx = txb.build()
+    txb.sign(0, keyPairs[0], p2sh.redeem.output)
+    txb.sign(0, keyPairs[2], p2sh.redeem.output)
+    const tx = txb.build()
 
-      // build and broadcast to the Bitcoin RegTest network
-      regtestUtils.broadcast(tx.toHex(), function (err) {
-        if (err) return done(err)
+    // build and broadcast to the Bitcoin RegTest network
+    await regtestUtils.broadcast(tx.toHex())
 
-        regtestUtils.verify({
-          txId: tx.getId(),
-          address: regtestUtils.RANDOM_ADDRESS,
-          vout: 0,
-          value: 1e4
-        }, done)
-      })
+    await regtestUtils.verify({
+      txId: tx.getId(),
+      address: regtestUtils.RANDOM_ADDRESS,
+      vout: 0,
+      value: 1e4
     })
   })
 
-  it('can create (and broadcast via 3PBP) a Transaction, w/ a P2SH(P2WPKH) input', function (done) {
+  it('can create (and broadcast via 3PBP) a Transaction, w/ a P2SH(P2WPKH) input', async () => {
     const keyPair = bitcoin.ECPair.makeRandom({ network: regtest })
     const p2wpkh = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey, network: regtest })
     const p2sh = bitcoin.payments.p2sh({ redeem: p2wpkh, network: regtest })
 
-    regtestUtils.faucet(p2sh.address, 5e4, function (err, unspent) {
-      if (err) return done(err)
+    const unspent = await regtestUtils.faucet(p2sh.address, 5e4)
 
-      const txb = new bitcoin.TransactionBuilder(regtest)
-      txb.addInput(unspent.txId, unspent.vout)
-      txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
-      txb.sign(0, keyPair, p2sh.redeem.output, null, unspent.value)
+    const txb = new bitcoin.TransactionBuilder(regtest)
+    txb.addInput(unspent.txId, unspent.vout)
+    txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
+    txb.sign(0, keyPair, p2sh.redeem.output, null, unspent.value)
 
-      const tx = txb.build()
+    const tx = txb.build()
 
-      // build and broadcast to the Bitcoin RegTest network
-      regtestUtils.broadcast(tx.toHex(), function (err) {
-        if (err) return done(err)
+    // build and broadcast to the Bitcoin RegTest network
+    await regtestUtils.broadcast(tx.toHex())
 
-        regtestUtils.verify({
-          txId: tx.getId(),
-          address: regtestUtils.RANDOM_ADDRESS,
-          vout: 0,
-          value: 2e4
-        }, done)
-      })
+    await regtestUtils.verify({
+      txId: tx.getId(),
+      address: regtestUtils.RANDOM_ADDRESS,
+      vout: 0,
+      value: 2e4
     })
   })
 
-  it('can create (and broadcast via 3PBP) a Transaction, w/ a P2WPKH input', function (done) {
+  it('can create (and broadcast via 3PBP) a Transaction, w/ a P2WPKH input', async () => {
     const keyPair = bitcoin.ECPair.makeRandom({ network: regtest })
     const p2wpkh = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey, network: regtest })
 
-    regtestUtils.faucetComplex(p2wpkh.address, 5e4, function (err, unspent) {
-      if (err) return done(err)
-
-      // XXX: build the Transaction w/ a P2WPKH input
-      const txb = new bitcoin.TransactionBuilder(regtest)
-      txb.addInput(unspent.txId, unspent.vout, null, p2wpkh.output) // NOTE: provide the prevOutScript!
-      txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
-      txb.sign(0, keyPair, null, null, unspent.value) // NOTE: no redeem script
-      const tx = txb.build()
-
-      // build and broadcast (the P2WPKH transaction) to the Bitcoin RegTest network
-      regtestUtils.broadcast(tx.toHex(), function (err) {
-        if (err) return done(err)
-
-        regtestUtils.verify({
-          txId: tx.getId(),
-          address: regtestUtils.RANDOM_ADDRESS,
-          vout: 0,
-          value: 2e4
-        }, done)
-      })
+    const unspent = await regtestUtils.faucetComplex(p2wpkh.address, 5e4)
+
+    // XXX: build the Transaction w/ a P2WPKH input
+    const txb = new bitcoin.TransactionBuilder(regtest)
+    txb.addInput(unspent.txId, unspent.vout, null, p2wpkh.output) // NOTE: provide the prevOutScript!
+    txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
+    txb.sign(0, keyPair, null, null, unspent.value) // NOTE: no redeem script
+    const tx = txb.build()
+
+    // build and broadcast (the P2WPKH transaction) to the Bitcoin RegTest network
+    await regtestUtils.broadcast(tx.toHex())
+
+    await regtestUtils.verify({
+      txId: tx.getId(),
+      address: regtestUtils.RANDOM_ADDRESS,
+      vout: 0,
+      value: 2e4
     })
   })
 
-  it('can create (and broadcast via 3PBP) a Transaction, w/ a P2WSH(P2PK) input', function (done) {
+  it('can create (and broadcast via 3PBP) a Transaction, w/ a P2WSH(P2PK) input', async () => {
     const keyPair = bitcoin.ECPair.makeRandom({ network: regtest })
     const p2pk = bitcoin.payments.p2pk({ pubkey: keyPair.publicKey, network: regtest })
     const p2wsh = bitcoin.payments.p2wsh({ redeem: p2pk, network: regtest })
 
-    regtestUtils.faucetComplex(p2wsh.address, 5e4, function (err, unspent) {
-      if (err) return done(err)
-
-      // XXX: build the Transaction w/ a P2WSH input
-      const txb = new bitcoin.TransactionBuilder(regtest)
-      txb.addInput(unspent.txId, unspent.vout, null, p2wsh.output) // NOTE: provide the prevOutScript!
-      txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
-      txb.sign(0, keyPair, null, null, 5e4, p2wsh.redeem.output) // NOTE: provide a witnessScript!
-      const tx = txb.build()
-
-      // build and broadcast (the P2WSH transaction) to the Bitcoin RegTest network
-      regtestUtils.broadcast(tx.toHex(), function (err) {
-        if (err) return done(err)
-
-        regtestUtils.verify({
-          txId: tx.getId(),
-          address: regtestUtils.RANDOM_ADDRESS,
-          vout: 0,
-          value: 2e4
-        }, done)
-      })
+    const unspent = await regtestUtils.faucetComplex(p2wsh.address, 5e4)
+
+    // XXX: build the Transaction w/ a P2WSH input
+    const txb = new bitcoin.TransactionBuilder(regtest)
+    txb.addInput(unspent.txId, unspent.vout, null, p2wsh.output) // NOTE: provide the prevOutScript!
+    txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
+    txb.sign(0, keyPair, null, null, 5e4, p2wsh.redeem.output) // NOTE: provide a witnessScript!
+    const tx = txb.build()
+
+    // build and broadcast (the P2WSH transaction) to the Bitcoin RegTest network
+    await regtestUtils.broadcast(tx.toHex())
+
+    await regtestUtils.verify({
+      txId: tx.getId(),
+      address: regtestUtils.RANDOM_ADDRESS,
+      vout: 0,
+      value: 2e4
     })
   })
 
-  it('can create (and broadcast via 3PBP) a Transaction, w/ a P2SH(P2WSH(P2MS(3 of 4))) (SegWit multisig) input', function (done) {
+  it('can create (and broadcast via 3PBP) a Transaction, w/ a P2SH(P2WSH(P2MS(3 of 4))) (SegWit multisig) input', async () => {
     const keyPairs = [
       bitcoin.ECPair.makeRandom({ network: regtest }),
       bitcoin.ECPair.makeRandom({ network: regtest }),
@@ -232,29 +210,25 @@ describe('bitcoinjs-lib (transactions)', function () {
     const p2wsh = bitcoin.payments.p2wsh({ redeem: p2ms, network: regtest })
     const p2sh = bitcoin.payments.p2sh({ redeem: p2wsh, network: regtest })
 
-    regtestUtils.faucet(p2sh.address, 6e4, function (err, unspent) {
-      if (err) return done(err)
+    const unspent = await regtestUtils.faucet(p2sh.address, 6e4)
 
-      const txb = new bitcoin.TransactionBuilder(regtest)
-      txb.addInput(unspent.txId, unspent.vout, null, p2sh.output)
-      txb.addOutput(regtestUtils.RANDOM_ADDRESS, 3e4)
-      txb.sign(0, keyPairs[0], p2sh.redeem.output, null, unspent.value, p2wsh.redeem.output)
-      txb.sign(0, keyPairs[2], p2sh.redeem.output, null, unspent.value, p2wsh.redeem.output)
-      txb.sign(0, keyPairs[3], p2sh.redeem.output, null, unspent.value, p2wsh.redeem.output)
+    const txb = new bitcoin.TransactionBuilder(regtest)
+    txb.addInput(unspent.txId, unspent.vout, null, p2sh.output)
+    txb.addOutput(regtestUtils.RANDOM_ADDRESS, 3e4)
+    txb.sign(0, keyPairs[0], p2sh.redeem.output, null, unspent.value, p2wsh.redeem.output)
+    txb.sign(0, keyPairs[2], p2sh.redeem.output, null, unspent.value, p2wsh.redeem.output)
+    txb.sign(0, keyPairs[3], p2sh.redeem.output, null, unspent.value, p2wsh.redeem.output)
 
-      const tx = txb.build()
+    const tx = txb.build()
 
-      // build and broadcast to the Bitcoin RegTest network
-      regtestUtils.broadcast(tx.toHex(), function (err) {
-        if (err) return done(err)
+    // build and broadcast to the Bitcoin RegTest network
+    await regtestUtils.broadcast(tx.toHex())
 
-        regtestUtils.verify({
-          txId: tx.getId(),
-          address: regtestUtils.RANDOM_ADDRESS,
-          vout: 0,
-          value: 3e4
-        }, done)
-      })
+    await regtestUtils.verify({
+      txId: tx.getId(),
+      address: regtestUtils.RANDOM_ADDRESS,
+      vout: 0,
+      value: 3e4
     })
   })
 

From 77bd66c22ffd19944db561e6cb9cbcc756e0e668 Mon Sep 17 00:00:00 2001
From: junderw <junderwood@bitcoinbank.co.jp>
Date: Mon, 8 Apr 2019 15:24:19 +0900
Subject: [PATCH 2/7] Fix Bad Request errors from the client side

---
 test/integration/_regtest.js | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/test/integration/_regtest.js b/test/integration/_regtest.js
index 650a79c..81821c1 100644
--- a/test/integration/_regtest.js
+++ b/test/integration/_regtest.js
@@ -35,10 +35,17 @@ function height () {
   })
 }
 
+function _faucetRequest (address, value) {
+  return dhttp({
+    method: 'POST',
+    url: APIURL + '/r/faucet?address=' + address + '&value=' + value + '&key=' + APIPASS
+  })
+}
+
 async function faucet (address, value) {
   let count = 0
   let _unspents = []
-  const sleep = ms => new Promise(r => setTimeout(r, ms))
+  const sleep = ms => new Promise((resolve, reject) => setTimeout(resolve, ms))
   do {
     if (count > 0) {
       if (count >= 5) throw new Error('Missing Inputs')
@@ -46,10 +53,20 @@ async function faucet (address, value) {
       await sleep(200)
     }
 
-    const txId = await dhttp({
-      method: 'POST',
-      url: APIURL + '/r/faucet?address=' + address + '&value=' + value + '&key=' + APIPASS
-    })
+    const txId = await _faucetRequest(address, value)
+      .then(
+        v => v, // Pass success value as is
+        async err => {
+          // Bad Request error is fixed by making sure height is >= 432
+          const currentHeight = await height()
+          if (err.message === 'Bad Request' && currentHeight < 432) {
+            await mine(432 - currentHeight)
+            return _faucetRequest(address, value)
+          } else {
+            throw err
+          }
+        }
+      )
 
     await sleep(100)
 

From b27df612daaf2365d9d4fb3f5bd7fb6c5b0f9f80 Mon Sep 17 00:00:00 2001
From: junderw <junderwood@bitcoinbank.co.jp>
Date: Mon, 8 Apr 2019 15:34:12 +0900
Subject: [PATCH 3/7] Randomize sleep times

---
 test/integration/_regtest.js | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/test/integration/_regtest.js b/test/integration/_regtest.js
index 81821c1..d2a3c7d 100644
--- a/test/integration/_regtest.js
+++ b/test/integration/_regtest.js
@@ -46,11 +46,12 @@ async function faucet (address, value) {
   let count = 0
   let _unspents = []
   const sleep = ms => new Promise((resolve, reject) => setTimeout(resolve, ms))
+  const randInt = (min, max) => min + Math.floor((max - min + 1) * Math.random())
   do {
     if (count > 0) {
       if (count >= 5) throw new Error('Missing Inputs')
       console.log('Missing Inputs, retry #' + count)
-      await sleep(200)
+      await sleep(randInt(150, 250))
     }
 
     const txId = await _faucetRequest(address, value)
@@ -68,7 +69,7 @@ async function faucet (address, value) {
         }
       )
 
-    await sleep(100)
+    await sleep(randInt(50, 150))
 
     const results = await unspents(address)
 

From d9fd6d619a58378e0bb6536928068602d33d5450 Mon Sep 17 00:00:00 2001
From: junderw <junderwood@bitcoinbank.co.jp>
Date: Mon, 8 Apr 2019 16:40:38 +0900
Subject: [PATCH 4/7] Fix race condition for two integration test jobs

---
 test/integration/_regtest.js | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/test/integration/_regtest.js b/test/integration/_regtest.js
index d2a3c7d..0ea6736 100644
--- a/test/integration/_regtest.js
+++ b/test/integration/_regtest.js
@@ -63,6 +63,8 @@ async function faucet (address, value) {
           if (err.message === 'Bad Request' && currentHeight < 432) {
             await mine(432 - currentHeight)
             return _faucetRequest(address, value)
+          } else if (err.message === 'Bad Request' && currentHeight >= 432) {
+            return _faucetRequest(address, value)
           } else {
             throw err
           }

From 16823e90131b7668575be9ada467a83a908b05e6 Mon Sep 17 00:00:00 2001
From: junderw <junderwood@bitcoinbank.co.jp>
Date: Tue, 9 Apr 2019 12:09:43 +0900
Subject: [PATCH 5/7] Add APIURL env for endpoint

---
 test/integration/_regtest.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/integration/_regtest.js b/test/integration/_regtest.js
index 0ea6736..e32e11b 100644
--- a/test/integration/_regtest.js
+++ b/test/integration/_regtest.js
@@ -10,7 +10,7 @@ const dhttp = options => new Promise((resolve, reject) => {
 })
 
 const APIPASS = process.env.APIPASS || 'satoshi'
-const APIURL = 'https://regtest.bitbank.cc/1'
+const APIURL = process.env.APIURL || 'https://regtest.bitbank.cc/1'
 const NETWORK = bitcoin.networks.testnet
 
 function broadcast (txHex) {

From dc1ef5958b7c7115e5c6960d6bccb2704f9c13cd Mon Sep 17 00:00:00 2001
From: junderw <junderwood@bitcoinbank.co.jp>
Date: Tue, 9 Apr 2019 15:09:50 +0900
Subject: [PATCH 6/7] Tests to arrow functions, use strict asserts, travis uses
 docker instead of regtest server

---
 .travis.yml                      |   8 +-
 test/address.js                  |  64 +++++-----
 test/bitcoin.core.js             |  78 ++++++------
 test/block.js                    |  84 ++++++-------
 test/bufferutils.js              |  26 ++--
 test/classify.js                 |  42 +++----
 test/crypto.js                   |  10 +-
 test/ecpair.js                   | 102 ++++++++--------
 test/integration/_regtest.js     |   4 +-
 test/integration/addresses.js    |  20 ++--
 test/integration/bip32.js        |  16 +--
 test/integration/blocks.js       |   4 +-
 test/integration/cltv.js         |  14 +--
 test/integration/csv.js          |  10 +-
 test/integration/payments.js     |   6 +-
 test/integration/transactions.js |  16 +--
 test/payments.js                 |  26 ++--
 test/payments.utils.js           |  13 +-
 test/script.js                   |  70 +++++------
 test/script_number.js            |  14 +--
 test/script_signature.js         |  28 ++---
 test/transaction.js              | 124 +++++++++----------
 test/transaction_builder.js      | 200 +++++++++++++++----------------
 test/types.js                    |  24 ++--
 24 files changed, 505 insertions(+), 498 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 5c1cfd3..7921fac 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,11 @@
 sudo: false
 language: node_js
+services:
+  - docker
+before_install:
+  - docker pull junderw/bitcoinjs-regtest-server
+  - docker run -d -p 127.0.0.1:8080:8080 junderw/bitcoinjs-regtest-server
+  - docker ps -a
 node_js:
   - "8"
   - "lts/*"
@@ -15,5 +21,5 @@ matrix:
       env: TEST_SUITE=coverage
 env:
   - TEST_SUITE=unit
-  - TEST_SUITE=integration
+  - TEST_SUITE=integration APIURL=http://127.0.0.1:8080/1
 script: npm run-script $TEST_SUITE
diff --git a/test/address.js b/test/address.js
index a0f4df0..be16879 100644
--- a/test/address.js
+++ b/test/address.js
@@ -16,12 +16,12 @@ const NETWORKS = Object.assign({
   }
 }, require('../src/networks'))
 
-describe('address', function () {
-  describe('fromBase58Check', function () {
-    fixtures.standard.forEach(function (f) {
+describe('address', () => {
+  describe('fromBase58Check', () => {
+    fixtures.standard.forEach(f => {
       if (!f.base58check) return
 
-      it('decodes ' + f.base58check, function () {
+      it('decodes ' + f.base58check, () => {
         const decode = baddress.fromBase58Check(f.base58check)
 
         assert.strictEqual(decode.version, f.version)
@@ -29,20 +29,20 @@ describe('address', function () {
       })
     })
 
-    fixtures.invalid.fromBase58Check.forEach(function (f) {
-      it('throws on ' + f.exception, function () {
-        assert.throws(function () {
+    fixtures.invalid.fromBase58Check.forEach(f => {
+      it('throws on ' + f.exception, () => {
+        assert.throws(() => {
           baddress.fromBase58Check(f.address)
         }, new RegExp(f.address + ' ' + f.exception))
       })
     })
   })
 
-  describe('fromBech32', function () {
-    fixtures.standard.forEach((f) => {
+  describe('fromBech32', () => {
+    fixtures.standard.forEach(f => {
       if (!f.bech32) return
 
-      it('decodes ' + f.bech32, function () {
+      it('decodes ' + f.bech32, () => {
         const actual = baddress.fromBech32(f.bech32)
 
         assert.strictEqual(actual.version, f.version)
@@ -52,17 +52,17 @@ describe('address', function () {
     })
 
     fixtures.invalid.bech32.forEach((f, i) => {
-      it('decode fails for ' + f.bech32 + '(' + f.exception + ')', function () {
-        assert.throws(function () {
+      it('decode fails for ' + f.bech32 + '(' + f.exception + ')', () => {
+        assert.throws(() => {
           baddress.fromBech32(f.address)
         }, new RegExp(f.exception))
       })
     })
   })
 
-  describe('fromOutputScript', function () {
-    fixtures.standard.forEach(function (f) {
-      it('encodes ' + f.script.slice(0, 30) + '... (' + f.network + ')', function () {
+  describe('fromOutputScript', () => {
+    fixtures.standard.forEach(f => {
+      it('encodes ' + f.script.slice(0, 30) + '... (' + f.network + ')', () => {
         const script = bscript.fromASM(f.script)
         const address = baddress.fromOutputScript(script, NETWORKS[f.network])
 
@@ -70,22 +70,22 @@ describe('address', function () {
       })
     })
 
-    fixtures.invalid.fromOutputScript.forEach(function (f) {
-      it('throws when ' + f.script.slice(0, 30) + '... ' + f.exception, function () {
+    fixtures.invalid.fromOutputScript.forEach(f => {
+      it('throws when ' + f.script.slice(0, 30) + '... ' + f.exception, () => {
         const script = bscript.fromASM(f.script)
 
-        assert.throws(function () {
+        assert.throws(() => {
           baddress.fromOutputScript(script)
         }, new RegExp(f.exception))
       })
     })
   })
 
-  describe('toBase58Check', function () {
-    fixtures.standard.forEach(function (f) {
+  describe('toBase58Check', () => {
+    fixtures.standard.forEach(f => {
       if (!f.base58check) return
 
-      it('encodes ' + f.hash + ' (' + f.network + ')', function () {
+      it('encodes ' + f.hash + ' (' + f.network + ')', () => {
         const address = baddress.toBase58Check(Buffer.from(f.hash, 'hex'), f.version)
 
         assert.strictEqual(address, f.base58check)
@@ -93,39 +93,39 @@ describe('address', function () {
     })
   })
 
-  describe('toBech32', function () {
+  describe('toBech32', () => {
     fixtures.bech32.forEach((f, i) => {
       if (!f.bech32) return
       const data = Buffer.from(f.data, 'hex')
 
-      it('encode ' + f.address, function () {
-        assert.deepEqual(baddress.toBech32(data, f.version, f.prefix), f.address)
+      it('encode ' + f.address, () => {
+        assert.deepStrictEqual(baddress.toBech32(data, f.version, f.prefix), f.address)
       })
     })
 
     fixtures.invalid.bech32.forEach((f, i) => {
       if (!f.prefix || f.version === undefined || f.data === undefined) return
 
-      it('encode fails (' + f.exception, function () {
-        assert.throws(function () {
+      it('encode fails (' + f.exception, () => {
+        assert.throws(() => {
           baddress.toBech32(Buffer.from(f.data, 'hex'), f.version, f.prefix)
         }, new RegExp(f.exception))
       })
     })
   })
 
-  describe('toOutputScript', function () {
-    fixtures.standard.forEach(function (f) {
-      it('decodes ' + f.script.slice(0, 30) + '... (' + f.network + ')', function () {
+  describe('toOutputScript', () => {
+    fixtures.standard.forEach(f => {
+      it('decodes ' + f.script.slice(0, 30) + '... (' + f.network + ')', () => {
         const script = baddress.toOutputScript(f.base58check || f.bech32, NETWORKS[f.network])
 
         assert.strictEqual(bscript.toASM(script), f.script)
       })
     })
 
-    fixtures.invalid.toOutputScript.forEach(function (f) {
-      it('throws when ' + f.exception, function () {
-        assert.throws(function () {
+    fixtures.invalid.toOutputScript.forEach(f => {
+      it('throws when ' + f.exception, () => {
+        assert.throws(() => {
           baddress.toOutputScript(f.address, f.network)
         }, new RegExp(f.address + ' ' + f.exception))
       })
diff --git a/test/bitcoin.core.js b/test/bitcoin.core.js
index 560bf20..734c9a9 100644
--- a/test/bitcoin.core.js
+++ b/test/bitcoin.core.js
@@ -12,21 +12,21 @@ 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 () {
+describe('Bitcoin-core', () => {
   // base58EncodeDecode
-  describe('base58', function () {
-    base58EncodeDecode.forEach(function (f) {
+  describe('base58', () => {
+    base58EncodeDecode.forEach(f => {
       const fhex = f[0]
       const fb58 = f[1]
 
-      it('can decode ' + fb58, function () {
+      it('can decode ' + fb58, () => {
         const buffer = base58.decode(fb58)
         const actual = buffer.toString('hex')
 
         assert.strictEqual(actual, fhex)
       })
 
-      it('can encode ' + fhex, function () {
+      it('can encode ' + fhex, () => {
         const buffer = Buffer.from(fhex, 'hex')
         const actual = base58.encode(buffer)
 
@@ -36,13 +36,13 @@ describe('Bitcoin-core', function () {
   })
 
   // base58KeysValid
-  describe('address.toBase58Check', function () {
+  describe('address.toBase58Check', () => {
     const typeMap = {
       'pubkey': 'pubKeyHash',
       'script': 'scriptHash'
     }
 
-    base58KeysValid.forEach(function (f) {
+    base58KeysValid.forEach(f => {
       const expected = f[0]
       const hash = Buffer.from(f[1], 'hex')
       const params = f[2]
@@ -52,14 +52,14 @@ describe('Bitcoin-core', function () {
       const network = params.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin
       const version = network[typeMap[params.addrType]]
 
-      it('can export ' + expected, function () {
+      it('can export ' + expected, () => {
         assert.strictEqual(bitcoin.address.toBase58Check(hash, version), expected)
       })
     })
   })
 
   // base58KeysInvalid
-  describe('address.fromBase58Check', function () {
+  describe('address.fromBase58Check', () => {
     const allowedNetworks = [
       bitcoin.networks.bitcoin.pubkeyhash,
       bitcoin.networks.bitcoin.scripthash,
@@ -67,22 +67,22 @@ describe('Bitcoin-core', function () {
       bitcoin.networks.testnet.scripthash
     ]
 
-    base58KeysInvalid.forEach(function (f) {
+    base58KeysInvalid.forEach(f => {
       const string = f[0]
 
-      it('throws on ' + string, function () {
-        assert.throws(function () {
+      it('throws on ' + string, () => {
+        assert.throws(() => {
           const address = bitcoin.address.fromBase58Check(string)
 
-          assert.notEqual(allowedNetworks.indexOf(address.version), -1, 'Invalid network')
+          assert.notStrictEqual(allowedNetworks.indexOf(address.version), -1, 'Invalid network')
         }, /(Invalid (checksum|network))|(too (short|long))/)
       })
     })
   })
 
   // base58KeysValid
-  describe('ECPair', function () {
-    base58KeysValid.forEach(function (f) {
+  describe('ECPair', () => {
+    base58KeysValid.forEach(f => {
       const string = f[0]
       const hex = f[1]
       const params = f[2]
@@ -92,38 +92,38 @@ describe('Bitcoin-core', function () {
       const network = params.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin
       const keyPair = bitcoin.ECPair.fromWIF(string, network)
 
-      it('fromWIF imports ' + string, function () {
+      it('fromWIF imports ' + string, () => {
         assert.strictEqual(keyPair.privateKey.toString('hex'), hex)
         assert.strictEqual(keyPair.compressed, params.isCompressed)
       })
 
-      it('toWIF exports ' + hex + ' to ' + string, function () {
+      it('toWIF exports ' + hex + ' to ' + string, () => {
         assert.strictEqual(keyPair.toWIF(), string)
       })
     })
   })
 
   // base58KeysInvalid
-  describe('ECPair.fromWIF', function () {
+  describe('ECPair.fromWIF', () => {
     const allowedNetworks = [
       bitcoin.networks.bitcoin,
       bitcoin.networks.testnet
     ]
 
-    base58KeysInvalid.forEach(function (f) {
+    base58KeysInvalid.forEach(f => {
       const string = f[0]
 
-      it('throws on ' + string, function () {
-        assert.throws(function () {
+      it('throws on ' + string, () => {
+        assert.throws(() => {
           bitcoin.ECPair.fromWIF(string, allowedNetworks)
         }, /(Invalid|Unknown) (checksum|compression flag|network version|WIF length)/)
       })
     })
   })
 
-  describe('Block.fromHex', function () {
-    blocksValid.forEach(function (f) {
-      it('can parse ' + f.id, function () {
+  describe('Block.fromHex', () => {
+    blocksValid.forEach(f => {
+      it('can parse ' + f.id, () => {
         const block = bitcoin.Block.fromHex(f.hex)
 
         assert.strictEqual(block.getId(), f.id)
@@ -133,8 +133,8 @@ describe('Bitcoin-core', function () {
   })
 
   // txValid
-  describe('Transaction.fromHex', function () {
-    txValid.forEach(function (f) {
+  describe('Transaction.fromHex', () => {
+    txValid.forEach(f => {
       // Objects that are only a single string are ignored
       if (f.length === 1) return
 
@@ -142,17 +142,17 @@ describe('Bitcoin-core', function () {
       const fhex = f[1]
       //      const verifyFlags = f[2] // TODO: do we need to test this?
 
-      it('can decode ' + fhex, function () {
+      it('can decode ' + fhex, () => {
         const transaction = bitcoin.Transaction.fromHex(fhex)
 
-        transaction.ins.forEach(function (txIn, i) {
+        transaction.ins.forEach((txIn, i) => {
           const input = inputs[i]
 
           // reverse because test data is reversed
           const prevOutHash = Buffer.from(input[0], 'hex').reverse()
           const prevOutIndex = input[1]
 
-          assert.deepEqual(txIn.hash, prevOutHash)
+          assert.deepStrictEqual(txIn.hash, prevOutHash)
 
           // we read UInt32, not Int32
           assert.strictEqual(txIn.index & 0xffffffff, prevOutIndex)
@@ -162,8 +162,8 @@ describe('Bitcoin-core', function () {
   })
 
   // sighash
-  describe('Transaction', function () {
-    sigHash.forEach(function (f) {
+  describe('Transaction', () => {
+    sigHash.forEach(f => {
       // Objects that are only a single string are ignored
       if (f.length === 1) return
 
@@ -181,7 +181,7 @@ describe('Bitcoin-core', function () {
 
       const hashTypeName = hashTypes.join(' | ')
 
-      it('should hash ' + txHex.slice(0, 40) + '... (' + hashTypeName + ')', function () {
+      it('should hash ' + txHex.slice(0, 40) + '... (' + hashTypeName + ')', () => {
         const transaction = bitcoin.Transaction.fromHex(txHex)
         assert.strictEqual(transaction.toHex(), txHex)
 
@@ -192,16 +192,16 @@ describe('Bitcoin-core', function () {
         const hash = transaction.hashForSignature(inIndex, script, hashType)
 
         // reverse because test data is reversed
-        assert.equal(hash.reverse().toString('hex'), expectedHash)
+        assert.strictEqual(hash.reverse().toString('hex'), expectedHash)
       })
     })
   })
 
-  describe('script.signature.decode', function () {
-    sigCanonical.forEach(function (hex) {
+  describe('script.signature.decode', () => {
+    sigCanonical.forEach(hex => {
       const buffer = Buffer.from(hex, 'hex')
 
-      it('can parse ' + hex, function () {
+      it('can parse ' + hex, () => {
         const parsed = bitcoin.script.signature.decode(buffer)
         const actual = bitcoin.script.signature.encode(parsed.signature, parsed.hashType)
 
@@ -209,15 +209,15 @@ describe('Bitcoin-core', function () {
       })
     })
 
-    sigNoncanonical.forEach(function (hex, i) {
+    sigNoncanonical.forEach((hex, i) => {
       if (i === 0) return
       if (i % 2 !== 0) return
 
       const description = sigNoncanonical[i - 1].slice(0, -1)
       const buffer = Buffer.from(hex, 'hex')
 
-      it('throws on ' + description, function () {
-        assert.throws(function () {
+      it('throws on ' + description, () => {
+        assert.throws(() => {
           bitcoin.script.signature.decode(buffer)
         }, /Expected DER (integer|sequence)|(R|S) value (excessively padded|is negative)|(R|S|DER sequence) length is (zero|too short|too long|invalid)|Invalid hashType/)
       })
diff --git a/test/block.js b/test/block.js
index e646737..d5e41af 100644
--- a/test/block.js
+++ b/test/block.js
@@ -4,29 +4,29 @@ const Block = require('..').Block
 
 const fixtures = require('./fixtures/block')
 
-describe('Block', function () {
-  describe('version', function () {
-    it('should be interpreted as an int32le', function () {
+describe('Block', () => {
+  describe('version', () => {
+    it('should be interpreted as an int32le', () => {
       const blockHex = 'ffffffff0000000000000000000000000000000000000000000000000000000000000000414141414141414141414141414141414141414141414141414141414141414101000000020000000300000000'
       const block = Block.fromHex(blockHex)
-      assert.equal(-1, block.version)
-      assert.equal(1, block.timestamp)
+      assert.strictEqual(-1, block.version)
+      assert.strictEqual(1, block.timestamp)
     })
   })
 
-  describe('calculateTarget', function () {
-    fixtures.targets.forEach(function (f) {
-      it('returns ' + f.expected + ' for 0x' + f.bits, function () {
+  describe('calculateTarget', () => {
+    fixtures.targets.forEach(f => {
+      it('returns ' + f.expected + ' for 0x' + f.bits, () => {
         const bits = parseInt(f.bits, 16)
 
-        assert.equal(Block.calculateTarget(bits).toString('hex'), f.expected)
+        assert.strictEqual(Block.calculateTarget(bits).toString('hex'), f.expected)
       })
     })
   })
 
-  describe('fromBuffer/fromHex', function () {
-    fixtures.valid.forEach(function (f) {
-      it('imports ' + f.description, function () {
+  describe('fromBuffer/fromHex', () => {
+    fixtures.valid.forEach(f => {
+      it('imports ' + f.description, () => {
         const block = Block.fromHex(f.hex)
 
         assert.strictEqual(block.version, f.version)
@@ -42,54 +42,54 @@ describe('Block', function () {
       })
     })
 
-    fixtures.invalid.forEach(function (f) {
-      it('throws on ' + f.exception, function () {
-        assert.throws(function () {
+    fixtures.invalid.forEach(f => {
+      it('throws on ' + f.exception, () => {
+        assert.throws(() => {
           Block.fromHex(f.hex)
         }, new RegExp(f.exception))
       })
     })
   })
 
-  describe('toBuffer/toHex', function () {
-    fixtures.valid.forEach(function (f) {
+  describe('toBuffer/toHex', () => {
+    fixtures.valid.forEach(f => {
       let block
 
-      beforeEach(function () {
+      beforeEach(() => {
         block = Block.fromHex(f.hex)
       })
 
-      it('exports ' + f.description, function () {
+      it('exports ' + f.description, () => {
         assert.strictEqual(block.toHex(true), f.hex.slice(0, 160))
         assert.strictEqual(block.toHex(), f.hex)
       })
     })
   })
 
-  describe('getHash/getId', function () {
-    fixtures.valid.forEach(function (f) {
+  describe('getHash/getId', () => {
+    fixtures.valid.forEach(f => {
       let block
 
-      beforeEach(function () {
+      beforeEach(() => {
         block = Block.fromHex(f.hex)
       })
 
-      it('returns ' + f.id + ' for ' + f.description, function () {
+      it('returns ' + f.id + ' for ' + f.description, () => {
         assert.strictEqual(block.getHash().toString('hex'), f.hash)
         assert.strictEqual(block.getId(), f.id)
       })
     })
   })
 
-  describe('getUTCDate', function () {
-    fixtures.valid.forEach(function (f) {
+  describe('getUTCDate', () => {
+    fixtures.valid.forEach(f => {
       let block
 
-      beforeEach(function () {
+      beforeEach(() => {
         block = Block.fromHex(f.hex)
       })
 
-      it('returns UTC date of ' + f.id, function () {
+      it('returns UTC date of ' + f.id, () => {
         const utcDate = block.getUTCDate().getTime()
 
         assert.strictEqual(utcDate, f.timestamp * 1e3)
@@ -97,59 +97,59 @@ describe('Block', function () {
     })
   })
 
-  describe('calculateMerkleRoot', function () {
-    it('should throw on zero-length transaction array', function () {
-      assert.throws(function () {
+  describe('calculateMerkleRoot', () => {
+    it('should throw on zero-length transaction array', () => {
+      assert.throws(() => {
         Block.calculateMerkleRoot([])
       }, /Cannot compute merkle root for zero transactions/)
     })
 
-    fixtures.valid.forEach(function (f) {
+    fixtures.valid.forEach(f => {
       if (f.hex.length === 160) return
 
       let block
 
-      beforeEach(function () {
+      beforeEach(() => {
         block = Block.fromHex(f.hex)
       })
 
-      it('returns ' + f.merkleRoot + ' for ' + f.id, function () {
+      it('returns ' + f.merkleRoot + ' for ' + f.id, () => {
         assert.strictEqual(Block.calculateMerkleRoot(block.transactions).toString('hex'), f.merkleRoot)
       })
 
       if (f.witnessCommit) {
-        it('returns witness commit ' + f.witnessCommit + ' for ' + f.id, function () {
+        it('returns witness commit ' + f.witnessCommit + ' for ' + f.id, () => {
           assert.strictEqual(Block.calculateMerkleRoot(block.transactions, true).toString('hex'), f.witnessCommit)
         })
       }
     })
   })
 
-  describe('checkTxRoots', function () {
-    fixtures.valid.forEach(function (f) {
+  describe('checkTxRoots', () => {
+    fixtures.valid.forEach(f => {
       if (f.hex.length === 160) return
 
       let block
 
-      beforeEach(function () {
+      beforeEach(() => {
         block = Block.fromHex(f.hex)
       })
 
-      it('returns ' + f.valid + ' for ' + f.id, function () {
+      it('returns ' + f.valid + ' for ' + f.id, () => {
         assert.strictEqual(block.checkTxRoots(), true)
       })
     })
   })
 
-  describe('checkProofOfWork', function () {
-    fixtures.valid.forEach(function (f) {
+  describe('checkProofOfWork', () => {
+    fixtures.valid.forEach(f => {
       let block
 
-      beforeEach(function () {
+      beforeEach(() => {
         block = Block.fromHex(f.hex)
       })
 
-      it('returns ' + f.valid + ' for ' + f.id, function () {
+      it('returns ' + f.valid + ' for ' + f.id, () => {
         assert.strictEqual(block.checkProofOfWork(), f.valid)
       })
     })
diff --git a/test/bufferutils.js b/test/bufferutils.js
index 5f2c39e..1a38406 100644
--- a/test/bufferutils.js
+++ b/test/bufferutils.js
@@ -4,10 +4,10 @@ const bufferutils = require('../src/bufferutils')
 
 const fixtures = require('./fixtures/bufferutils.json')
 
-describe('bufferutils', function () {
-  describe('readUInt64LE', function () {
-    fixtures.valid.forEach(function (f) {
-      it('decodes ' + f.hex, function () {
+describe('bufferutils', () => {
+  describe('readUInt64LE', () => {
+    fixtures.valid.forEach(f => {
+      it('decodes ' + f.hex, () => {
         const buffer = Buffer.from(f.hex, 'hex')
         const number = bufferutils.readUInt64LE(buffer, 0)
 
@@ -15,20 +15,20 @@ describe('bufferutils', function () {
       })
     })
 
-    fixtures.invalid.readUInt64LE.forEach(function (f) {
-      it('throws on ' + f.description, function () {
+    fixtures.invalid.readUInt64LE.forEach(f => {
+      it('throws on ' + f.description, () => {
         const buffer = Buffer.from(f.hex, 'hex')
 
-        assert.throws(function () {
+        assert.throws(() => {
           bufferutils.readUInt64LE(buffer, 0)
         }, new RegExp(f.exception))
       })
     })
   })
 
-  describe('writeUInt64LE', function () {
-    fixtures.valid.forEach(function (f) {
-      it('encodes ' + f.dec, function () {
+  describe('writeUInt64LE', () => {
+    fixtures.valid.forEach(f => {
+      it('encodes ' + f.dec, () => {
         const buffer = Buffer.alloc(8, 0)
 
         bufferutils.writeUInt64LE(buffer, f.dec, 0)
@@ -36,11 +36,11 @@ describe('bufferutils', function () {
       })
     })
 
-    fixtures.invalid.readUInt64LE.forEach(function (f) {
-      it('throws on ' + f.description, function () {
+    fixtures.invalid.readUInt64LE.forEach(f => {
+      it('throws on ' + f.description, () => {
         const buffer = Buffer.alloc(8, 0)
 
-        assert.throws(function () {
+        assert.throws(() => {
           bufferutils.writeUInt64LE(buffer, f.dec, 0)
         }, new RegExp(f.exception))
       })
diff --git a/test/classify.js b/test/classify.js
index 3efcc74..86da74d 100644
--- a/test/classify.js
+++ b/test/classify.js
@@ -25,12 +25,12 @@ const tmap = {
   witnessCommitment
 }
 
-describe('classify', function () {
-  describe('input', function () {
-    fixtures.valid.forEach(function (f) {
+describe('classify', () => {
+  describe('input', () => {
+    fixtures.valid.forEach(f => {
       if (!f.input) return
 
-      it('classifies ' + f.input + ' as ' + f.type, function () {
+      it('classifies ' + f.input + ' as ' + f.type, () => {
         const input = bscript.fromASM(f.input)
         const type = classify.input(input)
 
@@ -38,11 +38,11 @@ describe('classify', function () {
       })
     })
 
-    fixtures.valid.forEach(function (f) {
+    fixtures.valid.forEach(f => {
       if (!f.input) return
       if (!f.typeIncomplete) return
 
-      it('classifies incomplete ' + f.input + ' as ' + f.typeIncomplete, function () {
+      it('classifies incomplete ' + f.input + ' as ' + f.typeIncomplete, () => {
         const input = bscript.fromASM(f.input)
         const type = classify.input(input, true)
 
@@ -51,11 +51,11 @@ describe('classify', function () {
     })
   })
 
-  describe('classifyOutput', function () {
-    fixtures.valid.forEach(function (f) {
+  describe('classifyOutput', () => {
+    fixtures.valid.forEach(f => {
       if (!f.output) return
 
-      it('classifies ' + f.output + ' as ' + f.type, function () {
+      it('classifies ' + f.output + ' as ' + f.type, () => {
         const output = bscript.fromASM(f.output)
         const type = classify.output(output)
 
@@ -73,12 +73,12 @@ describe('classify', function () {
     'multisig',
     'nullData',
     'witnessCommitment'
-  ].forEach(function (name) {
+  ].forEach(name => {
     const inputType = tmap[name].input
     const outputType = tmap[name].output
 
-    describe(name + '.input.check', function () {
-      fixtures.valid.forEach(function (f) {
+    describe(name + '.input.check', () => {
+      fixtures.valid.forEach(f => {
         if (name.toLowerCase() === classify.types.P2WPKH) return
         if (name.toLowerCase() === classify.types.P2WSH) return
         const expected = name.toLowerCase() === f.type.toLowerCase()
@@ -86,14 +86,14 @@ describe('classify', function () {
         if (inputType && f.input) {
           const input = bscript.fromASM(f.input)
 
-          it('returns ' + expected + ' for ' + f.input, function () {
+          it('returns ' + expected + ' for ' + f.input, () => {
             assert.strictEqual(inputType.check(input), expected)
           })
 
           if (f.typeIncomplete) {
             const expectedIncomplete = name.toLowerCase() === f.typeIncomplete
 
-            it('returns ' + expected + ' for ' + f.input, function () {
+            it('returns ' + expected + ' for ' + f.input, () => {
               assert.strictEqual(inputType.check(input, true), expectedIncomplete)
             })
           }
@@ -102,10 +102,10 @@ describe('classify', function () {
 
       if (!(fixtures.invalid[name])) return
 
-      fixtures.invalid[name].inputs.forEach(function (f) {
+      fixtures.invalid[name].inputs.forEach(f => {
         if (!f.input && !f.inputHex) return
 
-        it('returns false for ' + f.description + ' (' + (f.input || f.inputHex) + ')', function () {
+        it('returns false for ' + f.description + ' (' + (f.input || f.inputHex) + ')', () => {
           let input
 
           if (f.input) {
@@ -119,12 +119,12 @@ describe('classify', function () {
       })
     })
 
-    describe(name + '.output.check', function () {
-      fixtures.valid.forEach(function (f) {
+    describe(name + '.output.check', () => {
+      fixtures.valid.forEach(f => {
         const expected = name.toLowerCase() === f.type
 
         if (outputType && f.output) {
-          it('returns ' + expected + ' for ' + f.output, function () {
+          it('returns ' + expected + ' for ' + f.output, () => {
             const output = bscript.fromASM(f.output)
 
             if (name.toLowerCase() === 'nulldata' && f.type === classify.types.WITNESS_COMMITMENT) return
@@ -136,10 +136,10 @@ describe('classify', function () {
 
       if (!(fixtures.invalid[name])) return
 
-      fixtures.invalid[name].outputs.forEach(function (f) {
+      fixtures.invalid[name].outputs.forEach(f => {
         if (!f.output && !f.outputHex) return
 
-        it('returns false for ' + f.description + ' (' + (f.output || f.outputHex) + ')', function () {
+        it('returns false for ' + f.description + ' (' + (f.output || f.outputHex) + ')', () => {
           let output
 
           if (f.output) {
diff --git a/test/crypto.js b/test/crypto.js
index 3f7802a..14b4f33 100644
--- a/test/crypto.js
+++ b/test/crypto.js
@@ -4,14 +4,14 @@ const bcrypto = require('../src/crypto')
 
 const fixtures = require('./fixtures/crypto')
 
-describe('crypto', function () {
-  ['hash160', 'hash256', 'ripemd160', 'sha1', 'sha256'].forEach(function (algorithm) {
-    describe(algorithm, function () {
-      fixtures.forEach(function (f) {
+describe('crypto', () => {
+  ['hash160', 'hash256', 'ripemd160', 'sha1', 'sha256'].forEach(algorithm => {
+    describe(algorithm, () => {
+      fixtures.forEach(f => {
         const fn = bcrypto[algorithm]
         const expected = f[algorithm]
 
-        it('returns ' + expected + ' for ' + f.hex, function () {
+        it('returns ' + expected + ' for ' + f.hex, () => {
           const data = Buffer.from(f.hex, 'hex')
           const actual = fn(data).toString('hex')
 
diff --git a/test/ecpair.js b/test/ecpair.js
index de5c485..ce32683 100644
--- a/test/ecpair.js
+++ b/test/ecpair.js
@@ -19,15 +19,15 @@ const ONE = Buffer.from('0000000000000000000000000000000000000000000000000000000
 const GROUP_ORDER = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141', 'hex')
 const GROUP_ORDER_LESS_1 = Buffer.from('fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140', 'hex')
 
-describe('ECPair', function () {
-  describe('getPublicKey', function () {
+describe('ECPair', () => {
+  describe('getPublicKey', () => {
     let keyPair
 
-    beforeEach(function () {
+    beforeEach(() => {
       keyPair = ECPair.fromPrivateKey(ONE)
     })
 
-    it('calls pointFromScalar lazily', hoodwink(function () {
+    it('calls pointFromScalar lazily', hoodwink(() => {
       assert.strictEqual(keyPair.__Q, undefined)
 
       // .publicKey forces the memoization
@@ -36,14 +36,14 @@ describe('ECPair', function () {
     }))
   })
 
-  describe('fromPrivateKey', function () {
-    it('defaults to compressed', function () {
+  describe('fromPrivateKey', () => {
+    it('defaults to compressed', () => {
       const keyPair = ECPair.fromPrivateKey(ONE)
 
       assert.strictEqual(keyPair.compressed, true)
     })
 
-    it('supports the uncompressed option', function () {
+    it('supports the uncompressed option', () => {
       const keyPair = ECPair.fromPrivateKey(ONE, {
         compressed: false
       })
@@ -51,7 +51,7 @@ describe('ECPair', function () {
       assert.strictEqual(keyPair.compressed, false)
     })
 
-    it('supports the network option', function () {
+    it('supports the network option', () => {
       const keyPair = ECPair.fromPrivateKey(ONE, {
         compressed: false,
         network: NETWORKS.testnet
@@ -60,8 +60,8 @@ describe('ECPair', function () {
       assert.strictEqual(keyPair.network, NETWORKS.testnet)
     })
 
-    fixtures.valid.forEach(function (f) {
-      it('derives public key for ' + f.WIF, function () {
+    fixtures.valid.forEach(f => {
+      it('derives public key for ' + f.WIF, () => {
         const d = Buffer.from(f.d, 'hex')
         const keyPair = ECPair.fromPrivateKey(d, {
           compressed: f.compressed
@@ -71,30 +71,30 @@ describe('ECPair', function () {
       })
     })
 
-    fixtures.invalid.fromPrivateKey.forEach(function (f) {
-      it('throws ' + f.exception, function () {
+    fixtures.invalid.fromPrivateKey.forEach(f => {
+      it('throws ' + f.exception, () => {
         const d = Buffer.from(f.d, 'hex')
-        assert.throws(function () {
+        assert.throws(() => {
           ECPair.fromPrivateKey(d, f.options)
         }, new RegExp(f.exception))
       })
     })
   })
 
-  describe('fromPublicKey', function () {
-    fixtures.invalid.fromPublicKey.forEach(function (f) {
-      it('throws ' + f.exception, function () {
+  describe('fromPublicKey', () => {
+    fixtures.invalid.fromPublicKey.forEach(f => {
+      it('throws ' + f.exception, () => {
         const Q = Buffer.from(f.Q, 'hex')
-        assert.throws(function () {
+        assert.throws(() => {
           ECPair.fromPublicKey(Q, f.options)
         }, new RegExp(f.exception))
       })
     })
   })
 
-  describe('fromWIF', function () {
-    fixtures.valid.forEach(function (f) {
-      it('imports ' + f.WIF + ' (' + f.network + ')', function () {
+  describe('fromWIF', () => {
+    fixtures.valid.forEach(f => {
+      it('imports ' + f.WIF + ' (' + f.network + ')', () => {
         const network = NETWORKS[f.network]
         const keyPair = ECPair.fromWIF(f.WIF, network)
 
@@ -104,8 +104,8 @@ describe('ECPair', function () {
       })
     })
 
-    fixtures.valid.forEach(function (f) {
-      it('imports ' + f.WIF + ' (via list of networks)', function () {
+    fixtures.valid.forEach(f => {
+      it('imports ' + f.WIF + ' (via list of networks)', () => {
         const keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST)
 
         assert.strictEqual(keyPair.privateKey.toString('hex'), f.d)
@@ -114,9 +114,9 @@ describe('ECPair', function () {
       })
     })
 
-    fixtures.invalid.fromWIF.forEach(function (f) {
-      it('throws on ' + f.WIF, function () {
-        assert.throws(function () {
+    fixtures.invalid.fromWIF.forEach(f => {
+      it('throws on ' + f.WIF, () => {
+        assert.throws(() => {
           const networks = f.network ? NETWORKS[f.network] : NETWORKS_LIST
 
           ECPair.fromWIF(f.WIF, networks)
@@ -125,9 +125,9 @@ describe('ECPair', function () {
     })
   })
 
-  describe('toWIF', function () {
-    fixtures.valid.forEach(function (f) {
-      it('exports ' + f.WIF, function () {
+  describe('toWIF', () => {
+    fixtures.valid.forEach(f => {
+      it('exports ' + f.WIF, () => {
         const keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST)
         const result = keyPair.toWIF()
         assert.strictEqual(result, f.WIF)
@@ -135,13 +135,13 @@ describe('ECPair', function () {
     })
   })
 
-  describe('makeRandom', function () {
+  describe('makeRandom', () => {
     const d = Buffer.alloc(32, 4)
     const exWIF = 'KwMWvwRJeFqxYyhZgNwYuYjbQENDAPAudQx5VEmKJrUZcq6aL2pv'
 
-    describe('uses randombytes RNG', function () {
-      it('generates a ECPair', function () {
-        const stub = { randombytes: function () { return d } }
+    describe('uses randombytes RNG', () => {
+      it('generates a ECPair', () => {
+        const stub = { randombytes: () => { return d } }
         const ProxiedECPair = proxyquire('../src/ecpair', stub)
 
         const keyPair = ProxiedECPair.makeRandom()
@@ -149,22 +149,22 @@ describe('ECPair', function () {
       })
     })
 
-    it('allows a custom RNG to be used', function () {
+    it('allows a custom RNG to be used', () => {
       const keyPair = ECPair.makeRandom({
-        rng: function (size) { return d.slice(0, size) }
+        rng: size => { return d.slice(0, size) }
       })
 
       assert.strictEqual(keyPair.toWIF(), exWIF)
     })
 
-    it('retains the same defaults as ECPair constructor', function () {
+    it('retains the same defaults as ECPair constructor', () => {
       const keyPair = ECPair.makeRandom()
 
       assert.strictEqual(keyPair.compressed, true)
       assert.strictEqual(keyPair.network, NETWORKS.bitcoin)
     })
 
-    it('supports the options parameter', function () {
+    it('supports the options parameter', () => {
       const keyPair = ECPair.makeRandom({
         compressed: false,
         network: NETWORKS.testnet
@@ -174,18 +174,18 @@ describe('ECPair', function () {
       assert.strictEqual(keyPair.network, NETWORKS.testnet)
     })
 
-    it('throws if d is bad length', function () {
+    it('throws if d is bad length', () => {
       function rng () {
         return Buffer.alloc(28)
       }
 
-      assert.throws(function () {
+      assert.throws(() => {
         ECPair.makeRandom({ rng: rng })
       }, /Expected Buffer\(Length: 32\), got Buffer\(Length: 28\)/)
     })
 
     it('loops until d is within interval [1, n) : 1', hoodwink(function () {
-      const rng = this.stub(function () {
+      const rng = this.stub(() => {
         if (rng.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 () {
-      const rng = this.stub(function () {
+      const rng = this.stub(() => {
         if (rng.calls === 0) return ZERO // <1
         if (rng.calls === 1) return GROUP_ORDER // >n-1
         return GROUP_ORDER_LESS_1 // n-1
@@ -204,9 +204,9 @@ describe('ECPair', function () {
     }))
   })
 
-  describe('.network', function () {
-    fixtures.valid.forEach(function (f) {
-      it('returns ' + f.network + ' for ' + f.WIF, function () {
+  describe('.network', () => {
+    fixtures.valid.forEach(f => {
+      it('returns ' + f.network + ' for ' + f.WIF, () => {
         const network = NETWORKS[f.network]
         const keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST)
 
@@ -215,20 +215,20 @@ describe('ECPair', function () {
     })
   })
 
-  describe('tinysecp wrappers', function () {
+  describe('tinysecp wrappers', () => {
     let keyPair
     let hash
     let signature
 
-    beforeEach(function () {
+    beforeEach(() => {
       keyPair = ECPair.makeRandom()
       hash = ZERO
       signature = Buffer.alloc(64, 1)
     })
 
-    describe('signing', function () {
+    describe('signing', () => {
       it('wraps tinysecp.sign', hoodwink(function () {
-        this.mock(tinysecp, 'sign', function (h, d) {
+        this.mock(tinysecp, 'sign', (h, d) => {
           assert.strictEqual(h, hash)
           assert.strictEqual(d, keyPair.privateKey)
           return signature
@@ -237,18 +237,18 @@ describe('ECPair', function () {
         assert.strictEqual(keyPair.sign(hash), signature)
       }))
 
-      it('throws if no private key is found', function () {
+      it('throws if no private key is found', () => {
         delete keyPair.__D
 
-        assert.throws(function () {
+        assert.throws(() => {
           keyPair.sign(hash)
         }, /Missing private key/)
       })
     })
 
-    describe('verify', function () {
+    describe('verify', () => {
       it('wraps tinysecp.verify', hoodwink(function () {
-        this.mock(tinysecp, 'verify', function (h, q, s) {
+        this.mock(tinysecp, 'verify', (h, q, s) => {
           assert.strictEqual(h, hash)
           assert.strictEqual(q, keyPair.publicKey)
           assert.strictEqual(s, signature)
diff --git a/test/integration/_regtest.js b/test/integration/_regtest.js
index e32e11b..abfee1a 100644
--- a/test/integration/_regtest.js
+++ b/test/integration/_regtest.js
@@ -47,7 +47,7 @@ async function faucet (address, value) {
   let _unspents = []
   const sleep = ms => new Promise((resolve, reject) => setTimeout(resolve, ms))
   const randInt = (min, max) => min + Math.floor((max - min + 1) * Math.random())
-  do {
+  while (_unspents.length === 0) {
     if (count > 0) {
       if (count >= 5) throw new Error('Missing Inputs')
       console.log('Missing Inputs, retry #' + count)
@@ -78,7 +78,7 @@ async function faucet (address, value) {
     _unspents = results.filter(x => x.txId === txId)
 
     count++
-  } while (_unspents.length === 0)
+  }
 
   return _unspents.pop()
 }
diff --git a/test/integration/addresses.js b/test/integration/addresses.js
index f37dbc7..1d28020 100644
--- a/test/integration/addresses.js
+++ b/test/integration/addresses.js
@@ -4,8 +4,8 @@ const bitcoin = require('../../')
 const dhttp = require('./_regtest').dhttp
 const TESTNET = bitcoin.networks.testnet
 
-describe('bitcoinjs-lib (addresses)', function () {
-  it('can generate a random address [and support the retrieval of transactions for that address (via 3PBP)', async function () {
+describe('bitcoinjs-lib (addresses)', () => {
+  it('can generate a random address [and support the retrieval of transactions for that address (via 3PBP)', async () => {
     const keyPair = bitcoin.ECPair.makeRandom()
     const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey })
 
@@ -23,14 +23,14 @@ describe('bitcoinjs-lib (addresses)', function () {
     assert.strictEqual(result.total_sent, 0)
   })
 
-  it('can import an address via WIF', function () {
+  it('can import an address via WIF', () => {
     const keyPair = bitcoin.ECPair.fromWIF('KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn')
     const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey })
 
     assert.strictEqual(address, '1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH')
   })
 
-  it('can generate a P2SH, pay-to-multisig (2-of-3) address', function () {
+  it('can generate a P2SH, pay-to-multisig (2-of-3) address', () => {
     const pubkeys = [
       '026477115981fe981a6918a6297d9803c4dc04f328f22041bedff886bbc2962e01',
       '02c96db2302d19b43d4c69368babace7854cc84eb9e061cde51cfa77ca4a22b8b9',
@@ -43,14 +43,14 @@ describe('bitcoinjs-lib (addresses)', function () {
     assert.strictEqual(address, '36NUkt6FWUi3LAWBqWRdDmdTWbt91Yvfu7')
   })
 
-  it('can generate a SegWit address', function () {
+  it('can generate a SegWit address', () => {
     const keyPair = bitcoin.ECPair.fromWIF('KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn')
     const { address } = bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey })
 
     assert.strictEqual(address, 'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4')
   })
 
-  it('can generate a SegWit address (via P2SH)', function () {
+  it('can generate a SegWit address (via P2SH)', () => {
     const keyPair = bitcoin.ECPair.fromWIF('KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn')
     const { address } = bitcoin.payments.p2sh({
       redeem: bitcoin.payments.p2wpkh({ pubkey: keyPair.publicKey })
@@ -59,7 +59,7 @@ describe('bitcoinjs-lib (addresses)', function () {
     assert.strictEqual(address, '3JvL6Ymt8MVWiCNHC7oWU6nLeHNJKLZGLN')
   })
 
-  it('can generate a P2WSH (SegWit), pay-to-multisig (3-of-4) address', function () {
+  it('can generate a P2WSH (SegWit), pay-to-multisig (3-of-4) address', () => {
     const pubkeys = [
       '026477115981fe981a6918a6297d9803c4dc04f328f22041bedff886bbc2962e01',
       '02c96db2302d19b43d4c69368babace7854cc84eb9e061cde51cfa77ca4a22b8b9',
@@ -73,7 +73,7 @@ describe('bitcoinjs-lib (addresses)', function () {
     assert.strictEqual(address, 'bc1q75f6dv4q8ug7zhujrsp5t0hzf33lllnr3fe7e2pra3v24mzl8rrqtp3qul')
   })
 
-  it('can generate a P2SH(P2WSH(...)), pay-to-multisig (2-of-2) address', function () {
+  it('can generate a P2SH(P2WSH(...)), pay-to-multisig (2-of-2) address', () => {
     const pubkeys = [
       '026477115981fe981a6918a6297d9803c4dc04f328f22041bedff886bbc2962e01',
       '02c96db2302d19b43d4c69368babace7854cc84eb9e061cde51cfa77ca4a22b8b9'
@@ -88,7 +88,7 @@ describe('bitcoinjs-lib (addresses)', function () {
   })
 
   // examples using other network information
-  it('can generate a Testnet address', function () {
+  it('can generate a Testnet address', () => {
     const keyPair = bitcoin.ECPair.makeRandom({ network: TESTNET })
     const { address } = bitcoin.payments.p2pkh({ pubkey: keyPair.publicKey, network: TESTNET })
 
@@ -96,7 +96,7 @@ describe('bitcoinjs-lib (addresses)', function () {
     assert.strictEqual(address.startsWith('m') || address.startsWith('n'), true)
   })
 
-  it('can generate a Litecoin address', function () {
+  it('can generate a Litecoin address', () => {
     // WARNING: although possible, bitcoinjs is NOT necessarily compatible with Litecoin
     const LITECOIN = {
       messagePrefix: '\x19Litecoin Signed Message:\n',
diff --git a/test/integration/bip32.js b/test/integration/bip32.js
index 5f948fa..255669c 100644
--- a/test/integration/bip32.js
+++ b/test/integration/bip32.js
@@ -8,15 +8,15 @@ function getAddress (node, network) {
   return bitcoin.payments.p2pkh({ pubkey: node.publicKey, network }).address
 }
 
-describe('bitcoinjs-lib (BIP32)', function () {
-  it('can import a BIP32 testnet xpriv and export to WIF', function () {
+describe('bitcoinjs-lib (BIP32)', () => {
+  it('can import a BIP32 testnet xpriv and export to WIF', () => {
     const xpriv = 'tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK'
     const node = bip32.fromBase58(xpriv, bitcoin.networks.testnet)
 
     assert.strictEqual(node.toWIF(), 'cQfoY67cetFNunmBUX5wJiw3VNoYx3gG9U9CAofKE6BfiV1fSRw7')
   })
 
-  it('can export a BIP32 xpriv, then import it', function () {
+  it('can export a BIP32 xpriv, then import it', () => {
     const mnemonic = 'praise you muffin lion enable neck grocery crumble super myself license ghost'
     const seed = bip39.mnemonicToSeed(mnemonic)
     const node = bip32.fromSeed(seed)
@@ -27,7 +27,7 @@ describe('bitcoinjs-lib (BIP32)', function () {
     assert.strictEqual(node.toWIF(), restored.toWIF()) // same private key
   })
 
-  it('can export a BIP32 xpub', function () {
+  it('can export a BIP32 xpub', () => {
     const mnemonic = 'praise you muffin lion enable neck grocery crumble super myself license ghost'
     const seed = bip39.mnemonicToSeed(mnemonic)
     const node = bip32.fromSeed(seed)
@@ -36,7 +36,7 @@ describe('bitcoinjs-lib (BIP32)', function () {
     assert.strictEqual(string, 'xpub661MyMwAqRbcGhVeaVfEBA25e3cP9DsJQZoE8iep5fZSxy3TnPBNBgWnMZx56oreNc48ZoTkQfatNJ9VWnQ7ZcLZcVStpaXLTeG8bGrzX3n')
   })
 
-  it('can create a BIP32, bitcoin, account 0, external address', function () {
+  it('can create a BIP32, bitcoin, account 0, external address', () => {
     const path = "m/0'/0/0"
     const root = bip32.fromSeed(Buffer.from('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', 'hex'))
 
@@ -51,7 +51,7 @@ describe('bitcoinjs-lib (BIP32)', function () {
     assert.strictEqual(getAddress(child1b), '1JHyB1oPXufr4FXkfitsjgNB5yRY9jAaa7')
   })
 
-  it('can create a BIP44, bitcoin, account 0, external address', function () {
+  it('can create a BIP44, bitcoin, account 0, external address', () => {
     const root = bip32.fromSeed(Buffer.from('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', 'hex'))
 
     const child1 = root.derivePath("m/44'/0'/0'/0/0")
@@ -67,7 +67,7 @@ describe('bitcoinjs-lib (BIP32)', function () {
     assert.strictEqual(getAddress(child1b), '12Tyvr1U8A3ped6zwMEU5M8cx3G38sP5Au')
   })
 
-  it('can create a BIP49, bitcoin testnet, account 0, external address', function () {
+  it('can create a BIP49, bitcoin testnet, account 0, external address', () => {
     const mnemonic = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about'
     const seed = bip39.mnemonicToSeed(mnemonic)
     const root = bip32.fromSeed(seed)
@@ -82,7 +82,7 @@ describe('bitcoinjs-lib (BIP32)', function () {
     assert.strictEqual(address, '2Mww8dCYPUpKHofjgcXcBCEGmniw9CoaiD2')
   })
 
-  it('can use BIP39 to generate BIP32 addresses', function () {
+  it('can use BIP39 to generate BIP32 addresses', () => {
     // var mnemonic = bip39.generateMnemonic()
     const mnemonic = 'praise you muffin lion enable neck grocery crumble super myself license ghost'
     assert(bip39.validateMnemonic(mnemonic))
diff --git a/test/integration/blocks.js b/test/integration/blocks.js
index 915fd65..044862d 100644
--- a/test/integration/blocks.js
+++ b/test/integration/blocks.js
@@ -4,8 +4,8 @@ const { describe, it } = require('mocha')
 const assert = require('assert')
 const bitcoin = require('../../')
 
-describe('bitcoinjs-lib (blocks)', function () {
-  it('can extract a height from a CoinBase transaction', function () {
+describe('bitcoinjs-lib (blocks)', () => {
+  it('can extract a height from a CoinBase transaction', () => {
     // from 00000000000000000097669cdca131f24d40c4cc7d80eaa65967a2d09acf6ce6
     const txHex = '010000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff50037f9a07174d696e656420627920416e74506f6f6c685b205a2b1f7bfabe6d6d36afe1910eca9405b66f97750940a656e38e2c0312958190ff8e98fd16761d220400000000000000aa340000d49f0000ffffffff02b07fc366000000001976a9148349212dc27ce3ab4c5b29b85c4dec643d764b1788ac0000000000000000266a24aa21a9ed72d9432948505e3d3062f1307a3f027a5dea846ff85e47159680919c12bf1e400120000000000000000000000000000000000000000000000000000000000000000000000000'
     const tx = bitcoin.Transaction.fromHex(txHex)
diff --git a/test/integration/cltv.js b/test/integration/cltv.js
index 66afb94..b2fd478 100644
--- a/test/integration/cltv.js
+++ b/test/integration/cltv.js
@@ -8,9 +8,9 @@ const bip65 = require('bip65')
 const alice = bitcoin.ECPair.fromWIF('cScfkGjbzzoeewVWmU2hYPUHeVGJRDdFt7WhmrVVGkxpmPP8BHWe', regtest)
 const bob = bitcoin.ECPair.fromWIF('cMkopUXKWsEzAjfa1zApksGRwjVpJRB3831qM9W4gKZsLwjHXA9x', regtest)
 
-describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
+describe('bitcoinjs-lib (transactions w/ CLTV)', () => {
   // force update MTP
-  before(async function () {
+  before(async () => {
     await regtestUtils.mine(11)
   })
 
@@ -38,7 +38,7 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
   }
 
   // expiry past, {Alice's signature} OP_TRUE
-  it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the past)', async function () {
+  it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the past)', async () => {
     // 3 hours ago
     const lockTime = bip65.encode({ utc: utcNow() - (3600 * 3) })
     const redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
@@ -77,7 +77,7 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
   })
 
   // expiry will pass, {Alice's signature} OP_TRUE
-  it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)', async function () {
+  it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)', async () => {
     const height = await regtestUtils.height()
     // 5 blocks from now
     const lockTime = bip65.encode({ blocks: height + 5 })
@@ -120,7 +120,7 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
   })
 
   // expiry ignored, {Bob's signature} {Alice's signature} OP_FALSE
-  it('can create (and broadcast via 3PBP) a Transaction where Alice and Bob can redeem the output at any time', async function () {
+  it('can create (and broadcast via 3PBP) a Transaction where Alice and Bob can redeem the output at any time', async () => {
     // two hours ago
     const lockTime = bip65.encode({ utc: utcNow() - (3600 * 2) })
     const redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
@@ -159,7 +159,7 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
   })
 
   // expiry in the future, {Alice's signature} OP_TRUE
-  it('can create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry', async function () {
+  it('can create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry', async () => {
     // two hours from now
     const lockTime = bip65.encode({ utc: utcNow() + (3600 * 2) })
     const redeemScript = cltvCheckSigOutput(alice, bob, lockTime)
@@ -189,7 +189,7 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
     tx.setInputScript(0, redeemScriptSig)
 
     await regtestUtils.broadcast(tx.toHex()).catch(err => {
-      assert.throws(function () {
+      assert.throws(() => {
         if (err) throw err
       }, /Error: non-final \(code 64\)/)
     })
diff --git a/test/integration/csv.js b/test/integration/csv.js
index 1ad8c90..8833412 100644
--- a/test/integration/csv.js
+++ b/test/integration/csv.js
@@ -8,9 +8,9 @@ const bip68 = require('bip68')
 const alice = bitcoin.ECPair.fromWIF('cScfkGjbzzoeewVWmU2hYPUHeVGJRDdFt7WhmrVVGkxpmPP8BHWe', regtest)
 const bob = bitcoin.ECPair.fromWIF('cMkopUXKWsEzAjfa1zApksGRwjVpJRB3831qM9W4gKZsLwjHXA9x', regtest)
 
-describe('bitcoinjs-lib (transactions w/ CSV)', function () {
+describe('bitcoinjs-lib (transactions w/ CSV)', () => {
   // force update MTP
-  before(async function () {
+  before(async () => {
     await regtestUtils.mine(11)
   })
 
@@ -35,7 +35,7 @@ describe('bitcoinjs-lib (transactions w/ CSV)', function () {
   }
 
   // expiry will pass, {Alice's signature} OP_TRUE
-  it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)', async function () {
+  it('can create (and broadcast via 3PBP) a Transaction where Alice can redeem the output after the expiry (in the future)', async () => {
     // 5 blocks from now
     const sequence = bip68.encode({ blocks: 5 })
     const p2sh = bitcoin.payments.p2sh({
@@ -84,7 +84,7 @@ describe('bitcoinjs-lib (transactions w/ CSV)', function () {
   })
 
   // expiry in the future, {Alice's signature} OP_TRUE
-  it('can create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry', async function () {
+  it('can create (but fail to broadcast via 3PBP) a Transaction where Alice attempts to redeem before the expiry', async () => {
     // two hours after confirmation
     const sequence = bip68.encode({ seconds: 7168 })
     const p2sh = bitcoin.payments.p2sh({
@@ -119,7 +119,7 @@ describe('bitcoinjs-lib (transactions w/ CSV)', function () {
     tx.setInputScript(0, redeemScriptSig)
 
     await regtestUtils.broadcast(tx.toHex()).catch(err => {
-      assert.throws(function () {
+      assert.throws(() => {
         if (err) throw err
       }, /Error: non-BIP68-final \(code 64\)/)
     })
diff --git a/test/integration/payments.js b/test/integration/payments.js
index 2fcdbda..66b0a13 100644
--- a/test/integration/payments.js
+++ b/test/integration/payments.js
@@ -16,7 +16,7 @@ async function buildAndSign (depends, prevOutput, redeemScript, witnessScript) {
   txb.addOutput(regtestUtils.RANDOM_ADDRESS, 2e4)
 
   if (depends.signatures) {
-    keyPairs.forEach((keyPair) => {
+    keyPairs.forEach(keyPair => {
       txb.sign(0, keyPair, redeemScript, null, unspent.value, witnessScript)
     })
   } else if (depends.signature) {
@@ -26,7 +26,7 @@ async function buildAndSign (depends, prevOutput, redeemScript, witnessScript) {
   return regtestUtils.broadcast(txb.build().toHex())
 }
 
-;['p2ms', 'p2pk', 'p2pkh', 'p2wpkh'].forEach((k) => {
+;['p2ms', 'p2pk', 'p2pkh', 'p2wpkh'].forEach(k => {
   const fixtures = require('../fixtures/' + k)
   const { depends } = fixtures.dynamic
   const fn = bitcoin.payments[k]
@@ -39,7 +39,7 @@ async function buildAndSign (depends, prevOutput, redeemScript, witnessScript) {
   const { output } = fn(base)
   if (!output) throw new TypeError('Missing output')
 
-  describe('bitcoinjs-lib (payments - ' + k + ')', function () {
+  describe('bitcoinjs-lib (payments - ' + k + ')', () => {
     it('can broadcast as an output, and be spent as an input', async () => {
       await buildAndSign(depends, output, null, null)
     })
diff --git a/test/integration/transactions.js b/test/integration/transactions.js
index a3836a7..c096b87 100644
--- a/test/integration/transactions.js
+++ b/test/integration/transactions.js
@@ -8,8 +8,8 @@ function rng () {
   return Buffer.from('YT8dAtK4d16A3P1z+TpwB2jJ4aFH3g9M1EioIBkLEV4=', 'base64')
 }
 
-describe('bitcoinjs-lib (transactions)', function () {
-  it('can create a 1-to-1 Transaction', function () {
+describe('bitcoinjs-lib (transactions)', () => {
+  it('can create a 1-to-1 Transaction', () => {
     const alice = bitcoin.ECPair.fromWIF('L1uyy5qTuGrVXrmrsvHWHgVzW9kKdrp27wBC7Vs6nZDTF2BRUVwy')
     const txb = new bitcoin.TransactionBuilder()
 
@@ -24,7 +24,7 @@ describe('bitcoinjs-lib (transactions)', function () {
     assert.strictEqual(txb.build().toHex(), '01000000019d344070eac3fe6e394a16d06d7704a7d5c0a10eb2a2c16bc98842b7cc20d561000000006b48304502210088828c0bdfcdca68d8ae0caeb6ec62cd3fd5f9b2191848edae33feb533df35d302202e0beadd35e17e7f83a733f5277028a9b453d525553e3f5d2d7a7aa8010a81d60121029f50f51d63b345039a290c94bffd3180c99ed659ff6ea6b1242bca47eb93b59fffffffff01e02e0000000000001976a91406afd46bcdfd22ef94ac122aa11f241244a37ecc88ac00000000')
   })
 
-  it('can create a 2-to-2 Transaction', function () {
+  it('can create a 2-to-2 Transaction', () => {
     const alice = bitcoin.ECPair.fromWIF('L1Knwj9W3qK3qMKdTvmg3VfzUs3ij2LETTFhxza9LfD5dngnoLG1')
     const bob = bitcoin.ECPair.fromWIF('KwcN2pT3wnRAurhy7qMczzbkpY5nXMW2ubh696UBc1bcwctTx26z')
 
@@ -232,17 +232,17 @@ describe('bitcoinjs-lib (transactions)', function () {
     })
   })
 
-  it('can verify Transaction (P2PKH) signatures', function () {
+  it('can verify Transaction (P2PKH) signatures', () => {
     const txHex = '010000000321c5f7e7bc98b3feda84aad36a5c99a02bcb8823a2f3eccbcd5da209698b5c20000000006b48304502210099e021772830207cf7c55b69948d3b16b4dcbf1f55a9cd80ebf8221a169735f9022064d33f11d62cd28240b3862afc0b901adc9f231c7124dd19bdb30367b61964c50121032b4c06c06c3ec0b7fa29519dfa5aae193ee2cc35ca127f29f14ec605d62fb63dffffffff8a75ce85441ddb3f342708ee33cc8ed418b07d9ba9e0e7c4e1cccfe9f52d8a88000000006946304302207916c23dae212c95a920423902fa44e939fb3d542f4478a7b46e9cde53705800021f0d74e9504146e404c1b8f9cba4dff2d4782e3075491c9ed07ce4a7d1c4461a01210216c92abe433106491bdeb4a261226f20f5a4ac86220cc6e37655aac6bf3c1f2affffffffdfef93f69fe32e944fad79fa8f882b3a155d80383252348caba1a77a5abbf7ef000000006b483045022100faa6e9ca289b46c64764a624c59ac30d9abcf1d4a04c4de9089e67cbe0d300a502206930afa683f6807502de5c2431bf9a1fd333c8a2910a76304df0f3d23d83443f0121039e05da8b8ea4f9868ecebb25998c7701542986233f4401799551fbecf316b18fffffffff01ff4b0000000000001976a9146c86476d1d85cd60116cd122a274e6a570a5a35c88acc96d0700'
     const keyPairs = [
       '032b4c06c06c3ec0b7fa29519dfa5aae193ee2cc35ca127f29f14ec605d62fb63d',
       '0216c92abe433106491bdeb4a261226f20f5a4ac86220cc6e37655aac6bf3c1f2a',
       '039e05da8b8ea4f9868ecebb25998c7701542986233f4401799551fbecf316b18f'
-    ].map(function (q) { return bitcoin.ECPair.fromPublicKey(Buffer.from(q, 'hex')) })
+    ].map(q => { return bitcoin.ECPair.fromPublicKey(Buffer.from(q, 'hex')) })
 
     const tx = bitcoin.Transaction.fromHex(txHex)
 
-    tx.ins.forEach(function (input, i) {
+    tx.ins.forEach((input, i) => {
       const keyPair = keyPairs[i]
       const p2pkh = bitcoin.payments.p2pkh({
         pubkey: keyPair.publicKey,
@@ -256,7 +256,7 @@ describe('bitcoinjs-lib (transactions)', function () {
     })
   })
 
-  it('can verify Transaction (P2SH(P2WPKH)) signatures', function () {
+  it('can verify Transaction (P2SH(P2WPKH)) signatures', () => {
     const utxos = {
       'f72d1d83ac40fcedd01415751556a905844ab5f44bbb7728565ebb91b1590109:0': {
         value: 50000
@@ -266,7 +266,7 @@ describe('bitcoinjs-lib (transactions)', function () {
     const txHex = '02000000000101090159b191bb5e562877bb4bf4b54a8405a95615751514d0edfc40ac831d2df7000000001716001435a179e5516947a39ae9c8a25e9fe62c0fc598edffffffff01204e0000000000001976a91431d43308d3c886d53e9ae8a45728370571ff456988ac0247304402206ec41f685b997a51f325b07ee852e82a535f6b52ef54485cc133e05168aa052a022070bafa86108acb51c77b2b259ae8fb7fd1efa10fef804fcfe9b13c2db719acf5012103fb03e9d0a9af86cbed94225dbb8bb70f6b82109bce0a61ddcf41dab6cbb4871100000000'
     const tx = bitcoin.Transaction.fromHex(txHex)
 
-    tx.ins.forEach(function (input, i) {
+    tx.ins.forEach((input, i) => {
       const txId = Buffer.from(input.hash).reverse().toString('hex')
       const utxo = utxos[`${txId}:${i}`]
       if (!utxo) throw new Error('Missing utxo')
diff --git a/test/payments.js b/test/payments.js
index a4f07bb..5619cdb 100644
--- a/test/payments.js
+++ b/test/payments.js
@@ -2,8 +2,8 @@ const { describe, it } = require('mocha')
 const assert = require('assert')
 const u = require('./payments.utils')
 
-;['embed', 'p2ms', 'p2pk', 'p2pkh', 'p2sh', 'p2wpkh', 'p2wsh'].forEach(function (p) {
-  describe(p, function () {
+;['embed', 'p2ms', 'p2pk', 'p2pkh', 'p2sh', 'p2wpkh', 'p2wsh'].forEach(p => {
+  describe(p, () => {
     let fn
     let payment = require('../src/payments/' + p)
     if (p === 'embed') {
@@ -13,15 +13,15 @@ const u = require('./payments.utils')
     }
     const fixtures = require('./fixtures/' + p)
 
-    fixtures.valid.forEach(function (f, i) {
-      it(f.description + ' as expected', function () {
+    fixtures.valid.forEach((f, i) => {
+      it(f.description + ' as expected', () => {
         const args = u.preform(f.arguments)
         const actual = fn(args, f.options)
 
         u.equate(actual, f.expected, f.arguments)
       })
 
-      it(f.description + ' as expected (no validation)', function () {
+      it(f.description + ' as expected (no validation)', () => {
         const args = u.preform(f.arguments)
         const actual = fn(args, Object.assign({}, f.options, {
           validate: false
@@ -31,11 +31,11 @@ const u = require('./payments.utils')
       })
     })
 
-    fixtures.invalid.forEach(function (f) {
-      it('throws ' + f.exception + (f.description ? ('for ' + f.description) : ''), function () {
+    fixtures.invalid.forEach(f => {
+      it('throws ' + f.exception + (f.description ? ('for ' + f.description) : ''), () => {
         const args = u.preform(f.arguments)
 
-        assert.throws(function () {
+        assert.throws(() => {
           fn(args, f.options)
         }, new RegExp(f.exception))
       })
@@ -45,23 +45,23 @@ const u = require('./payments.utils')
     if (!fixtures.dynamic) return
     const { depends, details } = fixtures.dynamic
 
-    details.forEach(function (f) {
+    details.forEach(f => {
       const detail = u.preform(f)
       const disabled = {}
-      if (f.disabled) f.disabled.forEach(function (k) { disabled[k] = true })
+      if (f.disabled) f.disabled.forEach(k => { disabled[k] = true })
 
       for (let key in depends) {
         if (key in disabled) continue
         const dependencies = depends[key]
 
-        dependencies.forEach(function (dependency) {
+        dependencies.forEach(dependency => {
           if (!Array.isArray(dependency)) dependency = [dependency]
 
           const args = {}
-          dependency.forEach(function (d) { u.from(d, detail, args) })
+          dependency.forEach(d => { u.from(d, detail, args) })
           const expected = u.from(key, detail)
 
-          it(f.description + ', ' + key + ' derives from ' + JSON.stringify(dependency), function () {
+          it(f.description + ', ' + key + ' derives from ' + JSON.stringify(dependency), () => {
             u.equate(fn(args), expected)
           })
         })
diff --git a/test/payments.utils.js b/test/payments.utils.js
index 485bf03..15414c4 100644
--- a/test/payments.utils.js
+++ b/test/payments.utils.js
@@ -39,7 +39,7 @@ function carryOver (a, b) {
 function equateBase (a, b, context) {
   if ('output' in b) t.strictEqual(tryASM(a.output), tryASM(b.output), `Inequal ${context}output`)
   if ('input' in b) t.strictEqual(tryASM(a.input), tryASM(b.input), `Inequal ${context}input`)
-  if ('witness' in b) t.deepEqual(tryHex(a.witness), tryHex(b.witness), `Inequal ${context}witness`)
+  if ('witness' in b) t.deepStrictEqual(tryHex(a.witness), tryHex(b.witness), `Inequal ${context}witness`)
 }
 
 function equate (a, b, args) {
@@ -58,19 +58,20 @@ function equate (a, b, args) {
 
   equateBase(a, b, '')
   if (b.redeem) equateBase(a.redeem, b.redeem, 'redeem.')
-  if (b.network) t.deepEqual(a.network, BNETWORKS[b.network], 'Inequal *.network')
+  if (b.network) t.deepStrictEqual(a.network, BNETWORKS[b.network], 'Inequal *.network')
 
   // contextual
   if (b.signature === null) b.signature = undefined
+  if (b.signatures === null) b.signatures = undefined
   if ('address' in b) t.strictEqual(a.address, b.address, 'Inequal *.address')
   if ('hash' in b) t.strictEqual(tryHex(a.hash), tryHex(b.hash), 'Inequal *.hash')
   if ('pubkey' in b) t.strictEqual(tryHex(a.pubkey), tryHex(b.pubkey), 'Inequal *.pubkey')
   if ('signature' in b) t.strictEqual(tryHex(a.signature), tryHex(b.signature), 'Inequal signature')
   if ('m' in b) t.strictEqual(a.m, b.m, 'Inequal *.m')
   if ('n' in b) t.strictEqual(a.n, b.n, 'Inequal *.n')
-  if ('pubkeys' in b) t.deepEqual(tryHex(a.pubkeys), tryHex(b.pubkeys), 'Inequal *.pubkeys')
-  if ('signatures' in b) t.deepEqual(tryHex(a.signatures), tryHex(b.signatures), 'Inequal *.signatures')
-  if ('data' in b) t.deepEqual(tryHex(a.data), tryHex(b.data), 'Inequal *.data')
+  if ('pubkeys' in b) t.deepStrictEqual(tryHex(a.pubkeys), tryHex(b.pubkeys), 'Inequal *.pubkeys')
+  if ('signatures' in b) t.deepStrictEqual(tryHex(a.signatures), tryHex(b.signatures), 'Inequal *.signatures')
+  if ('data' in b) t.deepStrictEqual(tryHex(a.data), tryHex(b.data), 'Inequal *.data')
 }
 
 function preform (x) {
@@ -94,7 +95,7 @@ function preform (x) {
   if (x.pubkey) x.pubkey = Buffer.from(x.pubkey, 'hex')
   if (x.signature) x.signature = Buffer.from(x.signature, 'hex')
   if (x.pubkeys) x.pubkeys = x.pubkeys.map(fromHex)
-  if (x.signatures) x.signatures = x.signatures.map(function (y) { return Number.isFinite(y) ? y : Buffer.from(y, 'hex') })
+  if (x.signatures) x.signatures = x.signatures.map(y => { return Number.isFinite(y) ? y : Buffer.from(y, 'hex') })
   if (x.redeem) {
     x.redeem = Object.assign({}, x.redeem)
     if (typeof x.redeem.input === 'string') x.redeem.input = asmToBuffer(x.redeem.input)
diff --git a/test/script.js b/test/script.js
index c2a60ad..d003558 100644
--- a/test/script.js
+++ b/test/script.js
@@ -6,44 +6,44 @@ const minimalData = require('minimaldata')
 const fixtures = require('./fixtures/script.json')
 const fixtures2 = require('./fixtures/templates.json')
 
-describe('script', function () {
+describe('script', () => {
   // TODO
-  describe('isCanonicalPubKey', function () {
-    it('rejects if not provided a Buffer', function () {
+  describe('isCanonicalPubKey', () => {
+    it('rejects if not provided a Buffer', () => {
       assert.strictEqual(false, bscript.isCanonicalPubKey(0))
     })
-    it('rejects smaller than 33', function () {
+    it('rejects smaller than 33', () => {
       for (var i = 0; i < 33; i++) {
         assert.strictEqual(false, bscript.isCanonicalPubKey(Buffer.from('', i)))
       }
     })
   })
-  describe.skip('isCanonicalScriptSignature', function () {
+  describe.skip('isCanonicalScriptSignature', () => {
   })
 
-  describe('fromASM/toASM', function () {
-    fixtures.valid.forEach(function (f) {
-      it('encodes/decodes ' + f.asm, function () {
+  describe('fromASM/toASM', () => {
+    fixtures.valid.forEach(f => {
+      it('encodes/decodes ' + f.asm, () => {
         const script = bscript.fromASM(f.asm)
         assert.strictEqual(bscript.toASM(script), f.asm)
       })
     })
 
-    fixtures.invalid.fromASM.forEach(function (f) {
-      it('throws ' + f.description, function () {
-        assert.throws(function () {
+    fixtures.invalid.fromASM.forEach(f => {
+      it('throws ' + f.description, () => {
+        assert.throws(() => {
           bscript.fromASM(f.script)
         }, new RegExp(f.description))
       })
     })
   })
 
-  describe('fromASM/toASM (templates)', function () {
-    fixtures2.valid.forEach(function (f) {
+  describe('fromASM/toASM (templates)', () => {
+    fixtures2.valid.forEach(f => {
       if (f.inputHex) {
         const ih = bscript.toASM(Buffer.from(f.inputHex, 'hex'))
 
-        it('encodes/decodes ' + ih, function () {
+        it('encodes/decodes ' + ih, () => {
           const script = bscript.fromASM(f.input)
           assert.strictEqual(script.toString('hex'), f.inputHex)
           assert.strictEqual(bscript.toASM(script), f.input)
@@ -51,7 +51,7 @@ describe('script', function () {
       }
 
       if (f.outputHex) {
-        it('encodes/decodes ' + f.output, function () {
+        it('encodes/decodes ' + f.output, () => {
           const script = bscript.fromASM(f.output)
           assert.strictEqual(script.toString('hex'), f.outputHex)
           assert.strictEqual(bscript.toASM(script), f.output)
@@ -60,9 +60,9 @@ describe('script', function () {
     })
   })
 
-  describe('isPushOnly', function () {
-    fixtures.valid.forEach(function (f) {
-      it('returns ' + !!f.stack + ' for ' + f.asm, function () {
+  describe('isPushOnly', () => {
+    fixtures.valid.forEach(f => {
+      it('returns ' + !!f.stack + ' for ' + f.asm, () => {
         const script = bscript.fromASM(f.asm)
         const chunks = bscript.decompile(script)
 
@@ -71,26 +71,26 @@ describe('script', function () {
     })
   })
 
-  describe('toStack', function () {
-    fixtures.valid.forEach(function (f) {
-      it('returns ' + !!f.stack + ' for ' + f.asm, function () {
+  describe('toStack', () => {
+    fixtures.valid.forEach(f => {
+      it('returns ' + !!f.stack + ' for ' + f.asm, () => {
         if (!f.stack || !f.asm) return
 
         const script = bscript.fromASM(f.asm)
 
         const stack = bscript.toStack(script)
-        assert.deepEqual(stack.map(function (x) {
+        assert.deepStrictEqual(stack.map(x => {
           return x.toString('hex')
         }), f.stack)
 
-        assert.equal(bscript.toASM(bscript.compile(stack)), f.asm, 'should rebuild same script from stack')
+        assert.strictEqual(bscript.toASM(bscript.compile(stack)), f.asm, 'should rebuild same script from stack')
       })
     })
   })
 
-  describe('compile (via fromASM)', function () {
-    fixtures.valid.forEach(function (f) {
-      it('(' + f.type + ') compiles ' + f.asm, function () {
+  describe('compile (via fromASM)', () => {
+    fixtures.valid.forEach(f => {
+      it('(' + f.type + ') compiles ' + f.asm, () => {
         const scriptSig = bscript.fromASM(f.asm)
 
         assert.strictEqual(scriptSig.toString('hex'), f.script)
@@ -104,9 +104,9 @@ describe('script', function () {
     })
   })
 
-  describe('decompile', function () {
-    fixtures.valid.forEach(function (f) {
-      it('decompiles ' + f.asm, function () {
+  describe('decompile', () => {
+    fixtures.valid.forEach(f => {
+      it('decompiles ' + f.asm, () => {
         const chunks = bscript.decompile(Buffer.from(f.script, 'hex'))
 
         assert.strictEqual(bscript.compile(chunks).toString('hex'), f.script)
@@ -123,8 +123,8 @@ describe('script', function () {
       })
     })
 
-    fixtures.invalid.decompile.forEach(function (f) {
-      it('fails to decompile ' + f.script + ',  because "' + f.description + '"', function () {
+    fixtures.invalid.decompile.forEach(f => {
+      it('fails to decompile ' + f.script + ',  because "' + f.description + '"', () => {
         const chunks = bscript.decompile(Buffer.from(f.script, 'hex'))
 
         assert.strictEqual(chunks, null)
@@ -132,9 +132,9 @@ describe('script', function () {
     })
   })
 
-  describe('SCRIPT_VERIFY_MINIMALDATA policy', function () {
-    fixtures.valid.forEach(function (f) {
-      it('compliant for ' + f.type + ' scriptSig ' + f.asm, function () {
+  describe('SCRIPT_VERIFY_MINIMALDATA policy', () => {
+    fixtures.valid.forEach(f => {
+      it('compliant for ' + f.type + ' scriptSig ' + f.asm, () => {
         const script = Buffer.from(f.script, 'hex')
 
         assert(minimalData(script))
@@ -142,7 +142,7 @@ describe('script', function () {
     })
 
     function testEncodingForSize (i) {
-      it('compliant for data PUSH of length ' + i, function () {
+      it('compliant for data PUSH of length ' + i, () => {
         const buffer = Buffer.alloc(i)
         const script = bscript.compile([buffer])
 
diff --git a/test/script_number.js b/test/script_number.js
index bc8f395..d5b97e2 100644
--- a/test/script_number.js
+++ b/test/script_number.js
@@ -3,10 +3,10 @@ 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 () {
+describe('script-number', () => {
+  describe('decode', () => {
+    fixtures.forEach(f => {
+      it(f.hex + ' returns ' + f.number, () => {
         const actual = scriptNumber.decode(Buffer.from(f.hex, 'hex'), f.bytes)
 
         assert.strictEqual(actual, f.number)
@@ -14,9 +14,9 @@ describe('script-number', function () {
     })
   })
 
-  describe('encode', function () {
-    fixtures.forEach(function (f) {
-      it(f.number + ' returns ' + f.hex, function () {
+  describe('encode', () => {
+    fixtures.forEach(f => {
+      it(f.number + ' returns ' + f.hex, () => {
         const actual = scriptNumber.encode(f.number)
 
         assert.strictEqual(actual.toString('hex'), f.hex)
diff --git a/test/script_signature.js b/test/script_signature.js
index cee69bd..6888ca5 100644
--- a/test/script_signature.js
+++ b/test/script_signature.js
@@ -4,7 +4,7 @@ const bscriptSig = require('../src/script').signature
 const Buffer = require('safe-buffer').Buffer
 const fixtures = require('./fixtures/signature.json')
 
-describe('Script Signatures', function () {
+describe('Script Signatures', () => {
   function fromRaw (signature) {
     return Buffer.concat([
       Buffer.from(signature.r, 'hex'),
@@ -19,43 +19,43 @@ describe('Script Signatures', function () {
     }
   }
 
-  describe('encode', function () {
-    fixtures.valid.forEach(function (f) {
-      it('encodes ' + f.hex, function () {
+  describe('encode', () => {
+    fixtures.valid.forEach(f => {
+      it('encodes ' + f.hex, () => {
         const buffer = bscriptSig.encode(fromRaw(f.raw), f.hashType)
 
         assert.strictEqual(buffer.toString('hex'), f.hex)
       })
     })
 
-    fixtures.invalid.forEach(function (f) {
+    fixtures.invalid.forEach(f => {
       if (!f.raw) return
 
-      it('throws ' + f.exception, function () {
+      it('throws ' + f.exception, () => {
         const signature = fromRaw(f.raw)
 
-        assert.throws(function () {
+        assert.throws(() => {
           bscriptSig.encode(signature, f.hashType)
         }, new RegExp(f.exception))
       })
     })
   })
 
-  describe('decode', function () {
-    fixtures.valid.forEach(function (f) {
-      it('decodes ' + f.hex, function () {
+  describe('decode', () => {
+    fixtures.valid.forEach(f => {
+      it('decodes ' + f.hex, () => {
         const decode = bscriptSig.decode(Buffer.from(f.hex, 'hex'))
 
-        assert.deepEqual(toRaw(decode.signature), f.raw)
+        assert.deepStrictEqual(toRaw(decode.signature), f.raw)
         assert.strictEqual(decode.hashType, f.hashType)
       })
     })
 
-    fixtures.invalid.forEach(function (f) {
-      it('throws on ' + f.hex, function () {
+    fixtures.invalid.forEach(f => {
+      it('throws on ' + f.hex, () => {
         const buffer = Buffer.from(f.hex, 'hex')
 
-        assert.throws(function () {
+        assert.throws(() => {
           bscriptSig.decode(buffer)
         }, new RegExp(f.exception))
       })
diff --git a/test/transaction.js b/test/transaction.js
index d923ce2..3fa9243 100644
--- a/test/transaction.js
+++ b/test/transaction.js
@@ -4,13 +4,13 @@ const bscript = require('../src/script')
 const fixtures = require('./fixtures/transaction')
 const Transaction = require('..').Transaction
 
-describe('Transaction', function () {
+describe('Transaction', () => {
   function fromRaw (raw, noWitness) {
     const tx = new Transaction()
     tx.version = raw.version
     tx.locktime = raw.locktime
 
-    raw.ins.forEach(function (txIn, i) {
+    raw.ins.forEach((txIn, i) => {
       const txHash = Buffer.from(txIn.hash, 'hex')
       let scriptSig
 
@@ -23,7 +23,7 @@ describe('Transaction', function () {
       tx.addInput(txHash, txIn.index, txIn.sequence, scriptSig)
 
       if (!noWitness && txIn.witness) {
-        const witness = txIn.witness.map(function (x) {
+        const witness = txIn.witness.map(x => {
           return Buffer.from(x, 'hex')
         })
 
@@ -31,7 +31,7 @@ describe('Transaction', function () {
       }
     })
 
-    raw.outs.forEach(function (txOut) {
+    raw.outs.forEach(txOut => {
       let script
 
       if (txOut.data) {
@@ -46,19 +46,19 @@ describe('Transaction', function () {
     return tx
   }
 
-  describe('fromBuffer/fromHex', function () {
+  describe('fromBuffer/fromHex', () => {
     function importExport (f) {
       const id = f.id || f.hash
       const txHex = f.hex || f.txHex
 
-      it('imports ' + f.description + ' (' + id + ')', function () {
+      it('imports ' + f.description + ' (' + id + ')', () => {
         const actual = Transaction.fromHex(txHex)
 
         assert.strictEqual(actual.toHex(), txHex)
       })
 
       if (f.whex) {
-        it('imports ' + f.description + ' (' + id + ') as witness', function () {
+        it('imports ' + f.description + ' (' + id + ') as witness', () => {
           const actual = Transaction.fromHex(f.whex)
 
           assert.strictEqual(actual.toHex(), f.whex)
@@ -70,38 +70,38 @@ describe('Transaction', function () {
     fixtures.hashForSignature.forEach(importExport)
     fixtures.hashForWitnessV0.forEach(importExport)
 
-    fixtures.invalid.fromBuffer.forEach(function (f) {
-      it('throws on ' + f.exception, function () {
-        assert.throws(function () {
+    fixtures.invalid.fromBuffer.forEach(f => {
+      it('throws on ' + f.exception, () => {
+        assert.throws(() => {
           Transaction.fromHex(f.hex)
         }, new RegExp(f.exception))
       })
     })
 
-    it('.version should be interpreted as an int32le', function () {
+    it('.version should be interpreted as an int32le', () => {
       const txHex = 'ffffffff0000ffffffff'
       const tx = Transaction.fromHex(txHex)
-      assert.equal(-1, tx.version)
-      assert.equal(0xffffffff, tx.locktime)
+      assert.strictEqual(-1, tx.version)
+      assert.strictEqual(0xffffffff, tx.locktime)
     })
   })
 
-  describe('toBuffer/toHex', function () {
-    fixtures.valid.forEach(function (f) {
-      it('exports ' + f.description + ' (' + f.id + ')', function () {
+  describe('toBuffer/toHex', () => {
+    fixtures.valid.forEach(f => {
+      it('exports ' + f.description + ' (' + f.id + ')', () => {
         const actual = fromRaw(f.raw, true)
         assert.strictEqual(actual.toHex(), f.hex)
       })
 
       if (f.whex) {
-        it('exports ' + f.description + ' (' + f.id + ') as witness', function () {
+        it('exports ' + f.description + ' (' + f.id + ') as witness', () => {
           const wactual = fromRaw(f.raw)
           assert.strictEqual(wactual.toHex(), f.whex)
         })
       }
     })
 
-    it('accepts target Buffer and offset parameters', function () {
+    it('accepts target Buffer and offset parameters', () => {
       const f = fixtures.valid[0]
       const actual = fromRaw(f.raw)
       const byteLength = actual.byteLength()
@@ -114,31 +114,31 @@ describe('Transaction', function () {
       assert.strictEqual(b.length, byteLength)
       assert.strictEqual(a.toString('hex'), f.hex)
       assert.strictEqual(b.toString('hex'), f.hex)
-      assert.deepEqual(a, b)
-      assert.deepEqual(a, target.slice(0, byteLength))
-      assert.deepEqual(b, target.slice(byteLength))
+      assert.deepStrictEqual(a, b)
+      assert.deepStrictEqual(a, target.slice(0, byteLength))
+      assert.deepStrictEqual(b, target.slice(byteLength))
     })
   })
 
-  describe('hasWitnesses', function () {
-    fixtures.valid.forEach(function (f) {
-      it('detects if the transaction has witnesses: ' + (f.whex ? 'true' : 'false'), function () {
+  describe('hasWitnesses', () => {
+    fixtures.valid.forEach(f => {
+      it('detects if the transaction has witnesses: ' + (f.whex ? 'true' : 'false'), () => {
         assert.strictEqual(Transaction.fromHex(f.whex ? f.whex : f.hex).hasWitnesses(), !!f.whex)
       })
     })
   })
 
-  describe('weight/virtualSize', function () {
-    it('computes virtual size', function () {
-      fixtures.valid.forEach(function (f) {
+  describe('weight/virtualSize', () => {
+    it('computes virtual size', () => {
+      fixtures.valid.forEach(f => {
         const transaction = Transaction.fromHex(f.whex ? f.whex : f.hex)
 
         assert.strictEqual(transaction.virtualSize(), f.virtualSize)
       })
     })
 
-    it('computes weight', function () {
-      fixtures.valid.forEach(function (f) {
+    it('computes weight', () => {
+      fixtures.valid.forEach(f => {
         const transaction = Transaction.fromHex(f.whex ? f.whex : f.hex)
 
         assert.strictEqual(transaction.weight(), f.weight)
@@ -146,19 +146,19 @@ describe('Transaction', function () {
     })
   })
 
-  describe('addInput', function () {
+  describe('addInput', () => {
     let prevTxHash
-    beforeEach(function () {
+    beforeEach(() => {
       prevTxHash = Buffer.from('ffffffff00ffff000000000000000000000000000000000000000000101010ff', 'hex')
     })
 
-    it('returns an index', function () {
+    it('returns an index', () => {
       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 () {
+    it('defaults to empty script, witness and 0xffffffff SEQUENCE number', () => {
       const tx = new Transaction()
       tx.addInput(prevTxHash, 0)
 
@@ -167,49 +167,49 @@ describe('Transaction', function () {
       assert.strictEqual(tx.ins[0].sequence, 0xffffffff)
     })
 
-    fixtures.invalid.addInput.forEach(function (f) {
-      it('throws on ' + f.exception, function () {
+    fixtures.invalid.addInput.forEach(f => {
+      it('throws on ' + f.exception, () => {
         const tx = new Transaction()
         const hash = Buffer.from(f.hash, 'hex')
 
-        assert.throws(function () {
+        assert.throws(() => {
           tx.addInput(hash, f.index)
         }, new RegExp(f.exception))
       })
     })
   })
 
-  describe('addOutput', function () {
-    it('returns an index', function () {
+  describe('addOutput', () => {
+    it('returns an index', () => {
       const tx = new Transaction()
       assert.strictEqual(tx.addOutput(Buffer.alloc(0), 0), 0)
       assert.strictEqual(tx.addOutput(Buffer.alloc(0), 0), 1)
     })
   })
 
-  describe('clone', function () {
-    fixtures.valid.forEach(function (f) {
+  describe('clone', () => {
+    fixtures.valid.forEach(f => {
       let actual
       let expected
 
-      beforeEach(function () {
+      beforeEach(() => {
         expected = Transaction.fromHex(f.hex)
         actual = expected.clone()
       })
 
-      it('should have value equality', function () {
-        assert.deepEqual(actual, expected)
+      it('should have value equality', () => {
+        assert.deepStrictEqual(actual, expected)
       })
 
-      it('should not have reference equality', function () {
-        assert.notEqual(actual, expected)
+      it('should not have reference equality', () => {
+        assert.notStrictEqual(actual, expected)
       })
     })
   })
 
-  describe('getHash/getId', function () {
+  describe('getHash/getId', () => {
     function verify (f) {
-      it('should return the id for ' + f.id + '(' + f.description + ')', function () {
+      it('should return the id for ' + f.id + '(' + f.description + ')', () => {
         const tx = Transaction.fromHex(f.whex || f.hex)
 
         assert.strictEqual(tx.getHash().toString('hex'), f.hash)
@@ -220,9 +220,9 @@ describe('Transaction', function () {
     fixtures.valid.forEach(verify)
   })
 
-  describe('isCoinbase', function () {
+  describe('isCoinbase', () => {
     function verify (f) {
-      it('should return ' + f.coinbase + ' for ' + f.id + '(' + f.description + ')', function () {
+      it('should return ' + f.coinbase + ' for ' + f.id + '(' + f.description + ')', () => {
         const tx = Transaction.fromHex(f.hex)
 
         assert.strictEqual(tx.isCoinbase(), f.coinbase)
@@ -232,8 +232,8 @@ describe('Transaction', function () {
     fixtures.valid.forEach(verify)
   })
 
-  describe('hashForSignature', function () {
-    it('does not use Witness serialization', function () {
+  describe('hashForSignature', () => {
+    it('does not use Witness serialization', () => {
       const randScript = Buffer.from('6a', 'hex')
 
       const tx = new Transaction()
@@ -241,24 +241,24 @@ describe('Transaction', function () {
       tx.addOutput(randScript, 5000000000)
 
       const original = tx.__toBuffer
-      tx.__toBuffer = function (a, b, c) {
+      tx.__toBuffer = (a, b, c) => {
         if (c !== false) throw new Error('hashForSignature MUST pass false')
 
         return original.call(this, a, b, c)
       }
 
-      assert.throws(function () {
+      assert.throws(() => {
         tx.__toBuffer(undefined, undefined, true)
       }, /hashForSignature MUST pass false/)
 
       // assert hashForSignature does not pass false
-      assert.doesNotThrow(function () {
+      assert.doesNotThrow(() => {
         tx.hashForSignature(0, randScript, 1)
       })
     })
 
-    fixtures.hashForSignature.forEach(function (f) {
-      it('should return ' + f.hash + ' for ' + (f.description ? ('case "' + f.description + '"') : f.script), function () {
+    fixtures.hashForSignature.forEach(f => {
+      it('should return ' + f.hash + ' for ' + (f.description ? ('case "' + f.description + '"') : f.script), () => {
         const tx = Transaction.fromHex(f.txHex)
         const script = bscript.fromASM(f.script)
 
@@ -267,9 +267,9 @@ describe('Transaction', function () {
     })
   })
 
-  describe('hashForWitnessV0', function () {
-    fixtures.hashForWitnessV0.forEach(function (f) {
-      it('should return ' + f.hash + ' for ' + (f.description ? ('case "' + f.description + '"') : ''), function () {
+  describe('hashForWitnessV0', () => {
+    fixtures.hashForWitnessV0.forEach(f => {
+      it('should return ' + f.hash + ' for ' + (f.description ? ('case "' + f.description + '"') : ''), () => {
         const tx = Transaction.fromHex(f.txHex)
         const script = bscript.fromASM(f.script)
 
@@ -278,9 +278,9 @@ describe('Transaction', function () {
     })
   })
 
-  describe('setWitness', function () {
-    it('only accepts a a witness stack (Array of Buffers)', function () {
-      assert.throws(function () {
+  describe('setWitness', () => {
+    it('only accepts a a witness stack (Array of Buffers)', () => {
+      assert.throws(() => {
         (new Transaction()).setWitness(0, 'foobar')
       }, /Expected property "1" of type \[Buffer], got String "foobar"/)
     })
diff --git a/test/transaction_builder.js b/test/transaction_builder.js
index 3f84b19..28aa545 100644
--- a/test/transaction_builder.js
+++ b/test/transaction_builder.js
@@ -15,9 +15,9 @@ function constructSign (f, txb) {
   const network = NETWORKS[f.network]
   const stages = f.stages && f.stages.concat()
 
-  f.inputs.forEach(function (input, index) {
+  f.inputs.forEach((input, index) => {
     if (!input.signs) return
-    input.signs.forEach(function (sign) {
+    input.signs.forEach(sign => {
       const keyPair = ECPair.fromWIF(sign.keyPair, network)
       let redeemScript
       let witnessScript
@@ -55,7 +55,7 @@ function construct (f, dontSign) {
   if (Number.isFinite(f.version)) txb.setVersion(f.version)
   if (f.locktime !== undefined) txb.setLockTime(f.locktime)
 
-  f.inputs.forEach(function (input) {
+  f.inputs.forEach(input => {
     let prevTx
     if (input.txRaw) {
       const constructed = construct(input.txRaw)
@@ -75,7 +75,7 @@ function construct (f, dontSign) {
     txb.addInput(prevTx, input.vout, input.sequence, prevTxScript)
   })
 
-  f.outputs.forEach(function (output) {
+  f.outputs.forEach(output => {
     if (output.address) {
       txb.addOutput(output.address, output.value)
     } else {
@@ -87,20 +87,20 @@ function construct (f, dontSign) {
   return constructSign(f, txb)
 }
 
-describe('TransactionBuilder', function () {
+describe('TransactionBuilder', () => {
   // constants
   const keyPair = ECPair.fromPrivateKey(Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex'))
   const scripts = [
     '1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH',
     '1cMh228HTCiwS8ZsaakH8A8wze1JR5ZsP'
-  ].map(function (x) {
+  ].map(x => {
     return baddress.toOutputScript(x)
   })
   const txHash = Buffer.from('0e7cea811c0be9f73c0aca591034396e7264473fc25c1ca45195d7417b36cbe2', 'hex')
 
-  describe('fromTransaction', function () {
-    fixtures.valid.build.forEach(function (f) {
-      it('returns TransactionBuilder, with ' + f.description, function () {
+  describe('fromTransaction', () => {
+    fixtures.valid.build.forEach(f => {
+      it('returns TransactionBuilder, with ' + f.description, () => {
         const network = NETWORKS[f.network || 'bitcoin']
 
         const tx = Transaction.fromHex(f.txHex)
@@ -112,82 +112,82 @@ describe('TransactionBuilder', function () {
       })
     })
 
-    fixtures.valid.fromTransaction.forEach(function (f) {
-      it('returns TransactionBuilder, with ' + f.description, function () {
+    fixtures.valid.fromTransaction.forEach(f => {
+      it('returns TransactionBuilder, with ' + f.description, () => {
         const tx = new Transaction()
 
-        f.inputs.forEach(function (input) {
+        f.inputs.forEach(input => {
           const txHash2 = Buffer.from(input.txId, 'hex').reverse()
 
           tx.addInput(txHash2, input.vout, undefined, bscript.fromASM(input.scriptSig))
         })
 
-        f.outputs.forEach(function (output) {
+        f.outputs.forEach(output => {
           tx.addOutput(bscript.fromASM(output.script), output.value)
         })
 
         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)
+        txAfter.ins.forEach((input, i) => {
+          assert.strictEqual(bscript.toASM(input.script), f.inputs[i].scriptSigAfter)
         })
 
-        txAfter.outs.forEach(function (output, i) {
-          assert.equal(bscript.toASM(output.script), f.outputs[i].script)
+        txAfter.outs.forEach((output, i) => {
+          assert.strictEqual(bscript.toASM(output.script), f.outputs[i].script)
         })
       })
     })
 
-    fixtures.valid.fromTransactionSequential.forEach(function (f) {
-      it('with ' + f.description, function () {
+    fixtures.valid.fromTransactionSequential.forEach(f => {
+      it('with ' + f.description, () => {
         const network = NETWORKS[f.network]
         const tx = Transaction.fromHex(f.txHex)
         const txb = TransactionBuilder.fromTransaction(tx, network)
 
-        tx.ins.forEach(function (input, i) {
-          assert.equal(bscript.toASM(input.script), f.inputs[i].scriptSig)
+        tx.ins.forEach((input, i) => {
+          assert.strictEqual(bscript.toASM(input.script), f.inputs[i].scriptSig)
         })
 
         constructSign(f, txb)
         const txAfter = f.incomplete ? txb.buildIncomplete() : txb.build()
 
-        txAfter.ins.forEach(function (input, i) {
-          assert.equal(bscript.toASM(input.script), f.inputs[i].scriptSigAfter)
+        txAfter.ins.forEach((input, i) => {
+          assert.strictEqual(bscript.toASM(input.script), f.inputs[i].scriptSigAfter)
         })
 
-        assert.equal(txAfter.toHex(), f.txHexAfter)
+        assert.strictEqual(txAfter.toHex(), f.txHexAfter)
       })
     })
 
-    it('classifies transaction inputs', function () {
+    it('classifies transaction inputs', () => {
       const tx = Transaction.fromHex(fixtures.valid.classification.hex)
       const txb = TransactionBuilder.fromTransaction(tx)
 
-      txb.__INPUTS.forEach(function (i) {
+      txb.__INPUTS.forEach(i => {
         assert.strictEqual(i.prevOutType, 'scripthash')
         assert.strictEqual(i.redeemScriptType, 'multisig')
       })
     })
 
-    fixtures.invalid.fromTransaction.forEach(function (f) {
-      it('throws ' + f.exception, function () {
+    fixtures.invalid.fromTransaction.forEach(f => {
+      it('throws ' + f.exception, () => {
         const tx = Transaction.fromHex(f.txHex)
 
-        assert.throws(function () {
+        assert.throws(() => {
           TransactionBuilder.fromTransaction(tx)
         }, new RegExp(f.exception))
       })
     })
   })
 
-  describe('addInput', function () {
+  describe('addInput', () => {
     let txb
-    beforeEach(function () {
+    beforeEach(() => {
       txb = new TransactionBuilder()
     })
 
-    it('accepts a txHash, index [and sequence number]', function () {
+    it('accepts a txHash, index [and sequence number]', () => {
       const vin = txb.addInput(txHash, 1, 54)
       assert.strictEqual(vin, 0)
 
@@ -198,7 +198,7 @@ describe('TransactionBuilder', function () {
       assert.strictEqual(txb.__INPUTS[0].prevOutScript, undefined)
     })
 
-    it('accepts a txHash, index [, sequence number and scriptPubKey]', function () {
+    it('accepts a txHash, index [, sequence number and scriptPubKey]', () => {
       const vin = txb.addInput(txHash, 1, 54, scripts[1])
       assert.strictEqual(vin, 0)
 
@@ -209,7 +209,7 @@ describe('TransactionBuilder', function () {
       assert.strictEqual(txb.__INPUTS[0].prevOutScript, scripts[1])
     })
 
-    it('accepts a prevTx, index [and sequence number]', function () {
+    it('accepts a prevTx, index [and sequence number]', () => {
       const prevTx = new Transaction()
       prevTx.addOutput(scripts[0], 0)
       prevTx.addOutput(scripts[1], 1)
@@ -218,116 +218,116 @@ describe('TransactionBuilder', function () {
       assert.strictEqual(vin, 0)
 
       const txIn = txb.__TX.ins[0]
-      assert.deepEqual(txIn.hash, prevTx.getHash())
+      assert.deepStrictEqual(txIn.hash, prevTx.getHash())
       assert.strictEqual(txIn.index, 1)
       assert.strictEqual(txIn.sequence, 54)
       assert.strictEqual(txb.__INPUTS[0].prevOutScript, scripts[1])
     })
 
-    it('returns the input index', function () {
+    it('returns the input index', () => {
       assert.strictEqual(txb.addInput(txHash, 0), 0)
       assert.strictEqual(txb.addInput(txHash, 1), 1)
     })
 
-    it('throws if SIGHASH_ALL has been used to sign any existing scriptSigs', function () {
+    it('throws if SIGHASH_ALL has been used to sign any existing scriptSigs', () => {
       txb.addInput(txHash, 0)
       txb.addOutput(scripts[0], 1000)
       txb.sign(0, keyPair)
 
-      assert.throws(function () {
+      assert.throws(() => {
         txb.addInput(txHash, 0)
       }, /No, this would invalidate signatures/)
     })
   })
 
-  describe('addOutput', function () {
+  describe('addOutput', () => {
     let txb
-    beforeEach(function () {
+    beforeEach(() => {
       txb = new TransactionBuilder()
     })
 
-    it('accepts an address string and value', function () {
+    it('accepts an address string and value', () => {
       const { address } = payments.p2pkh({ pubkey: keyPair.publicKey })
       const vout = txb.addOutput(address, 1000)
       assert.strictEqual(vout, 0)
 
       const txout = txb.__TX.outs[0]
-      assert.deepEqual(txout.script, scripts[0])
+      assert.deepStrictEqual(txout.script, scripts[0])
       assert.strictEqual(txout.value, 1000)
     })
 
-    it('accepts a ScriptPubKey and value', function () {
+    it('accepts a ScriptPubKey and value', () => {
       const vout = txb.addOutput(scripts[0], 1000)
       assert.strictEqual(vout, 0)
 
       const txout = txb.__TX.outs[0]
-      assert.deepEqual(txout.script, scripts[0])
+      assert.deepStrictEqual(txout.script, scripts[0])
       assert.strictEqual(txout.value, 1000)
     })
 
-    it('throws if address is of the wrong network', function () {
-      assert.throws(function () {
+    it('throws if address is of the wrong network', () => {
+      assert.throws(() => {
         txb.addOutput('2NGHjvjw83pcVFgMcA7QvSMh2c246rxLVz9', 1000)
       }, /2NGHjvjw83pcVFgMcA7QvSMh2c246rxLVz9 has no matching Script/)
     })
 
-    it('add second output after signed first input with SIGHASH_NONE', function () {
+    it('add second output after signed first input with SIGHASH_NONE', () => {
       txb.addInput(txHash, 0)
       txb.addOutput(scripts[0], 2000)
       txb.sign(0, keyPair, undefined, Transaction.SIGHASH_NONE)
-      assert.equal(txb.addOutput(scripts[1], 9000), 1)
+      assert.strictEqual(txb.addOutput(scripts[1], 9000), 1)
     })
 
-    it('add first output after signed first input with SIGHASH_NONE', function () {
+    it('add first output after signed first input with SIGHASH_NONE', () => {
       txb.addInput(txHash, 0)
       txb.sign(0, keyPair, undefined, Transaction.SIGHASH_NONE)
-      assert.equal(txb.addOutput(scripts[0], 2000), 0)
+      assert.strictEqual(txb.addOutput(scripts[0], 2000), 0)
     })
 
-    it('add second output after signed first input with SIGHASH_SINGLE', function () {
+    it('add second output after signed first input with SIGHASH_SINGLE', () => {
       txb.addInput(txHash, 0)
       txb.addOutput(scripts[0], 2000)
       txb.sign(0, keyPair, undefined, Transaction.SIGHASH_SINGLE)
-      assert.equal(txb.addOutput(scripts[1], 9000), 1)
+      assert.strictEqual(txb.addOutput(scripts[1], 9000), 1)
     })
 
-    it('add first output after signed first input with SIGHASH_SINGLE', function () {
+    it('add first output after signed first input with SIGHASH_SINGLE', () => {
       txb.addInput(txHash, 0)
       txb.sign(0, keyPair, undefined, Transaction.SIGHASH_SINGLE)
-      assert.throws(function () {
+      assert.throws(() => {
         txb.addOutput(scripts[0], 2000)
       }, /No, this would invalidate signatures/)
     })
 
-    it('throws if SIGHASH_ALL has been used to sign any existing scriptSigs', function () {
+    it('throws if SIGHASH_ALL has been used to sign any existing scriptSigs', () => {
       txb.addInput(txHash, 0)
       txb.addOutput(scripts[0], 2000)
       txb.sign(0, keyPair)
 
-      assert.throws(function () {
+      assert.throws(() => {
         txb.addOutput(scripts[1], 9000)
       }, /No, this would invalidate signatures/)
     })
   })
 
-  describe('setLockTime', function () {
-    it('throws if if there exist any scriptSigs', function () {
+  describe('setLockTime', () => {
+    it('throws if if there exist any scriptSigs', () => {
       const txb = new TransactionBuilder()
       txb.addInput(txHash, 0)
       txb.addOutput(scripts[0], 100)
       txb.sign(0, keyPair)
 
-      assert.throws(function () {
+      assert.throws(() => {
         txb.setLockTime(65535)
       }, /No, this would invalidate signatures/)
     })
   })
 
-  describe('sign', function () {
-    it('supports the alternative abstract interface { publicKey, sign }', function () {
+  describe('sign', () => {
+    it('supports the alternative abstract interface { publicKey, sign }', () => {
       const keyPair = {
-        publicKey: ECPair.makeRandom({ rng: function () { return Buffer.alloc(32, 1) } }).publicKey,
-        sign: function (hash) { return Buffer.alloc(64, 0x5f) }
+        publicKey: ECPair.makeRandom({ rng: () => { return Buffer.alloc(32, 1) } }).publicKey,
+        sign: hash => { return Buffer.alloc(64, 0x5f) }
       }
 
       const txb = new TransactionBuilder()
@@ -335,16 +335,16 @@ describe('TransactionBuilder', function () {
       txb.addInput('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', 1)
       txb.addOutput('1111111111111111111114oLvT2', 100000)
       txb.sign(0, keyPair)
-      assert.equal(txb.build().toHex(), '0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000006a47304402205f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f02205f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f0121031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078fffffffff01a0860100000000001976a914000000000000000000000000000000000000000088ac00000000')
+      assert.strictEqual(txb.build().toHex(), '0100000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff010000006a47304402205f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f02205f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f0121031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078fffffffff01a0860100000000001976a914000000000000000000000000000000000000000088ac00000000')
     })
 
-    fixtures.invalid.sign.forEach(function (f) {
-      it('throws ' + f.exception + (f.description ? ' (' + f.description + ')' : ''), function () {
+    fixtures.invalid.sign.forEach(f => {
+      it('throws ' + f.exception + (f.description ? ' (' + f.description + ')' : ''), () => {
         const txb = construct(f, true)
 
         let threw = false
-        f.inputs.forEach(function (input, index) {
-          input.signs.forEach(function (sign) {
+        f.inputs.forEach((input, index) => {
+          input.signs.forEach(sign => {
             const keyPairNetwork = NETWORKS[sign.network || f.network]
             const keyPair2 = ECPair.fromWIF(sign.keyPair, keyPairNetwork)
             let redeemScript
@@ -359,7 +359,7 @@ describe('TransactionBuilder', function () {
             }
 
             if (sign.throws) {
-              assert.throws(function () {
+              assert.throws(() => {
                 txb.sign(index, keyPair2, redeemScript, sign.hashType, sign.value, witnessScript)
               }, new RegExp(f.exception))
               threw = true
@@ -369,14 +369,14 @@ describe('TransactionBuilder', function () {
           })
         })
 
-        assert.equal(threw, true)
+        assert.strictEqual(threw, true)
       })
     })
   })
 
-  describe('build', function () {
-    fixtures.valid.build.forEach(function (f) {
-      it('builds "' + f.description + '"', function () {
+  describe('build', () => {
+    fixtures.valid.build.forEach(f => {
+      it('builds "' + f.description + '"', () => {
         const txb = construct(f)
         const tx = f.incomplete ? txb.buildIncomplete() : txb.build()
 
@@ -385,10 +385,10 @@ describe('TransactionBuilder', function () {
     })
 
     // TODO: remove duplicate test code
-    fixtures.invalid.build.forEach(function (f) {
-      describe('for ' + (f.description || f.exception), function () {
-        it('throws ' + f.exception, function () {
-          assert.throws(function () {
+    fixtures.invalid.build.forEach(f => {
+      describe('for ' + (f.description || f.exception), () => {
+        it('throws ' + f.exception, () => {
+          assert.throws(() => {
             let txb
             if (f.txHex) {
               txb = TransactionBuilder.fromTransaction(Transaction.fromHex(f.txHex))
@@ -402,8 +402,8 @@ describe('TransactionBuilder', function () {
 
         // if throws on incomplete too, enforce that
         if (f.incomplete) {
-          it('throws ' + f.exception, function () {
-            assert.throws(function () {
+          it('throws ' + f.exception, () => {
+            assert.throws(() => {
               let txb
               if (f.txHex) {
                 txb = TransactionBuilder.fromTransaction(Transaction.fromHex(f.txHex))
@@ -415,7 +415,7 @@ describe('TransactionBuilder', function () {
             }, new RegExp(f.exception))
           })
         } else {
-          it('does not throw if buildIncomplete', function () {
+          it('does not throw if buildIncomplete', () => {
             let txb
             if (f.txHex) {
               txb = TransactionBuilder.fromTransaction(Transaction.fromHex(f.txHex))
@@ -429,7 +429,7 @@ describe('TransactionBuilder', function () {
       })
     })
 
-    it('for incomplete with 0 signatures', function () {
+    it('for incomplete with 0 signatures', () => {
       const randomTxData = '0100000000010100010000000000000000000000000000000000000000000000000000000000000000000000ffffffff01e8030000000000001976a9144c9c3dfac4207d5d8cb89df5722cb3d712385e3f88ac02483045022100aa5d8aa40a90f23ce2c3d11bc845ca4a12acd99cbea37de6b9f6d86edebba8cb022022dedc2aa0a255f74d04c0b76ece2d7c691f9dd11a64a8ac49f62a99c3a05f9d01232103596d3451025c19dbbdeb932d6bf8bfb4ad499b95b6f88db8899efac102e5fc71ac00000000'
       const randomAddress = '1BgGZ9tcN4rm9KBzDn7KprQz87SZ26SAMH'
 
@@ -441,7 +441,7 @@ describe('TransactionBuilder', function () {
       assert(tx)
     })
 
-    it('for incomplete P2SH with 0 signatures', function () {
+    it('for incomplete P2SH with 0 signatures', () => {
       const inp = Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a80400000017a91471a8ec07ff69c6c4fee489184c462a9b1b9237488700000000', 'hex') // arbitrary P2SH input
       const inpTx = Transaction.fromBuffer(inp)
 
@@ -452,7 +452,7 @@ describe('TransactionBuilder', function () {
       txb.buildIncomplete()
     })
 
-    it('for incomplete P2WPKH with 0 signatures', function () {
+    it('for incomplete P2WPKH with 0 signatures', () => {
       const inp = Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a8040000001600141a15805e1f4040c9f68ccc887fca2e63547d794b00000000', 'hex')
       const inpTx = Transaction.fromBuffer(inp)
 
@@ -463,7 +463,7 @@ describe('TransactionBuilder', function () {
       txb.buildIncomplete()
     })
 
-    it('for incomplete P2WSH with 0 signatures', function () {
+    it('for incomplete P2WSH with 0 signatures', () => {
       const inpTx = Transaction.fromBuffer(Buffer.from('010000000173120703f67318aef51f7251272a6816d3f7523bb25e34b136d80be959391c100000000000ffffffff0100c817a80400000022002072df76fcc0b231b94bdf7d8c25d7eef4716597818d211e19ade7813bff7a250200000000', 'hex'))
 
       const txb = new TransactionBuilder(NETWORKS.testnet)
@@ -474,17 +474,17 @@ describe('TransactionBuilder', function () {
     })
   })
 
-  describe('multisig', function () {
-    fixtures.valid.multisig.forEach(function (f) {
-      it(f.description, function () {
+  describe('multisig', () => {
+    fixtures.valid.multisig.forEach(f => {
+      it(f.description, () => {
         const network = NETWORKS[f.network]
         let txb = construct(f, true)
         let tx
 
-        f.inputs.forEach(function (input, i) {
+        f.inputs.forEach((input, i) => {
           const redeemScript = bscript.fromASM(input.redeemScript)
 
-          input.signs.forEach(function (sign) {
+          input.signs.forEach(sign => {
             // rebuild the transaction each-time after the first
             if (tx) {
               // manually override the scriptSig?
@@ -513,10 +513,10 @@ describe('TransactionBuilder', function () {
     })
   })
 
-  describe('various edge case', function () {
+  describe('various edge case', () => {
     const network = NETWORKS.testnet
 
-    it('should warn of high fee for segwit transaction based on VSize, not Size', function () {
+    it('should warn of high fee for segwit transaction based on VSize, not Size', () => {
       const rawtx = '01000000000104fdaac89627208b4733484ca56bc291f4cf4fa8d7c5f29893c52b46788a0a' +
       '1df90000000000fffffffffdaac89627208b4733484ca56bc291f4cf4fa8d7c5f29893c52b46788a0a1df9' +
       '0100000000ffffffffa2ef7aaab316a3e5b5b0a78d1d35c774b95a079f9f0c762277a49caf1f26bca40000' +
@@ -538,12 +538,12 @@ describe('TransactionBuilder', function () {
       txb.__INPUTS[2].value = 248920
       txb.__INPUTS[3].value = 248920
 
-      assert.throws(function () {
+      assert.throws(() => {
         txb.build()
       }, new RegExp('Transaction has absurd fees'))
     })
 
-    it('should classify witness inputs with witness = true during multisigning', function () {
+    it('should classify witness inputs with witness = true during multisigning', () => {
       const keyPair = ECPair.fromWIF('cRAwuVuVSBZMPu7hdrYvMCZ8eevzmkExjFbaBLhqnDdrezxN3nTS', network)
       const witnessScript = Buffer.from('522102bbbd6eb01efcbe4bd9664b886f26f69de5afcb2e479d72596c8bf21929e352e22102d9c3f7180ef13ec5267723c9c2ffab56a4215241f837502ea8977c8532b9ea1952ae', 'hex')
       const redeemScript = Buffer.from('002024376a0a9abab599d0e028248d48ebe817bc899efcffa1cd2984d67289daf5af', 'hex')
@@ -558,13 +558,13 @@ describe('TransactionBuilder', function () {
       const tx = txb.buildIncomplete()
 
       // Only input is segwit, so txid should be accurate with the final tx
-      assert.equal(tx.getId(), 'f15d0a65b21b4471405b21a099f8b18e1ae4d46d55efbd0f4766cf11ad6cb821')
+      assert.strictEqual(tx.getId(), 'f15d0a65b21b4471405b21a099f8b18e1ae4d46d55efbd0f4766cf11ad6cb821')
 
       const txHex = tx.toHex()
       TransactionBuilder.fromTransaction(Transaction.fromHex(txHex))
     })
 
-    it('should handle badly pre-filled OP_0s', function () {
+    it('should handle badly pre-filled OP_0s', () => {
       // OP_0 is used where a signature is missing
       const redeemScripSig = bscript.fromASM('OP_0 OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae')
       const redeemScript = bscript.fromASM('OP_2 0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 04c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a 04f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e672 OP_3 OP_CHECKMULTISIG')
@@ -580,11 +580,11 @@ describe('TransactionBuilder', function () {
       txb.sign(0, keyPair2, redeemScript)
 
       const tx2 = txb.build()
-      assert.equal(tx2.getId(), 'eab59618a564e361adef6d918bd792903c3d41bcf1220137364fb847880467f9')
-      assert.equal(bscript.toASM(tx2.ins[0].script), 'OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae')
+      assert.strictEqual(tx2.getId(), 'eab59618a564e361adef6d918bd792903c3d41bcf1220137364fb847880467f9')
+      assert.strictEqual(bscript.toASM(tx2.ins[0].script), 'OP_0 3045022100daf0f4f3339d9fbab42b098045c1e4958ee3b308f4ae17be80b63808558d0adb02202f07e3d1f79dc8da285ae0d7f68083d769c11f5621ebd9691d6b48c0d4283d7d01 3045022100a346c61738304eac5e7702188764d19cdf68f4466196729db096d6c87ce18cdd022018c0e8ad03054b0e7e235cda6bedecf35881d7aa7d94ff425a8ace7220f38af001 52410479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b84104c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee51ae168fea63dc339a3c58419466ceaeef7f632653266d0e1236431a950cfe52a4104f9308a019258c31049344f85f89d5229b531c845836f99b08601f113bce036f9388f7b0f632de8140fe337e62a37f3566500a99934c2231b6cb9fd7584b8e67253ae')
     })
 
-    it('should not classify blank scripts as nonstandard', function () {
+    it('should not classify blank scripts as nonstandard', () => {
       let txb = new TransactionBuilder()
       txb.setVersion(1)
       txb.addInput('aa94ab02c182214f090e99a0d57021caffd0f195a81c24602b1028b130b63e31', 0)
@@ -596,14 +596,14 @@ describe('TransactionBuilder', function () {
       txb.addOutput('1Gokm82v6DmtwKEB8AiVhm82hyFSsEvBDK', 15000)
       txb.sign(0, keyPair)
       const txId = txb.build().getId()
-      assert.equal(txId, '54f097315acbaedb92a95455da3368eb45981cdae5ffbc387a9afc872c0f29b3')
+      assert.strictEqual(txId, '54f097315acbaedb92a95455da3368eb45981cdae5ffbc387a9afc872c0f29b3')
 
       // and, repeat
       txb = TransactionBuilder.fromTransaction(Transaction.fromHex(incomplete))
       txb.addOutput('1Gokm82v6DmtwKEB8AiVhm82hyFSsEvBDK', 15000)
       txb.sign(0, keyPair)
       const txId2 = txb.build().getId()
-      assert.equal(txId, txId2)
+      assert.strictEqual(txId, txId2)
     })
   })
 })
diff --git a/test/types.js b/test/types.js
index d245d53..8911ca1 100644
--- a/test/types.js
+++ b/test/types.js
@@ -3,38 +3,38 @@ const assert = require('assert')
 const types = require('../src/types')
 const typeforce = require('typeforce')
 
-describe('types', function () {
-  describe('Buffer Hash160/Hash256', function () {
+describe('types', () => {
+  describe('Buffer Hash160/Hash256', () => {
     const buffer20byte = Buffer.alloc(20)
     const buffer32byte = Buffer.alloc(32)
 
-    it('return true for valid size', function () {
+    it('return true for valid size', () => {
       assert(types.Hash160bit(buffer20byte))
       assert(types.Hash256bit(buffer32byte))
     })
 
-    it('return true for oneOf', function () {
-      assert.doesNotThrow(function () {
+    it('return true for oneOf', () => {
+      assert.doesNotThrow(() => {
         typeforce(types.oneOf(types.Hash160bit, types.Hash256bit), buffer32byte)
       })
 
-      assert.doesNotThrow(function () {
+      assert.doesNotThrow(() => {
         typeforce(types.oneOf(types.Hash256bit, types.Hash160bit), buffer32byte)
       })
     })
 
-    it('throws for invalid size', function () {
-      assert.throws(function () {
+    it('throws for invalid size', () => {
+      assert.throws(() => {
         types.Hash160bit(buffer32byte)
       }, /Expected Buffer\(Length: 20\), got Buffer\(Length: 32\)/)
 
-      assert.throws(function () {
+      assert.throws(() => {
         types.Hash256bit(buffer20byte)
       }, /Expected Buffer\(Length: 32\), got Buffer\(Length: 20\)/)
     })
   })
 
-  describe('Satoshi', function () {
+  describe('Satoshi', () => {
     [
       { value: -1, result: false },
       { value: 0, result: true },
@@ -42,8 +42,8 @@ describe('types', function () {
       { value: 20999999 * 1e8, result: true },
       { value: 21000000 * 1e8, result: true },
       { value: 21000001 * 1e8, result: false }
-    ].forEach(function (f) {
-      it('returns ' + f.result + ' for valid for ' + f.value, function () {
+    ].forEach(f => {
+      it('returns ' + f.result + ' for valid for ' + f.value, () => {
         assert.strictEqual(types.Satoshi(f.value), f.result)
       })
     })

From c77db1a14f3b08de38a068f28cef13bfe70b865c Mon Sep 17 00:00:00 2001
From: junderw <junderwood@bitcoinbank.co.jp>
Date: Tue, 9 Apr 2019 15:19:05 +0900
Subject: [PATCH 7/7] Only run docker in integration with cache

---
 .travis.yml                  | 8 +++++---
 test/integration/_regtest.js | 2 +-
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 7921fac..bb87738 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,9 +3,11 @@ language: node_js
 services:
   - docker
 before_install:
-  - docker pull junderw/bitcoinjs-regtest-server
-  - docker run -d -p 127.0.0.1:8080:8080 junderw/bitcoinjs-regtest-server
-  - docker ps -a
+  - if [ $TEST_SUITE = "integration" ]; then
+      docker pull junderw/bitcoinjs-regtest-server &&
+      docker run -d -p 127.0.0.1:8080:8080 junderw/bitcoinjs-regtest-server &&
+      docker ps -a;
+    fi
 node_js:
   - "8"
   - "lts/*"
diff --git a/test/integration/_regtest.js b/test/integration/_regtest.js
index abfee1a..8be864a 100644
--- a/test/integration/_regtest.js
+++ b/test/integration/_regtest.js
@@ -71,7 +71,7 @@ async function faucet (address, value) {
         }
       )
 
-    await sleep(randInt(50, 150))
+    await sleep(randInt(10, 40))
 
     const results = await unspents(address)