整体如图所示:
Block_Header:
Field | Purpose | Updated when... | Size (Bytes) |
---|---|---|---|
Version | Block version number | You upgrade the software and it specifies a new version | 4 |
hashPrevBlock | 256-bit hash of the previous block header | A new block comes in | 32 |
hashMerkleRoot | 256-bit hash based on all of the transactions in the block | A transaction is accepted | 32 |
Time | Current timestamp as seconds since 1970-01-01T00:00 UTC | Every few seconds | 4 |
Bits | Current target in compact format | The difficulty is adjusted | 4 |
Nonce | 32-bit number (starts at 0) | A hash is tried (increments) | 4 |
Hash = SHA256(SHA256(Block_Header))
以Block 125552为例:
import hashlib
import struct
import time
def calculate_block_hash(version, hash_prev_block, hash_merkle_root, timestamp, bits, nonce):
version = struct.pack("<I", version)
hash_prev_block = bytes.fromhex(hash_prev_block)[::-1]
hash_merkle_root = bytes.fromhex(hash_merkle_root)[::-1]
timestamp = struct.pack("<I", int(time.mktime(time.strptime(timestamp, "%Y-%m-%d %H:%M:%S"))))
bits = struct.pack("<I", bits)
nonce = struct.pack("<I", nonce)
block_header = version + hash_prev_block + hash_merkle_root + timestamp + bits + nonce
return ''.join( [ "%02x" % x for x in __calculate_block_hash(block_header) ] ).strip()
def __calculate_block_hash(block_header):
return hashlib.sha256(hashlib.sha256(block_header).digest()).digest()[::-1]
if __name__ == '__main__':
# https://www.blockchain.com/btc/block/125552
version = 0x1
hash_prev_block = "00000000000008a3a41b85b8b29ad444def299fee21793cd8b9e567eab02cd81"
hash_merkle_root = "2b12fcf1b09288fcaff797d71e950e71ae42b91e8bdb2304758dfcffc2b620e3"
timestamp = "2011-05-22 01:26:31" # But in BlockChain Explorer front-end(https://www.blockchain.com/), we can not see the 'second' part.
bits = 440711666
nonce = 2504433986
block_hash = calculate_block_hash(version, hash_prev_block, hash_merkle_root, timestamp, bits, nonce)
print(block_hash)