Mine the Genesis Block

Posted by David Harding, Will Binns, Balaji Srinivasan

Mining the Genesis Block

What you'll learn

We'll write a short Python3 script to re-mine Bitcoin's first block, the Genesis Block. In doing so, you'll learn about the six fields that make up a Bitcoin block header.

Install 21

The Block Header

In the previous tutorial, you got a look at the Genesis Block. Now let's learn more about the first part of that block, the block header.

Each Bitcoin block header is exactly 80 bytes long and is composed of the following fields.

Bytes Name Description
4 version Which set of block validation rules to follow.
32 Previous block header hash The previous block’s header
32 Merkle root hash A hash derived from hashes of all transactions included in this block
4 Time The approximate time the block was created.
4 nBits The target threshold this block’s header hash must be less than or equal to.
4 Nonce An arbitrary number miners change during mining

Let's start our script by importing some modules and defining the header fields. Use the nano text editor to open a file named miner.py

nano miner.py

Paste in the following code:

## Objective: mine the Bitcoin genesis block

from struct import pack
from hashlib import sha256
from codecs import decode
from binascii import hexlify

Bitcoin uses the SHA256-double (sha256d) hash function. It also does some weird byte reversals, so let's add a couple of helper functions:

## Bitcoin uses the SHA256d hash function, which is the SHA256 function
## run twice (double).
def sha256d(data):
  return sha256(sha256(data).digest()).digest()

## We want to display our results as hex in RPC Byte Order, so
## we need to reverse the byte order
def internal2rpc(hash):
  return hexlify(hash[::-1])

The Version

The first field in the block header is the version field, which indicates what block validation rules should be followed for this block. Blocks started with version 1 (0x01000000) and are currently on version 3. Since we're mining the Genesis Block, we'll add the same version 1 it used to our code:

## The version number 1 as a little-endian (<) unsigned-long (L)
version = pack("<L", 0x01)

The Previous Block Hash

The block header always contains a hash pointer to the hash of the previous block header linking the new block to all previous blocks in the chain. In the unique case of the Genesis Block, there was no previous block, so Nakamoto filled this field with zero bits.

## The previous block header hash is 32-bit zero
previous_header_hash = decode("0000000000000000000000000000000000000000000000000000000000000000", 'hex')

The merkle root

Bitcoin block headers include a merkle root, which is the final hash in a merkle tree that connects all of the transactions in a block to the block header using a cryptographic hash that can prove that none of the transactions have been modified.

alt text

The merkle tree is created by looking at all of the transactions in the block in the order they appear. The rules for creating a Bitcoin merkle root are mildly complex for most blocks, but for the genesis block they're easy—the merkle root is the same as the hash of the first (and only) transaction in the Genesis Block. Let's add that hash to our script:

## Merkle root (in this case, also a txid). We have to reverse it
## into Internal Byte Order
merkle_root = decode("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b", 'hex')[::-1]

The Timestamp

Bitcoin block headers use Unix epoch time, often simply called Unix time or epoch time. This is the number of seconds elapsed since midnight 1 January 1970 UTC. As you might suspect, it’s easy to get that time on a Unix-like system:

## Get the current Unix time
date +%s

You can also get the Unix time for an arbitrary date, such as the date Nakamoto used when mining the Genesis Block:

## Get the corresponding Unix time for the provided date
date +%s -d '3 Jan 2009 18:15:05 UTC'

Let's add that time to our mining script:

## Date in Unix time format
date = pack("<L", 1231006505)

nBits: encoding the target

In the Hashcash tutorial, you learned that Hashcash allowed you to increase your Proof Of Work (POW) security by increasing the number of leading zero bits, but that for each additional bit, you had to do twice as much work. Bitcoin also has a way of increasing the amount of POW security when miners are producing blocks too fast, but more fine-grained control was needed than simply waiting until miners were producing blocks twice as fast. So Nakamoto created the target number.

Bitcoin block header hashes are interpreted as numbers that must be less than the target value, which provides more granularity than whole bits do. To help keep track of the current target, a field in the block header stores the current 256-bit target compressed into just 32 bits (reducing granularity somewhat). To do this, the base-256 form of scientific notation is used.

alt text

The lowest allowed target in Bitcoin is called difficulty 1. In nBits, it’s 1d00ffff. The Genesis Block was officially mined at that difficulty, although the amount of proof of work in the Genesis Block is much higher than a typical difficulty-1 block.

Let's add the difficulty to our block:

## nBits is stored as a little-endian (>) unsigned-long (L)
nbits = pack("<L", 0x1d00ffff)

Let's also add some code to convert nBits into the target threshold so that we can determine when we've found a difficulty-1 block later:

## Convert current nbits into a big-endian string
nbits_calc = hexlify(nbits[::-1])

## The nbits calculation is base-256
base = 256

## The nbits exponent is the the first byte of the nBits
exponent = int(nbits_calc[0:2], 16) - 3
## The nbits significand is the other three bytes
significand = int(nbits_calc[2:8], 16)

## Do the nbits calculation
target = significand * ( base ** exponent )

The Nonce

When trying to create successful Proof Of Work (POW) for blocks, miners need to create many different hash results with minimal changes to the hashed data. Nakamoto gave them an easy way to do that by including a Number used Once (nonce) field in the block header. Mining software can change just the number in that field without affecting the other fields.

Typically miners start with a nonce of zero and iterate up to its maximum value, 0xffffffff. If none of those values work and it took them more than a second to search all possible nonces, they can simply update the time field to the new current time. If they were able to search all the fields in less than a second, they can change one of the transactions in the block to get a different merkle root. After either change, they can start searching nonces again.

In our case, we don't want to spend all day searching nonces, so we're going to enter a pre-computed nonce that is very close to the nonce we need to generate the Genesis Block header hash. Add this to your mining script:

nonce = 0x7c2bac10

Mining the Genesis Block on a CPU

Now you have all the pieces in place, let's use a simple loop to check header hashes until we find a block header hash with a sufficient amount of proof of work. Add the following code to the end of your script:

while nonce < 0x7c2bac1e:
  header = (
    + previous_header_hash
    + merkle_root
    + date
    + nbits
    + pack("<L", nonce)

  ## Get the header hash corresponding to the header
  header_hash = sha256d(header)

  ## If the header hash is less than the target, print the results and
  ## break the loop
  if int(hexlify(header_hash[::-1]), 16) < target:
    print("Nonce      Header Hash")
    print(nonce, internal2rpc(header_hash))

  ## Increment the nonce
  nonce += 1

Save and exit the file using the instructions that nano prints on the bottom of the screen. The ^ character means press-and-hold the Ctrl key. Then run your code like this:

python3 miner.py

In case you copied and pasted anything wrong, you can also download a copy of miner.py like this, and then run it the same as above:

wget https://gist.githubusercontent.com/harding/3e0874746baea1f10fda/raw/c66368c7332121d0bb33e13b463c2c733b6cd953/miner.py

When the script finishes running after a second or two, it should print the header hash of the Genesis Block. Notice the leading zeroes demonstrating proof of work. Congratulations, you mined the Genesis Block using a CPU just like Satoshi Nakamoto did (although he had to run his code much longer because he didn't know what nonce to start with).