Saturday, September 21, 2024
HomeBitcoinWhat are the keys used within the blockchain levelDB (ie what are...

What are the keys used within the blockchain levelDB (ie what are the important thing:worth pairs)?


import binascii

BLOCK_HAVE_DATA          =    8 #!< full block obtainable in blk*.dat
BLOCK_HAVE_UNDO          =   16 #!< undo information obtainable in rev*.dat

def encode_varint(quantity):

    # * Variable-length integers: bytes are a MSB base-128 encoding of the quantity.
    # * The excessive bit in every byte signifies whether or not one other digit follows. To make
    # * certain the encoding is one-to-one, one is subtracted from all however the final digit.
    # * Thus, the byte sequence a[] with size len, the place all however the final byte
    # * has bit 128 set, encodes the quantity:
    # *
    # *  (a[len-1] & 0x7F) + sum(i=1..len-1, 128^i*((a[len-i-1] & 0x7F)+1))
    # *
    # * Properties:
    # * * Very small (0-127: 1 byte, 128-16511: 2 bytes, 16512-2113663: 3 bytes)
    # * * Each integer has precisely one encoding
    # * * Encoding doesn't depend upon dimension of authentic integer sort
    # * * No redundancy: each (infinite) byte sequence corresponds to an inventory
    # *   of encoded integers.
    # *
    # * 0:         [0x00]  256:        [0x81 0x00]
    # * 1:         [0x01]  16383:      [0xFE 0x7F]
    # * 127:       [0x7F]  16384:      [0xFF 0x00]
    # * 128:  [0x80 0x00]  16511: [0x80 0xFF 0x7F]
    # * 255:  [0x80 0x7F]  65535: [0x82 0xFD 0x7F]
    # * 2^32:           [0x8E 0xFE 0xFE 0xFF 0x00]

    """Encodes a non-negative integer utilizing the MSB base-128 scheme."""
    if quantity < 0:
        increase ValueError("Solely non-negative integers will be encoded.")

    outcome = []
    whereas True:
        byte = quantity & 0x7F  # Extract decrease 7 bits
        quantity >>= 7  # Shift proper by 7
        if quantity:
            byte |= 0x80  # Set excessive bit for continuation
        outcome.append(byte)
        if quantity == 0:
            break
    return bytes(outcome)

def decode_varint(stream):
    """Decodes a variable-length integer from the MSB base-128 format."""
    n = 0
    whereas True:
        chData = ord(stream.get(1))
        n = (n << 7) | (chData & 0x7F)

        if chData & 0x80:
            n += 1
        else:
            return n
        
def read_int(stream, bits):
    information = stream.get(bits//8)
    information.reverse()
    return binascii.b2a_hex(information) if bits > 64 else int(binascii.b2a_hex(information), 16)


class Stream:
    '''Class to deal with byte stream'''
    def __init__(self, hexdata):
        self.information = bytearray(bytes.fromhex(hexdata))
        self.information.reverse()

    def get(self, n):
        outcome = self.information[:n]
        self.information = self.information[n:]
        return outcome
class BlockHeader:
    def __init__(self, stream):
        self.nVersion = read_int(stream, 32)
        self.hashPrev = read_int(stream, 256)
        self.hashMerkleRoot = read_int(stream, 256)
        self.nTime = read_int(stream, 32)
        self.nBits = read_int(stream, 32)
        self.nNonce = read_int(stream, 32)

class VarintCBlockIndex:
    def __init__(self, stream):
        self.nVer = decode_varint(stream)
        self.nHeight = decode_varint(stream)
        self.nStatus = decode_varint(stream)
        self.nTx = decode_varint(stream)
        self.nFile = decode_varint(stream) if self.nStatus & (BLOCK_HAVE_DATA | BLOCK_HAVE_UNDO) else -1
        self.nDataPos = decode_varint(stream) if self.nStatus & BLOCK_HAVE_DATA else -1
        self.nUndoPos = decode_varint(stream) if self.nStatus & BLOCK_HAVE_UNDO else -1


if __name__ == '__main__':

    data_hex = '572fe3011b5bede64c91a5338fb300e3fdb6f30a4c67233b997f99fdd518b968b9a3fd65857bfe78b260071900000000001937917bd2caba204bb1aa530ec1de9d0f6736e5d85d96da9c8bba0000000129ffd98136b19a8e00021d00f0833ced8e'

    # Utilization
    stream = Stream(data_hex)
    varint_cblockindex = VarintCBlockIndex(stream)
    block_header = BlockHeader(stream)

    # print all information from courses:
    print('varint_cblockindex:')
    print('tnVer=", varint_cblockindex.nVer)
    print("tnHeight=", varint_cblockindex.nHeight)
    print("tnStatus=", varint_cblockindex.nStatus)
    print("tnTx = ', varint_cblockindex.nTx)
    print('tnFile=", varint_cblockindex.nFile)
    print("tnDataPos=", varint_cblockindex.nDataPos)
    print("tnUndoPos=", varint_cblockindex.nUndoPos)

    print("block_header:')
    print('tnVersion = ', block_header.nVersion)
    print('thashPrev = ', block_header.hashPrev)
    print('thashMerkleRoot=", block_header.hashMerkleRoot)
    print("tnTime=", block_header.nTime)
    print("tnBits=", block_header.nBits)
    print("tnNonce=", block_header.nNonce)

I hope this may assist…

Key Construction (b + 32-byte block hash):

The important thing for every block index report begins with the letter “b’ to tell apart it from different sorts of entries within the database (e.g., transaction index entries may begin with ‘t’).

Following the ‘b’ is the 32-byte (256-bit) hash of the block. This hash serves as a singular identifier for the block.

The block hash is often represented in little-endian byte order within the database.

Worth Construction (Block Index Document):

Every block index report related to a selected block hash incorporates a mix of knowledge:

Block Header:

80 bytes in whole
Incorporates the next fields:
Model (4 bytes)
Earlier Block Hash (32 bytes)
Merkle Root (32 bytes)
Timestamp (4 bytes)
Bits (problem goal, 4 bytes)
Nonce (4 bytes)

Peak:

A variable-length integer (varint) representing the block’s peak within the blockchain.
Signifies what number of blocks precede this block within the chain.

Variety of Transactions:

A varint indicating the overall variety of transactions included within the block.

Validation Standing:

A varint representing flags that point out:

File Location and Place:

If the block’s information is accessible:

  • A varint indicating the file quantity (e.g., blkXXXXX.dat) the place the block information is saved.

  • A varint indicating the byte offset throughout the file the place the block information begins.

If the block’s undo information is accessible:

  • A varint indicating the file quantity (e.g., revXXXXX.dat) the place the undo information is saved.

  • A varint indicating the byte offset throughout the file the place the undo information begins.

Vital Notes:

Varints: Bitcoin makes use of varints for area effectivity. Smaller numbers are encoded with fewer bytes than bigger ones. This makes the dimensions of the block index report variable relying on the block peak, transaction depend, and so on.

Information Availability: Not all block information and undo information could be obtainable within the LevelDB index. The validation standing flags point out whether or not the information is current and the place to search out it within the precise block information on disk.

Endianness: The block hash and different fields throughout the block header are saved in little-endian byte order in LevelDB. This implies the least vital byte comes first.

Instance (Simplified):

As an instance a block index report appears to be like like this:

Key: b
Worth:

This report tells you:

The block hash (block_hash)
The block header information (block_header_bytes)
The block peak (varint_height)
The variety of transactions (varint_tx_count)
The block’s validation standing (varint_status)
The place to search out the block information and undo information on disk (if obtainable)

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments