Browse Source

Merge pull request #1111 from bitcoinjs/varlet

s/var/let and s/var/const
addLowRGrinding
Daniel Cousens 7 years ago
committed by GitHub
parent
commit
d78bf6a2b9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 32
      src/address.js
  2. 52
      src/block.js
  3. 4
      src/bufferutils.js
  4. 2
      src/crypto.js
  5. 20
      src/ecpair.js
  6. 4
      src/index.js
  7. 46
      src/script.js
  8. 19
      src/script_number.js
  9. 32
      src/script_signature.js
  10. 26
      src/templates/index.js
  11. 18
      src/templates/multisig/input.js
  12. 22
      src/templates/multisig/output.js
  13. 10
      src/templates/nulldata.js
  14. 8
      src/templates/pubkey/input.js
  15. 10
      src/templates/pubkey/output.js
  16. 8
      src/templates/pubkeyhash/input.js
  17. 10
      src/templates/pubkeyhash/output.js
  18. 32
      src/templates/scripthash/input.js
  19. 10
      src/templates/scripthash/output.js
  20. 16
      src/templates/witnesscommitment/output.js
  21. 6
      src/templates/witnesspubkeyhash/input.js
  22. 10
      src/templates/witnesspubkeyhash/output.js
  23. 18
      src/templates/witnessscripthash/input.js
  24. 10
      src/templates/witnessscripthash/output.js
  25. 90
      src/transaction.js
  26. 186
      src/transaction_builder.js
  27. 12
      src/types.js
  28. 26
      test/address.js
  29. 116
      test/bitcoin.core.js
  30. 28
      test/block.js
  31. 16
      test/bufferutils.js
  32. 14
      test/crypto.js
  33. 78
      test/ecpair.js
  34. 16
      test/integration/_regtest.js
  35. 80
      test/integration/addresses.js
  36. 74
      test/integration/bip32.js
  37. 14
      test/integration/blocks.js
  38. 80
      test/integration/cltv.js
  39. 86
      test/integration/crypto.js
  40. 48
      test/integration/csv.js
  41. 108
      test/integration/stealth.js
  42. 88
      test/integration/transactions.js
  43. 42
      test/script.js
  44. 10
      test/script_number.js
  45. 16
      test/script_signature.js
  46. 138
      test/templates.js
  47. 83
      test/transaction.js
  48. 213
      test/transaction_builder.js
  49. 10
      test/types.js

32
src/address.js

@ -1,28 +1,28 @@
var Buffer = require('safe-buffer').Buffer
var bech32 = require('bech32')
var bs58check = require('bs58check')
var bscript = require('./script')
var btemplates = require('./templates')
var networks = require('./networks')
var typeforce = require('typeforce')
var types = require('./types')
const Buffer = require('safe-buffer').Buffer
const bech32 = require('bech32')
const bs58check = require('bs58check')
const bscript = require('./script')
const btemplates = require('./templates')
const networks = require('./networks')
const typeforce = require('typeforce')
const types = require('./types')
function fromBase58Check (address) {
var payload = bs58check.decode(address)
const payload = bs58check.decode(address)
// TODO: 4.0.0, move to "toOutputScript"
if (payload.length < 21) throw new TypeError(address + ' is too short')
if (payload.length > 21) throw new TypeError(address + ' is too long')
var version = payload.readUInt8(0)
var hash = payload.slice(1)
const version = payload.readUInt8(0)
const hash = payload.slice(1)
return { version: version, hash: hash }
}
function fromBech32 (address) {
var result = bech32.decode(address)
var data = bech32.fromWords(result.words.slice(1))
const result = bech32.decode(address)
const data = bech32.fromWords(result.words.slice(1))
return {
version: result.words[0],
@ -34,7 +34,7 @@ function fromBech32 (address) {
function toBase58Check (hash, version) {
typeforce(types.tuple(types.Hash160bit, types.UInt8), arguments)
var payload = Buffer.allocUnsafe(21)
const payload = Buffer.allocUnsafe(21)
payload.writeUInt8(version, 0)
hash.copy(payload, 1)
@ -42,7 +42,7 @@ function toBase58Check (hash, version) {
}
function toBech32 (data, version, prefix) {
var words = bech32.toWords(data)
const words = bech32.toWords(data)
words.unshift(version)
return bech32.encode(prefix, words)
@ -62,7 +62,7 @@ function fromOutputScript (outputScript, network) {
function toOutputScript (address, network) {
network = network || networks.bitcoin
var decode
let decode
try {
decode = fromBase58Check(address)
} catch (e) {}

52
src/block.js

@ -1,11 +1,11 @@
var Buffer = require('safe-buffer').Buffer
var bcrypto = require('./crypto')
var fastMerkleRoot = require('merkle-lib/fastRoot')
var typeforce = require('typeforce')
var types = require('./types')
var varuint = require('varuint-bitcoin')
const Buffer = require('safe-buffer').Buffer
const bcrypto = require('./crypto')
const fastMerkleRoot = require('merkle-lib/fastRoot')
const typeforce = require('typeforce')
const types = require('./types')
const varuint = require('varuint-bitcoin')
var Transaction = require('./transaction')
const Transaction = require('./transaction')
function Block () {
this.version = 1
@ -19,25 +19,25 @@ function Block () {
Block.fromBuffer = function (buffer) {
if (buffer.length < 80) throw new Error('Buffer too small (< 80 bytes)')
var offset = 0
let offset = 0
function readSlice (n) {
offset += n
return buffer.slice(offset - n, offset)
}
function readUInt32 () {
var i = buffer.readUInt32LE(offset)
const i = buffer.readUInt32LE(offset)
offset += 4
return i
}
function readInt32 () {
var i = buffer.readInt32LE(offset)
const i = buffer.readInt32LE(offset)
offset += 4
return i
}
var block = new Block()
const block = new Block()
block.version = readInt32()
block.prevHash = readSlice(32)
block.merkleRoot = readSlice(32)
@ -48,22 +48,22 @@ Block.fromBuffer = function (buffer) {
if (buffer.length === 80) return block
function readVarInt () {
var vi = varuint.decode(buffer, offset)
const vi = varuint.decode(buffer, offset)
offset += varuint.decode.bytes
return vi
}
function readTransaction () {
var tx = Transaction.fromBuffer(buffer.slice(offset), true)
const tx = Transaction.fromBuffer(buffer.slice(offset), true)
offset += tx.byteLength()
return tx
}
var nTransactions = readVarInt()
const nTransactions = readVarInt()
block.transactions = []
for (var i = 0; i < nTransactions; ++i) {
var tx = readTransaction()
const tx = readTransaction()
block.transactions.push(tx)
}
@ -91,7 +91,7 @@ Block.prototype.getId = function () {
}
Block.prototype.getUTCDate = function () {
var date = new Date(0) // epoch
const date = new Date(0) // epoch
date.setUTCSeconds(this.timestamp)
return date
@ -99,9 +99,9 @@ Block.prototype.getUTCDate = function () {
// TODO: buffer, offset compatibility
Block.prototype.toBuffer = function (headersOnly) {
var buffer = Buffer.allocUnsafe(this.byteLength(headersOnly))
const buffer = Buffer.allocUnsafe(this.byteLength(headersOnly))
var offset = 0
let offset = 0
function writeSlice (slice) {
slice.copy(buffer, offset)
offset += slice.length
@ -129,7 +129,7 @@ Block.prototype.toBuffer = function (headersOnly) {
offset += varuint.encode.bytes
this.transactions.forEach(function (tx) {
var txSize = tx.byteLength() // TODO: extract from toBuffer?
const txSize = tx.byteLength() // TODO: extract from toBuffer?
tx.toBuffer(buffer, offset)
offset += txSize
})
@ -142,9 +142,9 @@ Block.prototype.toHex = function (headersOnly) {
}
Block.calculateTarget = function (bits) {
var exponent = ((bits & 0xff000000) >> 24) - 3
var mantissa = bits & 0x007fffff
var target = Buffer.alloc(32, 0)
const exponent = ((bits & 0xff000000) >> 24) - 3
const mantissa = bits & 0x007fffff
const target = Buffer.alloc(32, 0)
target.writeUInt32BE(mantissa, 28 - exponent)
return target
}
@ -153,7 +153,7 @@ Block.calculateMerkleRoot = function (transactions) {
typeforce([{ getHash: types.Function }], transactions)
if (transactions.length === 0) throw TypeError('Cannot compute merkle root for zero transactions')
var hashes = transactions.map(function (transaction) {
const hashes = transactions.map(function (transaction) {
return transaction.getHash()
})
@ -163,13 +163,13 @@ Block.calculateMerkleRoot = function (transactions) {
Block.prototype.checkMerkleRoot = function () {
if (!this.transactions) return false
var actualMerkleRoot = Block.calculateMerkleRoot(this.transactions)
const actualMerkleRoot = Block.calculateMerkleRoot(this.transactions)
return this.merkleRoot.compare(actualMerkleRoot) === 0
}
Block.prototype.checkProofOfWork = function () {
var hash = this.getHash().reverse()
var target = Block.calculateTarget(this.bits)
const hash = this.getHash().reverse()
const target = Block.calculateTarget(this.bits)
return hash.compare(target) <= 0
}

4
src/bufferutils.js

@ -7,8 +7,8 @@ function verifuint (value, max) {
}
function readUInt64LE (buffer, offset) {
var a = buffer.readUInt32LE(offset)
var b = buffer.readUInt32LE(offset + 4)
const a = buffer.readUInt32LE(offset)
let b = buffer.readUInt32LE(offset + 4)
b *= 0x100000000
verifuint(b + a, 0x001fffffffffffff)

2
src/crypto.js

@ -1,4 +1,4 @@
var createHash = require('create-hash')
const createHash = require('create-hash')
function ripemd160 (buffer) {
return createHash('rmd160').update(buffer).digest()

20
src/ecpair.js

@ -1,14 +1,14 @@
let ecc = require('tiny-secp256k1')
let randomBytes = require('randombytes')
let typeforce = require('typeforce')
let types = require('./types')
let wif = require('wif')
const ecc = require('tiny-secp256k1')
const randomBytes = require('randombytes')
const typeforce = require('typeforce')
const types = require('./types')
const wif = require('wif')
let NETWORKS = require('./networks')
const NETWORKS = require('./networks')
// TODO: why is the function name toJSON weird?
function isPoint (x) { return ecc.isPoint(x) }
let isOptions = typeforce.maybe(typeforce.compile({
const isOptions = typeforce.maybe(typeforce.compile({
compressed: types.maybe(types.Boolean),
network: types.maybe(types.Network)
}))
@ -63,8 +63,8 @@ function fromPublicKey (buffer, options) {
}
function fromWIF (string, network) {
let decoded = wif.decode(string)
let version = decoded.version
const decoded = wif.decode(string)
const version = decoded.version
// list of networks?
if (types.Array(network)) {
@ -90,7 +90,7 @@ function fromWIF (string, network) {
function makeRandom (options) {
typeforce(isOptions, options)
options = options || {}
let rng = options.rng || randomBytes
const rng = options.rng || randomBytes
let d
do {

4
src/index.js

@ -1,5 +1,5 @@
let script = require('./script')
let templates = require('./templates')
const script = require('./script')
const templates = require('./templates')
for (let key in templates) {
script[key] = templates[key]
}

46
src/script.js

@ -1,14 +1,14 @@
var Buffer = require('safe-buffer').Buffer
var bip66 = require('bip66')
let ecc = require('tiny-secp256k1')
var pushdata = require('pushdata-bitcoin')
var typeforce = require('typeforce')
var types = require('./types')
var scriptNumber = require('./script_number')
var OPS = require('bitcoin-ops')
var REVERSE_OPS = require('bitcoin-ops/map')
var OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1
const Buffer = require('safe-buffer').Buffer
const bip66 = require('bip66')
const ecc = require('tiny-secp256k1')
const pushdata = require('pushdata-bitcoin')
const typeforce = require('typeforce')
const types = require('./types')
const scriptNumber = require('./script_number')
const OPS = require('bitcoin-ops')
const REVERSE_OPS = require('bitcoin-ops/map')
const OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1
function isOPInt (value) {
return types.Number(value) &&
@ -38,7 +38,7 @@ function compile (chunks) {
typeforce(types.Array, chunks)
var bufferSize = chunks.reduce(function (accum, chunk) {
const bufferSize = chunks.reduce(function (accum, chunk) {
// data chunk
if (Buffer.isBuffer(chunk)) {
// adhere to BIP62.3, minimal push policy
@ -53,14 +53,14 @@ function compile (chunks) {
return accum + 1
}, 0.0)
var buffer = Buffer.allocUnsafe(bufferSize)
var offset = 0
const buffer = Buffer.allocUnsafe(bufferSize)
let offset = 0
chunks.forEach(function (chunk) {
// data chunk
if (Buffer.isBuffer(chunk)) {
// adhere to BIP62.3, minimal push policy
var opcode = asMinimalOP(chunk)
const opcode = asMinimalOP(chunk)
if (opcode !== undefined) {
buffer.writeUInt8(opcode, offset)
offset += 1
@ -88,15 +88,15 @@ function decompile (buffer) {
typeforce(types.Buffer, buffer)
var chunks = []
var i = 0
const chunks = []
let i = 0
while (i < buffer.length) {
var opcode = buffer[i]
const opcode = buffer[i]
// data chunk
if ((opcode > OPS.OP_0) && (opcode <= OPS.OP_PUSHDATA4)) {
var d = pushdata.decode(buffer, i)
const d = pushdata.decode(buffer, i)
// did reading a pushDataInt fail? empty script
if (d === null) return null
@ -105,11 +105,11 @@ function decompile (buffer) {
// attempt to read too much data? empty script
if (i + d.number > buffer.length) return null
var data = buffer.slice(i, i + d.number)
const data = buffer.slice(i, i + d.number)
i += d.number
// decompile minimally
var op = asMinimalOP(data)
const op = asMinimalOP(data)
if (op !== undefined) {
chunks.push(op)
} else {
@ -135,7 +135,7 @@ function toASM (chunks) {
return chunks.map(function (chunk) {
// data?
if (Buffer.isBuffer(chunk)) {
var op = asMinimalOP(chunk)
const op = asMinimalOP(chunk)
if (op === undefined) return chunk.toString('hex')
chunk = op
}
@ -175,7 +175,7 @@ function isCanonicalPubKey (buffer) {
}
function isDefinedHashType (hashType) {
var hashTypeMod = hashType & ~0x80
const hashTypeMod = hashType & ~0x80
// return hashTypeMod > SIGHASH_ALL && hashTypeMod < SIGHASH_SINGLE
return hashTypeMod > 0x00 && hashTypeMod < 0x04

19
src/script_number.js

@ -1,10 +1,10 @@
var Buffer = require('safe-buffer').Buffer
const Buffer = require('safe-buffer').Buffer
function decode (buffer, maxLength, minimal) {
maxLength = maxLength || 4
minimal = minimal === undefined ? true : minimal
var length = buffer.length
const length = buffer.length
if (length === 0) return 0
if (length > maxLength) throw new TypeError('Script number overflow')
if (minimal) {
@ -15,16 +15,15 @@ function decode (buffer, maxLength, minimal) {
// 40-bit
if (length === 5) {
var a = buffer.readUInt32LE(0)
var b = buffer.readUInt8(4)
const a = buffer.readUInt32LE(0)
const b = buffer.readUInt8(4)
if (b & 0x80) return -(((b & ~0x80) * 0x100000000) + a)
return (b * 0x100000000) + a
}
var result = 0
// 32-bit / 24-bit / 16-bit / 8-bit
let result = 0
for (var i = 0; i < length; ++i) {
result |= buffer[i] << (8 * i)
}
@ -43,10 +42,10 @@ function scriptNumSize (i) {
}
function encode (number) {
var value = Math.abs(number)
var size = scriptNumSize(value)
var buffer = Buffer.allocUnsafe(size)
var negative = number < 0
let value = Math.abs(number)
const size = scriptNumSize(value)
const buffer = Buffer.allocUnsafe(size)
const negative = number < 0
for (var i = 0; i < size; ++i) {
buffer.writeUInt8(value & 0xff, i)

32
src/script_signature.js

@ -1,9 +1,9 @@
let bip66 = require('bip66')
let Buffer = require('safe-buffer').Buffer
let typeforce = require('typeforce')
let types = require('./types')
const bip66 = require('bip66')
const Buffer = require('safe-buffer').Buffer
const typeforce = require('typeforce')
const types = require('./types')
let ZERO = Buffer.alloc(1, 0)
const ZERO = Buffer.alloc(1, 0)
function toDER (x) {
let i = 0
while (x[i] === 0) ++i
@ -15,21 +15,21 @@ function toDER (x) {
function fromDER (x) {
if (x[0] === 0x00) x = x.slice(1)
let buffer = Buffer.alloc(32, 0)
let bstart = Math.max(0, 32 - x.length)
const buffer = Buffer.alloc(32, 0)
const bstart = Math.max(0, 32 - x.length)
x.copy(buffer, bstart)
return buffer
}
// BIP62: 1 byte hashType flag (only 0x01, 0x02, 0x03, 0x81, 0x82 and 0x83 are allowed)
function decode (buffer) {
let hashType = buffer.readUInt8(buffer.length - 1)
let hashTypeMod = hashType & ~0x80
const hashType = buffer.readUInt8(buffer.length - 1)
const hashTypeMod = hashType & ~0x80
if (hashTypeMod <= 0 || hashTypeMod >= 4) throw new Error('Invalid hashType ' + hashType)
let decode = bip66.decode(buffer.slice(0, -1))
let r = fromDER(decode.r)
let s = fromDER(decode.s)
const decode = bip66.decode(buffer.slice(0, -1))
const r = fromDER(decode.r)
const s = fromDER(decode.s)
return {
signature: Buffer.concat([r, s], 64),
@ -43,14 +43,14 @@ function encode (signature, hashType) {
hashType: types.UInt8
}, { signature, hashType })
let hashTypeMod = hashType & ~0x80
const hashTypeMod = hashType & ~0x80
if (hashTypeMod <= 0 || hashTypeMod >= 4) throw new Error('Invalid hashType ' + hashType)
let hashTypeBuffer = Buffer.allocUnsafe(1)
const hashTypeBuffer = Buffer.allocUnsafe(1)
hashTypeBuffer.writeUInt8(hashType, 0)
let r = toDER(signature.slice(0, 32))
let s = toDER(signature.slice(32, 64))
const r = toDER(signature.slice(0, 32))
const s = toDER(signature.slice(32, 64))
return Buffer.concat([
bip66.encode(r, s),

26
src/templates/index.js

@ -1,14 +1,14 @@
var decompile = require('../script').decompile
var multisig = require('./multisig')
var nullData = require('./nulldata')
var pubKey = require('./pubkey')
var pubKeyHash = require('./pubkeyhash')
var scriptHash = require('./scripthash')
var witnessPubKeyHash = require('./witnesspubkeyhash')
var witnessScriptHash = require('./witnessscripthash')
var witnessCommitment = require('./witnesscommitment')
const decompile = require('../script').decompile
const multisig = require('./multisig')
const nullData = require('./nulldata')
const pubKey = require('./pubkey')
const pubKeyHash = require('./pubkeyhash')
const scriptHash = require('./scripthash')
const witnessPubKeyHash = require('./witnesspubkeyhash')
const witnessScriptHash = require('./witnessscripthash')
const witnessCommitment = require('./witnesscommitment')
var types = {
const types = {
MULTISIG: 'multisig',
NONSTANDARD: 'nonstandard',
NULLDATA: 'nulldata',
@ -27,7 +27,7 @@ function classifyOutput (script) {
if (scriptHash.output.check(script)) return types.P2SH
// XXX: optimization, below functions .decompile before use
var chunks = decompile(script)
const chunks = decompile(script)
if (!chunks) throw new TypeError('Invalid script')
if (multisig.output.check(chunks)) return types.MULTISIG
@ -40,7 +40,7 @@ function classifyOutput (script) {
function classifyInput (script, allowIncomplete) {
// XXX: optimization, below functions .decompile before use
var chunks = decompile(script)
const chunks = decompile(script)
if (!chunks) throw new TypeError('Invalid script')
if (pubKeyHash.input.check(chunks)) return types.P2PKH
@ -53,7 +53,7 @@ function classifyInput (script, allowIncomplete) {
function classifyWitness (script, allowIncomplete) {
// XXX: optimization, below functions .decompile before use
var chunks = decompile(script)
const chunks = decompile(script)
if (!chunks) throw new TypeError('Invalid script')
if (witnessPubKeyHash.input.check(chunks)) return types.P2WPKH

18
src/templates/multisig/input.js

@ -1,17 +1,17 @@
// OP_0 [signatures ...]
var Buffer = require('safe-buffer').Buffer
var bscript = require('../../script')
var p2mso = require('./output')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
const Buffer = require('safe-buffer').Buffer
const bscript = require('../../script')
const p2mso = require('./output')
const typeforce = require('typeforce')
const OPS = require('bitcoin-ops')
function partialSignature (value) {
return value === OPS.OP_0 || bscript.isCanonicalScriptSignature(value)
}
function check (script, allowIncomplete) {
var chunks = bscript.decompile(script)
const chunks = bscript.decompile(script)
if (chunks.length < 2) return false
if (chunks[0] !== OPS.OP_0) return false
@ -23,13 +23,13 @@ function check (script, allowIncomplete) {
}
check.toJSON = function () { return 'multisig input' }
var EMPTY_BUFFER = Buffer.allocUnsafe(0)
const EMPTY_BUFFER = Buffer.allocUnsafe(0)
function encodeStack (signatures, scriptPubKey) {
typeforce([partialSignature], signatures)
if (scriptPubKey) {
var scriptData = p2mso.decode(scriptPubKey)
const scriptData = p2mso.decode(scriptPubKey)
if (signatures.length < scriptData.m) {
throw new TypeError('Not enough signatures provided')
@ -59,7 +59,7 @@ function decodeStack (stack, allowIncomplete) {
}
function decode (buffer, allowIncomplete) {
var stack = bscript.decompile(buffer)
const stack = bscript.decompile(buffer)
return decodeStack(stack, allowIncomplete)
}

22
src/templates/multisig/output.js

@ -1,20 +1,20 @@
// m [pubKeys ...] n OP_CHECKMULTISIG
var bscript = require('../../script')
var types = require('../../types')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
var OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1
const bscript = require('../../script')
const types = require('../../types')
const typeforce = require('typeforce')
const OPS = require('bitcoin-ops')
const OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1
function check (script, allowIncomplete) {
var chunks = bscript.decompile(script)
const chunks = bscript.decompile(script)
if (chunks.length < 4) return false
if (chunks[chunks.length - 1] !== OPS.OP_CHECKMULTISIG) return false
if (!types.Number(chunks[0])) return false
if (!types.Number(chunks[chunks.length - 2])) return false
var m = chunks[0] - OP_INT_BASE
var n = chunks[chunks.length - 2] - OP_INT_BASE
const m = chunks[0] - OP_INT_BASE
const n = chunks[chunks.length - 2] - OP_INT_BASE
if (m <= 0) return false
if (n > 16) return false
@ -22,7 +22,7 @@ function check (script, allowIncomplete) {
if (n !== chunks.length - 3) return false
if (allowIncomplete) return true
var keys = chunks.slice(1, -2)
const keys = chunks.slice(1, -2)
return keys.every(bscript.isCanonicalPubKey)
}
check.toJSON = function () { return 'multi-sig output' }
@ -36,7 +36,7 @@ function encode (m, pubKeys) {
pubKeys: pubKeys
})
var n = pubKeys.length
const n = pubKeys.length
if (n < m) throw new TypeError('Not enough pubKeys provided')
return bscript.compile([].concat(
@ -48,7 +48,7 @@ function encode (m, pubKeys) {
}
function decode (buffer, allowIncomplete) {
var chunks = bscript.decompile(buffer)
const chunks = bscript.decompile(buffer)
typeforce(check, chunks, allowIncomplete)
return {

10
src/templates/nulldata.js

@ -1,12 +1,12 @@
// OP_RETURN {data}
var bscript = require('../script')
var types = require('../types')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
const bscript = require('../script')
const types = require('../types')
const typeforce = require('typeforce')
const OPS = require('bitcoin-ops')
function check (script) {
var buffer = bscript.compile(script)
const buffer = bscript.compile(script)
return buffer.length > 1 &&
buffer[0] === OPS.OP_RETURN

8
src/templates/pubkey/input.js

@ -1,10 +1,10 @@
// {signature}
var bscript = require('../../script')
var typeforce = require('typeforce')
const bscript = require('../../script')
const typeforce = require('typeforce')
function check (script) {
var chunks = bscript.decompile(script)
const chunks = bscript.decompile(script)
return chunks.length === 1 &&
bscript.isCanonicalScriptSignature(chunks[0])
@ -27,7 +27,7 @@ function decodeStack (stack) {
}
function decode (buffer) {
var stack = bscript.decompile(buffer)
const stack = bscript.decompile(buffer)
return decodeStack(stack)
}

10
src/templates/pubkey/output.js

@ -1,11 +1,11 @@
// {pubKey} OP_CHECKSIG
var bscript = require('../../script')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
const bscript = require('../../script')
const typeforce = require('typeforce')
const OPS = require('bitcoin-ops')
function check (script) {
var chunks = bscript.decompile(script)
const chunks = bscript.decompile(script)
return chunks.length === 2 &&
bscript.isCanonicalPubKey(chunks[0]) &&
@ -20,7 +20,7 @@ function encode (pubKey) {
}
function decode (buffer) {
var chunks = bscript.decompile(buffer)
const chunks = bscript.decompile(buffer)
typeforce(check, chunks)
return chunks[0]

8
src/templates/pubkeyhash/input.js

@ -1,10 +1,10 @@
// {signature} {pubKey}
var bscript = require('../../script')
var typeforce = require('typeforce')
const bscript = require('../../script')
const typeforce = require('typeforce')
function check (script) {
var chunks = bscript.decompile(script)
const chunks = bscript.decompile(script)
return chunks.length === 2 &&
bscript.isCanonicalScriptSignature(chunks[0]) &&
@ -39,7 +39,7 @@ function decodeStack (stack) {
}
function decode (buffer) {
var stack = bscript.decompile(buffer)
const stack = bscript.decompile(buffer)
return decodeStack(stack)
}

10
src/templates/pubkeyhash/output.js

@ -1,12 +1,12 @@
// OP_DUP OP_HASH160 {pubKeyHash} OP_EQUALVERIFY OP_CHECKSIG
var bscript = require('../../script')
var types = require('../../types')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
const bscript = require('../../script')
const types = require('../../types')
const typeforce = require('typeforce')
const OPS = require('bitcoin-ops')
function check (script) {
var buffer = bscript.compile(script)
const buffer = bscript.compile(script)
return buffer.length === 25 &&
buffer[0] === OPS.OP_DUP &&

32
src/templates/scripthash/input.js

@ -1,24 +1,24 @@
// <scriptSig> {serialized scriptPubKey script}
var Buffer = require('safe-buffer').Buffer
var bscript = require('../../script')
var typeforce = require('typeforce')
const Buffer = require('safe-buffer').Buffer
const bscript = require('../../script')
const typeforce = require('typeforce')
var p2ms = require('../multisig/')
var p2pk = require('../pubkey/')
var p2pkh = require('../pubkeyhash/')
var p2wpkho = require('../witnesspubkeyhash/output')
var p2wsho = require('../witnessscripthash/output')
const p2ms = require('../multisig/')
const p2pk = require('../pubkey/')
const p2pkh = require('../pubkeyhash/')
const p2wpkho = require('../witnesspubkeyhash/output')
const p2wsho = require('../witnessscripthash/output')
function check (script, allowIncomplete) {
var chunks = bscript.decompile(script)
const chunks = bscript.decompile(script)
if (chunks.length < 1) return false
var lastChunk = chunks[chunks.length - 1]
const lastChunk = chunks[chunks.length - 1]
if (!Buffer.isBuffer(lastChunk)) return false
var scriptSigChunks = bscript.decompile(bscript.compile(chunks.slice(0, -1)))
var redeemScriptChunks = bscript.decompile(lastChunk)
const scriptSigChunks = bscript.decompile(bscript.compile(chunks.slice(0, -1)))
const redeemScriptChunks = bscript.decompile(lastChunk)
// is redeemScript a valid script?
if (!redeemScriptChunks) return false
@ -47,13 +47,13 @@ function check (script, allowIncomplete) {
check.toJSON = function () { return 'scriptHash input' }
function encodeStack (redeemScriptStack, redeemScript) {
var serializedScriptPubKey = bscript.compile(redeemScript)
const serializedScriptPubKey = bscript.compile(redeemScript)
return [].concat(redeemScriptStack, serializedScriptPubKey)
}
function encode (redeemScriptSig, redeemScript) {
var redeemScriptStack = bscript.decompile(redeemScriptSig)
const redeemScriptStack = bscript.decompile(redeemScriptSig)
return bscript.compile(encodeStack(redeemScriptStack, redeemScript))
}
@ -69,8 +69,8 @@ function decodeStack (stack) {
}
function decode (buffer) {
var stack = bscript.decompile(buffer)
var result = decodeStack(stack)
const stack = bscript.decompile(buffer)
const result = decodeStack(stack)
result.redeemScriptSig = bscript.compile(result.redeemScriptStack)
delete result.redeemScriptStack
return result

10
src/templates/scripthash/output.js

@ -1,12 +1,12 @@
// OP_HASH160 {scriptHash} OP_EQUAL
var bscript = require('../../script')
var types = require('../../types')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
const bscript = require('../../script')
const types = require('../../types')
const typeforce = require('typeforce')
const OPS = require('bitcoin-ops')
function check (script) {
var buffer = bscript.compile(script)
const buffer = bscript.compile(script)
return buffer.length === 23 &&
buffer[0] === OPS.OP_HASH160 &&

16
src/templates/witnesscommitment/output.js

@ -1,15 +1,15 @@
// OP_RETURN {aa21a9ed} {commitment}
var Buffer = require('safe-buffer').Buffer
var bscript = require('../../script')
var types = require('../../types')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
const Buffer = require('safe-buffer').Buffer
const bscript = require('../../script')
const types = require('../../types')
const typeforce = require('typeforce')
const OPS = require('bitcoin-ops')
var HEADER = Buffer.from('aa21a9ed', 'hex')
const HEADER = Buffer.from('aa21a9ed', 'hex')
function check (script) {
var buffer = bscript.compile(script)
const buffer = bscript.compile(script)
return buffer.length > 37 &&
buffer[0] === OPS.OP_RETURN &&
@ -22,7 +22,7 @@ check.toJSON = function () { return 'Witness commitment output' }
function encode (commitment) {
typeforce(types.Hash256bit, commitment)
var buffer = Buffer.allocUnsafe(36)
const buffer = Buffer.allocUnsafe(36)
HEADER.copy(buffer, 0)
commitment.copy(buffer, 4)

6
src/templates/witnesspubkeyhash/input.js

@ -1,14 +1,14 @@
// {signature} {pubKey}
var bscript = require('../../script')
var typeforce = require('typeforce')
const bscript = require('../../script')
const typeforce = require('typeforce')
function isCompressedCanonicalPubKey (pubKey) {
return bscript.isCanonicalPubKey(pubKey) && pubKey.length === 33
}
function check (script) {
var chunks = bscript.decompile(script)
const chunks = bscript.decompile(script)
return chunks.length === 2 &&
bscript.isCanonicalScriptSignature(chunks[0]) &&

10
src/templates/witnesspubkeyhash/output.js

@ -1,12 +1,12 @@
// OP_0 {pubKeyHash}
var bscript = require('../../script')
var types = require('../../types')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
const bscript = require('../../script')
const types = require('../../types')
const typeforce = require('typeforce')
const OPS = require('bitcoin-ops')
function check (script) {
var buffer = bscript.compile(script)
const buffer = bscript.compile(script)
return buffer.length === 22 &&
buffer[0] === OPS.OP_0 &&

18
src/templates/witnessscripthash/input.js

@ -1,26 +1,26 @@
// <scriptSig> {serialized scriptPubKey script}
var bscript = require('../../script')
var types = require('../../types')
var typeforce = require('typeforce')
const bscript = require('../../script')
const types = require('../../types')
const typeforce = require('typeforce')
var p2ms = require('../multisig/')
var p2pk = require('../pubkey/')
var p2pkh = require('../pubkeyhash/')
const p2ms = require('../multisig/')
const p2pk = require('../pubkey/')
const p2pkh = require('../pubkeyhash/')
function check (chunks, allowIncomplete) {
typeforce(types.Array, chunks)
if (chunks.length < 1) return false
var witnessScript = chunks[chunks.length - 1]
const witnessScript = chunks[chunks.length - 1]
if (!Buffer.isBuffer(witnessScript)) return false
var witnessScriptChunks = bscript.decompile(witnessScript)
const witnessScriptChunks = bscript.decompile(witnessScript)
// is witnessScript a valid script?
if (witnessScriptChunks.length === 0) return false
var witnessRawScriptSig = bscript.compile(chunks.slice(0, -1))
const witnessRawScriptSig = bscript.compile(chunks.slice(0, -1))
// match types
if (p2pkh.input.check(witnessRawScriptSig) &&

10
src/templates/witnessscripthash/output.js

@ -1,12 +1,12 @@
// OP_0 {scriptHash}
var bscript = require('../../script')
var types = require('../../types')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
const bscript = require('../../script')
const types = require('../../types')
const typeforce = require('typeforce')
const OPS = require('bitcoin-ops')
function check (script) {
var buffer = bscript.compile(script)
const buffer = bscript.compile(script)
return buffer.length === 34 &&
buffer[0] === OPS.OP_0 &&

90
src/transaction.js

@ -1,20 +1,20 @@
var Buffer = require('safe-buffer').Buffer
var bcrypto = require('./crypto')
var bscript = require('./script')
var bufferutils = require('./bufferutils')
var opcodes = require('bitcoin-ops')
var typeforce = require('typeforce')
var types = require('./types')
var varuint = require('varuint-bitcoin')
const Buffer = require('safe-buffer').Buffer
const bcrypto = require('./crypto')
const bscript = require('./script')
const bufferutils = require('./bufferutils')
const opcodes = require('bitcoin-ops')
const typeforce = require('typeforce')
const types = require('./types')
const varuint = require('varuint-bitcoin')
function varSliceSize (someScript) {
var length = someScript.length
const length = someScript.length
return varuint.encodingLength(length) + length
}
function vectorSize (someVector) {
var length = someVector.length
const length = someVector.length
return varuint.encodingLength(length) + someVector.reduce(function (sum, witness) {
return sum + varSliceSize(witness)
@ -36,43 +36,43 @@ Transaction.SIGHASH_ANYONECANPAY = 0x80
Transaction.ADVANCED_TRANSACTION_MARKER = 0x00
Transaction.ADVANCED_TRANSACTION_FLAG = 0x01
var EMPTY_SCRIPT = Buffer.allocUnsafe(0)
var EMPTY_WITNESS = []
var ZERO = Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex')
var ONE = Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex')
var VALUE_UINT64_MAX = Buffer.from('ffffffffffffffff', 'hex')
var BLANK_OUTPUT = {
const EMPTY_SCRIPT = Buffer.allocUnsafe(0)
const EMPTY_WITNESS = []
const ZERO = Buffer.from('0000000000000000000000000000000000000000000000000000000000000000', 'hex')
const ONE = Buffer.from('0000000000000000000000000000000000000000000000000000000000000001', 'hex')
const VALUE_UINT64_MAX = Buffer.from('ffffffffffffffff', 'hex')
const BLANK_OUTPUT = {
script: EMPTY_SCRIPT,
valueBuffer: VALUE_UINT64_MAX
}
Transaction.fromBuffer = function (buffer, __noStrict) {
var offset = 0
let offset = 0
function readSlice (n) {
offset += n
return buffer.slice(offset - n, offset)
}
function readUInt32 () {
var i = buffer.readUInt32LE(offset)
const i = buffer.readUInt32LE(offset)
offset += 4
return i
}
function readInt32 () {
var i = buffer.readInt32LE(offset)
const i = buffer.readInt32LE(offset)
offset += 4
return i
}
function readUInt64 () {
var i = bufferutils.readUInt64LE(buffer, offset)
const i = bufferutils.readUInt64LE(buffer, offset)
offset += 8
return i
}
function readVarInt () {
var vi = varuint.decode(buffer, offset)
const vi = varuint.decode(buffer, offset)
offset += varuint.decode.bytes
return vi
}
@ -82,26 +82,26 @@ Transaction.fromBuffer = function (buffer, __noStrict) {
}
function readVector () {
var count = readVarInt()
var vector = []
const count = readVarInt()
const vector = []
for (var i = 0; i < count; i++) vector.push(readVarSlice())
return vector
}
var tx = new Transaction()
const tx = new Transaction()
tx.version = readInt32()
var marker = buffer.readUInt8(offset)
var flag = buffer.readUInt8(offset + 1)
const marker = buffer.readUInt8(offset)
const flag = buffer.readUInt8(offset + 1)
var hasWitnesses = false
let hasWitnesses = false
if (marker === Transaction.ADVANCED_TRANSACTION_MARKER &&
flag === Transaction.ADVANCED_TRANSACTION_FLAG) {
offset += 2
hasWitnesses = true
}
var vinLen = readVarInt()
const vinLen = readVarInt()
for (var i = 0; i < vinLen; ++i) {
tx.ins.push({
hash: readSlice(32),
@ -112,7 +112,7 @@ Transaction.fromBuffer = function (buffer, __noStrict) {
})
}
var voutLen = readVarInt()
const voutLen = readVarInt()
for (i = 0; i < voutLen; ++i) {
tx.outs.push({
value: readUInt64(),
@ -192,8 +192,8 @@ Transaction.prototype.hasWitnesses = function () {
}
Transaction.prototype.weight = function () {
var base = this.__byteLength(false)
var total = this.__byteLength(true)
const base = this.__byteLength(false)
const total = this.__byteLength(true)
return base * 3 + total
}
@ -206,7 +206,7 @@ Transaction.prototype.byteLength = function () {
}
Transaction.prototype.__byteLength = function (__allowWitness) {
var hasWitnesses = __allowWitness && this.hasWitnesses()
const hasWitnesses = __allowWitness && this.hasWitnesses()
return (
(hasWitnesses ? 10 : 8) +
@ -219,7 +219,7 @@ Transaction.prototype.__byteLength = function (__allowWitness) {
}
Transaction.prototype.clone = function () {
var newTx = new Transaction()
const newTx = new Transaction()
newTx.version = this.version
newTx.locktime = this.locktime
@ -258,11 +258,11 @@ Transaction.prototype.hashForSignature = function (inIndex, prevOutScript, hashT
if (inIndex >= this.ins.length) return ONE
// ignore OP_CODESEPARATOR
var ourScript = bscript.compile(bscript.decompile(prevOutScript).filter(function (x) {
const ourScript = bscript.compile(bscript.decompile(prevOutScript).filter(function (x) {
return x !== opcodes.OP_CODESEPARATOR
}))
var txTmp = this.clone()
const txTmp = this.clone()
// SIGHASH_NONE: ignore all outputs? (wildcard payee)
if ((hashType & 0x1f) === Transaction.SIGHASH_NONE) {
@ -309,7 +309,7 @@ Transaction.prototype.hashForSignature = function (inIndex, prevOutScript, hashT
}
// serialize and hash
var buffer = Buffer.allocUnsafe(txTmp.__byteLength(false) + 4)
const buffer = Buffer.allocUnsafe(txTmp.__byteLength(false) + 4)
buffer.writeInt32LE(hashType, buffer.length - 4)
txTmp.__toBuffer(buffer, 0, false)
@ -319,7 +319,7 @@ Transaction.prototype.hashForSignature = function (inIndex, prevOutScript, hashT
Transaction.prototype.hashForWitnessV0 = function (inIndex, prevOutScript, value, hashType) {
typeforce(types.tuple(types.UInt32, types.Buffer, types.Satoshi, types.UInt32), arguments)
var tbuffer, toffset
let tbuffer, toffset
function writeSlice (slice) { toffset += slice.copy(tbuffer, toffset) }
function writeUInt32 (i) { toffset = tbuffer.writeUInt32LE(i, toffset) }
function writeUInt64 (i) { toffset = bufferutils.writeUInt64LE(tbuffer, i, toffset) }
@ -329,9 +329,9 @@ Transaction.prototype.hashForWitnessV0 = function (inIndex, prevOutScript, value
}
function writeVarSlice (slice) { writeVarInt(slice.length); writeSlice(slice) }
var hashOutputs = ZERO
var hashPrevouts = ZERO
var hashSequence = ZERO
let hashOutputs = ZERO
let hashPrevouts = ZERO
let hashSequence = ZERO
if (!(hashType & Transaction.SIGHASH_ANYONECANPAY)) {
tbuffer = Buffer.allocUnsafe(36 * this.ins.length)
@ -360,7 +360,7 @@ Transaction.prototype.hashForWitnessV0 = function (inIndex, prevOutScript, value
if ((hashType & 0x1f) !== Transaction.SIGHASH_SINGLE &&
(hashType & 0x1f) !== Transaction.SIGHASH_NONE) {
var txOutsSize = this.outs.reduce(function (sum, output) {
const txOutsSize = this.outs.reduce(function (sum, output) {
return sum + 8 + varSliceSize(output.script)
}, 0)
@ -374,7 +374,7 @@ Transaction.prototype.hashForWitnessV0 = function (inIndex, prevOutScript, value
hashOutputs = bcrypto.hash256(tbuffer)
} else if ((hashType & 0x1f) === Transaction.SIGHASH_SINGLE && inIndex < this.outs.length) {
var output = this.outs[inIndex]
const output = this.outs[inIndex]
tbuffer = Buffer.allocUnsafe(8 + varSliceSize(output.script))
toffset = 0
@ -387,7 +387,7 @@ Transaction.prototype.hashForWitnessV0 = function (inIndex, prevOutScript, value
tbuffer = Buffer.allocUnsafe(156 + varSliceSize(prevOutScript))
toffset = 0
var input = this.ins[inIndex]
const input = this.ins[inIndex]
writeUInt32(this.version)
writeSlice(hashPrevouts)
writeSlice(hashSequence)
@ -418,7 +418,7 @@ Transaction.prototype.toBuffer = function (buffer, initialOffset) {
Transaction.prototype.__toBuffer = function (buffer, initialOffset, __allowWitness) {
if (!buffer) buffer = Buffer.allocUnsafe(this.__byteLength(__allowWitness))
var offset = initialOffset || 0
let offset = initialOffset || 0
function writeSlice (slice) { offset += slice.copy(buffer, offset) }
function writeUInt8 (i) { offset = buffer.writeUInt8(i, offset) }
function writeUInt32 (i) { offset = buffer.writeUInt32LE(i, offset) }
@ -433,7 +433,7 @@ Transaction.prototype.__toBuffer = function (buffer, initialOffset, __allowWitne
writeInt32(this.version)
var hasWitnesses = __allowWitness && this.hasWitnesses()
const hasWitnesses = __allowWitness && this.hasWitnesses()
if (hasWitnesses) {
writeUInt8(Transaction.ADVANCED_TRANSACTION_MARKER)

186
src/transaction_builder.js

@ -1,18 +1,18 @@
var Buffer = require('safe-buffer').Buffer
var baddress = require('./address')
var bcrypto = require('./crypto')
var bscript = require('./script')
var btemplates = require('./templates')
var networks = require('./networks')
var ops = require('bitcoin-ops')
var typeforce = require('typeforce')
var types = require('./types')
var scriptTypes = btemplates.types
var SIGNABLE = [btemplates.types.P2PKH, btemplates.types.P2PK, btemplates.types.MULTISIG]
var P2SH = SIGNABLE.concat([btemplates.types.P2WPKH, btemplates.types.P2WSH])
var ECPair = require('./ecpair')
var Transaction = require('./transaction')
const Buffer = require('safe-buffer').Buffer
const baddress = require('./address')
const bcrypto = require('./crypto')
const bscript = require('./script')
const btemplates = require('./templates')
const networks = require('./networks')
const ops = require('bitcoin-ops')
const typeforce = require('typeforce')
const types = require('./types')
const scriptTypes = btemplates.types
const SIGNABLE = [btemplates.types.P2PKH, btemplates.types.P2PK, btemplates.types.MULTISIG]
const P2SH = SIGNABLE.concat([btemplates.types.P2WPKH, btemplates.types.P2WSH])
const ECPair = require('./ecpair')
const Transaction = require('./transaction')
function supportedType (type) {
return SIGNABLE.indexOf(type) !== -1
@ -23,8 +23,8 @@ function supportedP2SHType (type) {
}
function extractChunks (type, chunks, script) {
var pubKeys = []
var signatures = []
let pubKeys = []
let signatures = []
switch (type) {
case scriptTypes.P2PKH:
// if (redeemScript) throw new Error('Nonstandard... P2SH(P2PKH)')
@ -39,7 +39,7 @@ function extractChunks (type, chunks, script) {
case scriptTypes.MULTISIG:
if (script) {
var multisig = btemplates.multisig.output.decode(script)
const multisig = btemplates.multisig.output.decode(script)
pubKeys = multisig.pubKeys
}
@ -57,22 +57,22 @@ function extractChunks (type, chunks, script) {
function expandInput (scriptSig, witnessStack) {
if (scriptSig.length === 0 && witnessStack.length === 0) return {}
var prevOutScript
var prevOutType
var scriptType
var script
var redeemScript
var witnessScript
var witnessScriptType
var redeemScriptType
var witness = false
var p2wsh = false
var p2sh = false
var witnessProgram
var chunks
var scriptSigChunks = bscript.decompile(scriptSig) || []
var sigType = btemplates.classifyInput(scriptSigChunks, true)
let prevOutScript
let prevOutType
let scriptType
let script
let redeemScript
let witnessScript
let witnessScriptType
let redeemScriptType
let witness = false
let p2wsh = false
let p2sh = false
let witnessProgram
let chunks
const scriptSigChunks = bscript.decompile(scriptSig) || []
const sigType = btemplates.classifyInput(scriptSigChunks, true)
if (sigType === scriptTypes.P2SH) {
p2sh = true
redeemScript = scriptSigChunks[scriptSigChunks.length - 1]
@ -82,7 +82,7 @@ function expandInput (scriptSig, witnessStack) {
script = redeemScript
}
var classifyWitness = btemplates.classifyWitness(witnessStack, true)
const classifyWitness = btemplates.classifyWitness(witnessStack, true)
if (classifyWitness === scriptTypes.P2WSH) {
witnessScript = witnessStack[witnessStack.length - 1]
witnessScriptType = btemplates.classifyOutput(witnessScript)
@ -114,8 +114,8 @@ function expandInput (scriptSig, witnessStack) {
chunks = witnessStack.slice(0, -1)
} else if (classifyWitness === scriptTypes.P2WPKH) {
witness = true
var key = witnessStack[witnessStack.length - 1]
var keyHash = bcrypto.hash160(key)
const key = witnessStack[witnessStack.length - 1]
const keyHash = bcrypto.hash160(key)
if (scriptSig.length === 0) {
prevOutScript = btemplates.witnessPubKeyHash.output.encode(keyHash)
prevOutType = scriptTypes.P2WPKH
@ -147,9 +147,9 @@ function expandInput (scriptSig, witnessStack) {
chunks = scriptSigChunks
}
var expanded = extractChunks(scriptType, chunks, script)
const expanded = extractChunks(scriptType, chunks, script)
var result = {
const result = {
pubKeys: expanded.pubKeys,
signatures: expanded.signatures,
prevOutScript: prevOutScript,
@ -177,11 +177,11 @@ function fixMultisigOrder (input, transaction, vin) {
if (input.redeemScriptType !== scriptTypes.MULTISIG || !input.redeemScript) return
if (input.pubKeys.length === input.signatures.length) return
var unmatched = input.signatures.concat()
const unmatched = input.signatures.concat()
input.signatures = input.pubKeys.map(function (pubKey) {
var keyPair = ECPair.fromPublicKey(pubKey)
var match
const keyPair = ECPair.fromPublicKey(pubKey)
let match
// check for a signature
unmatched.some(function (signature, i) {
@ -189,8 +189,8 @@ function fixMultisigOrder (input, transaction, vin) {
if (!signature) return false
// TODO: avoid O(n) hashForSignature
var parsed = bscript.signature.decode(signature)
var hash = transaction.hashForSignature(vin, input.redeemScript, parsed.hashType)
const parsed = bscript.signature.decode(signature)
const hash = transaction.hashForSignature(vin, input.redeemScript, parsed.hashType)
// skip if signature does not match pubKey
if (!keyPair.verify(hash, parsed.signature)) return false
@ -209,20 +209,20 @@ function fixMultisigOrder (input, transaction, vin) {
function expandOutput (script, scriptType, ourPubKey) {
typeforce(types.Buffer, script)
var scriptChunks = bscript.decompile(script) || []
const scriptChunks = bscript.decompile(script) || []
if (!scriptType) {
scriptType = btemplates.classifyOutput(script)
}
var pubKeys = []
let pubKeys = []
switch (scriptType) {
// does our hash160(pubKey) match the output scripts?
case scriptTypes.P2PKH:
if (!ourPubKey) break
var pkh1 = scriptChunks[2]
var pkh2 = bcrypto.hash160(ourPubKey)
const pkh1 = scriptChunks[2]
const pkh2 = bcrypto.hash160(ourPubKey)
if (pkh1.equals(pkh2)) pubKeys = [ourPubKey]
break
@ -230,8 +230,8 @@ function expandOutput (script, scriptType, ourPubKey) {
case scriptTypes.P2WPKH:
if (!ourPubKey) break
var wpkh1 = scriptChunks[1]
var wpkh2 = bcrypto.hash160(ourPubKey)
const wpkh1 = scriptChunks[1]
const wpkh2 = bcrypto.hash160(ourPubKey)
if (wpkh1.equals(wpkh2)) pubKeys = [ourPubKey]
break
@ -257,7 +257,7 @@ function checkP2SHInput (input, redeemScriptHash) {
if (input.prevOutType) {
if (input.prevOutType !== scriptTypes.P2SH) throw new Error('PrevOutScript must be P2SH')
var chunks = bscript.decompile(input.prevOutScript)
const chunks = bscript.decompile(input.prevOutScript)
if (!chunks) throw new Error('Invalid prevOutScript')
if (!chunks[1].equals(redeemScriptHash)) throw new Error('Inconsistent hash160(redeemScript)')
}
@ -267,28 +267,28 @@ function checkP2WSHInput (input, witnessScriptHash) {
if (input.prevOutType) {
if (input.prevOutType !== scriptTypes.P2WSH) throw new Error('PrevOutScript must be P2WSH')
var chunks = bscript.decompile(input.prevOutScript)
const chunks = bscript.decompile(input.prevOutScript)
if (!chunks) throw new Error('Invalid witnessScript')
if (!chunks[1].equals(witnessScriptHash)) throw new Error('Inconsistent sha256(witnessScript)')
}
}
function prepareInput (input, kpPubKey, redeemScript, witnessValue, witnessScript) {
var expanded
var prevOutType
var prevOutScript
let expanded
let prevOutType
let prevOutScript
var p2sh = false
var p2shType
var redeemScriptHash
let p2sh = false
let p2shType
let redeemScriptHash
var witness = false
var p2wsh = false
var witnessType
var witnessScriptHash
let witness = false
let p2wsh = false
let witnessType
let witnessScriptHash
var signType
var signScript
let signType
let signScript
if (redeemScript && witnessScript) {
redeemScriptHash = bcrypto.hash160(redeemScript)
@ -408,15 +408,15 @@ function buildStack (type, signatures, pubKeys, allowIncomplete) {
}
function buildInput (input, allowIncomplete) {
var scriptType = input.prevOutType
var sig = []
var witness = []
let scriptType = input.prevOutType
let sig = []
let witness = []
if (supportedType(scriptType)) {
sig = buildStack(scriptType, input.signatures, input.pubKeys, allowIncomplete)
}
var p2sh = false
let p2sh = false
if (scriptType === btemplates.types.P2SH) {
// We can remove this error later when we have a guarantee prepareInput
// rejects unsignable scripts - it MUST be signable at this point.
@ -503,7 +503,7 @@ TransactionBuilder.prototype.setVersion = function (version) {
}
TransactionBuilder.fromTransaction = function (transaction, network) {
var txb = new TransactionBuilder(network)
const txb = new TransactionBuilder(network)
// Copy transaction fields
txb.setVersion(transaction.version)
@ -536,7 +536,7 @@ TransactionBuilder.prototype.addInput = function (txHash, vout, sequence, prevOu
throw new Error('No, this would invalidate signatures')
}
var value
let value
// is it a hex string?
if (typeof txHash === 'string') {
@ -545,7 +545,7 @@ TransactionBuilder.prototype.addInput = function (txHash, vout, sequence, prevOu
// is it a Transaction object?
} else if (txHash instanceof Transaction) {
var txOut = txHash.outs[vout]
const txOut = txHash.outs[vout]
prevOutScript = txOut.script
value = txOut.value
@ -564,10 +564,10 @@ TransactionBuilder.prototype.__addInputUnsafe = function (txHash, vout, options)
throw new Error('coinbase inputs not supported')
}
var prevTxOut = txHash.toString('hex') + ':' + vout
const prevTxOut = txHash.toString('hex') + ':' + vout
if (this.__prevTxSet[prevTxOut] !== undefined) throw new Error('Duplicate TxOut: ' + prevTxOut)
var input = {}
let input = {}
// derive what we can from the scriptSig
if (options.script !== undefined) {
@ -581,10 +581,10 @@ TransactionBuilder.prototype.__addInputUnsafe = function (txHash, vout, options)
// derive what we can from the previous transactions output script
if (!input.prevOutScript && options.prevOutScript) {
var prevOutType
let prevOutType
if (!input.pubKeys && !input.signatures) {
var expanded = expandOutput(options.prevOutScript)
const expanded = expandOutput(options.prevOutScript)
if (expanded.pubKeys) {
input.pubKeys = expanded.pubKeys
@ -598,7 +598,7 @@ TransactionBuilder.prototype.__addInputUnsafe = function (txHash, vout, options)
input.prevOutType = prevOutType || btemplates.classifyOutput(options.prevOutScript)
}
var vin = this.__tx.addInput(txHash, vout, options.sequence, options.scriptSig)
const vin = this.__tx.addInput(txHash, vout, options.sequence, options.scriptSig)
this.__inputs[vin] = input
this.__prevTxSet[prevTxOut] = true
return vin
@ -630,12 +630,12 @@ TransactionBuilder.prototype.__build = function (allowIncomplete) {
if (!this.__tx.outs.length) throw new Error('Transaction has no outputs')
}
var tx = this.__tx.clone()
const tx = this.__tx.clone()
// Create script signatures from inputs
this.__inputs.forEach(function (input, i) {
var scriptType = input.witnessScriptType || input.redeemScriptType || input.prevOutType
const scriptType = input.witnessScriptType || input.redeemScriptType || input.prevOutType
if (!scriptType && !allowIncomplete) throw new Error('Transaction is not complete')
var result = buildInput(input, allowIncomplete)
const result = buildInput(input, allowIncomplete)
// skip if no result
if (!allowIncomplete) {
@ -677,7 +677,7 @@ TransactionBuilder.prototype.sign = function (vin, keyPair, redeemScript, hashTy
if (!this.__inputs[vin]) throw new Error('No input at index: ' + vin)
hashType = hashType || Transaction.SIGHASH_ALL
var input = this.__inputs[vin]
const input = this.__inputs[vin]
// if redeemScript was previously provided, enforce consistency
if (input.redeemScript !== undefined &&
@ -686,7 +686,7 @@ TransactionBuilder.prototype.sign = function (vin, keyPair, redeemScript, hashTy
throw new Error('Inconsistent redeemScript')
}
var kpPubKey = keyPair.publicKey || keyPair.getPublicKey()
const kpPubKey = keyPair.publicKey || keyPair.getPublicKey()
if (!canSign(input)) {
if (witnessValue !== undefined) {
if (input.value !== undefined && input.value !== witnessValue) throw new Error('Input didn\'t match witnessValue')
@ -699,7 +699,7 @@ TransactionBuilder.prototype.sign = function (vin, keyPair, redeemScript, hashTy
}
// ready to sign
var signatureHash
let signatureHash
if (input.witness) {
signatureHash = this.__tx.hashForWitnessV0(vin, input.signScript, input.value, hashType)
} else {
@ -707,7 +707,7 @@ TransactionBuilder.prototype.sign = function (vin, keyPair, redeemScript, hashTy
}
// enforce in order signing of public keys
var signed = input.pubKeys.some(function (pubKey, i) {
const signed = input.pubKeys.some(function (pubKey, i) {
if (!kpPubKey.equals(pubKey)) return false
if (input.signatures[i]) throw new Error('Signature already exists')
@ -717,7 +717,7 @@ TransactionBuilder.prototype.sign = function (vin, keyPair, redeemScript, hashTy
input.prevOutType === scriptTypes.P2WSH
)) throw new Error('BIP143 rejects uncompressed public keys in P2WPKH or P2WSH')
let signature = keyPair.sign(signatureHash)
const signature = keyPair.sign(signatureHash)
input.signatures[i] = bscript.signature.encode(signature, hashType)
return true
})
@ -736,7 +736,7 @@ TransactionBuilder.prototype.__canModifyInputs = function () {
return input.signatures.every(function (signature) {
if (!signature) return true
var hashType = signatureHashType(signature)
const hashType = signatureHashType(signature)
// if SIGHASH_ANYONECANPAY is set, signatures would not
// be invalidated by more inputs
@ -746,17 +746,17 @@ TransactionBuilder.prototype.__canModifyInputs = function () {
}
TransactionBuilder.prototype.__canModifyOutputs = function () {
var nInputs = this.__tx.ins.length
var nOutputs = this.__tx.outs.length
const nInputs = this.__tx.ins.length
const nOutputs = this.__tx.outs.length
return this.__inputs.every(function (input) {
if (input.signatures === undefined) return true
return input.signatures.every(function (signature) {
if (!signature) return true
var hashType = signatureHashType(signature)
const hashType = signatureHashType(signature)
var hashTypeMod = hashType & 0x1f
const hashTypeMod = hashType & 0x1f
if (hashTypeMod === Transaction.SIGHASH_NONE) return true
if (hashTypeMod === Transaction.SIGHASH_SINGLE) {
// if SIGHASH_SINGLE is set, and nInputs > nOutputs
@ -770,13 +770,13 @@ TransactionBuilder.prototype.__canModifyOutputs = function () {
TransactionBuilder.prototype.__overMaximumFees = function (bytes) {
// not all inputs will have .value defined
var incoming = this.__inputs.reduce(function (a, x) { return a + (x.value >>> 0) }, 0)
const incoming = this.__inputs.reduce(function (a, x) { return a + (x.value >>> 0) }, 0)
// but all outputs do, and if we have any input value
// we can immediately determine if the outputs are too small
var outgoing = this.__tx.outs.reduce(function (a, x) { return a + x.value }, 0)
var fee = incoming - outgoing
var feeRate = fee / bytes
const outgoing = this.__tx.outs.reduce(function (a, x) { return a + x.value }, 0)
const fee = incoming - outgoing
const feeRate = fee / bytes
return feeRate > this.maximumFeeRate
}

12
src/types.js

@ -1,6 +1,6 @@
var typeforce = require('typeforce')
const typeforce = require('typeforce')
var UINT31_MAX = Math.pow(2, 31) - 1
const UINT31_MAX = Math.pow(2, 31) - 1
function UInt31 (value) {
return typeforce.UInt32(value) && value <= UINT31_MAX
}
@ -10,16 +10,16 @@ function BIP32Path (value) {
}
BIP32Path.toJSON = function () { return 'BIP32 derivation path' }
var SATOSHI_MAX = 21 * 1e14
const SATOSHI_MAX = 21 * 1e14
function Satoshi (value) {
return typeforce.UInt53(value) && value <= SATOSHI_MAX
}
// external dependent types
var ECPoint = typeforce.quacksLike('Point')
const ECPoint = typeforce.quacksLike('Point')
// exposed, external API
var Network = typeforce.compile({
const Network = typeforce.compile({
messagePrefix: typeforce.oneOf(typeforce.Buffer, typeforce.String),
bip32: {
public: typeforce.UInt32,
@ -31,7 +31,7 @@ var Network = typeforce.compile({
})
// extend typeforce types with ours
var types = {
const types = {
BIP32Path: BIP32Path,
Buffer256bit: typeforce.BufferN(32),
ECPoint: ECPoint,

26
test/address.js

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

116
test/bitcoin.core.js

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

28
test/block.js

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

16
test/bufferutils.js

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

14
test/crypto.js

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

78
test/ecpair.js

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

16
test/integration/_regtest.js

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

80
test/integration/addresses.js

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

74
test/integration/bip32.js

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

14
test/integration/blocks.js

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

80
test/integration/cltv.js

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

86
test/integration/crypto.js

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

48
test/integration/csv.js

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

108
test/integration/stealth.js

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

88
test/integration/transactions.js

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

42
test/script.js

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

10
test/script_number.js

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

16
test/script_signature.js

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

138
test/templates.js

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

83
test/transaction.js

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

213
test/transaction_builder.js

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

10
test/types.js

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

Loading…
Cancel
Save