diff --git a/src/block.js b/src/block.js index eb3fb8b..9419989 100644 --- a/src/block.js +++ b/src/block.js @@ -1,9 +1,9 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); +const bufferutils_1 = require("./bufferutils"); +const bcrypto = require("./crypto"); const transaction_1 = require("./transaction"); const types = require("./types"); -const bcrypto = require("./crypto"); -const bufferutils_1 = require("./bufferutils"); const fastMerkleRoot = require('merkle-lib/fastRoot'); const typeforce = require('typeforce'); const varuint = require('varuint-bitcoin'); @@ -28,16 +28,6 @@ function anyTxHasWitness(transactions) { input.witness.length > 0))); } class Block { - constructor() { - this.version = 1; - this.timestamp = 0; - this.bits = 0; - this.nonce = 0; - this.prevHash = undefined; - this.merkleRoot = undefined; - this.witnessCommit = undefined; - this.transactions = undefined; - } static fromBuffer(buffer) { if (buffer.length < 80) throw new Error('Buffer too small (< 80 bytes)'); @@ -77,11 +67,11 @@ class Block { }; const nTransactions = readVarInt(); block.transactions = []; - for (var i = 0; i < nTransactions; ++i) { + for (let i = 0; i < nTransactions; ++i) { const tx = readTransaction(); block.transactions.push(tx); } - let witnessCommit = block.getWitnessCommit(); + const witnessCommit = block.getWitnessCommit(); // This Block contains a witness commit if (witnessCommit) block.witnessCommit = witnessCommit; @@ -109,6 +99,16 @@ class Block { ? bcrypto.hash256(Buffer.concat([rootHash, transactions[0].ins[0].witness[0]])) : rootHash; } + constructor() { + this.version = 1; + this.timestamp = 0; + this.bits = 0; + this.nonce = 0; + this.prevHash = undefined; + this.merkleRoot = undefined; + this.witnessCommit = undefined; + this.transactions = undefined; + } getWitnessCommit() { if (!txesHaveWitnessCommit(this.transactions)) return null; @@ -116,11 +116,11 @@ 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)); + const 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) - let result = witnessCommits[witnessCommits.length - 1]; + const result = witnessCommits[witnessCommits.length - 1]; if (!(result instanceof Buffer && result.length === 32)) return null; return result; @@ -193,7 +193,7 @@ class Block { checkTxRoots() { // If the Block has segwit transactions but no witness commit, // there's no way it can be valid, so fail the check. - let hasWitnessCommit = this.hasWitnessCommit(); + const hasWitnessCommit = this.hasWitnessCommit(); if (!hasWitnessCommit && this.hasWitness()) return false; return (this.__checkMerkleRoot() && @@ -204,6 +204,11 @@ class Block { 'deprecated in v5. Please use checkTxRoots instead.'); return this.checkTxRoots(); } + checkProofOfWork() { + const hash = bufferutils_1.reverseBuffer(this.getHash()); + const target = Block.calculateTarget(this.bits); + return hash.compare(target) <= 0; + } __checkMerkleRoot() { if (!this.transactions) throw errorMerkleNoTxes; @@ -218,10 +223,5 @@ class Block { const actualWitnessCommit = Block.calculateMerkleRoot(this.transactions, true); return this.witnessCommit.compare(actualWitnessCommit) === 0; } - checkProofOfWork() { - const hash = bufferutils_1.reverseBuffer(this.getHash()); - const target = Block.calculateTarget(this.bits); - return hash.compare(target) <= 0; - } } exports.Block = Block; diff --git a/ts_src/block.ts b/ts_src/block.ts index feb141e..888337d 100644 --- a/ts_src/block.ts +++ b/ts_src/block.ts @@ -1,7 +1,7 @@ +import { reverseBuffer } from './bufferutils'; +import * as bcrypto from './crypto'; import { Transaction } from './transaction'; import * as types from './types'; -import * as bcrypto from './crypto'; -import { reverseBuffer } from './bufferutils'; const fastMerkleRoot = require('merkle-lib/fastRoot'); const typeforce = require('typeforce'); @@ -14,7 +14,7 @@ const errorWitnessNotSegwit = new TypeError( 'Cannot compute witness commit for non-segwit block', ); -function txesHaveWitnessCommit(transactions: Array): boolean { +function txesHaveWitnessCommit(transactions: Transaction[]): boolean { return ( transactions instanceof Array && transactions[0] && @@ -27,7 +27,7 @@ function txesHaveWitnessCommit(transactions: Array): boolean { ); } -function anyTxHasWitness(transactions: Array): boolean { +function anyTxHasWitness(transactions: Transaction[]): boolean { return ( transactions instanceof Array && transactions.some( @@ -45,26 +45,6 @@ function anyTxHasWitness(transactions: Array): boolean { } export class Block { - version: number; - prevHash?: Buffer; - merkleRoot?: Buffer; - timestamp: number; - witnessCommit?: Buffer; - bits: number; - nonce: number; - transactions?: Array; - - constructor() { - this.version = 1; - this.timestamp = 0; - this.bits = 0; - this.nonce = 0; - this.prevHash = undefined; - this.merkleRoot = undefined; - this.witnessCommit = undefined; - this.transactions = undefined; - } - static fromBuffer(buffer: Buffer): Block { if (buffer.length < 80) throw new Error('Buffer too small (< 80 bytes)'); @@ -111,12 +91,12 @@ export class Block { const nTransactions = readVarInt(); block.transactions = []; - for (var i = 0; i < nTransactions; ++i) { + for (let i = 0; i < nTransactions; ++i) { const tx = readTransaction(); block.transactions.push(tx); } - let witnessCommit = block.getWitnessCommit(); + const witnessCommit = block.getWitnessCommit(); // This Block contains a witness commit if (witnessCommit) block.witnessCommit = witnessCommit; @@ -136,7 +116,7 @@ export class Block { } static calculateMerkleRoot( - transactions: Array, + transactions: Transaction[], forWitness?: boolean, ): Buffer { typeforce([{ getHash: types.Function }], transactions); @@ -157,6 +137,26 @@ export class Block { : rootHash; } + version: number; + prevHash?: Buffer; + merkleRoot?: Buffer; + timestamp: number; + witnessCommit?: Buffer; + bits: number; + nonce: number; + transactions?: Transaction[]; + + constructor() { + this.version = 1; + this.timestamp = 0; + this.bits = 0; + this.nonce = 0; + this.prevHash = undefined; + this.merkleRoot = undefined; + this.witnessCommit = undefined; + this.transactions = undefined; + } + getWitnessCommit(): Buffer | null { if (!txesHaveWitnessCommit(this.transactions!)) return null; @@ -164,12 +164,12 @@ export 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 => + const 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) - let result = witnessCommits[witnessCommits.length - 1]; + const result = witnessCommits[witnessCommits.length - 1]; if (!(result instanceof Buffer && result.length === 32)) return null; return result; @@ -261,7 +261,7 @@ export class Block { checkTxRoots(): boolean { // If the Block has segwit transactions but no witness commit, // there's no way it can be valid, so fail the check. - let hasWitnessCommit = this.hasWitnessCommit(); + const hasWitnessCommit = this.hasWitnessCommit(); if (!hasWitnessCommit && this.hasWitness()) return false; return ( this.__checkMerkleRoot() && @@ -277,14 +277,21 @@ export class Block { return this.checkTxRoots(); } - __checkMerkleRoot(): boolean { + checkProofOfWork(): boolean { + const hash: Buffer = reverseBuffer(this.getHash()); + const target = Block.calculateTarget(this.bits); + + return hash.compare(target) <= 0; + } + + private __checkMerkleRoot(): boolean { if (!this.transactions) throw errorMerkleNoTxes; const actualMerkleRoot = Block.calculateMerkleRoot(this.transactions); return this.merkleRoot!.compare(actualMerkleRoot) === 0; } - __checkWitnessCommit(): boolean { + private __checkWitnessCommit(): boolean { if (!this.transactions) throw errorMerkleNoTxes; if (!this.hasWitnessCommit()) throw errorWitnessNotSegwit; @@ -294,11 +301,4 @@ export class Block { ); return this.witnessCommit!.compare(actualWitnessCommit) === 0; } - - checkProofOfWork(): boolean { - const hash: Buffer = reverseBuffer(this.getHash()); - const target = Block.calculateTarget(this.bits); - - return hash.compare(target) <= 0; - } } diff --git a/tslint.json b/tslint.json index 18bf61d..9708e8b 100644 --- a/tslint.json +++ b/tslint.json @@ -2,6 +2,7 @@ "defaultSeverity": "error", "extends": ["tslint:recommended"], "rules": { + "arrow-parens": [true, "ban-single-arg-parens"], "curly": false, "indent": [ true, @@ -12,6 +13,8 @@ "match-default-export-name": true, "max-classes-per-file": [false], "member-access": [true, "no-public"], + "no-bitwise": false, + "no-console": false, "no-empty": [true, "allow-empty-catch"], "no-implicit-dependencies": true, "no-return-await": true, diff --git a/types/block.d.ts b/types/block.d.ts index 8b4f2f1..6f2d5b9 100644 --- a/types/block.d.ts +++ b/types/block.d.ts @@ -1,6 +1,10 @@ /// import { Transaction } from './transaction'; export declare class Block { + static fromBuffer(buffer: Buffer): Block; + static fromHex(hex: string): Block; + static calculateTarget(bits: number): Buffer; + static calculateMerkleRoot(transactions: Transaction[], forWitness?: boolean): Buffer; version: number; prevHash?: Buffer; merkleRoot?: Buffer; @@ -8,12 +12,8 @@ export declare class Block { witnessCommit?: Buffer; bits: number; nonce: number; - transactions?: Array; + transactions?: Transaction[]; constructor(); - static fromBuffer(buffer: Buffer): Block; - static fromHex(hex: string): Block; - static calculateTarget(bits: number): Buffer; - static calculateMerkleRoot(transactions: Array, forWitness?: boolean): Buffer; getWitnessCommit(): Buffer | null; hasWitnessCommit(): boolean; hasWitness(): boolean; @@ -25,7 +25,7 @@ export declare class Block { toHex(headersOnly: boolean): string; checkTxRoots(): boolean; checkMerkleRoot(): boolean; - __checkMerkleRoot(): boolean; - __checkWitnessCommit(): boolean; checkProofOfWork(): boolean; + private __checkMerkleRoot; + private __checkWitnessCommit; }