From 0ad8fbc6ba35b1f24113d498e16182ae5155db72 Mon Sep 17 00:00:00 2001 From: d-yokoi Date: Sun, 3 Mar 2019 23:31:17 +0900 Subject: [PATCH] style: add build output after applying prettier --- src/address.js | 3 +- src/block.js | 21 ++++--- src/classify.js | 2 +- src/crypto.js | 12 +++- src/ecpair.js | 13 +++-- src/networks.js | 12 ++-- src/payments/embed.js | 5 +- src/payments/lazy.js | 4 +- src/payments/p2ms.js | 10 ++-- src/payments/p2pk.js | 17 ++---- src/payments/p2pkh.js | 14 ++--- src/payments/p2sh.js | 24 +++----- src/payments/p2wpkh.js | 15 ++--- src/payments/p2wsh.js | 31 +++++----- src/script.js | 14 +++-- src/script_number.js | 19 +++--- src/script_signature.js | 9 +-- src/templates/nulldata.js | 7 ++- src/transaction.js | 62 ++++++++++---------- src/transaction_builder.js | 116 +++++++++++++++++++++---------------- src/types.js | 8 ++- types/index.d.ts | 2 +- 22 files changed, 217 insertions(+), 203 deletions(-) diff --git a/src/address.js b/src/address.js index ed11e5c..f12cd8d 100644 --- a/src/address.js +++ b/src/address.js @@ -25,7 +25,7 @@ function fromBech32(address) { return { version: result.words[0], prefix: result.prefix, - data: Buffer.from(data) + data: Buffer.from(data), }; } exports.fromBech32 = fromBech32; @@ -44,6 +44,7 @@ function toBech32(data, version, prefix) { } exports.toBech32 = toBech32; function fromOutputScript(output, network) { + //TODO: Network network = network || networks.bitcoin; try { return payments.p2pkh({ output, network }).address; diff --git a/src/block.js b/src/block.js index cb593ac..eb3fb8b 100644 --- a/src/block.js +++ b/src/block.js @@ -10,22 +10,22 @@ const varuint = require('varuint-bitcoin'); const errorMerkleNoTxes = new TypeError('Cannot compute merkle root for zero transactions'); const errorWitnessNotSegwit = new TypeError('Cannot compute witness commit for non-segwit block'); function txesHaveWitnessCommit(transactions) { - return transactions instanceof Array && + return (transactions instanceof Array && transactions[0] && transactions[0].ins && transactions[0].ins instanceof Array && transactions[0].ins[0] && transactions[0].ins[0].witness && transactions[0].ins[0].witness instanceof Array && - transactions[0].ins[0].witness.length > 0; + transactions[0].ins[0].witness.length > 0); } function anyTxHasWitness(transactions) { - return transactions instanceof Array && + return (transactions instanceof Array && transactions.some(tx => typeof tx === 'object' && tx.ins instanceof Array && tx.ins.some(input => typeof input === 'object' && input.witness instanceof Array && - input.witness.length > 0)); + input.witness.length > 0))); } class Block { constructor() { @@ -116,9 +116,7 @@ class Block { // There is no rule for the index of the output, so use filter to find it. // The root is prepended with 0xaa21a9ed so check for 0x6a24aa21a9ed // If multiple commits are found, the output with highest index is assumed. - let witnessCommits = this.transactions[0].outs - .filter(out => out.script.slice(0, 6).equals(Buffer.from('6a24aa21a9ed', 'hex'))) - .map(out => out.script.slice(6, 38)); + let witnessCommits = this.transactions[0].outs.filter(out => out.script.slice(0, 6).equals(Buffer.from('6a24aa21a9ed', 'hex'))).map(out => out.script.slice(6, 38)); if (witnessCommits.length === 0) return null; // Use the commit with the highest output (should only be one though) @@ -141,8 +139,9 @@ class Block { byteLength(headersOnly) { if (headersOnly || !this.transactions) return 80; - return 80 + varuint.encodingLength(this.transactions.length) + - this.transactions.reduce((a, x) => a + x.byteLength(), 0); + return (80 + + varuint.encodingLength(this.transactions.length) + + this.transactions.reduce((a, x) => a + x.byteLength(), 0)); } getHash() { return bcrypto.hash256(this.toBuffer(true)); @@ -197,8 +196,8 @@ class Block { let hasWitnessCommit = this.hasWitnessCommit(); if (!hasWitnessCommit && this.hasWitness()) return false; - return this.__checkMerkleRoot() && - (hasWitnessCommit ? this.__checkWitnessCommit() : true); + return (this.__checkMerkleRoot() && + (hasWitnessCommit ? this.__checkWitnessCommit() : true)); } checkMerkleRoot() { console.warn('Deprecation Warning: Block method checkMerkleRoot will be ' + diff --git a/src/classify.js b/src/classify.js index a2109c2..0aec5c4 100644 --- a/src/classify.js +++ b/src/classify.js @@ -18,7 +18,7 @@ const types = { P2SH: 'scripthash', P2WPKH: 'witnesspubkeyhash', P2WSH: 'witnessscripthash', - WITNESS_COMMITMENT: 'witnesscommitment' + WITNESS_COMMITMENT: 'witnesscommitment', }; exports.types = types; function classifyOutput(script) { diff --git a/src/crypto.js b/src/crypto.js index 4165d30..d494b86 100644 --- a/src/crypto.js +++ b/src/crypto.js @@ -2,15 +2,21 @@ Object.defineProperty(exports, "__esModule", { value: true }); const createHash = require('create-hash'); function ripemd160(buffer) { - return createHash('rmd160').update(buffer).digest(); + return createHash('rmd160') + .update(buffer) + .digest(); } exports.ripemd160 = ripemd160; function sha1(buffer) { - return createHash('sha1').update(buffer).digest(); + return createHash('sha1') + .update(buffer) + .digest(); } exports.sha1 = sha1; function sha256(buffer) { - return createHash('sha256').update(buffer).digest(); + return createHash('sha256') + .update(buffer) + .digest(); } exports.sha256 = sha256; function hash160(buffer) { diff --git a/src/ecpair.js b/src/ecpair.js index d4dc94f..7d376ac 100644 --- a/src/ecpair.js +++ b/src/ecpair.js @@ -8,13 +8,14 @@ const typeforce = require('typeforce'); const wif = require('wif'); const isOptions = typeforce.maybe(typeforce.compile({ compressed: types.maybe(types.Boolean), - network: types.maybe(types.Network) + network: types.maybe(types.Network), })); class ECPair { constructor(d, Q, options) { if (options === undefined) options = {}; - this.compressed = options.compressed === undefined ? true : options.compressed; + this.compressed = + options.compressed === undefined ? true : options.compressed; this.network = options.network || NETWORKS.bitcoin; this.__d = undefined; this.__Q = undefined; @@ -64,9 +65,11 @@ function fromWIF(string, network) { const version = decoded.version; // list of networks? if (types.Array(network)) { - network = network.filter(function (x) { + network = network + .filter(function (x) { return version === x.wif; - }).pop(); + }) + .pop(); if (!network) throw new Error('Unknown network version'); // otherwise, assume a network object (or default to bitcoin) @@ -78,7 +81,7 @@ function fromWIF(string, network) { } return fromPrivateKey(decoded.privateKey, { compressed: decoded.compressed, - network: network + network: network, }); } exports.fromWIF = fromWIF; diff --git a/src/networks.js b/src/networks.js index 821cd96..298808d 100644 --- a/src/networks.js +++ b/src/networks.js @@ -5,31 +5,31 @@ exports.bitcoin = { bech32: 'bc', bip32: { public: 0x0488b21e, - private: 0x0488ade4 + private: 0x0488ade4, }, pubKeyHash: 0x00, scriptHash: 0x05, - wif: 0x80 + wif: 0x80, }; exports.regtest = { messagePrefix: '\x18Bitcoin Signed Message:\n', bech32: 'bcrt', bip32: { public: 0x043587cf, - private: 0x04358394 + private: 0x04358394, }, pubKeyHash: 0x6f, scriptHash: 0xc4, - wif: 0xef + wif: 0xef, }; exports.testnet = { messagePrefix: '\x18Bitcoin Signed Message:\n', bech32: 'tb', bip32: { public: 0x043587cf, - private: 0x04358394 + private: 0x04358394, }, pubKeyHash: 0x6f, scriptHash: 0xc4, - wif: 0xef + wif: 0xef, }; diff --git a/src/payments/embed.js b/src/payments/embed.js index 7d341ab..0e2a0ae 100644 --- a/src/payments/embed.js +++ b/src/payments/embed.js @@ -14,14 +14,13 @@ function stacksEqual(a, b) { } // output: OP_RETURN ... function p2data(a, opts) { - if (!a.data && - !a.output) + if (!a.data && !a.output) throw new TypeError('Not enough data'); opts = Object.assign({ validate: true }, opts || {}); typef({ network: typef.maybe(typef.Object), output: typef.maybe(typef.Buffer), - data: typef.maybe(typef.arrayOf(typef.Buffer)) + data: typef.maybe(typef.arrayOf(typef.Buffer)), }, a); const network = a.network || networks_1.bitcoin; const o = { network }; diff --git a/src/payments/lazy.js b/src/payments/lazy.js index 2c848e1..9eda8e8 100644 --- a/src/payments/lazy.js +++ b/src/payments/lazy.js @@ -14,9 +14,9 @@ function prop(object, name, f) { configurable: true, enumerable: true, value: value, - writable: true + writable: true, }); - } + }, }); } exports.prop = prop; diff --git a/src/payments/p2ms.js b/src/payments/p2ms.js index a45bd48..4e3c115 100644 --- a/src/payments/p2ms.js +++ b/src/payments/p2ms.js @@ -24,9 +24,8 @@ function p2ms(a, opts) { throw new TypeError('Not enough data'); opts = Object.assign({ validate: true }, opts || {}); function isAcceptableSignature(x) { - return bscript.isCanonicalScriptSignature(x) || - (opts.allowIncomplete && - (x === OPS.OP_0)) !== undefined; // eslint-disable-line + return (bscript.isCanonicalScriptSignature(x) || + (opts.allowIncomplete && x === OPS.OP_0) !== undefined); // eslint-disable-line } typef({ network: typef.maybe(typef.Object), @@ -35,7 +34,7 @@ function p2ms(a, opts) { output: typef.maybe(typef.Buffer), pubkeys: typef.maybe(typef.arrayOf(ecc.isPoint)), signatures: typef.maybe(typef.arrayOf(isAcceptableSignature)), - input: typef.maybe(typef.Buffer) + input: typef.maybe(typef.Buffer), }, a); const network = a.network || networks_1.bitcoin; const o = { network }; @@ -131,7 +130,8 @@ function p2ms(a, opts) { if (a.input) { if (a.input[0] !== OPS.OP_0) throw new TypeError('Input is invalid'); - if (o.signatures.length === 0 || !o.signatures.every(isAcceptableSignature)) + if (o.signatures.length === 0 || + !o.signatures.every(isAcceptableSignature)) throw new TypeError('Input has invalid signature(s)'); if (a.signatures && !stacksEqual(a.signatures, o.signatures)) throw new TypeError('Signature mismatch'); diff --git a/src/payments/p2pk.js b/src/payments/p2pk.js index ab8654d..9c9318f 100644 --- a/src/payments/p2pk.js +++ b/src/payments/p2pk.js @@ -9,11 +9,7 @@ const ecc = require('tiny-secp256k1'); // input: {signature} // output: {pubKey} OP_CHECKSIG function p2pk(a, opts) { - if (!a.input && - !a.output && - !a.pubkey && - !a.input && - !a.signature) + if (!a.input && !a.output && !a.pubkey && !a.input && !a.signature) throw new TypeError('Not enough data'); opts = Object.assign({ validate: true }, opts || {}); typef({ @@ -21,18 +17,17 @@ function p2pk(a, opts) { output: typef.maybe(typef.Buffer), pubkey: typef.maybe(ecc.isPoint), signature: typef.maybe(bscript.isCanonicalScriptSignature), - input: typef.maybe(typef.Buffer) + input: typef.maybe(typef.Buffer), }, a); - const _chunks = lazy.value(function () { return bscript.decompile(a.input); }); + const _chunks = lazy.value(function () { + return bscript.decompile(a.input); + }); const network = a.network || networks_1.bitcoin; const o = { network }; lazy.prop(o, 'output', function () { if (!a.pubkey) return; - return bscript.compile([ - a.pubkey, - OPS.OP_CHECKSIG - ]); + return bscript.compile([a.pubkey, OPS.OP_CHECKSIG]); }); lazy.prop(o, 'pubkey', function () { if (!a.output) diff --git a/src/payments/p2pkh.js b/src/payments/p2pkh.js index 55f4817..6b41a77 100644 --- a/src/payments/p2pkh.js +++ b/src/payments/p2pkh.js @@ -11,11 +11,7 @@ const bs58check = require('bs58check'); // input: {signature} {pubkey} // output: OP_DUP OP_HASH160 {hash160(pubkey)} OP_EQUALVERIFY OP_CHECKSIG function p2pkh(a, opts) { - if (!a.address && - !a.hash && - !a.output && - !a.pubkey && - !a.input) + if (!a.address && !a.hash && !a.output && !a.pubkey && !a.input) throw new TypeError('Not enough data'); opts = Object.assign({ validate: true }, opts || {}); typef({ @@ -25,7 +21,7 @@ function p2pkh(a, opts) { output: typef.maybe(typef.BufferN(25)), pubkey: typef.maybe(ecc.isPoint), signature: typef.maybe(bscript.isCanonicalScriptSignature), - input: typef.maybe(typef.Buffer) + input: typef.maybe(typef.Buffer), }, a); const _address = lazy.value(function () { const payload = bs58check.decode(a.address); @@ -33,7 +29,9 @@ function p2pkh(a, opts) { const hash = payload.slice(1); return { version, hash }; }); - const _chunks = lazy.value(function () { return bscript.decompile(a.input); }); + const _chunks = lazy.value(function () { + return bscript.decompile(a.input); + }); const network = a.network || networks_1.bitcoin; const o = { network }; lazy.prop(o, 'address', function () { @@ -60,7 +58,7 @@ function p2pkh(a, opts) { OPS.OP_HASH160, o.hash, OPS.OP_EQUALVERIFY, - OPS.OP_CHECKSIG + OPS.OP_CHECKSIG, ]); }); lazy.prop(o, 'pubkey', function () { diff --git a/src/payments/p2sh.js b/src/payments/p2sh.js index 8ec9910..bb8f0a0 100644 --- a/src/payments/p2sh.js +++ b/src/payments/p2sh.js @@ -18,11 +18,7 @@ function stacksEqual(a, b) { // witness: // output: OP_HASH160 {hash160(redeemScript)} OP_EQUAL function p2sh(a, opts) { - if (!a.address && - !a.hash && - !a.output && - !a.redeem && - !a.input) + if (!a.address && !a.hash && !a.output && !a.redeem && !a.input) throw new TypeError('Not enough data'); opts = Object.assign({ validate: true }, opts || {}); typef({ @@ -34,10 +30,10 @@ function p2sh(a, opts) { network: typef.maybe(typef.Object), output: typef.maybe(typef.Buffer), input: typef.maybe(typef.Buffer), - witness: typef.maybe(typef.arrayOf(typef.Buffer)) + witness: typef.maybe(typef.arrayOf(typef.Buffer)), }), input: typef.maybe(typef.Buffer), - witness: typef.maybe(typef.arrayOf(typef.Buffer)) + witness: typef.maybe(typef.arrayOf(typef.Buffer)), }, a); let network = a.network; if (!network) { @@ -50,14 +46,16 @@ function p2sh(a, opts) { const hash = payload.slice(1); return { version, hash }; }); - const _chunks = lazy.value(function () { return bscript.decompile(a.input); }); + const _chunks = lazy.value(function () { + return bscript.decompile(a.input); + }); const _redeem = lazy.value(function () { const chunks = _chunks(); return { network, output: chunks[chunks.length - 1], input: bscript.compile(chunks.slice(0, -1)), - witness: a.witness || [] + witness: a.witness || [], }; }); // output dependents @@ -81,11 +79,7 @@ function p2sh(a, opts) { lazy.prop(o, 'output', function () { if (!o.hash) return; - return bscript.compile([ - OPS.OP_HASH160, - o.hash, - OPS.OP_EQUAL - ]); + return bscript.compile([OPS.OP_HASH160, o.hash, OPS.OP_EQUAL]); }); // input dependents lazy.prop(o, 'redeem', function () { @@ -153,7 +147,7 @@ function p2sh(a, opts) { if (hasInput && hasWitness) throw new TypeError('Input and witness provided'); if (hasInput) { - const richunks = bscript.decompile(redeem.input); + const richunks = (bscript.decompile(redeem.input)); if (!bscript.isPushOnly(richunks)) throw new TypeError('Non push-only scriptSig'); } diff --git a/src/payments/p2wpkh.js b/src/payments/p2wpkh.js index 7b269b7..9165f96 100644 --- a/src/payments/p2wpkh.js +++ b/src/payments/p2wpkh.js @@ -13,11 +13,7 @@ const EMPTY_BUFFER = Buffer.alloc(0); // input: <> // output: OP_0 {pubKeyHash} function p2wpkh(a, opts) { - if (!a.address && - !a.hash && - !a.output && - !a.pubkey && - !a.witness) + if (!a.address && !a.hash && !a.output && !a.pubkey && !a.witness) throw new TypeError('Not enough data'); opts = Object.assign({ validate: true }, opts || {}); typef({ @@ -28,7 +24,7 @@ function p2wpkh(a, opts) { output: typef.maybe(typef.BufferN(22)), pubkey: typef.maybe(ecc.isPoint), signature: typef.maybe(bscript.isCanonicalScriptSignature), - witness: typef.maybe(typef.arrayOf(typef.Buffer)) + witness: typef.maybe(typef.arrayOf(typef.Buffer)), }, a); const _address = lazy.value(function () { const result = bech32.decode(a.address); @@ -37,7 +33,7 @@ function p2wpkh(a, opts) { return { version, prefix: result.prefix, - data: Buffer.from(data) + data: Buffer.from(data), }; }); const network = a.network || networks_1.bitcoin; @@ -60,10 +56,7 @@ function p2wpkh(a, opts) { lazy.prop(o, 'output', function () { if (!o.hash) return; - return bscript.compile([ - OPS.OP_0, - o.hash - ]); + return bscript.compile([OPS.OP_0, o.hash]); }); lazy.prop(o, 'pubkey', function () { if (a.pubkey) diff --git a/src/payments/p2wsh.js b/src/payments/p2wsh.js index a7e9f8b..c5eb067 100644 --- a/src/payments/p2wsh.js +++ b/src/payments/p2wsh.js @@ -19,11 +19,7 @@ function stacksEqual(a, b) { // witness: [redeemScriptSig ...] {redeemScript} // output: OP_0 {sha256(redeemScript)} function p2wsh(a, opts) { - if (!a.address && - !a.hash && - !a.output && - !a.redeem && - !a.witness) + if (!a.address && !a.hash && !a.output && !a.redeem && !a.witness) throw new TypeError('Not enough data'); opts = Object.assign({ validate: true }, opts || {}); typef({ @@ -35,10 +31,10 @@ function p2wsh(a, opts) { input: typef.maybe(typef.Buffer), network: typef.maybe(typef.Object), output: typef.maybe(typef.Buffer), - witness: typef.maybe(typef.arrayOf(typef.Buffer)) + witness: typef.maybe(typef.arrayOf(typef.Buffer)), }), input: typef.maybe(typef.BufferN(0)), - witness: typef.maybe(typef.arrayOf(typef.Buffer)) + witness: typef.maybe(typef.arrayOf(typef.Buffer)), }, a); const _address = lazy.value(function () { const result = bech32.decode(a.address); @@ -47,10 +43,12 @@ function p2wsh(a, opts) { return { version, prefix: result.prefix, - data: Buffer.from(data) + data: Buffer.from(data), }; }); - const _rchunks = lazy.value(function () { return bscript.decompile(a.redeem.input); }); + const _rchunks = lazy.value(function () { + return bscript.decompile(a.redeem.input); + }); let network = a.network; if (!network) { network = (a.redeem && a.redeem.network) || networks_1.bitcoin; @@ -74,10 +72,7 @@ function p2wsh(a, opts) { lazy.prop(o, 'output', function () { if (!o.hash) return; - return bscript.compile([ - OPS.OP_0, - o.hash - ]); + return bscript.compile([OPS.OP_0, o.hash]); }); lazy.prop(o, 'redeem', function () { if (!a.witness) @@ -85,7 +80,7 @@ function p2wsh(a, opts) { return { output: a.witness[a.witness.length - 1], input: EMPTY_BUFFER, - witness: a.witness.slice(0, -1) + witness: a.witness.slice(0, -1), }; }); lazy.prop(o, 'input', function () { @@ -165,11 +160,15 @@ function p2wsh(a, opts) { } if (a.redeem.input && !bscript.isPushOnly(_rchunks())) throw new TypeError('Non push-only scriptSig'); - if (a.witness && a.redeem.witness && !stacksEqual(a.witness, a.redeem.witness)) + if (a.witness && + a.redeem.witness && + !stacksEqual(a.witness, a.redeem.witness)) throw new TypeError('Witness and redeem.witness mismatch'); } if (a.witness) { - if (a.redeem && a.redeem.output && !a.redeem.output.equals(a.witness[a.witness.length - 1])) + if (a.redeem && + a.redeem.output && + !a.redeem.output.equals(a.witness[a.witness.length - 1])) throw new TypeError('Witness and redeem.output mismatch'); } } diff --git a/src/script.js b/src/script.js index 3d115cb..a114d1f 100644 --- a/src/script.js +++ b/src/script.js @@ -11,10 +11,10 @@ exports.OPS = require('bitcoin-ops'); const REVERSE_OPS = require('bitcoin-ops/map'); const OP_INT_BASE = exports.OPS.OP_RESERVED; // OP_1 - 1 function isOPInt(value) { - return types.Number(value) && - ((value === exports.OPS.OP_0) || + return (types.Number(value) && + (value === exports.OPS.OP_0 || (value >= exports.OPS.OP_1 && value <= exports.OPS.OP_16) || - (value === exports.OPS.OP_1NEGATE)); + value === exports.OPS.OP_1NEGATE)); } function isPushOnlyChunk(value) { return types.Buffer(value) || isOPInt(value); @@ -96,7 +96,7 @@ function decompile(buffer) { while (i < buffer.length) { const opcode = buffer[i]; // data chunk - if ((opcode > exports.OPS.OP_0) && (opcode <= exports.OPS.OP_PUSHDATA4)) { + if (opcode > exports.OPS.OP_0 && opcode <= exports.OPS.OP_PUSHDATA4) { const d = pushdata.decode(buffer, i); // did reading a pushDataInt fail? if (d === null) @@ -129,7 +129,8 @@ function toASM(chunks) { if (chunksIsBuffer(chunks)) { chunks = decompile(chunks); } - return chunks.map(function (chunk) { + return chunks + .map(function (chunk) { // data? if (singleChunkIsBuffer(chunk)) { const op = asMinimalOP(chunk); @@ -139,7 +140,8 @@ function toASM(chunks) { } // opcode! return REVERSE_OPS[chunk]; - }).join(' '); + }) + .join(' '); } exports.toASM = toASM; function fromASM(asm) { diff --git a/src/script_number.js b/src/script_number.js index da12de6..a8c42d3 100644 --- a/src/script_number.js +++ b/src/script_number.js @@ -19,8 +19,8 @@ function decode(buffer, maxLength, minimal) { const a = buffer.readUInt32LE(0); const b = buffer.readUInt8(4); if (b & 0x80) - return -(((b & ~0x80) * 0x100000000) + a); - return (b * 0x100000000) + a; + return -((b & ~0x80) * 0x100000000 + a); + return b * 0x100000000 + a; } // 32-bit / 24-bit / 16-bit / 8-bit let result = 0; @@ -33,11 +33,16 @@ function decode(buffer, maxLength, minimal) { } exports.decode = decode; function scriptNumSize(i) { - return i > 0x7fffffff ? 5 - : i > 0x7fffff ? 4 - : i > 0x7fff ? 3 - : i > 0x7f ? 2 - : i > 0x00 ? 1 + return i > 0x7fffffff + ? 5 + : i > 0x7fffff + ? 4 + : i > 0x7fff + ? 3 + : i > 0x7f + ? 2 + : i > 0x00 + ? 1 : 0; } function encode(number) { diff --git a/src/script_signature.js b/src/script_signature.js index c3372cd..c185981 100644 --- a/src/script_signature.js +++ b/src/script_signature.js @@ -34,14 +34,14 @@ function decode(buffer) { const s = fromDER(decode.s); return { signature: Buffer.concat([r, s], 64), - hashType: hashType + hashType: hashType, }; } exports.decode = decode; function encode(signature, hashType) { typeforce({ signature: types.BufferN(64), - hashType: types.UInt8 + hashType: types.UInt8, }, { signature, hashType }); const hashTypeMod = hashType & ~0x80; if (hashTypeMod <= 0 || hashTypeMod >= 4) @@ -50,9 +50,6 @@ function encode(signature, hashType) { hashTypeBuffer.writeUInt8(hashType, 0); const r = toDER(signature.slice(0, 32)); const s = toDER(signature.slice(32, 64)); - return Buffer.concat([ - bip66.encode(r, s), - hashTypeBuffer - ]); + return Buffer.concat([bip66.encode(r, s), hashTypeBuffer]); } exports.encode = encode; diff --git a/src/templates/nulldata.js b/src/templates/nulldata.js index fd5320d..b5ffdce 100644 --- a/src/templates/nulldata.js +++ b/src/templates/nulldata.js @@ -5,10 +5,11 @@ const bscript = require("../script"); const OPS = bscript.OPS; function check(script) { const buffer = bscript.compile(script); - return buffer.length > 1 && - buffer[0] === OPS.OP_RETURN; + return buffer.length > 1 && buffer[0] === OPS.OP_RETURN; } exports.check = check; -check.toJSON = function () { return 'null data output'; }; +check.toJSON = function () { + return 'null data output'; +}; const output = { check }; exports.output = output; diff --git a/src/transaction.js b/src/transaction.js index 34d7b40..cfd31fe 100644 --- a/src/transaction.js +++ b/src/transaction.js @@ -14,9 +14,10 @@ function varSliceSize(someScript) { } function vectorSize(someVector) { const length = someVector.length; - return varuint.encodingLength(length) + someVector.reduce((sum, witness) => { - return sum + varSliceSize(witness); - }, 0); + return (varuint.encodingLength(length) + + someVector.reduce((sum, witness) => { + return sum + varSliceSize(witness); + }, 0)); } const EMPTY_SCRIPT = Buffer.allocUnsafe(0); const EMPTY_WITNESS = []; @@ -25,7 +26,7 @@ const ONE = Buffer.from('0000000000000000000000000000000000000000000000000000000 const VALUE_UINT64_MAX = Buffer.from('ffffffffffffffff', 'hex'); const BLANK_OUTPUT = { script: EMPTY_SCRIPT, - valueBuffer: VALUE_UINT64_MAX + valueBuffer: VALUE_UINT64_MAX, }; function isOutput(out) { return out.value !== undefined; @@ -90,14 +91,14 @@ class Transaction { index: readUInt32(), script: readVarSlice(), sequence: readUInt32(), - witness: EMPTY_WITNESS + witness: EMPTY_WITNESS, }); } const voutLen = readVarInt(); for (i = 0; i < voutLen; ++i) { tx.outs.push({ value: readUInt64(), - script: readVarSlice() + script: readVarSlice(), }); } if (hasWitnesses) { @@ -127,7 +128,7 @@ class Transaction { return true; } isCoinbase() { - return this.ins.length === 1 && Transaction.isCoinbaseHash(this.ins[0].hash); + return (this.ins.length === 1 && Transaction.isCoinbaseHash(this.ins[0].hash)); } addInput(hash, index, sequence, scriptSig) { typeforce(types.tuple(types.Hash256bit, types.UInt32, types.maybe(types.UInt32), types.maybe(types.Buffer)), arguments); @@ -140,7 +141,7 @@ class Transaction { index: index, script: scriptSig || EMPTY_SCRIPT, sequence: sequence, - witness: EMPTY_WITNESS + witness: EMPTY_WITNESS, }) - 1); } addOutput(scriptPubKey, value) { @@ -148,11 +149,11 @@ class Transaction { // Add the output and return the output's index return (this.outs.push({ script: scriptPubKey, - value: value + value: value, }) - 1); } hasWitnesses() { - return this.ins.some((x) => { + return this.ins.some(x => { return x.witness.length !== 0; }); } @@ -178,27 +179,29 @@ class Transaction { this.outs.reduce((sum, output) => { return sum + 8 + varSliceSize(output.script); }, 0) + - (hasWitnesses ? this.ins.reduce((sum, input) => { - return sum + vectorSize(input.witness); - }, 0) : 0)); + (hasWitnesses + ? this.ins.reduce((sum, input) => { + return sum + vectorSize(input.witness); + }, 0) + : 0)); } clone() { const newTx = new Transaction(); newTx.version = this.version; newTx.locktime = this.locktime; - newTx.ins = this.ins.map((txIn) => { + newTx.ins = this.ins.map(txIn => { return { hash: txIn.hash, index: txIn.index, script: txIn.script, sequence: txIn.sequence, - witness: txIn.witness + witness: txIn.witness, }; }); - newTx.outs = this.outs.map((txOut) => { + newTx.outs = this.outs.map(txOut => { return { script: txOut.script, - value: txOut.value + value: txOut.value, }; }); return newTx; @@ -217,7 +220,7 @@ class Transaction { if (inIndex >= this.ins.length) return ONE; // ignore OP_CODESEPARATOR - const ourScript = bscript.compile(bscript.decompile(prevOutScript).filter((x) => { + const ourScript = bscript.compile(bscript.decompile(prevOutScript).filter(x => { return x !== script_1.OPS.OP_CODESEPARATOR; })); const txTmp = this.clone(); @@ -257,7 +260,7 @@ class Transaction { } else { // "blank" others input scripts - txTmp.ins.forEach((input) => { + txTmp.ins.forEach(input => { input.script = EMPTY_SCRIPT; }); txTmp.ins[inIndex].script = ourScript; @@ -295,7 +298,7 @@ class Transaction { if (!(hashType & Transaction.SIGHASH_ANYONECANPAY)) { tbuffer = Buffer.allocUnsafe(36 * this.ins.length); toffset = 0; - this.ins.forEach((txIn) => { + this.ins.forEach(txIn => { writeSlice(txIn.hash); writeUInt32(txIn.index); }); @@ -306,7 +309,7 @@ class Transaction { (hashType & 0x1f) !== Transaction.SIGHASH_NONE) { tbuffer = Buffer.allocUnsafe(4 * this.ins.length); toffset = 0; - this.ins.forEach((txIn) => { + this.ins.forEach(txIn => { writeUInt32(txIn.sequence); }); hashSequence = bcrypto.hash256(tbuffer); @@ -318,13 +321,14 @@ class Transaction { }, 0); tbuffer = Buffer.allocUnsafe(txOutsSize); toffset = 0; - this.outs.forEach((out) => { + this.outs.forEach(out => { writeUInt64(out.value); writeVarSlice(out.script); }); hashOutputs = bcrypto.hash256(tbuffer); } - else if ((hashType & 0x1f) === Transaction.SIGHASH_SINGLE && inIndex < this.outs.length) { + else if ((hashType & 0x1f) === Transaction.SIGHASH_SINGLE && + inIndex < this.outs.length) { const output = this.outs[inIndex]; tbuffer = Buffer.allocUnsafe(8 + varSliceSize(output.script)); toffset = 0; @@ -369,13 +373,13 @@ class Transaction { offset += slice.copy(buffer, offset); } function writeUInt8(i) { - offset = (buffer).writeUInt8(i, offset); + offset = buffer.writeUInt8(i, offset); } function writeUInt32(i) { - offset = (buffer).writeUInt32LE(i, offset); + offset = buffer.writeUInt32LE(i, offset); } function writeInt32(i) { - offset = (buffer).writeInt32LE(i, offset); + offset = buffer.writeInt32LE(i, offset); } function writeUInt64(i) { offset = bufferutils.writeUInt64LE(buffer, i, offset); @@ -399,14 +403,14 @@ class Transaction { writeUInt8(Transaction.ADVANCED_TRANSACTION_FLAG); } writeVarInt(this.ins.length); - this.ins.forEach((txIn) => { + this.ins.forEach(txIn => { writeSlice(txIn.hash); writeUInt32(txIn.index); writeVarSlice(txIn.script); writeUInt32(txIn.sequence); }); writeVarInt(this.outs.length); - this.outs.forEach((txOut) => { + this.outs.forEach(txOut => { if (isOutput(txOut)) { writeUInt64(txOut.value); } @@ -416,7 +420,7 @@ class Transaction { writeVarSlice(txOut.script); }); if (hasWitnesses) { - this.ins.forEach((input) => { + this.ins.forEach(input => { writeVector(input.witness); }); } diff --git a/src/transaction_builder.js b/src/transaction_builder.js index 1cdc6bf..540a17a 100644 --- a/src/transaction_builder.js +++ b/src/transaction_builder.js @@ -43,7 +43,7 @@ class TransactionBuilder { txb.__addInputUnsafe(txIn.hash, txIn.index, { sequence: txIn.sequence, script: txIn.script, - witness: txIn.witness + witness: txIn.witness, }); }); // fix some things not possible through the public API @@ -89,7 +89,7 @@ class TransactionBuilder { return this.__addInputUnsafe(txHash, vout, { sequence: sequence, prevOutScript: prevOutScript, - value: value + value: value, }); } __addInputUnsafe(txHash, vout, options) { @@ -194,7 +194,7 @@ class TransactionBuilder { if (!canSign(input)) { if (witnessValue !== undefined) { if (input.value !== undefined && input.value !== witnessValue) - throw new Error('Input didn\'t match witnessValue'); + throw new Error("Input didn't match witnessValue"); typeforce(types.Satoshi, witnessValue); input.value = witnessValue; } @@ -251,18 +251,19 @@ class TransactionBuilder { } // if inputs are being signed with SIGHASH_NONE, we don't strictly need outputs // .build() will fail, but .buildIncomplete() is OK - return (this.__tx.outs.length === 0) && this.__inputs.some((input) => { - if (!input.signatures) - return false; - return input.signatures.some((signature) => { - if (!signature) - return false; // no signature, no issue - const hashType = signatureHashType(signature); - if (hashType & transaction_1.Transaction.SIGHASH_NONE) - return false; // SIGHASH_NONE doesn't care about outputs - return true; // SIGHASH_* does care - }); - }); + return (this.__tx.outs.length === 0 && + this.__inputs.some(input => { + if (!input.signatures) + return false; + return input.signatures.some(signature => { + if (!signature) + return false; // no signature, no issue + const hashType = signatureHashType(signature); + if (hashType & transaction_1.Transaction.SIGHASH_NONE) + return false; // SIGHASH_NONE doesn't care about outputs + return true; // SIGHASH_* does care + }); + })); } __canModifyOutputs() { const nInputs = this.__tx.ins.length; @@ -313,21 +314,25 @@ function expandInput(scriptSig, witnessStack, type, scriptPubKey) { } switch (type) { case SCRIPT_TYPES.P2WPKH: { - const { output, pubkey, signature } = payments.p2wpkh({ witness: witnessStack }); + const { output, pubkey, signature } = payments.p2wpkh({ + witness: witnessStack, + }); return { prevOutScript: output, prevOutType: SCRIPT_TYPES.P2WPKH, pubkeys: [pubkey], - signatures: [signature] + signatures: [signature], }; } case SCRIPT_TYPES.P2PKH: { - const { output, pubkey, signature } = payments.p2pkh({ input: scriptSig }); + const { output, pubkey, signature } = payments.p2pkh({ + input: scriptSig, + }); return { prevOutScript: output, prevOutType: SCRIPT_TYPES.P2PKH, pubkeys: [pubkey], - signatures: [signature] + signatures: [signature], }; } case SCRIPT_TYPES.P2PK: { @@ -335,26 +340,26 @@ function expandInput(scriptSig, witnessStack, type, scriptPubKey) { return { prevOutType: SCRIPT_TYPES.P2PK, pubkeys: [undefined], - signatures: [signature] + signatures: [signature], }; } case SCRIPT_TYPES.P2MS: { const { m, pubkeys, signatures } = payments.p2ms({ input: scriptSig, - output: scriptPubKey + output: scriptPubKey, }, { allowIncomplete: true }); return { prevOutType: SCRIPT_TYPES.P2MS, pubkeys: pubkeys, signatures: signatures, - maxSignatures: m + maxSignatures: m, }; } } if (type === SCRIPT_TYPES.P2SH) { const { output, redeem } = payments.p2sh({ input: scriptSig, - witness: witnessStack + witness: witnessStack, }); const outputType = classify.output(redeem.output); const expanded = expandInput(redeem.input, redeem.witness, outputType, redeem.output); @@ -368,13 +373,13 @@ function expandInput(scriptSig, witnessStack, type, scriptPubKey) { witnessScript: expanded.witnessScript, witnessScriptType: expanded.witnessScriptType, pubkeys: expanded.pubkeys, - signatures: expanded.signatures + signatures: expanded.signatures, }; } if (type === SCRIPT_TYPES.P2WSH) { const { output, redeem } = payments.p2wsh({ input: scriptSig, - witness: witnessStack + witness: witnessStack, }); const outputType = classify.output(redeem.output); let expanded; @@ -392,12 +397,12 @@ function expandInput(scriptSig, witnessStack, type, scriptPubKey) { witnessScript: redeem.output, witnessScriptType: expanded.prevOutType, pubkeys: expanded.pubkeys, - signatures: expanded.signatures + signatures: expanded.signatures, }; } return { prevOutType: SCRIPT_TYPES.NONSTANDARD, - prevOutScript: scriptSig + prevOutScript: scriptSig, }; } // could be done in expandInput, but requires the original Transaction for hashForSignature @@ -444,7 +449,7 @@ function expandOutput(script, ourPubKey) { return { type, pubkeys: [ourPubKey], - signatures: [undefined] + signatures: [undefined], }; } case SCRIPT_TYPES.P2WPKH: { @@ -458,7 +463,7 @@ function expandOutput(script, ourPubKey) { return { type, pubkeys: [ourPubKey], - signatures: [undefined] + signatures: [undefined], }; } case SCRIPT_TYPES.P2PK: { @@ -466,7 +471,7 @@ function expandOutput(script, ourPubKey) { return { type, pubkeys: [p2pk.pubkey], - signatures: [undefined] + signatures: [undefined], }; } case SCRIPT_TYPES.P2MS: { @@ -475,7 +480,7 @@ function expandOutput(script, ourPubKey) { type, pubkeys: p2ms.pubkeys, signatures: p2ms.pubkeys.map(() => undefined), - maxSignatures: p2ms.m + maxSignatures: p2ms.m, }; } } @@ -483,7 +488,7 @@ function expandOutput(script, ourPubKey) { } function prepareInput(input, ourPubKey, redeemScript, witnessScript) { if (redeemScript && witnessScript) { - const p2wsh = payments.p2wsh({ redeem: { output: witnessScript } }); + const p2wsh = (payments.p2wsh({ redeem: { output: witnessScript } })); const p2wshAlt = payments.p2wsh({ output: redeemScript }); const p2sh = payments.p2sh({ redeem: { output: redeemScript } }); const p2shAlt = payments.p2sh({ redeem: p2wsh }); @@ -494,7 +499,10 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) { throw new Error('Redeem script inconsistent with prevOutScript'); const expanded = expandOutput(p2wsh.redeem.output, ourPubKey); if (!expanded.pubkeys) - throw new Error(expanded.type + ' not supported as witnessScript (' + bscript.toASM(witnessScript) + ')'); + throw new Error(expanded.type + + ' not supported as witnessScript (' + + bscript.toASM(witnessScript) + + ')'); if (input.signatures && input.signatures.some(x => x !== undefined)) { expanded.signatures = input.signatures; } @@ -513,7 +521,7 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) { signType: expanded.type, pubkeys: expanded.pubkeys, signatures: expanded.signatures, - maxSignatures: expanded.maxSignatures + maxSignatures: expanded.maxSignatures, }; } if (redeemScript) { @@ -531,7 +539,10 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) { } const expanded = expandOutput(p2sh.redeem.output, ourPubKey); if (!expanded.pubkeys) - throw new Error(expanded.type + ' not supported as redeemScript (' + bscript.toASM(redeemScript) + ')'); + throw new Error(expanded.type + + ' not supported as redeemScript (' + + bscript.toASM(redeemScript) + + ')'); if (input.signatures && input.signatures.some(x => x !== undefined)) { expanded.signatures = input.signatures; } @@ -549,7 +560,7 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) { signType: expanded.type, pubkeys: expanded.pubkeys, signatures: expanded.signatures, - maxSignatures: expanded.maxSignatures + maxSignatures: expanded.maxSignatures, }; } if (witnessScript) { @@ -561,7 +572,10 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) { } const expanded = expandOutput(p2wsh.redeem.output, ourPubKey); if (!expanded.pubkeys) - throw new Error(expanded.type + ' not supported as witnessScript (' + bscript.toASM(witnessScript) + ')'); + throw new Error(expanded.type + + ' not supported as witnessScript (' + + bscript.toASM(witnessScript) + + ')'); if (input.signatures && input.signatures.some(x => x !== undefined)) { expanded.signatures = input.signatures; } @@ -578,7 +592,7 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) { signType: expanded.type, pubkeys: expanded.pubkeys, signatures: expanded.signatures, - maxSignatures: expanded.maxSignatures + maxSignatures: expanded.maxSignatures, }; } if (input.prevOutType && input.prevOutScript) { @@ -591,13 +605,16 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) { throw new Error('PrevOutScript is missing'); const expanded = expandOutput(input.prevOutScript, ourPubKey); if (!expanded.pubkeys) - throw new Error(expanded.type + ' not supported (' + bscript.toASM(input.prevOutScript) + ')'); + throw new Error(expanded.type + + ' not supported (' + + bscript.toASM(input.prevOutScript) + + ')'); if (input.signatures && input.signatures.some(x => x !== undefined)) { expanded.signatures = input.signatures; } let signScript = input.prevOutScript; if (expanded.type === SCRIPT_TYPES.P2WPKH) { - signScript = payments.p2pkh({ pubkey: expanded.pubkeys[0] }).output; + signScript = (payments.p2pkh({ pubkey: expanded.pubkeys[0] }).output); } return { prevOutType: expanded.type, @@ -607,7 +624,7 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) { signType: expanded.type, pubkeys: expanded.pubkeys, signatures: expanded.signatures, - maxSignatures: expanded.maxSignatures + maxSignatures: expanded.maxSignatures, }; } const prevOutScript = payments.p2pkh({ pubkey: ourPubKey }).output; @@ -618,7 +635,7 @@ function prepareInput(input, ourPubKey, redeemScript, witnessScript) { signScript: prevOutScript, signType: SCRIPT_TYPES.P2PKH, pubkeys: [ourPubKey], - signatures: [undefined] + signatures: [undefined], }; } function build(type, input, allowIncomplete) { @@ -656,7 +673,7 @@ function build(type, input, allowIncomplete) { } // if the transaction is not not complete (complete), or if signatures.length === m, validate // otherwise, the number of OP_0's may be >= m, so don't validate (boo) - const validate = !allowIncomplete || (m === signatures.length); + const validate = !allowIncomplete || m === signatures.length; return payments.p2ms({ m, pubkeys, signatures }, { allowIncomplete, validate }); } case SCRIPT_TYPES.P2SH: { @@ -667,8 +684,8 @@ function build(type, input, allowIncomplete) { redeem: { output: redeem.output || input.redeemScript, input: redeem.input, - witness: redeem.witness - } + witness: redeem.witness, + }, }); } case SCRIPT_TYPES.P2WSH: { @@ -679,21 +696,20 @@ function build(type, input, allowIncomplete) { redeem: { output: input.witnessScript, input: redeem.input, - witness: redeem.witness - } + witness: redeem.witness, + }, }); } } } function canSign(input) { - return input.signScript !== undefined && + return (input.signScript !== undefined && input.signType !== undefined && input.pubkeys !== undefined && input.signatures !== undefined && input.signatures.length === input.pubkeys.length && input.pubkeys.length > 0 && - (input.hasWitness === false || - input.value !== undefined); + (input.hasWitness === false || input.value !== undefined)); } function signatureHashType(buffer) { return buffer.readUInt8(buffer.length - 1); diff --git a/src/types.js b/src/types.js index 13d1bc8..76b98cf 100644 --- a/src/types.js +++ b/src/types.js @@ -10,7 +10,9 @@ function BIP32Path(value) { return typeforce.String(value) && !!value.match(/^(m\/)?(\d+'?\/)*\d+'?$/); } exports.BIP32Path = BIP32Path; -BIP32Path.toJSON = function () { return 'BIP32 derivation path'; }; +BIP32Path.toJSON = function () { + return 'BIP32 derivation path'; +}; const SATOSHI_MAX = 21 * 1e14; function Satoshi(value) { return typeforce.UInt53(value) && value <= SATOSHI_MAX; @@ -23,11 +25,11 @@ exports.Network = typeforce.compile({ messagePrefix: typeforce.oneOf(typeforce.Buffer, typeforce.String), bip32: { public: typeforce.UInt32, - private: typeforce.UInt32 + private: typeforce.UInt32, }, pubKeyHash: typeforce.UInt8, scriptHash: typeforce.UInt8, - wif: typeforce.UInt8 + wif: typeforce.UInt8, }); exports.Buffer256bit = typeforce.BufferN(32); exports.Hash160bit = typeforce.BufferN(20); diff --git a/types/index.d.ts b/types/index.d.ts index 9682271..3512872 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -5,7 +5,7 @@ import * as crypto from './crypto'; import * as networks from './networks'; import * as payments from './payments'; import * as script from './script'; -export { ECPair, address, bip32, crypto, networks, payments, script, }; +export { ECPair, address, bip32, crypto, networks, payments, script }; export { Block } from './block'; export { Transaction } from './transaction'; export { TransactionBuilder } from './transaction_builder';