A basic understanding of the bitcoiin source code structure and the function of the module code, today look at the block.

Blocks are the basic units that make up blocks, and we can view the basic information of a block by using the Bitcoin-CLI command.

Next we will look for the block definition in the source code, since we do not know where the block definition is. Let’s try searching block.h(or block. CPP) globally:

In fact, we have already mentioned in the directory structure of the source structure of bitcoiin in the last article. Next, let’s take a look at blocks.

The source code first look

CBlockHeader

/** Nodes collect new transactions into a block, hash them into a hash tree, * and scan through nonce values to make the block's hash satisfy proof-of-work * requirements. When they solve the proof-of-work, they broadcast the block * to everyone and the block is added to the block chain. The first transaction * in the block Is a special one that creates a new coin owned by the creator * of the block. All transactions are hashed in pairs to form a Merkle tree * the packaging process is to fulfill the proof-of-work requirement. When the node has solved the current random number, * it broadcasts the current block to all other nodes and adds it to the blockchain. * The first transaction in the block, called a CoinBase transaction, is the creation of new coins that are awarded to the block creator * * Add by Chaors 20180419 */

class CBlockHeader
{
public:
    // header
    int32_t nVersion;       / / version
    uint256 hashPrevBlock;  // Hash of the previous block
    uint256 hashMerkleRoot; // Merkle root that contains trading information
    uint32_t nTime;         / / timestamp
    uint32_t nBits;         // Proof of work (POW) difficulty
    uint32_t nNonce;        // A random number that matches POW

    CBlockHeader()          The constructor initializes a member variable
    {
        SetNull();          
    }

    ADD_SERIALIZE_METHODS;  // Serialize the class through the encapsulated template

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action) {
        READWRITE(this->nVersion);
        READWRITE(hashPrevBlock);
        READWRITE(hashMerkleRoot);
        READWRITE(nTime);
        READWRITE(nBits);
        READWRITE(nNonce);
    }

    void SetNull(a)          // Initialize a member variable
    {
        nVersion = 0;
        hashPrevBlock.SetNull();
        hashMerkleRoot.SetNull();
        nTime = 0;
        nBits = 0;
        nNonce = 0;
    }

    bool IsNull(a) const
    {
        return (nBits == 0);     // A difficulty of 0 indicates that the block has not yet been created and the block header is empty
    }

    uint256 GetHash(a) const;     // get the hash

    int64_t GetBlockTime() const // Get block time
    {
        return (int64_t)nTime; }};Copy the code

CBlock

class CBlock : public CBlockHeader         // Inherits from CBlockHeader and owns all of its member variables
{
public:
    // network and disk
    std: :vector<CTransactionRef> vtx;      // Containers for all transactions

    // memory only
    mutable bool fChecked;                 // Whether the transaction is validated

    CBlock()
    {
        SetNull();
    }

    CBlock(const CBlockHeader &header)
    {
        SetNull();
        *((CBlockHeader*)this) = header;
    }

    ADD_SERIALIZE_METHODS;

    template <typename Stream, typename Operation>
    inline void SerializationOp(Stream& s, Operation ser_action) {
        READWRITE(*(CBlockHeader*)this);
        READWRITE(vtx);
    }

    void SetNull(a)
    {
        CBlockHeader::SetNull();
        vtx.clear();
        fChecked = false;
    }

    CBlockHeader GetBlockHeader(a) const
    {
        CBlockHeader block;
        block.nVersion       = nVersion;
        block.hashPrevBlock  = hashPrevBlock;
        block.hashMerkleRoot = hashMerkleRoot;
        block.nTime          = nTime;
        block.nBits          = nBits;
        block.nNonce         = nNonce;
        return block;
    }

    std: :string ToString(a) const;
};
Copy the code

CBlockLocator

/** Describes a place in the block chain to another node such that if the * other node doesn't have the same branch, it can find a recent common trunk. * The further back it is, The further before the fork it may be. ** * Describes a location in the blockchain at other nodes, * if other nodes do not have the same branch, it can find a nearest relay (the nearest same block). */ struct CBlockLocator {STD ::vector<uint256> vHave; CBlockLocator() {} explicit CBlockLocator(const std::vector<uint256>& vHaveIn) : vHave(vHaveIn) {} ADD_SERIALIZE_METHODS; template <typename Stream, typename Operation> inline void SerializationOp(Stream& s, Operation ser_action) { int nVersion = s.GetVersion(); if (! (s.GetType() & SER_GETHASH)) READWRITE(nVersion); READWRITE(vHave); } void SetNull() { vHave.clear(); } bool IsNull() const { return vHave.empty(); }};Copy the code

.cpp function

uint256 CBlockHeader::GetHash() const
{
    return SerializeHash(*this);        // Generate a 256-bit hash value
}

std: :string CBlock::ToString() const    // Block object format string output
{
    std: :stringstream s;
    s << strprintf("CBlock(hash=%s, ver=0x%08x, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%u)\n",
        GetHash().ToString(),
        nVersion,
        hashPrevBlock.ToString(),
        hashMerkleRoot.ToString(),
        nTime, nBits, nNonce,
        vtx.size());
    for (const auto& tx : vtx) {
        s << "" << tx->ToString() << "\n";
    }
    return s.str();
}
Copy the code

Block structure analysis

A block is a container data structure that forms a blockchain by linking back and forth. It consists of a block header that describes the main information of the block and a block that contains several transaction data. The block header is 80 bytes, while the average transaction is at least 250 bytes, and the average block contains at least over 500 transactions. So, a block is a data body much larger than the block head. This is why Bitcoin uses Merkcle trees to verify the existence of transactions.

The overall structure

A data item Size (Byte) describe
Block Size 4 Block size
Block Header 80 Size of block header information
Transactions m*n(n>=250) A list of all transactions
Transactions Counter 1-9 Transaction amount

Bitcoin’s block size is currently strictly limited to 1MB. The 4-byte block size field is not included in this!

Block head

A data item Size (Byte) storage describe
Version 4 The small end Block version, which specifies the validation rules to be followed by blocks
Previous Block Hash 32 Internal byte order Last Block hash (SHA256(SHA256(Block Header))
Merkle Root 32 Internal byte order MerkleThe root, which contains the hash of all transactions
Timestamp 4 The small end Blocks generate timestamps that are greater than the average of the previous 11 blocks, and the entire node rejects blocks whose timestamps are longer than 2 hours
nBitS 4 The small end Proof of Work (POW) target difficulty value that the current block difficulty value needs to go throughTarget nBits codingCan be converted to a target hash
Nonce 4 The small end A random number used for a POW that may run out of Nonce digits as computation power increases. The protocol specifies that the timestamp and CoinbaseTransaction information can be modified to extend the Nonce digits

Block identifier

  • The BlockHash BlockHash value is obtained by hashing the block header information using SHA256 algorithm. This value must meet POW’s DifficultyTarget to be considered valid in this block. It is also a unique identifier of the block, which can be queried using BlockHash via bitcoin-CLI (we used this at the beginning of this article).

  • BlockHeight Specifies the location of a block in the blockchain. The height of the Genesis block is 0, and the height of each block added after the block increases by 1. Block hashes can be queried by height via bitcoin-CLI (we used this at the beginning of this article)

Note: BlockHeight is not a unique identifier. When a blockchain is temporarily forked, there may be cases where two blocks have the same height.

The foundation block

The first block on the blockchain is called the Genesis block, which is the common ancestor of all blocks. We can take a look at bitcoin’s Genesis block:

Bitcoin founder Tsongge contained a hidden message in the Trands block. The Coinbase entry included The phrase “The Times 03/Jan/2009 Chancellor on The brink of second Bailout Forbanks,” which was The headline of a front-page article in The Times that day, The purpose of this is unknown. But the ease with which such a non-transaction message could be inserted into Bitcoin is worth pondering. In this way, it is not difficult to understand the recent exposure of “criminals using bitcoin to store child pornography” news, of course, this kind of storage may be far more complicated than the words of the wise brother.

thinking

    1. What do the following fields not in the source code structure mean in the block information we are looking at? Why are they not in the block structure defined by the source code? confirmations strippedsize weight mediantime bits chainwork
  • 2. Why is the block hash not defined inside the block header?

Note: I may not have the answer to the above questions, we can leave a message to exchange common progress.

This concludes the understanding of blocks, and the next article is ready to explore the bitcoin data structure – the structure of transactions.

reference

  • Mastering Bitcoin 2nd Edition

  • Bitcoin Developer Documentation

  • bitcoin wiki

.

### The Internet upends the world, blockchain upends the Internet!

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — behold, 20180419