All files Block.ts

100% Statements 21/21
100% Branches 0/0
100% Functions 3/3
100% Lines 20/20

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 901x   1x   1x                   1x             2x     2x     2x     2x 2x 2x 2x       2x                                                   2x 2x                 1x     1x     1x     1x 1x     1x      
import { BufferReader, BufferWriter, StreamReader } from "@node-lightning/bufio";
import { Bits } from "./Bits";
import { BlockHeader } from "./BlockHeader";
import { HashValue } from "./HashValue";
import { Tx } from "./Tx";
 
/**
 * This class represents a Bitcoin block including fully constructed
 * transactions. It can be used to deserialize a raw transaction receive
 * from a peer or deserialized from HEX.
 *
 * This class extends the `BlockHeader` type since all properties on
 * a `BlockHeader` are part of a `Block`.
 */
export class Block extends BlockHeader {
    /**
     * Parses a Block with full transactions information by first
     * parsing the `BlockHeader` then the transactions.
     * @param buf
     */
    public static fromBuffer(buf: Buffer): Block {
        const r = new BufferReader(buf);
 
        // parse the header
        const header = BlockHeader.fromBuffer(r.readBytes(BlockHeader.ByteSize));
 
        // number of transactions
        const numTxs = Number(r.readVarUint());
 
        // read txs as a stream
        const txsStream = StreamReader.fromBuffer(r.readBytes());
        const txs: Tx[] = [];
        for (let i = 0; i < numTxs; i++) {
            txs.push(Tx.decode(txsStream));
        }
 
        // return block
        return new Block(
            header.version,
            header.previousBlockHash,
            header.merkleRoot,
            header.timestamp,
            header.bits,
            header.nonce,
            txs,
        );
    }
 
    /**
     * Complete list of transactions, in the order they weere included
     * in the `Block`.
     */
    public txs: Tx[];
 
    constructor(
        version: number,
        previousBlockHash: HashValue,
        merkleRoot: HashValue,
        timestamp: number,
        bits: Bits,
        nonce: number,
        txs: Tx[],
    ) {
        super(version, previousBlockHash, merkleRoot, timestamp, bits, nonce);
        this.txs = txs;
    }
 
    /**
     * Serializes the `Block` into a Buffer by first serializing the
     * `BlockHeader` followed by a `varint` that encodes the number of
     * transactions followed by a sequence of `Tx`.
     */
    public toBuffer(): Buffer {
        const bw = new BufferWriter();
 
        // serialize the header
        bw.writeBytes(super.toBuffer());
 
        // serialize tx count
        bw.writeVarInt(this.txs.length);
 
        // serialize txs
        for (const tx of this.txs) {
            bw.writeBytes(tx.serialize());
        }
 
        return bw.toBuffer();
    }
}