function Block() {
this.version = 1
this.prevHash = null
this.merkleRoot = null
this.timestamp = 0
this.bits = 0
this.nonce = 0
}n/a
function ECPair(d, Q, options) {
if (options) {
typeforce({
compressed: types.maybe(types.Boolean),
network: types.maybe(types.Network)
}, options)
}
options = options || {}
if (d) {
if (d.signum() <= 0) throw new Error('Private key must be greater than 0')
if (d.compareTo(secp256k1.n) >= 0) throw new Error('Private key must be less than the curve order')
if (Q) throw new TypeError('Unexpected publicKey parameter')
this.d = d
} else {
typeforce(types.ECPoint, Q)
this.__Q = Q
}
this.compressed = options.compressed === undefined ? true : options.compressed
this.network = options.network || NETWORKS.bitcoin
}n/a
function ECSignature(r, s) {
typeforce(types.tuple(types.BigInt, types.BigInt), arguments)
this.r = r
this.s = s
}n/a
function HDNode(keyPair, chainCode) {
typeforce(types.tuple('ECPair', types.Buffer256bit), arguments)
if (!keyPair.compressed) throw new TypeError('BIP32 only allows compressed keyPairs')
this.keyPair = keyPair
this.chainCode = chainCode
this.depth = 0
this.index = 0
this.parentFingerprint = 0x00000000
}n/a
function Transaction() {
this.version = 1
this.locktime = 0
this.ins = []
this.outs = []
}n/a
function TransactionBuilder(network, maximumFeeRate) {
this.prevTxMap = {}
this.network = network || networks.bitcoin
// WARNING: This is __NOT__ to be relied on, its just another potential safety mechanism (safety in-depth)
this.maximumFeeRate = maximumFeeRate || 1000
this.inputs = []
this.tx = new Transaction()
}n/a
function Block() {
this.version = 1
this.prevHash = null
this.merkleRoot = null
this.timestamp = 0
this.bits = 0
this.nonce = 0
}n/a
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) {
return transaction.getHash()
})
return fastMerkleRoot(hashes, bcrypto.hash256)
}n/a
calculateTarget = function (bits) {
var exponent = ((bits & 0xff000000) >> 24) - 3
var mantissa = bits & 0x007fffff
var target = new Buffer(32)
target.fill(0)
target.writeUInt32BE(mantissa, 28 - exponent)
return target
}n/a
fromBuffer = function (buffer) {
if (buffer.length < 80) throw new Error('Buffer too small (< 80 bytes)')
var offset = 0
function readSlice (n) {
offset += n
return buffer.slice(offset - n, offset)
}
function readUInt32 () {
var i = buffer.readUInt32LE(offset)
offset += 4
return i
}
function readInt32 () {
var i = buffer.readInt32LE(offset)
offset += 4
return i
}
var block = new Block()
block.version = readInt32()
block.prevHash = readSlice(32)
block.merkleRoot = readSlice(32)
block.timestamp = readUInt32()
block.bits = readUInt32()
block.nonce = readUInt32()
if (buffer.length === 80) return block
function readVarInt () {
var vi = varuint.decode(buffer, offset)
offset += varuint.decode.bytes
return vi
}
function readTransaction () {
var tx = Transaction.fromBuffer(buffer.slice(offset), true)
offset += tx.byteLength()
return tx
}
var nTransactions = readVarInt()
block.transactions = []
for (var i = 0; i < nTransactions; ++i) {
var tx = readTransaction()
block.transactions.push(tx)
}
return block
}...
// Step G
v = createHmac('sha256', k).update(v).digest()
// Step H1/H2a, ignored as tlen === qlen (256 bit)
// Step H2b
v = createHmac('sha256', k).update(v).digest()
var T = BigInteger.fromBuffer(v)
// Step H3, repeat until T is within the interval [1, n - 1] and is suitable for ECDSA
while (T.signum() <= 0 || T.compareTo(secp256k1.n) >= 0 || !checkSig(T)) {
k = createHmac('sha256', k)
.update(v)
.update(ZERO)
.digest()
...fromHex = function (hex) {
return Block.fromBuffer(new Buffer(hex, 'hex'))
}n/a
byteLength = function (headersOnly) {
if (headersOnly || !this.transactions) return 80
return 80 + varuint.encodingLength(this.transactions.length) + this.transactions.reduce(function (a, x) {
return a + x.byteLength()
}, 0)
}n/a
checkMerkleRoot = function () {
if (!this.transactions) return false
var actualMerkleRoot = Block.calculateMerkleRoot(this.transactions)
return this.merkleRoot.compare(actualMerkleRoot) === 0
}n/a
checkProofOfWork = function () {
var hash = this.getHash().reverse()
var target = Block.calculateTarget(this.bits)
return hash.compare(target) <= 0
}n/a
getHash = function () {
return bcrypto.hash256(this.toBuffer(true))
}n/a
getId = function () {
return this.getHash().reverse().toString('hex')
}n/a
getUTCDate = function () {
var date = new Date(0) // epoch
date.setUTCSeconds(this.timestamp)
return date
}n/a
toBuffer = function (headersOnly) {
var buffer = new Buffer(this.byteLength(headersOnly))
var offset = 0
function writeSlice (slice) {
slice.copy(buffer, offset)
offset += slice.length
}
function writeInt32 (i) {
buffer.writeInt32LE(i, offset)
offset += 4
}
function writeUInt32 (i) {
buffer.writeUInt32LE(i, offset)
offset += 4
}
writeInt32(this.version)
writeSlice(this.prevHash)
writeSlice(this.merkleRoot)
writeUInt32(this.timestamp)
writeUInt32(this.bits)
writeUInt32(this.nonce)
if (headersOnly || !this.transactions) return buffer
varuint.encode(this.transactions.length, buffer, offset)
offset += varuint.encode.bytes
this.transactions.forEach(function (tx) {
var txSize = tx.byteLength() // TODO: extract from toBuffer?
tx.toBuffer(buffer, offset)
offset += txSize
})
return buffer
}...
}
var N_OVER_TWO = secp256k1.n.shiftRight(1)
function sign (hash, d) {
typeforce(types.tuple(types.Hash256bit, types.BigInt), arguments)
var x = d.toBuffer(32)
var e = BigInteger.fromBuffer(hash)
var n = secp256k1.n
var G = secp256k1.G
var r, s
deterministicGenerateK(hash, x, function (k) {
var Q = G.multiply(k)
...toHex = function (headersOnly) {
return this.toBuffer(headersOnly).toString('hex')
}n/a
function ECPair(d, Q, options) {
if (options) {
typeforce({
compressed: types.maybe(types.Boolean),
network: types.maybe(types.Network)
}, options)
}
options = options || {}
if (d) {
if (d.signum() <= 0) throw new Error('Private key must be greater than 0')
if (d.compareTo(secp256k1.n) >= 0) throw new Error('Private key must be less than the curve order')
if (Q) throw new TypeError('Unexpected publicKey parameter')
this.d = d
} else {
typeforce(types.ECPoint, Q)
this.__Q = Q
}
this.compressed = options.compressed === undefined ? true : options.compressed
this.network = options.network || NETWORKS.bitcoin
}n/a
fromPublicKeyBuffer = function (buffer, network) {
var Q = ecurve.Point.decodeFrom(secp256k1, buffer)
return new ECPair(null, Q, {
compressed: Q.compressed,
network: network
})
}n/a
fromWIF = function (string, network) {
var decoded = wif.decode(string)
var version = decoded.version
// list of networks?
if (types.Array(network)) {
network = network.filter(function (x) {
return version === x.wif
}).pop()
if (!network) throw new Error('Unknown network version')
// otherwise, assume a network object (or default to bitcoin)
} else {
network = network || NETWORKS.bitcoin
if (version !== network.wif) throw new Error('Invalid network version')
}
var d = BigInteger.fromBuffer(decoded.privateKey)
return new ECPair(d, null, {
compressed: decoded.compressed,
network: network
})
}n/a
makeRandom = function (options) {
options = options || {}
var rng = options.rng || randomBytes
var d
do {
var buffer = rng(32)
typeforce(types.Buffer256bit, buffer)
d = BigInteger.fromBuffer(buffer)
} while (d.signum() <= 0 || d.compareTo(secp256k1.n) >= 0)
return new ECPair(d, null, options)
}n/a
getAddress = function () {
return baddress.toBase58Check(bcrypto.hash160(this.getPublicKeyBuffer()), this.getNetwork().pubKeyHash)
}n/a
getNetwork = function () {
return this.network
}n/a
getPublicKeyBuffer = function () {
return this.Q.getEncoded(this.compressed)
}n/a
sign = function (hash) {
if (!this.d) throw new Error('Missing private key')
return ecdsa.sign(hash, this.d)
}n/a
toWIF = function () {
if (!this.d) throw new Error('Missing private key')
return wif.encode(this.network.wif, this.d.toBuffer(32), this.compressed)
}n/a
verify = function (hash, signature) {
return ecdsa.verify(hash, signature, this.Q)
}n/a
function ECSignature(r, s) {
typeforce(types.tuple(types.BigInt, types.BigInt), arguments)
this.r = r
this.s = s
}n/a
fromDER = function (buffer) {
var decode = bip66.decode(buffer)
var r = BigInteger.fromDERInteger(decode.r)
var s = BigInteger.fromDERInteger(decode.s)
return new ECSignature(r, s)
}n/a
parseCompact = function (buffer) {
if (buffer.length !== 65) throw new Error('Invalid signature length')
var flagByte = buffer.readUInt8(0) - 27
if (flagByte !== (flagByte & 7)) throw new Error('Invalid signature parameter')
var compressed = !!(flagByte & 4)
var recoveryParam = flagByte & 3
var r = BigInteger.fromBuffer(buffer.slice(1, 33))
var s = BigInteger.fromBuffer(buffer.slice(33))
return {
compressed: compressed,
i: recoveryParam,
signature: new ECSignature(r, s)
}
}n/a
parseScriptSignature = function (buffer) {
var hashType = buffer.readUInt8(buffer.length - 1)
var hashTypeMod = hashType & ~0x80
if (hashTypeMod <= 0x00 || hashTypeMod >= 0x04) throw new Error('Invalid hashType ' + hashType)
return {
signature: ECSignature.fromDER(buffer.slice(0, -1)),
hashType: hashType
}
}n/a
toCompact = function (i, compressed) {
if (compressed) {
i += 4
}
i += 27
var buffer = new Buffer(65)
buffer.writeUInt8(i, 0)
this.r.toBuffer(32).copy(buffer, 1)
this.s.toBuffer(32).copy(buffer, 33)
return buffer
}n/a
toDER = function () {
var r = new Buffer(this.r.toDERInteger())
var s = new Buffer(this.s.toDERInteger())
return bip66.encode(r, s)
}n/a
toScriptSignature = function (hashType) {
var hashTypeMod = hashType & ~0x80
if (hashTypeMod <= 0 || hashTypeMod >= 4) throw new Error('Invalid hashType ' + hashType)
var hashTypeBuffer = new Buffer(1)
hashTypeBuffer.writeUInt8(hashType, 0)
return Buffer.concat([this.toDER(), hashTypeBuffer])
}n/a
function HDNode(keyPair, chainCode) {
typeforce(types.tuple('ECPair', types.Buffer256bit), arguments)
if (!keyPair.compressed) throw new TypeError('BIP32 only allows compressed keyPairs')
this.keyPair = keyPair
this.chainCode = chainCode
this.depth = 0
this.index = 0
this.parentFingerprint = 0x00000000
}n/a
fromBase58 = function (string, networks) {
var buffer = base58check.decode(string)
if (buffer.length !== 78) throw new Error('Invalid buffer length')
// 4 bytes: version bytes
var version = buffer.readUInt32BE(0)
var network
// list of networks?
if (Array.isArray(networks)) {
network = networks.filter(function (x) {
return version === x.bip32.private ||
version === x.bip32.public
}).pop()
if (!network) throw new Error('Unknown network version')
// otherwise, assume a network object (or default to bitcoin)
} else {
network = networks || NETWORKS.bitcoin
}
if (version !== network.bip32.private &&
version !== network.bip32.public) throw new Error('Invalid network version')
// 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ...
var depth = buffer[4]
// 4 bytes: the fingerprint of the parent's key (0x00000000 if master key)
var parentFingerprint = buffer.readUInt32BE(5)
if (depth === 0) {
if (parentFingerprint !== 0x00000000) throw new Error('Invalid parent fingerprint')
}
// 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized.
// This is encoded in MSB order. (0x00000000 if master key)
var index = buffer.readUInt32BE(9)
if (depth === 0 && index !== 0) throw new Error('Invalid index')
// 32 bytes: the chain code
var chainCode = buffer.slice(13, 45)
var keyPair
// 33 bytes: private key data (0x00 + k)
if (version === network.bip32.private) {
if (buffer.readUInt8(45) !== 0x00) throw new Error('Invalid private key')
var d = BigInteger.fromBuffer(buffer.slice(46, 78))
keyPair = new ECPair(d, null, { network: network })
// 33 bytes: public key data (0x02 + X or 0x03 + X)
} else {
var Q = ecurve.Point.decodeFrom(curve, buffer.slice(45, 78))
// Q.compressed is assumed, if somehow this assumption is broken, `new HDNode` will throw
// Verify that the X coordinate in the public point corresponds to a point on the curve.
// If not, the extended public key is invalid.
curve.validate(Q)
keyPair = new ECPair(null, Q, { network: network })
}
var hd = new HDNode(keyPair, chainCode)
hd.depth = depth
hd.index = index
hd.parentFingerprint = parentFingerprint
return hd
}n/a
fromSeedBuffer = function (seed, network) {
typeforce(types.tuple(types.Buffer, types.maybe(types.Network)), arguments)
if (seed.length < 16) throw new TypeError('Seed should be at least 128 bits')
if (seed.length > 64) throw new TypeError('Seed should be at most 512 bits')
var I = createHmac('sha512', HDNode.MASTER_SECRET).update(seed).digest()
var IL = I.slice(0, 32)
var IR = I.slice(32)
// In case IL is 0 or >= n, the master key is invalid
// This is handled by the ECPair constructor
var pIL = BigInteger.fromBuffer(IL)
var keyPair = new ECPair(pIL, null, {
network: network
})
return new HDNode(keyPair, IR)
}n/a
fromSeedHex = function (hex, network) {
return HDNode.fromSeedBuffer(new Buffer(hex, 'hex'), network)
}n/a
derive = function (index) {
typeforce(types.UInt32, index)
var isHardened = index >= HDNode.HIGHEST_BIT
var data = new Buffer(37)
// Hardened child
if (isHardened) {
if (this.isNeutered()) throw new TypeError('Could not derive hardened child key')
// data = 0x00 || ser256(kpar) || ser32(index)
data[0] = 0x00
this.keyPair.d.toBuffer(32).copy(data, 1)
data.writeUInt32BE(index, 33)
// Normal child
} else {
// data = serP(point(kpar)) || ser32(index)
// = serP(Kpar) || ser32(index)
this.keyPair.getPublicKeyBuffer().copy(data, 0)
data.writeUInt32BE(index, 33)
}
var I = createHmac('sha512', this.chainCode).update(data).digest()
var IL = I.slice(0, 32)
var IR = I.slice(32)
var pIL = BigInteger.fromBuffer(IL)
// In case parse256(IL) >= n, proceed with the next value for i
if (pIL.compareTo(curve.n) >= 0) {
return this.derive(index + 1)
}
// Private parent key -> private child key
var derivedKeyPair
if (!this.isNeutered()) {
// ki = parse256(IL) + kpar (mod n)
var ki = pIL.add(this.keyPair.d).mod(curve.n)
// In case ki == 0, proceed with the next value for i
if (ki.signum() === 0) {
return this.derive(index + 1)
}
derivedKeyPair = new ECPair(ki, null, {
network: this.keyPair.network
})
// Public parent key -> public child key
} else {
// Ki = point(parse256(IL)) + Kpar
// = G*IL + Kpar
var Ki = curve.G.multiply(pIL).add(this.keyPair.Q)
// In case Ki is the point at infinity, proceed with the next value for i
if (curve.isInfinity(Ki)) {
return this.derive(index + 1)
}
derivedKeyPair = new ECPair(null, Ki, {
network: this.keyPair.network
})
}
var hd = new HDNode(derivedKeyPair, IR)
hd.depth = this.depth + 1
hd.index = index
hd.parentFingerprint = this.getFingerprint().readUInt32BE(0)
return hd
}n/a
deriveHardened = function (index) {
typeforce(types.UInt31, index)
// Only derives hardened private keys by default
return this.derive(index + HDNode.HIGHEST_BIT)
}n/a
derivePath = function (path) {
typeforce(types.BIP32Path, path)
var splitPath = path.split('/')
if (splitPath[0] === 'm') {
if (this.parentFingerprint) {
throw new Error('Not a master node')
}
splitPath = splitPath.slice(1)
}
return splitPath.reduce(function (prevHd, indexStr) {
var index
if (indexStr.slice(-1) === "'") {
index = parseInt(indexStr.slice(0, -1), 10)
return prevHd.deriveHardened(index)
} else {
index = parseInt(indexStr, 10)
return prevHd.derive(index)
}
}, this)
}n/a
getAddress = function () {
return this.keyPair.getAddress()
}n/a
getFingerprint = function () {
return this.getIdentifier().slice(0, 4)
}n/a
getIdentifier = function () {
return bcrypto.hash160(this.keyPair.getPublicKeyBuffer())
}n/a
getNetwork = function () {
return this.keyPair.getNetwork()
}n/a
getPublicKeyBuffer = function () {
return this.keyPair.getPublicKeyBuffer()
}n/a
isNeutered = function () {
return !(this.keyPair.d)
}n/a
neutered = function () {
var neuteredKeyPair = new ECPair(null, this.keyPair.Q, {
network: this.keyPair.network
})
var neutered = new HDNode(neuteredKeyPair, this.chainCode)
neutered.depth = this.depth
neutered.index = this.index
neutered.parentFingerprint = this.parentFingerprint
return neutered
}n/a
sign = function (hash) {
return this.keyPair.sign(hash)
}n/a
toBase58 = function (__isPrivate) {
if (__isPrivate !== undefined) throw new TypeError('Unsupported argument in 2.0.0')
// Version
var network = this.keyPair.network
var version = (!this.isNeutered()) ? network.bip32.private : network.bip32.public
var buffer = new Buffer(78)
// 4 bytes: version bytes
buffer.writeUInt32BE(version, 0)
// 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ....
buffer.writeUInt8(this.depth, 4)
// 4 bytes: the fingerprint of the parent's key (0x00000000 if master key)
buffer.writeUInt32BE(this.parentFingerprint, 5)
// 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized.
// This is encoded in big endian. (0x00000000 if master key)
buffer.writeUInt32BE(this.index, 9)
// 32 bytes: the chain code
this.chainCode.copy(buffer, 13)
// 33 bytes: the public key or private key data
if (!this.isNeutered()) {
// 0x00 + k for private keys
buffer.writeUInt8(0, 45)
this.keyPair.d.toBuffer(32).copy(buffer, 46)
// 33 bytes: the public key
} else {
// X9.62 encoding for public keys
this.keyPair.getPublicKeyBuffer().copy(buffer, 45)
}
return base58check.encode(buffer)
}n/a
verify = function (hash, signature) {
return this.keyPair.verify(hash, signature)
}n/a
function Transaction() {
this.version = 1
this.locktime = 0
this.ins = []
this.outs = []
}n/a
fromBuffer = function (buffer, __noStrict) {
var offset = 0
function readSlice (n) {
offset += n
return buffer.slice(offset - n, offset)
}
function readUInt32 () {
var i = buffer.readUInt32LE(offset)
offset += 4
return i
}
function readInt32 () {
var i = buffer.readInt32LE(offset)
offset += 4
return i
}
function readUInt64 () {
var i = bufferutils.readUInt64LE(buffer, offset)
offset += 8
return i
}
function readVarInt () {
var vi = varuint.decode(buffer, offset)
offset += varuint.decode.bytes
return vi
}
function readVarSlice () {
return readSlice(readVarInt())
}
function readVector () {
var count = readVarInt()
var vector = []
for (var i = 0; i < count; i++) vector.push(readVarSlice())
return vector
}
var tx = new Transaction()
tx.version = readInt32()
var marker = buffer.readUInt8(offset)
var flag = buffer.readUInt8(offset + 1)
var hasWitnesses = false
if (marker === Transaction.ADVANCED_TRANSACTION_MARKER &&
flag === Transaction.ADVANCED_TRANSACTION_FLAG) {
offset += 2
hasWitnesses = true
}
var vinLen = readVarInt()
for (var i = 0; i < vinLen; ++i) {
tx.ins.push({
hash: readSlice(32),
index: readUInt32(),
script: readVarSlice(),
sequence: readUInt32(),
witness: EMPTY_WITNESS
})
}
var voutLen = readVarInt()
for (i = 0; i < voutLen; ++i) {
tx.outs.push({
value: readUInt64(),
script: readVarSlice()
})
}
if (hasWitnesses) {
for (i = 0; i < vinLen; ++i) {
tx.ins[i].witness = readVector()
}
// was this pointless?
if (!tx.hasWitnesses()) throw new Error('Transaction has superfluous witness data')
}
tx.locktime = readUInt32()
if (__noStrict) return tx
if (offset !== buffer.length) throw new Error('Transaction has unexpected data')
return tx
}...
// Step G
v = createHmac('sha256', k).update(v).digest()
// Step H1/H2a, ignored as tlen === qlen (256 bit)
// Step H2b
v = createHmac('sha256', k).update(v).digest()
var T = BigInteger.fromBuffer(v)
// Step H3, repeat until T is within the interval [1, n - 1] and is suitable for ECDSA
while (T.signum() <= 0 || T.compareTo(secp256k1.n) >= 0 || !checkSig(T)) {
k = createHmac('sha256', k)
.update(v)
.update(ZERO)
.digest()
...fromHex = function (hex) {
return Transaction.fromBuffer(Buffer.from(hex, 'hex'))
}n/a
isCoinbaseHash = function (buffer) {
typeforce(types.Hash256bit, buffer)
for (var i = 0; i < 32; ++i) {
if (buffer[i] !== 0) return false
}
return true
}n/a
__byteLength = function (__allowWitness) {
var hasWitnesses = __allowWitness && this.hasWitnesses()
return (
(hasWitnesses ? 10 : 8) +
varuint.encodingLength(this.ins.length) +
varuint.encodingLength(this.outs.length) +
this.ins.reduce(function (sum, input) { return sum + 40 + varSliceSize(input.script) }, 0) +
this.outs.reduce(function (sum, output) { return sum + 8 + varSliceSize(output.script) }, 0) +
(hasWitnesses ? this.ins.reduce(function (sum, input) { return sum + vectorSize(input.witness) }, 0) : 0)
)
}n/a
__toBuffer = function (buffer, initialOffset, __allowWitness) {
if (!buffer) buffer = new Buffer(this.__byteLength(__allowWitness))
var 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) }
function writeInt32 (i) { offset = buffer.writeInt32LE(i, offset) }
function writeUInt64 (i) { offset = bufferutils.writeUInt64LE(buffer, i, offset) }
function writeVarInt (i) {
varuint.encode(i, buffer, offset)
offset += varuint.encode.bytes
}
function writeVarSlice (slice) { writeVarInt(slice.length); writeSlice(slice) }
function writeVector (vector) { writeVarInt(vector.length); vector.forEach(writeVarSlice) }
writeInt32(this.version)
var hasWitnesses = __allowWitness && this.hasWitnesses()
if (hasWitnesses) {
writeUInt8(Transaction.ADVANCED_TRANSACTION_MARKER)
writeUInt8(Transaction.ADVANCED_TRANSACTION_FLAG)
}
writeVarInt(this.ins.length)
this.ins.forEach(function (txIn) {
writeSlice(txIn.hash)
writeUInt32(txIn.index)
writeVarSlice(txIn.script)
writeUInt32(txIn.sequence)
})
writeVarInt(this.outs.length)
this.outs.forEach(function (txOut) {
if (!txOut.valueBuffer) {
writeUInt64(txOut.value)
} else {
writeSlice(txOut.valueBuffer)
}
writeVarSlice(txOut.script)
})
if (hasWitnesses) {
this.ins.forEach(function (input) {
writeVector(input.witness)
})
}
writeUInt32(this.locktime)
// avoid slicing unless necessary
if (initialOffset !== undefined) return buffer.slice(initialOffset, offset)
return buffer
}n/a
addInput = function (hash, index, sequence, scriptSig) {
typeforce(types.tuple(
types.Hash256bit,
types.UInt32,
types.maybe(types.UInt32),
types.maybe(types.Buffer)
), arguments)
if (types.Null(sequence)) {
sequence = Transaction.DEFAULT_SEQUENCE
}
// Add the input and return the input's index
return (this.ins.push({
hash: hash,
index: index,
script: scriptSig || EMPTY_SCRIPT,
sequence: sequence,
witness: EMPTY_WITNESS
}) - 1)
}n/a
addOutput = function (scriptPubKey, value) {
typeforce(types.tuple(types.Buffer, types.Satoshi), arguments)
// Add the output and return the output's index
return (this.outs.push({
script: scriptPubKey,
value: value
}) - 1)
}n/a
byteLength = function () {
return this.__byteLength(true)
}n/a
clone = function () {
var newTx = new Transaction()
newTx.version = this.version
newTx.locktime = this.locktime
newTx.ins = this.ins.map(function (txIn) {
return {
hash: txIn.hash,
index: txIn.index,
script: txIn.script,
sequence: txIn.sequence,
witness: txIn.witness
}
})
newTx.outs = this.outs.map(function (txOut) {
return {
script: txOut.script,
value: txOut.value
}
})
return newTx
}n/a
getHash = function () {
return bcrypto.hash256(this.__toBuffer(undefined, undefined, false))
}n/a
getId = function () {
// transaction hash's are displayed in reverse order
return this.getHash().reverse().toString('hex')
}n/a
hasWitnesses = function () {
return this.ins.some(function (x) {
return x.witness.length !== 0
})
}n/a
hashForSignature = function (inIndex, prevOutScript, hashType) {
typeforce(types.tuple(types.UInt32, types.Buffer, /* types.UInt8 */ types.Number), arguments)
// https://github.com/bitcoin/bitcoin/blob/master/src/test/sighash_tests.cpp#L29
if (inIndex >= this.ins.length) return ONE
// ignore OP_CODESEPARATOR
var ourScript = bscript.compile(bscript.decompile(prevOutScript).filter(function (x) {
return x !== opcodes.OP_CODESEPARATOR
}))
var txTmp = this.clone()
// SIGHASH_NONE: ignore all outputs? (wildcard payee)
if ((hashType & 0x1f) === Transaction.SIGHASH_NONE) {
txTmp.outs = []
// ignore sequence numbers (except at inIndex)
txTmp.ins.forEach(function (input, i) {
if (i === inIndex) return
input.sequence = 0
})
// SIGHASH_SINGLE: ignore all outputs, except at the same index?
} else if ((hashType & 0x1f) === Transaction.SIGHASH_SINGLE) {
// https://github.com/bitcoin/bitcoin/blob/master/src/test/sighash_tests.cpp#L60
if (inIndex >= this.outs.length) return ONE
// truncate outputs after
txTmp.outs.length = inIndex + 1
// "blank" outputs before
for (var i = 0; i < inIndex; i++) {
txTmp.outs[i] = BLANK_OUTPUT
}
// ignore sequence numbers (except at inIndex)
txTmp.ins.forEach(function (input, y) {
if (y === inIndex) return
input.sequence = 0
})
}
// SIGHASH_ANYONECANPAY: ignore inputs entirely?
if (hashType & Transaction.SIGHASH_ANYONECANPAY) {
txTmp.ins = [txTmp.ins[inIndex]]
txTmp.ins[0].script = ourScript
// SIGHASH_ALL: only ignore input scripts
} else {
// "blank" others input scripts
txTmp.ins.forEach(function (input) { input.script = EMPTY_SCRIPT })
txTmp.ins[inIndex].script = ourScript
}
// serialize and hash
var buffer = new Buffer(txTmp.__byteLength(false) + 4)
buffer.writeInt32LE(hashType, buffer.length - 4)
txTmp.__toBuffer(buffer, 0, false)
return bcrypto.hash256(buffer)
}n/a
hashForWitnessV0 = function (inIndex, prevOutScript, value, hashType) {
typeforce(types.tuple(types.UInt32, types.Buffer, types.Satoshi, types.UInt32), arguments)
var 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) }
function writeVarInt (i) {
varuint.encode(i, tbuffer, toffset)
toffset += varuint.encode.bytes
}
function writeVarSlice (slice) { writeVarInt(slice.length); writeSlice(slice) }
var hashOutputs = ZERO
var hashPrevouts = ZERO
var hashSequence = ZERO
if (!(hashType & Transaction.SIGHASH_ANYONECANPAY)) {
tbuffer = new Buffer(36 * this.ins.length)
toffset = 0
this.ins.forEach(function (txIn) {
writeSlice(txIn.hash)
writeUInt32(txIn.index)
})
hashPrevouts = bcrypto.hash256(tbuffer)
}
if (!(hashType & Transaction.SIGHASH_ANYONECANPAY) &&
(hashType & 0x1f) !== Transaction.SIGHASH_SINGLE &&
(hashType & 0x1f) !== Transaction.SIGHASH_NONE) {
tbuffer = new Buffer(4 * this.ins.length)
toffset = 0
this.ins.forEach(function (txIn) {
writeUInt32(txIn.sequence)
})
hashSequence = bcrypto.hash256(tbuffer)
}
if ((hashType & 0x1f) !== Transaction.SIGHASH_SINGLE &&
(hashType & 0x1f) !== Transaction.SIGHASH_NONE) {
var txOutsSize = this.outs.reduce(function (sum, output) {
return sum + 8 + varSliceSize(output.script)
}, 0)
tbuffer = new Buffer(txOutsSize)
toffset = 0
this.outs.forEach(function (out) {
writeUInt64(out.value)
writeVarSlice(out.script)
})
hashOutputs = bcrypto.hash256(tbuffer)
} else if ((hashType & 0x1f) === Transaction.SIGHASH_SINGLE && inIndex < this.outs.length) {
var output = this.outs[inIndex]
tbuffer = new Buffer(8 + varSliceSize(output.script))
toffset = 0
writeUInt64(output.value)
writeVarSlice(output.script)
hashOutputs = bcrypto.hash256(tbuffer)
}
tbuffer = new Buffer(156 + varSliceSize(prevOutScript))
toffset = 0
var input = this.ins[inIndex]
writeUInt32(this.version)
writeSlice(hashPrevouts)
writeSlice(hashSequence)
writeSlice(input.hash)
writeUInt32(input.index)
writeVarSlice(prevOutScript)
writeUInt64(value)
writeUInt32(input.sequence)
writeSlice(hashOutputs)
writeUInt32(this.locktime)
writeUInt32(hashType)
return bcrypto.hash256(tbuffer)
}n/a
isCoinbase = function () {
return this.ins.length === 1 && Transaction.isCoinbaseHash(this.ins[0].hash)
}n/a
setInputScript = function (index, scriptSig) {
typeforce(types.tuple(types.Number, types.Buffer), arguments)
this.ins[index].script = scriptSig
}n/a
setWitness = function (index, witness) {
typeforce(types.tuple(types.Number, [types.Buffer]), arguments)
this.ins[index].witness = witness
}n/a
toBuffer = function (buffer, initialOffset) {
return this.__toBuffer(buffer, initialOffset, true)
}...
}
var N_OVER_TWO = secp256k1.n.shiftRight(1)
function sign (hash, d) {
typeforce(types.tuple(types.Hash256bit, types.BigInt), arguments)
var x = d.toBuffer(32)
var e = BigInteger.fromBuffer(hash)
var n = secp256k1.n
var G = secp256k1.G
var r, s
deterministicGenerateK(hash, x, function (k) {
var Q = G.multiply(k)
...toHex = function () {
return this.toBuffer().toString('hex')
}n/a
function TransactionBuilder(network, maximumFeeRate) {
this.prevTxMap = {}
this.network = network || networks.bitcoin
// WARNING: This is __NOT__ to be relied on, its just another potential safety mechanism (safety in-depth)
this.maximumFeeRate = maximumFeeRate || 1000
this.inputs = []
this.tx = new Transaction()
}n/a
fromTransaction = function (transaction, network) {
var txb = new TransactionBuilder(network)
// Copy transaction fields
txb.setVersion(transaction.version)
txb.setLockTime(transaction.locktime)
// Copy outputs (done first to avoid signature invalidation)
transaction.outs.forEach(function (txOut) {
txb.addOutput(txOut.script, txOut.value)
})
// Copy inputs
transaction.ins.forEach(function (txIn) {
txb.__addInputUnsafe(txIn.hash, txIn.index, {
sequence: txIn.sequence,
script: txIn.script,
witness: txIn.witness
})
})
// fix some things not possible through the public API
txb.inputs.forEach(function (input, i) {
fixMultisigOrder(input, transaction, i)
})
return txb
}n/a
__addInputUnsafe = function (txHash, vout, options) {
if (Transaction.isCoinbaseHash(txHash)) {
throw new Error('coinbase inputs not supported')
}
var prevTxOut = txHash.toString('hex') + ':' + vout
if (this.prevTxMap[prevTxOut] !== undefined) throw new Error('Duplicate TxOut: ' + prevTxOut)
var input = {}
// derive what we can from the scriptSig
if (options.script !== undefined) {
input = expandInput(options.script, options.witness)
}
// if an input value was given, retain it
if (options.value !== undefined) {
input.value = options.value
}
// derive what we can from the previous transactions output script
if (!input.prevOutScript && options.prevOutScript) {
var prevOutType
if (!input.pubKeys && !input.signatures) {
var expanded = expandOutput(options.prevOutScript)
if (expanded.pubKeys) {
input.pubKeys = expanded.pubKeys
input.signatures = expanded.signatures
}
prevOutType = expanded.scriptType
}
input.prevOutScript = options.prevOutScript
input.prevOutType = prevOutType || bscript.classifyOutput(options.prevOutScript)
}
var vin = this.tx.addInput(txHash, vout, options.sequence, options.scriptSig)
this.inputs[vin] = input
this.prevTxMap[prevTxOut] = vin
return vin
}n/a
__build = function (allowIncomplete) {
if (!allowIncomplete) {
if (!this.tx.ins.length) throw new Error('Transaction has no inputs')
if (!this.tx.outs.length) throw new Error('Transaction has no outputs')
}
var tx = this.tx.clone()
// Create script signatures from inputs
this.inputs.forEach(function (input, i) {
var scriptType = input.witnessScriptType || input.redeemScriptType || input.prevOutType
if (!scriptType && !allowIncomplete) throw new Error('Transaction is not complete')
var result = buildInput(input, allowIncomplete)
// skip if no result
if (!allowIncomplete) {
if (SIGNABLE.indexOf(result.type) === -1 && result.type !== bscript.types.P2WPKH) {
throw new Error(result.type + ' not supported')
}
}
tx.setInputScript(i, result.script)
tx.setWitness(i, result.witness)
})
if (!allowIncomplete) {
// do not rely on this, its merely a last resort
if (this.__overMaximumFees(tx.byteLength())) {
throw new Error('Transaction has absurd fees')
}
}
return tx
}n/a
__canModifyInputs = function () {
return this.inputs.every(function (input) {
// any signatures?
if (input.signatures === undefined) return true
return input.signatures.every(function (signature) {
if (!signature) return true
var hashType = signatureHashType(signature)
// if SIGHASH_ANYONECANPAY is set, signatures would not
// be invalidated by more inputs
return hashType & Transaction.SIGHASH_ANYONECANPAY
})
})
}n/a
__canModifyOutputs = function () {
var nInputs = this.tx.ins.length
var 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)
var hashTypeMod = hashType & 0x1f
if (hashTypeMod === Transaction.SIGHASH_NONE) return true
if (hashTypeMod === Transaction.SIGHASH_SINGLE) {
// if SIGHASH_SINGLE is set, and nInputs > nOutputs
// some signatures would be invalidated by the addition
// of more outputs
return nInputs <= nOutputs
}
})
})
}n/a
__overMaximumFees = function (bytes) {
// not all inputs will have .value defined
var 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
return feeRate > this.maximumFeeRate
}n/a
addInput = function (txHash, vout, sequence, prevOutScript) {
if (!this.__canModifyInputs()) {
throw new Error('No, this would invalidate signatures')
}
var value
// is it a hex string?
if (typeof txHash === 'string') {
// transaction hashs's are displayed in reverse order, un-reverse it
txHash = new Buffer(txHash, 'hex').reverse()
// is it a Transaction object?
} else if (txHash instanceof Transaction) {
var txOut = txHash.outs[vout]
prevOutScript = txOut.script
value = txOut.value
txHash = txHash.getHash()
}
return this.__addInputUnsafe(txHash, vout, {
sequence: sequence,
prevOutScript: prevOutScript,
value: value
})
}n/a
addOutput = function (scriptPubKey, value) {
if (!this.__canModifyOutputs()) {
throw new Error('No, this would invalidate signatures')
}
// Attempt to get a script if it's a base58 address string
if (typeof scriptPubKey === 'string') {
scriptPubKey = baddress.toOutputScript(scriptPubKey, this.network)
}
return this.tx.addOutput(scriptPubKey, value)
}n/a
build = function () {
return this.__build(false)
}n/a
buildIncomplete = function () {
return this.__build(true)
}n/a
setLockTime = function (locktime) {
typeforce(types.UInt32, locktime)
// if any signatures exist, throw
if (this.inputs.some(function (input) {
if (!input.signatures) return false
return input.signatures.some(function (s) { return s })
})) {
throw new Error('No, this would invalidate signatures')
}
this.tx.locktime = locktime
}n/a
setVersion = function (version) {
typeforce(types.UInt32, version)
// XXX: this might eventually become more complex depending on what the versions represent
this.tx.version = version
}n/a
sign = function (vin, keyPair, redeemScript, hashType, witnessValue, witnessScript) {
if (keyPair.network !== this.network) throw new Error('Inconsistent network')
if (!this.inputs[vin]) throw new Error('No input at index: ' + vin)
hashType = hashType || Transaction.SIGHASH_ALL
var input = this.inputs[vin]
// if redeemScript was previously provided, enforce consistency
if (input.redeemScript !== undefined &&
redeemScript &&
!input.redeemScript.equals(redeemScript)) {
throw new Error('Inconsistent redeemScript')
}
var kpPubKey = keyPair.getPublicKeyBuffer()
if (!canSign(input)) {
prepareInput(input, kpPubKey, redeemScript, witnessValue, witnessScript)
if (!canSign(input)) throw Error(input.prevOutType + ' not supported')
}
// ready to sign
var signatureHash
if (input.witness) {
signatureHash = this.tx.hashForWitnessV0(vin, input.signScript, witnessValue, hashType)
} else {
signatureHash = this.tx.hashForSignature(vin, input.signScript, hashType)
}
// enforce in order signing of public keys
var signed = input.pubKeys.some(function (pubKey, i) {
if (!kpPubKey.equals(pubKey)) return false
if (input.signatures[i]) throw new Error('Signature already exists')
input.signatures[i] = keyPair.sign(signatureHash).toScriptSignature(hashType)
return true
})
if (!signed) throw new Error('Key pair cannot sign for this input')
}n/a
function fromBase58Check(address) {
var payload = bs58check.decode(address)
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[0]
var hash = payload.slice(1)
return { hash: hash, version: version }
}n/a
function fromOutputScript(outputScript, network) {
network = network || networks.bitcoin
if (bscript.pubKeyHash.output.check(outputScript)) return toBase58Check(bscript.compile(outputScript).slice(3, 23), network.pubKeyHash
)
if (bscript.scriptHash.output.check(outputScript)) return toBase58Check(bscript.compile(outputScript).slice(2, 22), network.scriptHash
)
throw new Error(bscript.toASM(outputScript) + ' has no matching Address')
}n/a
function toBase58Check(hash, version) {
typeforce(types.tuple(types.Hash160bit, types.UInt8), arguments)
var payload = new Buffer(21)
payload.writeUInt8(version, 0)
hash.copy(payload, 1)
return bs58check.encode(payload)
}n/a
function toOutputScript(address, network) {
network = network || networks.bitcoin
var decode = fromBase58Check(address)
if (decode.version === network.pubKeyHash) return bscript.pubKeyHash.output.encode(decode.hash)
if (decode.version === network.scriptHash) return bscript.scriptHash.output.encode(decode.hash)
throw new Error(address + ' has no matching Script')
}n/a
function encodingLength(i) {
return i < OPS.OP_PUSHDATA1 ? 1
: i <= 0xff ? 2
: i <= 0xffff ? 3
: 5
}n/a
function decode(buffer, offset) {
var opcode = buffer.readUInt8(offset)
var number, size
// ~6 bit
if (opcode < OPS.OP_PUSHDATA1) {
number = opcode
size = 1
// 8 bit
} else if (opcode === OPS.OP_PUSHDATA1) {
if (offset + 2 > buffer.length) return null
number = buffer.readUInt8(offset + 1)
size = 2
// 16 bit
} else if (opcode === OPS.OP_PUSHDATA2) {
if (offset + 3 > buffer.length) return null
number = buffer.readUInt16LE(offset + 1)
size = 3
// 32 bit
} else {
if (offset + 5 > buffer.length) return null
if (opcode !== OPS.OP_PUSHDATA4) throw new Error('Unexpected opcode')
number = buffer.readUInt32LE(offset + 1)
size = 5
}
return {
opcode: opcode,
number: number,
size: size
}
}n/a
function readUInt64LE(buffer, offset) {
var a = buffer.readUInt32LE(offset)
var b = buffer.readUInt32LE(offset + 4)
b *= 0x100000000
verifuint(b + a, 0x001fffffffffffff)
return b + a
}n/a
function readVarInt(buffer, offset) {
var result = varuint.decode(buffer, offset)
return {
number: result,
size: varuint.decode.bytes
}
}n/a
function encode(number, buffer, offset) {
checkUInt53(number)
if (!buffer) buffer = new Buffer(encodingLength(number))
if (!Buffer.isBuffer(buffer)) throw new TypeError('buffer must be a Buffer instance')
if (!offset) offset = 0
// 8 bit
if (number < 0xfd) {
buffer.writeUInt8(number, offset)
encode.bytes = 1
// 16 bit
} else if (number <= 0xffff) {
buffer.writeUInt8(0xfd, offset)
buffer.writeUInt16LE(number, offset + 1)
encode.bytes = 3
// 32 bit
} else if (number <= 0xffffffff) {
buffer.writeUInt8(0xfe, offset)
buffer.writeUInt32LE(number, offset + 1)
encode.bytes = 5
// 64 bit
} else {
buffer.writeUInt8(0xff, offset)
buffer.writeUInt32LE(number >>> 0, offset + 1)
buffer.writeUInt32LE((number / 0x100000000) | 0, offset + 5)
encode.bytes = 9
}
return buffer
}n/a
function encodingLength(number) {
checkUInt53(number)
return (
number < 0xfd ? 1
: number <= 0xffff ? 3
: number <= 0xffffffff ? 5
: 9
)
}n/a
function encode(buffer, number, offset) {
var size = encodingLength(number)
// ~6 bit
if (size === 1) {
buffer.writeUInt8(number, offset)
// 8 bit
} else if (size === 2) {
buffer.writeUInt8(OPS.OP_PUSHDATA1, offset)
buffer.writeUInt8(number, offset + 1)
// 16 bit
} else if (size === 3) {
buffer.writeUInt8(OPS.OP_PUSHDATA2, offset)
buffer.writeUInt16LE(number, offset + 1)
// 32 bit
} else {
buffer.writeUInt8(OPS.OP_PUSHDATA4, offset)
buffer.writeUInt32LE(number, offset + 1)
}
return size
}n/a
function writeUInt64LE(buffer, value, offset) {
verifuint(value, 0x001fffffffffffff)
buffer.writeInt32LE(value & -1, offset)
buffer.writeUInt32LE(Math.floor(value / 0x100000000), offset + 4)
return offset + 8
}n/a
function writeVarInt(buffer, number, offset) {
varuint.encode(number, buffer, offset)
return varuint.encode.bytes
}n/a
function hash160(buffer) {
return ripemd160(sha256(buffer))
}n/a
function hash256(buffer) {
return sha256(sha256(buffer))
}n/a
function ripemd160(buffer) {
return createHash('rmd160').update(buffer).digest()
}n/a
function sha1(buffer) {
return createHash('sha1').update(buffer).digest()
}n/a
function sha256(buffer) {
return createHash('sha256').update(buffer).digest()
}n/a
function deterministicGenerateK(hash, x, checkSig) {
typeforce(types.tuple(
types.Hash256bit,
types.Buffer256bit,
types.Function
), arguments)
var k = new Buffer(32)
var v = new Buffer(32)
// Step A, ignored as hash already provided
// Step B
v.fill(1)
// Step C
k.fill(0)
// Step D
k = createHmac('sha256', k)
.update(v)
.update(ZERO)
.update(x)
.update(hash)
.digest()
// Step E
v = createHmac('sha256', k).update(v).digest()
// Step F
k = createHmac('sha256', k)
.update(v)
.update(ONE)
.update(x)
.update(hash)
.digest()
// Step G
v = createHmac('sha256', k).update(v).digest()
// Step H1/H2a, ignored as tlen === qlen (256 bit)
// Step H2b
v = createHmac('sha256', k).update(v).digest()
var T = BigInteger.fromBuffer(v)
// Step H3, repeat until T is within the interval [1, n - 1] and is suitable for ECDSA
while (T.signum() <= 0 || T.compareTo(secp256k1.n) >= 0 || !checkSig(T)) {
k = createHmac('sha256', k)
.update(v)
.update(ZERO)
.digest()
v = createHmac('sha256', k).update(v).digest()
// Step H1/H2a, again, ignored as tlen === qlen (256 bit)
// Step H2b again
v = createHmac('sha256', k).update(v).digest()
T = BigInteger.fromBuffer(v)
}
return T
}n/a
function sign(hash, d) {
typeforce(types.tuple(types.Hash256bit, types.BigInt), arguments)
var x = d.toBuffer(32)
var e = BigInteger.fromBuffer(hash)
var n = secp256k1.n
var G = secp256k1.G
var r, s
deterministicGenerateK(hash, x, function (k) {
var Q = G.multiply(k)
if (secp256k1.isInfinity(Q)) return false
r = Q.affineX.mod(n)
if (r.signum() === 0) return false
s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n)
if (s.signum() === 0) return false
return true
})
// enforce low S values, see bip62: 'low s values in signatures'
if (s.compareTo(N_OVER_TWO) > 0) {
s = n.subtract(s)
}
return new ECSignature(r, s)
}n/a
function verify(hash, signature, Q) {
typeforce(types.tuple(
types.Hash256bit,
types.ECSignature,
types.ECPoint
), arguments)
var n = secp256k1.n
var G = secp256k1.G
var r = signature.r
var s = signature.s
// 1.4.1 Enforce r and s are both integers in the interval [1, n − 1]
if (r.signum() <= 0 || r.compareTo(n) >= 0) return false
if (s.signum() <= 0 || s.compareTo(n) >= 0) return false
// 1.4.2 H = Hash(M), already done by the user
// 1.4.3 e = H
var e = BigInteger.fromBuffer(hash)
// Compute s^-1
var sInv = s.modInverse(n)
// 1.4.4 Compute u1 = es^−1 mod n
// u2 = rs^−1 mod n
var u1 = e.multiply(sInv).mod(n)
var u2 = r.multiply(sInv).mod(n)
// 1.4.5 Compute R = (xR, yR)
// R = u1G + u2Q
var R = G.multiplyTwo(u1, Q, u2)
// 1.4.5 (cont.) Enforce R is not at infinity
if (secp256k1.isInfinity(R)) return false
// 1.4.6 Convert the field element R.x to an integer
var xR = R.affineX
// 1.4.7 Set v = xR mod n
var v = xR.mod(n)
// 1.4.8 If v = r, output "valid", and if v != r, output "invalid"
return v.equals(r)
}n/a
function classifyInput(script, allowIncomplete) {
// XXX: optimization, below functions .decompile before use
var chunks = decompile(script)
if (pubKeyHash.input.check(chunks)) return types.P2PKH
if (scriptHash.input.check(chunks, allowIncomplete)) return types.P2SH
if (multisig.input.check(chunks, allowIncomplete)) return types.MULTISIG
if (pubKey.input.check(chunks)) return types.P2PK
return types.NONSTANDARD
}n/a
function classifyOutput(script) {
if (witnessPubKeyHash.output.check(script)) return types.P2WPKH
if (witnessScriptHash.output.check(script)) return types.P2WSH
if (pubKeyHash.output.check(script)) return types.P2PKH
if (scriptHash.output.check(script)) return types.P2SH
// XXX: optimization, below functions .decompile before use
var chunks = decompile(script)
if (multisig.output.check(chunks)) return types.MULTISIG
if (pubKey.output.check(chunks)) return types.P2PK
if (witnessCommitment.output.check(chunks)) return types.WITNESS_COMMITMENT
if (nullData.output.check(chunks)) return types.NULLDATA
return types.NONSTANDARD
}n/a
function classifyWitness(script, allowIncomplete) {
// XXX: optimization, below functions .decompile before use
var chunks = decompile(script)
if (witnessPubKeyHash.input.check(chunks)) return types.P2WPKH
if (witnessScriptHash.input.check(chunks, allowIncomplete)) return types.P2WSH
return types.NONSTANDARD
}n/a
function check(script, allowIncomplete) {
var chunks = bscript.decompile(script)
if (chunks.length < 2) return false
if (chunks[0] !== OPS.OP_0) return false
if (allowIncomplete) {
return chunks.slice(1).every(partialSignature)
}
return chunks.slice(1).every(bscript.isCanonicalSignature)
}...
P2SH: 'scripthash',
P2WPKH: 'witnesspubkeyhash',
P2WSH: 'witnessscripthash',
WITNESS_COMMITMENT: 'witnesscommitment'
}
function classifyOutput (script) {
if (witnessPubKeyHash.output.check(script)) return types.P2WPKH
if (witnessScriptHash.output.check(script)) return types.P2WSH
if (pubKeyHash.output.check(script)) return types.P2PKH
if (scriptHash.output.check(script)) return types.P2SH
// XXX: optimization, below functions .decompile before use
var chunks = decompile(script)
if (multisig.output.check(chunks)) return types.MULTISIG
...function decode(buffer, allowIncomplete) {
var stack = bscript.decompile(buffer)
return decodeStack(stack, allowIncomplete)
}...
}
check.toJSON = function () { return 'multisig input' }
function encodeStack (signatures, scriptPubKey) {
typeforce([partialSignature], signatures)
if (scriptPubKey) {
var scriptData = bscript.multisig.output.decode(scriptPubKey)
if (signatures.length < scriptData.m) {
throw new TypeError('Not enough signatures provided')
}
if (signatures.length > scriptData.pubKeys.length) {
throw new TypeError('Too many signatures provided')
...function decodeStack(stack, allowIncomplete) {
typeforce(check, stack, allowIncomplete)
return stack.slice(1)
}n/a
function encode(signatures, scriptPubKey) {
return bscript.compile(encodeStack(signatures, scriptPubKey))
}n/a
function encodeStack(signatures, scriptPubKey) {
typeforce([partialSignature], signatures)
if (scriptPubKey) {
var scriptData = bscript.multisig.output.decode(scriptPubKey)
if (signatures.length < scriptData.m) {
throw new TypeError('Not enough signatures provided')
}
if (signatures.length > scriptData.pubKeys.length) {
throw new TypeError('Too many signatures provided')
}
}
return [].concat(new Buffer(0), signatures)
}n/a
function check(script, allowIncomplete) {
var 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
if (m <= 0) return false
if (n > 16) return false
if (m > n) return false
if (n !== chunks.length - 3) return false
if (allowIncomplete) return true
var keys = chunks.slice(1, -2)
return keys.every(bscript.isCanonicalPubKey)
}...
P2SH: 'scripthash',
P2WPKH: 'witnesspubkeyhash',
P2WSH: 'witnessscripthash',
WITNESS_COMMITMENT: 'witnesscommitment'
}
function classifyOutput (script) {
if (witnessPubKeyHash.output.check(script)) return types.P2WPKH
if (witnessScriptHash.output.check(script)) return types.P2WSH
if (pubKeyHash.output.check(script)) return types.P2PKH
if (scriptHash.output.check(script)) return types.P2SH
// XXX: optimization, below functions .decompile before use
var chunks = decompile(script)
if (multisig.output.check(chunks)) return types.MULTISIG
...function decode(buffer, allowIncomplete) {
var chunks = bscript.decompile(buffer)
typeforce(check, chunks, allowIncomplete)
return {
m: chunks[0] - OP_INT_BASE,
pubKeys: chunks.slice(1, -2)
}
}...
}
check.toJSON = function () { return 'multisig input' }
function encodeStack (signatures, scriptPubKey) {
typeforce([partialSignature], signatures)
if (scriptPubKey) {
var scriptData = bscript.multisig.output.decode(scriptPubKey)
if (signatures.length < scriptData.m) {
throw new TypeError('Not enough signatures provided')
}
if (signatures.length > scriptData.pubKeys.length) {
throw new TypeError('Too many signatures provided')
...function encode(m, pubKeys) {
typeforce({
m: types.Number,
pubKeys: [bscript.isCanonicalPubKey]
}, {
m: m,
pubKeys: pubKeys
})
var n = pubKeys.length
if (n < m) throw new TypeError('Not enough pubKeys provided')
return bscript.compile([].concat(
OP_INT_BASE + m,
pubKeys,
OP_INT_BASE + n,
OPS.OP_CHECKMULTISIG
))
}n/a
function classifyInput(script, allowIncomplete) {
// XXX: optimization, below functions .decompile before use
var chunks = decompile(script)
if (pubKeyHash.input.check(chunks)) return types.P2PKH
if (scriptHash.input.check(chunks, allowIncomplete)) return types.P2SH
if (multisig.input.check(chunks, allowIncomplete)) return types.MULTISIG
if (pubKey.input.check(chunks)) return types.P2PK
return types.NONSTANDARD
}n/a
function classifyOutput(script) {
if (witnessPubKeyHash.output.check(script)) return types.P2WPKH
if (witnessScriptHash.output.check(script)) return types.P2WSH
if (pubKeyHash.output.check(script)) return types.P2PKH
if (scriptHash.output.check(script)) return types.P2SH
// XXX: optimization, below functions .decompile before use
var chunks = decompile(script)
if (multisig.output.check(chunks)) return types.MULTISIG
if (pubKey.output.check(chunks)) return types.P2PK
if (witnessCommitment.output.check(chunks)) return types.WITNESS_COMMITMENT
if (nullData.output.check(chunks)) return types.NULLDATA
return types.NONSTANDARD
}n/a
function classifyWitness(script, allowIncomplete) {
// XXX: optimization, below functions .decompile before use
var chunks = decompile(script)
if (witnessPubKeyHash.input.check(chunks)) return types.P2WPKH
if (witnessScriptHash.input.check(chunks, allowIncomplete)) return types.P2WSH
return types.NONSTANDARD
}n/a
function compile(chunks) {
// TODO: remove me
if (Buffer.isBuffer(chunks)) return chunks
typeforce(types.Array, chunks)
var bufferSize = chunks.reduce(function (accum, chunk) {
// data chunk
if (Buffer.isBuffer(chunk)) {
// adhere to BIP62.3, minimal push policy
if (chunk.length === 1 && (chunk[0] === 0x81 || (chunk[0] >= 1 && chunk[0] <= 16))) {
return accum + 1
}
return accum + pushdata.encodingLength(chunk.length) + chunk.length
}
// opcode
return accum + 1
}, 0.0)
var buffer = new Buffer(bufferSize)
var offset = 0
chunks.forEach(function (chunk) {
// data chunk
if (Buffer.isBuffer(chunk)) {
// adhere to BIP62.3, minimal push policy
if (chunk.length === 1 && chunk[0] >= 1 && chunk[0] <= 16) {
var opcode = OP_INT_BASE + chunk[0]
buffer.writeUInt8(opcode, offset)
offset += 1
return
}
if (chunk.length === 1 && chunk[0] === 0x81) {
buffer.writeUInt8(OPS.OP_1NEGATE, offset)
offset += 1
return
}
offset += pushdata.encode(buffer, chunk.length, offset)
chunk.copy(buffer, offset)
offset += chunk.length
// opcode
} else {
buffer.writeUInt8(chunk, offset)
offset += 1
}
})
if (offset !== buffer.length) throw new Error('Could not decode chunks')
return buffer
}...
}
// external dependent types
var BigInt = typeforce.quacksLike('BigInteger')
var ECPoint = typeforce.quacksLike('Point')
// exposed, external API
var ECSignature = typeforce.compile({ r: BigInt, s: BigInt })
var Network = typeforce.compile({
messagePrefix: typeforce.oneOf(typeforce.Buffer, typeforce.String),
bip32: {
public: typeforce.UInt32,
private: typeforce.UInt32
},
pubKeyHash: typeforce.UInt8,
...function decompile(buffer) {
// TODO: remove me
if (types.Array(buffer)) return buffer
typeforce(types.Buffer, buffer)
var chunks = []
var i = 0
while (i < buffer.length) {
var opcode = buffer[i]
// data chunk
if ((opcode > OPS.OP_0) && (opcode <= OPS.OP_PUSHDATA4)) {
var d = pushdata.decode(buffer, i)
// did reading a pushDataInt fail? empty script
if (d === null) return []
i += d.size
// attempt to read too much data? empty script
if (i + d.number > buffer.length) return []
var data = buffer.slice(i, i + d.number)
i += d.number
chunks.push(data)
// opcode
} else {
chunks.push(opcode)
i += 1
}
}
return chunks
}...
var OPS = require('bitcoin-ops')
function partialSignature (value) {
return value === OPS.OP_0 || bscript.isCanonicalSignature(value)
}
function check (script, allowIncomplete) {
var chunks = bscript.decompile(script)
if (chunks.length < 2) return false
if (chunks[0] !== OPS.OP_0) return false
if (allowIncomplete) {
return chunks.slice(1).every(partialSignature)
}
...function fromASM(asm) {
typeforce(types.String, asm)
return compile(asm.split(' ').map(function (chunkStr) {
// opcode?
if (OPS[chunkStr] !== undefined) return OPS[chunkStr]
typeforce(types.Hex, chunkStr)
// data!
return new Buffer(chunkStr, 'hex')
}))
}n/a
function isCanonicalPubKey(buffer) {
if (!Buffer.isBuffer(buffer)) return false
if (buffer.length < 33) return false
switch (buffer[0]) {
case 0x02:
case 0x03:
return buffer.length === 33
case 0x04:
return buffer.length === 65
}
return false
}n/a
function isCanonicalSignature(buffer) {
if (!Buffer.isBuffer(buffer)) return false
if (!isDefinedHashType(buffer[buffer.length - 1])) return false
return bip66.check(buffer.slice(0, -1))
}...
// OP_0 [signatures ...]
var bscript = require('../../script')
var typeforce = require('typeforce')
var OPS = require('bitcoin-ops')
function partialSignature (value) {
return value === OPS.OP_0 || bscript.isCanonicalSignature(value)
}
function check (script, allowIncomplete) {
var chunks = bscript.decompile(script)
if (chunks.length < 2) return false
if (chunks[0] !== OPS.OP_0) return false
...function isDefinedHashType(hashType) {
var hashTypeMod = hashType & ~0x80
// return hashTypeMod > SIGHASH_ALL && hashTypeMod < SIGHASH_SINGLE
return hashTypeMod > 0x00 && hashTypeMod < 0x04
}n/a
function isPushOnly(value) {
return types.Array(value) && value.every(isPushOnlyChunk)
}n/a
function toASM(chunks) {
if (Buffer.isBuffer(chunks)) {
chunks = decompile(chunks)
}
return chunks.map(function (chunk) {
// data?
if (Buffer.isBuffer(chunk)) return chunk.toString('hex')
// opcode!
return REVERSE_OPS[chunk]
}).join(' ')
}n/a
function toStack(chunks) {
chunks = decompile(chunks)
typeforce(isPushOnly, chunks)
return chunks.map(function (op) {
if (Buffer.isBuffer(op)) return op
if (op === OPS.OP_0) return new Buffer(0)
return scriptNumber.encode(op - OP_INT_BASE)
})
}n/a
function decode(buffer, maxLength, minimal) {
maxLength = maxLength || 4
minimal = minimal === undefined ? true : minimal
var length = buffer.length
if (length === 0) return 0
if (length > maxLength) throw new TypeError('Script number overflow')
if (minimal) {
if ((buffer[length - 1] & 0x7f) === 0) {
if (length <= 1 || (buffer[length - 2] & 0x80) === 0) throw new Error('Non-minimally encoded script number')
}
}
// 40-bit
if (length === 5) {
var a = buffer.readUInt32LE(0)
var 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
for (var i = 0; i < length; ++i) {
result |= buffer[i] << (8 * i)
}
if (buffer[length - 1] & 0x80) return -(result & ~(0x80 << (8 * (length - 1))))
return result
}...
}
check.toJSON = function () { return 'multisig input' }
function encodeStack (signatures, scriptPubKey) {
typeforce([partialSignature], signatures)
if (scriptPubKey) {
var scriptData = bscript.multisig.output.decode(scriptPubKey)
if (signatures.length < scriptData.m) {
throw new TypeError('Not enough signatures provided')
}
if (signatures.length > scriptData.pubKeys.length) {
throw new TypeError('Too many signatures provided')
...function encode(number) {
var value = Math.abs(number)
var size = scriptNumSize(value)
var buffer = new Buffer(size)
var negative = number < 0
for (var i = 0; i < size; ++i) {
buffer.writeUInt8(value & 0xff, i)
value >>= 8
}
if (buffer[size - 1] & 0x80) {
buffer.writeUInt8(negative ? 0x80 : 0x00, size - 1)
} else if (negative) {
buffer[size - 1] |= 0x80
}
return buffer
}n/a
Array = function (value) { return value !== null && value !== undefined && value.constructor === Array }n/a
function BIP32Path(value) {
return typeforce.String(value) && value.match(/^(m\/)?(\d+'?\/)*\d+'?$/)
}n/a
function _quacksLike(value) {
return type === getValueTypeName(value)
}n/a
Boolean = function (value) { return typeof value === 'boolean' }n/a
function _Buffer(value) {
return Buffer.isBuffer(value)
}n/a
function BufferN(value) {
if (!Buffer.isBuffer(value)) return false
if (value.length !== length) {
throw errors.tfCustomError('Buffer(Length: ' + length + ')', 'Buffer(Length: ' + value.length + ')')
}
return true
}n/a
function _BufferN(length) {
function BufferN (value) {
if (!Buffer.isBuffer(value)) return false
if (value.length !== length) {
throw errors.tfCustomError('Buffer(Length: ' + length + ')', 'Buffer(Length: ' + value.length + ')')
}
return true
}
BufferN.toJSON = function () { return 'Buffer' }
return BufferN
}...
wif: typeforce.UInt8
})
// extend typeforce types with ours
var types = {
BigInt: BigInt,
BIP32Path: BIP32Path,
Buffer256bit: typeforce.BufferN(32),
ECPoint: ECPoint,
ECSignature: ECSignature,
Hash160bit: typeforce.BufferN(20),
Hash256bit: typeforce.BufferN(32),
Network: Network,
Satoshi: Satoshi,
UInt31: UInt31
...function _quacksLike(value) {
return type === getValueTypeName(value)
}n/a
function _object(value, strict) {
if (!NATIVE.Object(value)) return false
if (NATIVE.Null(value)) return false
var propertyName
try {
for (propertyName in type) {
var propertyType = type[propertyName]
var propertyValue = value[propertyName]
typeforce(propertyType, propertyValue, strict)
}
} catch (e) {
throw tfSubError(e, propertyName)
}
if (strict) {
for (propertyName in value) {
if (type[propertyName]) continue
throw new TfPropertyTypeError(undefined, propertyName)
}
}
return true
}n/a
function Finite(value) {
return typeof value === 'number' && isFinite(value)
}n/a
Function = function (value) { return typeof value === 'function' }n/a
function BufferN(value) {
if (!Buffer.isBuffer(value)) return false
if (value.length !== length) {
throw errors.tfCustomError('Buffer(Length: ' + length + ')', 'Buffer(Length: ' + value.length + ')')
}
return true
}n/a
function BufferN(value) {
if (!Buffer.isBuffer(value)) return false
if (value.length !== length) {
throw errors.tfCustomError('Buffer(Length: ' + length + ')', 'Buffer(Length: ' + value.length + ')')
}
return true
}n/a
function Hex(value) {
return typeof value === 'string' && /^([0-9a-f]{2})+$/i.test(value)
}n/a
function _HexN(length) {
function HexN (value) {
if (!Hex(value)) return false
if (value.length !== length) {
throw errors.tfCustomError('Hex(Length: ' + length + ')', 'Hex(Length: ' + value.length + ')')
}
return true
}
HexN.toJSON = function () { return 'Hex' }
return HexN
}n/a
function Int16(value) { return ((value << 16) >> 16) === value }n/a
function Int32(value) { return (value | 0) === value }n/a
function Int8(value) { return ((value << 24) >> 24) === value }n/a
function _object(value, strict) {
if (!NATIVE.Object(value)) return false
if (NATIVE.Null(value)) return false
var propertyName
try {
for (propertyName in type) {
var propertyType = type[propertyName]
var propertyValue = value[propertyName]
typeforce(propertyType, propertyValue, strict)
}
} catch (e) {
throw tfSubError(e, propertyName)
}
if (strict) {
for (propertyName in value) {
if (type[propertyName]) continue
throw new TfPropertyTypeError(undefined, propertyName)
}
}
return true
}n/a
Null = function (value) { return value === undefined || value === null }n/a
Number = function (value) { return typeof value === 'number' }...
var OP_INT_BASE = OPS.OP_RESERVED // OP_1 - 1
function check (script, allowIncomplete) {
var 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
if (m <= 0) return false
if (n > 16) return false
if (m > n) return false
...Object = function (value) { return typeof value === 'object' }n/a
function Satoshi(value) {
return typeforce.UInt53(value) && value <= SATOSHI_MAX
}n/a
String = function (value) { return typeof value === 'string' }...
var UINT31_MAX = Math.pow(2, 31) - 1
function UInt31 (value) {
return typeforce.UInt32(value) && value <= UINT31_MAX
}
function BIP32Path (value) {
return typeforce.String(value) && value.match(/^(m\/)?(\d+'?\/)*\d+
x27;?$/)
}
BIP32Path.toJSON = function () { return 'BIP32 derivation path' }
var SATOSHI_MAX = 21 * 1e14
function Satoshi (value) {
return typeforce.UInt53(value) && value <= SATOSHI_MAX
}
...function TfPropertyTypeError(type, property, label, value, error, valueTypeName) {
this.__error = error || Error.call(this)
this.__label = label
this.__property = property
this.__type = type
this.__value = value
this.__valueTypeName = valueTypeName
var message
Object.defineProperty(this, 'message', {
enumerable: true,
get: function () {
if (message) return message
if (type) {
valueTypeName = valueTypeName || getValueTypeName(value)
message = tfPropertyErrorString(type, label, property, value, valueTypeName)
} else {
message = 'Unexpected property "' + property + '"'
}
return message
}
})
}n/a
function TfTypeError(type, value, valueTypeName) {
this.__error = Error.call(this)
this.__type = type
this.__value = value
this.__valueTypeName = valueTypeName
var message
Object.defineProperty(this, 'message', {
enumerable: true,
get: function () {
if (message) return message
valueTypeName = valueTypeName || getValueTypeName(value)
message = tfErrorString(type, value, valueTypeName)
return message
}
})
}n/a
function UInt16(value) { return (value & 0xffff) === value }n/a
function UInt31(value) {
return typeforce.UInt32(value) && value <= UINT31_MAX
}n/a
function UInt32(value) { return (value >>> 0) === value }...
var typeforce = require('typeforce')
var UINT31_MAX = Math.pow(2, 31) - 1
function UInt31 (value) {
return typeforce.UInt32(value) && value <= UINT31_MAX
}
function BIP32Path (value) {
return typeforce.String(value) && value.match(/^(m\/)?(\d+'?\/)*\d+'?$/)
}
BIP32Path.toJSON = function () { return 'BIP32 derivation path' }
...function UInt53(value) {
return typeof value === 'number' &&
value >= 0 &&
value <= UINT53_MAX &&
Math.floor(value) === value
}...
function BIP32Path (value) {
return typeforce.String(value) && value.match(/^(m\/)?(\d+'?\/)*\d+'?$/)
}
BIP32Path.toJSON = function () { return 'BIP32 derivation path' }
var SATOSHI_MAX = 21 * 1e14
function Satoshi (value) {
return typeforce.UInt53(value) && value <= SATOSHI_MAX
}
// external dependent types
var BigInt = typeforce.quacksLike('BigInteger')
var ECPoint = typeforce.quacksLike('Point')
// exposed, external API
...function UInt8(value) { return (value & 0xff) === value }n/a
function arrayOf(type) {
type = compile(type)
function _arrayOf (array, strict) {
if (!NATIVE.Array(array)) return false
return array.every(function (value, i) {
try {
return typeforce(type, value, strict)
} catch (e) {
throw tfSubError(e, i)
}
})
}
_arrayOf.toJSON = function () { return '[' + tfJSON(type) + ']' }
return _arrayOf
}n/a
function __async(type, value, strict, callback) {
// default to falsy strict if using shorthand overload
if (typeof strict === 'function') return __async(type, value, false, strict)
try {
typeforce(type, value, strict)
} catch (e) {
return callback(e)
}
callback()
}n/a
function compile(type) {
if (NATIVE.String(type)) {
if (type[0] === '?') return TYPES.maybe(compile(type.slice(1)))
return NATIVE[type] || TYPES.quacksLike(type)
} else if (type && NATIVE.Object(type)) {
if (NATIVE.Array(type)) return TYPES.arrayOf(compile(type[0]))
return TYPES.object(type)
} else if (NATIVE.Function(type)) {
return type
}
return TYPES.value(type)
}...
}
// external dependent types
var BigInt = typeforce.quacksLike('BigInteger')
var ECPoint = typeforce.quacksLike('Point')
// exposed, external API
var ECSignature = typeforce.compile({ r: BigInt, s: BigInt })
var Network = typeforce.compile({
messagePrefix: typeforce.oneOf(typeforce.Buffer, typeforce.String),
bip32: {
public: typeforce.UInt32,
private: typeforce.UInt32
},
pubKeyHash: typeforce.UInt8,
...function map(propertyType, propertyKeyType) {
propertyType = compile(propertyType)
if (propertyKeyType) propertyKeyType = compile(propertyKeyType)
function _map (value, strict) {
if (!NATIVE.Object(value, strict)) return false
if (NATIVE.Null(value, strict)) return false
for (var propertyName in value) {
try {
if (propertyKeyType) {
typeforce(propertyKeyType, propertyName, strict)
}
} catch (e) {
throw tfSubError(e, propertyName, 'key')
}
try {
var propertyValue = value[propertyName]
typeforce(propertyType, propertyValue, strict)
} catch (e) {
throw tfSubError(e, propertyName)
}
}
return true
}
if (propertyKeyType) {
_map.toJSON = function () {
return '{' + tfJSON(propertyKeyType) + ': ' + tfJSON(propertyType) + '}'
}
} else {
_map.toJSON = function () { return '{' + tfJSON(propertyType) + '}' }
}
return _map
}n/a
function maybe(type) {
type = compile(type)
function _maybe (value, strict) {
return NATIVE.Null(value) || type(value, strict, maybe)
}
_maybe.toJSON = function () { return '?' + tfJSON(type) }
return _maybe
}n/a
function object(uncompiled) {
var type = {}
for (var typePropertyName in uncompiled) {
type[typePropertyName] = compile(uncompiled[typePropertyName])
}
function _object (value, strict) {
if (!NATIVE.Object(value)) return false
if (NATIVE.Null(value)) return false
var propertyName
try {
for (propertyName in type) {
var propertyType = type[propertyName]
var propertyValue = value[propertyName]
typeforce(propertyType, propertyValue, strict)
}
} catch (e) {
throw tfSubError(e, propertyName)
}
if (strict) {
for (propertyName in value) {
if (type[propertyName]) continue
throw new TfPropertyTypeError(undefined, propertyName)
}
}
return true
}
_object.toJSON = function () { return tfJSON(type) }
return _object
}n/a
function oneOf() {
var types = [].slice.call(arguments).map(compile)
function _oneOf (value, strict) {
return types.some(function (type) {
try {
return typeforce(type, value, strict)
} catch (e) {
return false
}
})
}
_oneOf.toJSON = function () { return types.map(tfJSON).join('|') }
return _oneOf
}...
// external dependent types
var BigInt = typeforce.quacksLike('BigInteger')
var ECPoint = typeforce.quacksLike('Point')
// exposed, external API
var ECSignature = typeforce.compile({ r: BigInt, s: BigInt })
var Network = typeforce.compile({
messagePrefix: typeforce.oneOf(typeforce.Buffer, typeforce.String),
bip32: {
public: typeforce.UInt32,
private: typeforce.UInt32
},
pubKeyHash: typeforce.UInt8,
scriptHash: typeforce.UInt8,
wif: typeforce.UInt8
...function quacksLike(type) {
function _quacksLike (value) {
return type === getValueTypeName(value)
}
_quacksLike.toJSON = function () { return type }
return _quacksLike
}...
var SATOSHI_MAX = 21 * 1e14
function Satoshi (value) {
return typeforce.UInt53(value) && value <= SATOSHI_MAX
}
// external dependent types
var BigInt = typeforce.quacksLike('BigInteger')
var ECPoint = typeforce.quacksLike('Point')
// exposed, external API
var ECSignature = typeforce.compile({ r: BigInt, s: BigInt })
var Network = typeforce.compile({
messagePrefix: typeforce.oneOf(typeforce.Buffer, typeforce.String),
bip32: {
...function tuple() {
var types = [].slice.call(arguments).map(compile)
function _tuple (values, strict) {
return types.every(function (type, i) {
try {
return typeforce(type, values[i], strict)
} catch (e) {
throw tfSubError(e, i)
}
}) && (!strict || values.length === arguments.length)
}
_tuple.toJSON = function () { return '(' + types.map(tfJSON).join(', ') + ')' }
return _tuple
}...
var ONE = new Buffer([1])
var ecurve = require('ecurve')
var secp256k1 = ecurve.getCurveByName('secp256k1')
// https://tools.ietf.org/html/rfc6979#section-3.2
function deterministicGenerateK (hash, x, checkSig) {
typeforce(types.tuple(
types.Hash256bit,
types.Buffer256bit,
types.Function
), arguments)
var k = new Buffer(32)
var v = new Buffer(32)
...function value(expected) {
function _value (actual) {
return actual === expected
}
_value.toJSON = function () { return expected }
return _value
}n/a