Block headers serve an important intermediary role in the creation and transmission of blocks.
They are a fixed-width (80-byte) representation of the entire block.
With a block header, you can:
Since validation of all the transactions in the block can be expensive, the ability to perform these checks on the block before downloading and validating its transactions helps make denial-of-service attacks on the network significantly more expensive for attackers.
|previous block hash||32 bytes||block hash(LE)||The hash of the block immediately preceding this block in the blockchain.|
|target||4 bytes||compressed target(LE)||The target that the block hash must be below to be valid. This value is determined by the timestamps of previously mined blocks. See Target for more information.|
|ancestor hash||32 bytes||block hash(LE)||The hash of a specific ancestor block (see ancestorHash spec.|
|merkle tree root hash||32 bytes||merkle root(LE)||The merkle tree root of the transactions in the block.|
|transaction filter hash||32 bytes||MUST BE ZERO(LE)||Currently defined as 0, this will be populated with the hash of a probabilistic data structure that summarizes the transactions in the block|
|timestamp||4 bytes||unix timestamp(LE)||The epoch timestamp of the block in seconds.|
|height||variable||varint||Current height of this block in the blockchain (genesis block is height 0).|
|chain work||32 bytes||uint256(LE)||The cumulative expected work in the blockchain, including this block|
|size||8 bytes||uint64(LE)||Block size in bytes, excluding the nonce|
|transaction count||variable||varint||Number of transactions in the block|
|fee pool amount||variable||varint (MUST BE 0)||Currently defined as 0, this will be the current value of satoshis in a fee pool|
|UTXO commitment||variable bytes||byte vector (MUST BE LENGTH 0)||Currently defined as a vector of length zero, this will be a commitment to the current UTXO data set|
|Miner Data||variable bytes||byte vector (MUST BE LENGTH 0)||Currently defined as a vector of length zero, this will be a structure where miners make well-defined statements|
|nonce||variable bytes||byte vector of length less than or equal to 16 bytes||A random value that is repeatedly changes during block mining in order to achieve the proof-of-work requirements.|
Note that the size field is the size of the serialized block, without the nonce field. Or, since the nonce field is serialized as an array and is therefore preceded with a 1 byte length field.
size = serializedLengthOf(block) - (nonce.length + 1)
Within the block header, the target uses a special floating-point representation that helps keep the size of the block header small.
While the difficulty adjustment algorithm attempts to calculate the ideal target (i.e. the value the block hash must be “less than”), it undergoes a lossy conversion when put in the block header:
|exponent||1 byte||byte||Used to calculate the offset for the signficand. The actual exponent is
|significand||3 byte||bytes||The significand, or mantissa, of the value.|
Ultimately, the target is equal to:
significand * 2(8 * (exponent - 3))
Vectors are serialized with a prefix byte specifying the length of the vector, and then the bytes of the vector.
The first thing to note is that unlike Bitcoin and Bitcoin Cash the mining puzzle solution (Proof-of-work problem) is separated out from the block hash. This was done because the Nexa mining puzzle is both computationally expensive and algorithmically expensive (that is, more work to implement). There is no need for all that if you just want to get a probabilistically unique identifier for a block.
In the following algorithm description “sha256()” refers to the SHA-256 cryptographic hash algorithm. This algorithm operates over an array of bytes. Any argument provided is serialized using the standard Nexa/Bitcoin Cash/Bitcoin serialization algorithm (HASH variant). Within the context of serialization, the “||” operator denotes byte array concatenation.
The algorithm is as follows:
miniheaderhash = sha256(hashprevblock || nbits)
extheaderhash = sha256(hashAncestor || hashTxFilter || hashMerkleRoot || nTime || ((uint64_t)height) || chainWork || size || txCount || feePoolAmt || utxoCommitment || minerData || nonce)
blockhash = SHA256( miniHeaderHash || extendedHeaderHash)