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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | 1x 1x 12x 12x 12x 12x 2x 2x 1x 1x 1x 1x 2x 20x 5x 5x 5x 5x 7x 7x 7x 5x 5x | import { bigToBufBE, BufferReader, BufferWriter } from "@node-lightning/bufio"; /** * Bits encodes the proof-of-work necessary in this block. It contains * two parts: exponent and coefficient. It is a succinct way to express * a really large number. It can be converted into a `target` or the * `difficulty`. */ export class Bits { /** * Parses nBits from a LE buffer as represented inside of a block * where first three bytes are the coefficient and the last byte * is the exponent. * @param buf * @returns */ public static fromBuffer(buf: Buffer): Bits { const reader = new BufferReader(buf); const coefficient = reader.readUIntLE(3); const exponent = reader.readUInt8(); return new Bits(coefficient, exponent); } /** * Converts a target into a `Bits` instance. This is the inverse of * the `target` property on a `Bits` instance. The algorithm to * convert a target is to write the number into a Buffer in * big-endian. The required bytes is the exponent and the * coefficient is the top three most bytes. If the topmost bit is * set then we * @param target */ public static fromTarget(target: bigint): Bits { let exponent: number; let coefficient: number; // Convert the number to BE bytes const rawBytes = bigToBufBE(target); // The target is always positive, therefore we need to prevent this from // being treated as a negative number. If the first bit is a 1 (>=0x80), // push a 0x00 as the first byte of the coefficient if (rawBytes[0] > 0x7f) { exponent = rawBytes.length + 1; coefficient = (rawBytes[0] << 8) + rawBytes[1]; } else { exponent = rawBytes.length; coefficient = (rawBytes[0] << 16) + (rawBytes[1] << 8) + rawBytes[2]; } return new Bits(coefficient, exponent); } /** * Constructs a new `Bits` instance. * @param coefficient * @param exponent */ constructor(readonly coefficient: number, readonly exponent: number) {} /** * Serializes the bits to a Buffer in the format used for RPC block * serialization. This means that hte lower three bytes are the * coefficient little-endian and the upper byte is the exponent. * One final piece of complexity is that if the coefficient is * greater than 0x800000 then we pad it and */ public toBuffer(): Buffer { const writer = new BufferWriter(Buffer.alloc(4)); writer.writeUIntLE(this.coefficient, 3); writer.writeUInt8(this.exponent); return writer.toBuffer(); } /** * Calculates the proof-of-work requirements from the bits. Target * is calculated as: * * ``` * target = coefficient * 256^(exponent-3) * ``` * * The target looks like: * 0000000000000000013ce9000000000000000000000000000000000000000000 * */ public get target(): bigint { const exp = BigInt(this.exponent); const coeff = BigInt(this.coefficient); return coeff * 256n ** (exp - 3n); } /** * Difficulty is a more readable version of the target and makes the * targets more easy to compare and comprehend. The genesis block * had a difficulty of 1. * * It is calculated with the formula: * * ``` * difficulty = 0xffff * 256 ^ (0x1d - 3) / target * ``` */ public get difficulty(): bigint { const genesis = 0xffffn * 256n ** (0x1dn - 3n); return genesis / this.target; } } |