Creating Your First Blockchain with Python

In this tutorial we’ll learn how to create a very basic Blockchain with Python. We will create a Blockchain with just 30 lines of code! The aim is to introduce you to Blockchain programming without getting into inessential details. You should already know fundamentals of Blockchain, if not then you may want to read this article first. You should also know basic Python programming and object oriented concepts.

Prerequisites

  1. Python 3 Installed on Windows, Linux or Mac.
  2. Knowledge of running Python programs on terminal or IDLE.

The Fundamentals

A Blockchain is merely a series of blocks. These blocks are logically connected to each other as each one stores previous block’s hash. We will create a class that represents a block and store its predecessor’s address as one of the variables within it. Other variables in the Block class include:

  1. Data: Actual data to be stored in the block
  2. Hash: Hash of this data
  3. Timestamp: Denotes when the block was added to the blockchain
  4. Nonce: A random number that is used to find target hash

Python Libraries

Firstly we import these three Python libraries. You need not to download them as they are part of standard distribution:

  1. hashlib: To generate SHA-256 of block’s data.
  2. datetime: To get current timestamp.
  3. random: To generate nonces.

#for computing sha256
import hashlib

#for generating timestamps
import datetime

#for generating random numbers
import random

The Block Class

Block class uses a constructor to initialize variables when it is instantiated. Let’s define proof-of-work as finding a hash value that must start with two zeroes (“00”). We define a function getPoWHash() which returns a hash value which satisfies our proof-of-work condition. Basically it appends different random numbers (nonces) to the data until it finds a target hash. When we find the target hash, we also store nonce used to find this hash in the block so that others can verify it.

class Block:
def getPoWHash (self, data):
nonce = str(random.randint(0, 300000))
noncedData = data + nonce
hash = hashlib.sha256 (noncedData.encode(‘utf-8’)).hexdigest()
#hashlib requires data to be encoded before hashed.
if hash.startswith (“00”):
self.nonce = nonce
return hash
else:
return self.getPoWHash (data)

def __init__ (self, data, previousHash):
self.data = data
self.nonce = None
self.previousHash = previousHash
self.timeStamp = datetime.datetime.now()
self.hash = self.getPoWHash (data)

Adding Genesis Block and Other Blocks

Next, we add some blocks to our Blockchain. First block is special, so we don’t have previous block’s hash instead we use a 0 here for the sake of simplicity. We simply instantiate the Block class each time we want to add a block.

genesisBlock = Block(“I am genesis block!”, 0)

secondBlock = Block(“I am second block”, genesisBlock.hash)

thirdBlock = Block(“I am third block”, secondBlock.hash)

Viewing the Blockchain

To view our Blockchain we can simply print the hashes of each of the blocks.

print (“Genesis Block Hash: “, genesisBlock.hash)

print (“Second Block Hash: “, secondBlock.hash)

print (“Third Block Hash: “, thirdBlock.hash)

Output: As you can see all hashes start with two zeroes as that is the condition we’ve set as proof-of-work. In Bitcoin, this requirement is 17 leading zeroes.

Genesis Block Hash: 00ddef133aa388b89d431ffd80874d94c808b363ce1467eb6e38a7c38c7712d1

Second Block Hash: 0029e17e48976fdd651e75ce283770634c33ddaca2ab9d05b2df30a0ab779bfa

Third Block Hash: 0094e2b65446530ff4a046be4a0843799e48e4d8d993fd01669a0328bcf43e79

Congrats! You’ve Made It.

We are all done! Here is the full code for this tutorial:

import hashlib
import datetime
import random

class Block:
def getPoWHash (self, data):
nonce = str(random.randint(0, 300000))
noncedData = data + nonce
hash = hashlib.sha256 (noncedData.encode(‘utf-8’)).hexdigest()
#hashlib requires data to be encoded before hashed.
if hash.startswith (“00”):
self.nonce = nonce
return hash
else:
return self.getPoWHash (data)

def __init__ (self, data, previousHash):
self.data = data
self.nonce = None
self.previousHash = previousHash
self.timeStamp = datetime.datetime.now()
self.hash = self.getPoWHash (data)

genesisBlock = Block(“I am genesis block!”, 0)
secondBlock = Block(“I am second block”, genesisBlock.hash)
thirdBlock = Block(“I am third block”, secondBlock.hash)

print (“Genesis Block Hash: “, genesisBlock.hash)
print (“Second Block Hash: “, secondBlock.hash)
print (“Third Block Hash: “, thirdBlock.hash)

What’s Ahead?

Our Blockchain is stored on a single machine but a Blockchain serves its purpose only when it is distributed. Nevertheless, it is a great start isn’t it?

Author

Devji Chhanga

Posted on

2018-09-07

Updated on

2023-08-22

Licensed under

Comments