Creating Your First Blockchain with Python

Image: 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?

4
Comments

avatar
2 Comment threads
2 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
2 Comment authors
Devji Chhangasmit modhsmit modh Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
smit modh
Guest
smit

can we create node js backhand?? and host this blockchain?

smit modh
Member
smit modh

or what can be the next step?

smit modh
Member
smit modh

getting following error while changing genesisBlock = Block(“I am genesis block!”,0) to genesisBlock = Block(“I am genesis block”,0) …. File “blockDev.py”, line 14, in getPoWHash return self.getPoWHash (data) File “blockDev.py”, line 14, in getPoWHash return self.getPoWHash (data) File “blockDev.py”, line 14, in getPoWHash return self.getPoWHash (data) File “blockDev.py”, line 7, in getPoWHash nonce = str(random.randint(0,300000)) File “/usr/lib/python3.5/random.py”, line 218, in randint return self.randrange(a, b+1) File “/usr/lib/python3.5/random.py”, line 194, in randrange return istart + self._randbelow(width) File “/usr/lib/python3.5/random.py”, line 228, in _randbelow if type(random) is BuiltinMethod or type(getrandbits) is Method: RecursionError: maximum recursion depth exceeded while calling a Python object