Merge branch 'master' into bnjs
This commit is contained in:
commit
8220e33d76
49 changed files with 1050 additions and 1042 deletions
|
@ -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
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
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var createHash = require('create-hash')
|
||||
const createHash = require('create-hash')
|
||||
|
||||
function ripemd160 (buffer) {
|
||||
return createHash('rmd160').update(buffer).digest()
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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]
|
||||
}
|
||||
|
|
|
@ -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')
|
||||
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')
|
||||
|
||||
var OPS = require('bitcoin-ops')
|
||||
var REVERSE_OPS = require('bitcoin-ops/map')
|
||||
var OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1
|
||||
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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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]) &&
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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) &&
|
||||
|
|
|
@ -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 &&
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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])
|
||||
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])
|
||||
|
||||
var ECPair = require('./ecpair')
|
||||
var Transaction = require('./transaction')
|
||||
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
|
||||
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
|
||||
|
||||
var scriptSigChunks = bscript.decompile(scriptSig) || []
|
||||
var sigType = btemplates.classifyInput(scriptSigChunks, true)
|
||||
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
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,
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
/* global describe, it */
|
||||
|
||||
var assert = require('assert')
|
||||
var base58 = require('bs58')
|
||||
var bitcoin = require('../')
|
||||
const assert = require('assert')
|
||||
const base58 = require('bs58')
|
||||
const bitcoin = require('../')
|
||||
|
||||
var base58EncodeDecode = require('./fixtures/core/base58_encode_decode.json')
|
||||
var base58KeysInvalid = require('./fixtures/core/base58_keys_invalid.json')
|
||||
var base58KeysValid = require('./fixtures/core/base58_keys_valid.json')
|
||||
var blocksValid = require('./fixtures/core/blocks.json')
|
||||
var sigCanonical = require('./fixtures/core/sig_canonical.json')
|
||||
var sigHash = require('./fixtures/core/sighash.json')
|
||||
var sigNoncanonical = require('./fixtures/core/sig_noncanonical.json')
|
||||
var txValid = require('./fixtures/core/tx_valid.json')
|
||||
const base58EncodeDecode = require('./fixtures/core/base58_encode_decode.json')
|
||||
const base58KeysInvalid = require('./fixtures/core/base58_keys_invalid.json')
|
||||
const base58KeysValid = require('./fixtures/core/base58_keys_valid.json')
|
||||
const blocksValid = require('./fixtures/core/blocks.json')
|
||||
const sigCanonical = require('./fixtures/core/sig_canonical.json')
|
||||
const sigHash = require('./fixtures/core/sighash.json')
|
||||
const sigNoncanonical = require('./fixtures/core/sig_noncanonical.json')
|
||||
const txValid = require('./fixtures/core/tx_valid.json')
|
||||
|
||||
describe('Bitcoin-core', function () {
|
||||
// base58EncodeDecode
|
||||
describe('base58', function () {
|
||||
base58EncodeDecode.forEach(function (f) {
|
||||
var fhex = f[0]
|
||||
var fb58 = f[1]
|
||||
const fhex = f[0]
|
||||
const fb58 = f[1]
|
||||
|
||||
it('can decode ' + fb58, function () {
|
||||
var buffer = base58.decode(fb58)
|
||||
var actual = buffer.toString('hex')
|
||||
const buffer = base58.decode(fb58)
|
||||
const actual = buffer.toString('hex')
|
||||
|
||||
assert.strictEqual(actual, fhex)
|
||||
})
|
||||
|
||||
it('can encode ' + fhex, function () {
|
||||
var buffer = Buffer.from(fhex, 'hex')
|
||||
var actual = base58.encode(buffer)
|
||||
const buffer = Buffer.from(fhex, 'hex')
|
||||
const actual = base58.encode(buffer)
|
||||
|
||||
assert.strictEqual(actual, fb58)
|
||||
})
|
||||
|
@ -38,20 +38,20 @@ describe('Bitcoin-core', function () {
|
|||
|
||||
// base58KeysValid
|
||||
describe('address.toBase58Check', function () {
|
||||
var typeMap = {
|
||||
const typeMap = {
|
||||
'pubkey': 'pubKeyHash',
|
||||
'script': 'scriptHash'
|
||||
}
|
||||
|
||||
base58KeysValid.forEach(function (f) {
|
||||
var expected = f[0]
|
||||
var hash = Buffer.from(f[1], 'hex')
|
||||
var params = f[2]
|
||||
const expected = f[0]
|
||||
const hash = Buffer.from(f[1], 'hex')
|
||||
const params = f[2]
|
||||
|
||||
if (params.isPrivkey) return
|
||||
|
||||
var network = params.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin
|
||||
var version = network[typeMap[params.addrType]]
|
||||
const network = params.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin
|
||||
const version = network[typeMap[params.addrType]]
|
||||
|
||||
it('can export ' + expected, function () {
|
||||
assert.strictEqual(bitcoin.address.toBase58Check(hash, version), expected)
|
||||
|
@ -61,7 +61,7 @@ describe('Bitcoin-core', function () {
|
|||
|
||||
// base58KeysInvalid
|
||||
describe('address.fromBase58Check', function () {
|
||||
var allowedNetworks = [
|
||||
const allowedNetworks = [
|
||||
bitcoin.networks.bitcoin.pubkeyhash,
|
||||
bitcoin.networks.bitcoin.scripthash,
|
||||
bitcoin.networks.testnet.pubkeyhash,
|
||||
|
@ -69,11 +69,11 @@ describe('Bitcoin-core', function () {
|
|||
]
|
||||
|
||||
base58KeysInvalid.forEach(function (f) {
|
||||
var string = f[0]
|
||||
const string = f[0]
|
||||
|
||||
it('throws on ' + string, function () {
|
||||
assert.throws(function () {
|
||||
var address = bitcoin.address.fromBase58Check(string)
|
||||
const address = bitcoin.address.fromBase58Check(string)
|
||||
|
||||
assert.notEqual(allowedNetworks.indexOf(address.version), -1, 'Invalid network')
|
||||
}, /(Invalid (checksum|network))|(too (short|long))/)
|
||||
|
@ -84,14 +84,14 @@ describe('Bitcoin-core', function () {
|
|||
// base58KeysValid
|
||||
describe('ECPair', function () {
|
||||
base58KeysValid.forEach(function (f) {
|
||||
var string = f[0]
|
||||
var hex = f[1]
|
||||
var params = f[2]
|
||||
const string = f[0]
|
||||
const hex = f[1]
|
||||
const params = f[2]
|
||||
|
||||
if (!params.isPrivkey) return
|
||||
|
||||
var network = params.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin
|
||||
var keyPair = bitcoin.ECPair.fromWIF(string, network)
|
||||
const network = params.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin
|
||||
const keyPair = bitcoin.ECPair.fromWIF(string, network)
|
||||
|
||||
it('fromWIF imports ' + string, function () {
|
||||
assert.strictEqual(keyPair.privateKey.toString('hex'), hex)
|
||||
|
@ -106,13 +106,13 @@ describe('Bitcoin-core', function () {
|
|||
|
||||
// base58KeysInvalid
|
||||
describe('ECPair.fromWIF', function () {
|
||||
var allowedNetworks = [
|
||||
const allowedNetworks = [
|
||||
bitcoin.networks.bitcoin,
|
||||
bitcoin.networks.testnet
|
||||
]
|
||||
|
||||
base58KeysInvalid.forEach(function (f) {
|
||||
var string = f[0]
|
||||
const string = f[0]
|
||||
|
||||
it('throws on ' + string, function () {
|
||||
assert.throws(function () {
|
||||
|
@ -125,7 +125,7 @@ describe('Bitcoin-core', function () {
|
|||
describe('Block.fromHex', function () {
|
||||
blocksValid.forEach(function (f) {
|
||||
it('can parse ' + f.id, function () {
|
||||
var block = bitcoin.Block.fromHex(f.hex)
|
||||
const block = bitcoin.Block.fromHex(f.hex)
|
||||
|
||||
assert.strictEqual(block.getId(), f.id)
|
||||
assert.strictEqual(block.transactions.length, f.transactions)
|
||||
|
@ -139,19 +139,19 @@ describe('Bitcoin-core', function () {
|
|||
// Objects that are only a single string are ignored
|
||||
if (f.length === 1) return
|
||||
|
||||
var inputs = f[0]
|
||||
var fhex = f[1]
|
||||
// var verifyFlags = f[2] // TODO: do we need to test this?
|
||||
const inputs = f[0]
|
||||
const fhex = f[1]
|
||||
// const verifyFlags = f[2] // TODO: do we need to test this?
|
||||
|
||||
it('can decode ' + fhex, function () {
|
||||
var transaction = bitcoin.Transaction.fromHex(fhex)
|
||||
const transaction = bitcoin.Transaction.fromHex(fhex)
|
||||
|
||||
transaction.ins.forEach(function (txIn, i) {
|
||||
var input = inputs[i]
|
||||
const input = inputs[i]
|
||||
|
||||
// reverse because test data is reversed
|
||||
var prevOutHash = Buffer.from(input[0], 'hex').reverse()
|
||||
var prevOutIndex = input[1]
|
||||
const prevOutHash = Buffer.from(input[0], 'hex').reverse()
|
||||
const prevOutIndex = input[1]
|
||||
|
||||
assert.deepEqual(txIn.hash, prevOutHash)
|
||||
|
||||
|
@ -168,29 +168,29 @@ describe('Bitcoin-core', function () {
|
|||
// Objects that are only a single string are ignored
|
||||
if (f.length === 1) return
|
||||
|
||||
var txHex = f[0]
|
||||
var scriptHex = f[1]
|
||||
var inIndex = f[2]
|
||||
var hashType = f[3]
|
||||
var expectedHash = f[4]
|
||||
const txHex = f[0]
|
||||
const scriptHex = f[1]
|
||||
const inIndex = f[2]
|
||||
const hashType = f[3]
|
||||
const expectedHash = f[4]
|
||||
|
||||
var hashTypes = []
|
||||
const hashTypes = []
|
||||
if ((hashType & 0x1f) === bitcoin.Transaction.SIGHASH_NONE) hashTypes.push('SIGHASH_NONE')
|
||||
else if ((hashType & 0x1f) === bitcoin.Transaction.SIGHASH_SINGLE) hashTypes.push('SIGHASH_SINGLE')
|
||||
else hashTypes.push('SIGHASH_ALL')
|
||||
if (hashType & bitcoin.Transaction.SIGHASH_ANYONECANPAY) hashTypes.push('SIGHASH_ANYONECANPAY')
|
||||
|
||||
var hashTypeName = hashTypes.join(' | ')
|
||||
const hashTypeName = hashTypes.join(' | ')
|
||||
|
||||
it('should hash ' + txHex.slice(0, 40) + '... (' + hashTypeName + ')', function () {
|
||||
var transaction = bitcoin.Transaction.fromHex(txHex)
|
||||
const transaction = bitcoin.Transaction.fromHex(txHex)
|
||||
assert.strictEqual(transaction.toHex(), txHex)
|
||||
|
||||
var script = Buffer.from(scriptHex, 'hex')
|
||||
var scriptChunks = bitcoin.script.decompile(script)
|
||||
const script = Buffer.from(scriptHex, 'hex')
|
||||
const scriptChunks = bitcoin.script.decompile(script)
|
||||
assert.strictEqual(bitcoin.script.compile(scriptChunks).toString('hex'), scriptHex)
|
||||
|
||||
var hash = transaction.hashForSignature(inIndex, script, hashType)
|
||||
const hash = transaction.hashForSignature(inIndex, script, hashType)
|
||||
|
||||
// reverse because test data is reversed
|
||||
assert.equal(hash.reverse().toString('hex'), expectedHash)
|
||||
|
@ -200,11 +200,11 @@ describe('Bitcoin-core', function () {
|
|||
|
||||
describe('script.signature.decode', function () {
|
||||
sigCanonical.forEach(function (hex) {
|
||||
var buffer = Buffer.from(hex, 'hex')
|
||||
const buffer = Buffer.from(hex, 'hex')
|
||||
|
||||
it('can parse ' + hex, function () {
|
||||
var parsed = bitcoin.script.signature.decode(buffer)
|
||||
var actual = bitcoin.script.signature.encode(parsed.signature, parsed.hashType)
|
||||
const parsed = bitcoin.script.signature.decode(buffer)
|
||||
const actual = bitcoin.script.signature.encode(parsed.signature, parsed.hashType)
|
||||
|
||||
assert.strictEqual(actual.toString('hex'), hex)
|
||||
})
|
||||
|
@ -214,8 +214,8 @@ describe('Bitcoin-core', function () {
|
|||
if (i === 0) return
|
||||
if (i % 2 !== 0) return
|
||||
|
||||
var description = sigNoncanonical[i - 1].slice(0, -1)
|
||||
var buffer = Buffer.from(hex, 'hex')
|
||||
const description = sigNoncanonical[i - 1].slice(0, -1)
|
||||
const buffer = Buffer.from(hex, 'hex')
|
||||
|
||||
it('throws on ' + description, function () {
|
||||
assert.throws(function () {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,32 +1,33 @@
|
|||
/* global describe, it */
|
||||
|
||||
var assert = require('assert')
|
||||
var BN = require('bn.js')
|
||||
var bitcoin = require('../../')
|
||||
var bip32 = require('bip32')
|
||||
var crypto = require('crypto')
|
||||
var tinysecp = require('tiny-secp256k1')
|
||||
|
||||
var ecurve = require('ecurve')
|
||||
var secp256k1 = ecurve.getCurveByName('secp256k1')
|
||||
const assert = require('assert')
|
||||
const bigi = require('bigi')
|
||||
const bitcoin = require('../../')
|
||||
const bip32 = require('bip32')
|
||||
const crypto = require('crypto')
|
||||
const tinysecp = require('tiny-secp256k1')
|
||||
|
||||
const ecurve = require('ecurve')
|
||||
const secp256k1 = ecurve.getCurveByName('secp256k1')
|
||||
|
||||
describe('bitcoinjs-lib (crypto)', function () {
|
||||
it('can recover a private key from duplicate R values', function () {
|
||||
this.timeout(30000)
|
||||
|
||||
// https://blockchain.info/tx/f4c16475f2a6e9c602e4a287f9db3040e319eb9ece74761a4b84bc820fbeef50
|
||||
var tx = bitcoin.Transaction.fromHex('01000000020b668015b32a6178d8524cfef6dc6fc0a4751915c2e9b2ed2d2eab02424341c8000000006a47304402205e00298dc5265b7a914974c9d0298aa0e69a0ca932cb52a360436d6a622e5cd7022024bf5f506968f5f23f1835574d5afe0e9021b4a5b65cf9742332d5e4acb68f41012103fd089f73735129f3d798a657aaaa4aa62a00fa15c76b61fc7f1b27ed1d0f35b8ffffffffa95fa69f11dc1cbb77ef64f25a95d4b12ebda57d19d843333819d95c9172ff89000000006b48304502205e00298dc5265b7a914974c9d0298aa0e69a0ca932cb52a360436d6a622e5cd7022100832176b59e8f50c56631acbc824bcba936c9476c559c42a4468be98975d07562012103fd089f73735129f3d798a657aaaa4aa62a00fa15c76b61fc7f1b27ed1d0f35b8ffffffff02b000eb04000000001976a91472956eed9a8ecb19ae7e3ebd7b06cae4668696a788ac303db000000000001976a9146c0bd55dd2592287cd9992ce3ba3fc1208fb76da88ac00000000')
|
||||
const tx = bitcoin.Transaction.fromHex('01000000020b668015b32a6178d8524cfef6dc6fc0a4751915c2e9b2ed2d2eab02424341c8000000006a47304402205e00298dc5265b7a914974c9d0298aa0e69a0ca932cb52a360436d6a622e5cd7022024bf5f506968f5f23f1835574d5afe0e9021b4a5b65cf9742332d5e4acb68f41012103fd089f73735129f3d798a657aaaa4aa62a00fa15c76b61fc7f1b27ed1d0f35b8ffffffffa95fa69f11dc1cbb77ef64f25a95d4b12ebda57d19d843333819d95c9172ff89000000006b48304502205e00298dc5265b7a914974c9d0298aa0e69a0ca932cb52a360436d6a622e5cd7022100832176b59e8f50c56631acbc824bcba936c9476c559c42a4468be98975d07562012103fd089f73735129f3d798a657aaaa4aa62a00fa15c76b61fc7f1b27ed1d0f35b8ffffffff02b000eb04000000001976a91472956eed9a8ecb19ae7e3ebd7b06cae4668696a788ac303db000000000001976a9146c0bd55dd2592287cd9992ce3ba3fc1208fb76da88ac00000000')
|
||||
|
||||
tx.ins.forEach(function (input, vin) {
|
||||
var script = input.script
|
||||
var scriptChunks = bitcoin.script.decompile(script)
|
||||
const script = input.script
|
||||
const scriptChunks = bitcoin.script.decompile(script)
|
||||
|
||||
assert(bitcoin.script.pubKeyHash.input.check(scriptChunks), 'Expected pubKeyHash script')
|
||||
var prevOutScript = bitcoin.address.toOutputScript('1ArJ9vRaQcoQ29mTWZH768AmRwzb6Zif1z')
|
||||
var scriptSignature = bitcoin.script.signature.decode(scriptChunks[0])
|
||||
var publicKey = bitcoin.ECPair.fromPublicKey(scriptChunks[1])
|
||||
const prevOutScript = bitcoin.address.toOutputScript('1ArJ9vRaQcoQ29mTWZH768AmRwzb6Zif1z')
|
||||
const scriptSignature = bitcoin.script.signature.decode(scriptChunks[0])
|
||||
const publicKey = bitcoin.ECPair.fromPublicKey(scriptChunks[1])
|
||||
|
||||
var m = tx.hashForSignature(vin, prevOutScript, scriptSignature.hashType)
|
||||
const m = tx.hashForSignature(vin, prevOutScript, scriptSignature.hashType)
|
||||
assert(publicKey.verify(m, scriptSignature.signature), 'Invalid m')
|
||||
|
||||
// store the required information
|
||||
|
@ -34,35 +35,35 @@ describe('bitcoinjs-lib (crypto)', function () {
|
|||
input.z = new BN(m)
|
||||
})
|
||||
|
||||
// finally, run the tasks, then on to the mathmod
|
||||
var n = new BN(secp256k1.n.toString())
|
||||
// finally, run the tasks, then on to the math
|
||||
const n = new BN(secp256k1.n.toString())
|
||||
|
||||
for (var i = 0; i < tx.ins.length; ++i) {
|
||||
for (var j = i + 1; j < tx.ins.length; ++j) {
|
||||
var inputA = tx.ins[i]
|
||||
var inputB = tx.ins[j]
|
||||
const inputA = tx.ins[i]
|
||||
const inputB = tx.ins[j]
|
||||
|
||||
// enforce matching r values
|
||||
let r = inputA.signature.slice(0, 32)
|
||||
let rB = inputB.signature.slice(0, 32)
|
||||
const r = inputA.signature.slice(0, 32)
|
||||
const rB = inputB.signature.slice(0, 32)
|
||||
assert.strictEqual(r.toString('hex'), rB.toString('hex'))
|
||||
|
||||
var rInv = new BN(r).invm(n)
|
||||
const rInv = new BN(r).invm(n)
|
||||
|
||||
var s1 = new BN(inputA.signature.slice(32, 64))
|
||||
var s2 = new BN(inputB.signature.slice(32, 64))
|
||||
var z1 = inputA.z
|
||||
var z2 = inputB.z
|
||||
const s1 = new BN(inputA.signature.slice(32, 64))
|
||||
const s2 = new BN(inputB.signature.slice(32, 64))
|
||||
const z1 = inputA.z
|
||||
const z2 = inputB.z
|
||||
|
||||
var zz = z1.sub(z2).mod(n)
|
||||
var ss = s1.sub(s2).mod(n)
|
||||
const zz = z1.sub(z2).mod(n)
|
||||
const ss = s1.sub(s2).mod(n)
|
||||
|
||||
// k = (z1 - z2) / (s1 - s2)
|
||||
// d1 = (s1 * k - z1) / r
|
||||
// d2 = (s2 * k - z2) / r
|
||||
var k = zz.mul(ss.invm(n)).mod(n)
|
||||
var d1 = ((s1.mul(k).mod(n)).sub(z1).mod(n)).mul(rInv).mod(n)
|
||||
var d2 = ((s2.mul(k).mod(n)).sub(z2).mod(n)).mul(rInv).mod(n)
|
||||
const k = zz.mul(ss.invm(n)).mod(n)
|
||||
const d1 = ((s1.mul(k).mod(n)).sub(z1).mod(n)).mul(rInv).mod(n)
|
||||
const d2 = ((s2.mul(k).mod(n)).sub(z2).mod(n)).mul(rInv).mod(n)
|
||||
|
||||
// enforce matching private keys
|
||||
assert.strictEqual(d1.toString(), d2.toString())
|
||||
|
@ -75,41 +76,41 @@ describe('bitcoinjs-lib (crypto)', function () {
|
|||
assert(master.isNeutered(), 'You already have the parent private key')
|
||||
assert(!child.isNeutered(), 'Missing child private key')
|
||||
|
||||
var serQP = master.publicKey
|
||||
var d1 = child.privateKey
|
||||
var d2
|
||||
var data = Buffer.alloc(37)
|
||||
const serQP = master.publicKey
|
||||
const d1 = child.privateKey
|
||||
const data = Buffer.alloc(37)
|
||||
serQP.copy(data, 0)
|
||||
|
||||
// search index space until we find it
|
||||
let d2
|
||||
for (var i = 0; i < 0x80000000; ++i) {
|
||||
data.writeUInt32BE(i, 33)
|
||||
|
||||
// calculate I
|
||||
var I = crypto.createHmac('sha512', master.chainCode).update(data).digest()
|
||||
var IL = I.slice(0, 32)
|
||||
const I = crypto.createHmac('sha512', master.chainCode).update(data).digest()
|
||||
const IL = I.slice(0, 32)
|
||||
|
||||
// See bip32.js:273 to understand
|
||||
d2 = tinysecp.privateSub(d1, IL)
|
||||
|
||||
var Qp = bip32.fromPrivateKey(d2, Buffer.alloc(32, 0)).publicKey
|
||||
const Qp = bip32.fromPrivateKey(d2, Buffer.alloc(32, 0)).publicKey
|
||||
if (Qp.equals(serQP)) break
|
||||
}
|
||||
|
||||
var node = bip32.fromPrivateKey(d2, master.chainCode, master.network)
|
||||
const node = bip32.fromPrivateKey(d2, master.chainCode, master.network)
|
||||
node.depth = master.depth
|
||||
node.index = master.index
|
||||
node.masterFingerprint = master.masterFingerprint
|
||||
return node
|
||||
}
|
||||
|
||||
var seed = crypto.randomBytes(32)
|
||||
var master = bip32.fromSeed(seed)
|
||||
var child = master.derive(6) // m/6
|
||||
const seed = crypto.randomBytes(32)
|
||||
const master = bip32.fromSeed(seed)
|
||||
const child = master.derive(6) // m/6
|
||||
|
||||
// now for the recovery
|
||||
var neuteredMaster = master.neutered()
|
||||
var recovered = recoverParent(neuteredMaster, child)
|
||||
const neuteredMaster = master.neutered()
|
||||
const recovered = recoverParent(neuteredMaster, child)
|
||||
assert.strictEqual(recovered.toBase58(), master.toBase58())
|
||||
})
|
||||
})
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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'))
|
||||
})
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -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…
Reference in a new issue