[Python Block Chain] Part 1 : The Basic Blockchain
![[Python Block Chain] Part 1 : The Basic Blockchain](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Funsplash%2FOqtafYT5kTw%2Fupload%2Fv1639091485679%2FLy_4WnlWl.jpeg&w=3840&q=75)
Search for a command to run...
![[Python Block Chain] Part 1 : The Basic Blockchain](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Funsplash%2FOqtafYT5kTw%2Fupload%2Fv1639091485679%2FLy_4WnlWl.jpeg&w=3840&q=75)
No comments yet. Be the first to comment.
In this series I will talk about Blockchain from a technology point of view, I will try to explain a lot of topics ranging from basic concepts till how to build your own block chain.
You would have been living in an underground cave for the past 10 years if you havn't heard about cryptocurrencies. We all heard about Bitcoin, Ethereum and the rest of the crypto currencies. At the time of writing (2021-12-05) the price of 1 Bitcoin...
Public cloud providers such as AWS (Amazon Web Services), and GCP (Google Cloud Platform) offer many network services to customers that can be configured through graphical interfaces, command line, and API endpoints. In this article, which is aimed a...
Have you ever tried to refactor/clean up some program code only to discover you are just dealing with a different type of mess? reordering spaghetti in a pan doesn't make it a different type of pasta. It is only by having a deep understanding of OOD ...
Having worked in a couple of multinational software companies as well as startups, I feel I have seen or at least heard about almost every type of software comment there is, I will try to list them, and I am happy for you to reach out to me if there ...

It is important to define the various levels of access to an information technology system individuals require. The levels of access given to individuals are determined on two primary factors: The individual's role within the organization. The sensi...
![Information Security Series: [Part2] Principles of Privileges](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1647290198557%2FdaFz7fDND.png&w=3840&q=75)
In this series, we are going to talk about the basic principles of information security & the fundamental frameworks that are used to protect data and systems. The CIA Triad In 1998 a security model called the CIA triad started being used for creatin...
![Information Security Series: [Part1] Principles of Security](/_next/image?url=https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1647209120646%2FxVK4QYmwq.png&w=3840&q=75)
The basic idea of blockchain is very simple: a distributed immutable ledger that maintains a continuously growing list of records. the ledger is distributed among multiple peers
Now, some of these peers might be evil and intentionally report a tampered version of blockchain data. The entire network uses democracy to come to a consensus on the current state of data and any non-conformant or outlier peers are ignored/blocked.
This means that in order for a blockchain network to be fair and valid, most of the nodes have to be agree on the same version of data. If 51% of the nodes are compromised the network is hacked. Since the networks should be globally distributed, this is not a possibility.
In this chapter we will implement a basic version of such blockchain in python. At the end of the chapter we will have the following basic functionalities of blockchain:
The full code that will be implemented in this chapter can be found here. version-1 only contains the empty project structure.
The blockchain in simple words is a chain of linked blocks containing data, each node in the chain contains a set of records and the hash (signature) of the previous node. Keeping track of the previous node guarantees that you can never change any of the nodes data because if there is a change in any node's data will change its hash and so the next node which keeps track of the (previous hash) will be invalid. and so the only way to edit a record in the middle is to modify every consecutive node.

this guarantees that the blockchain is immutable, you can only add new nodes to the chain but you cannot edit any of the middle node's data.
We will start by defining the block structure. Only the most essential properties are included at the block at this point.
The first block in the block chain is special because there it doesn't have a previous hash this is why it is special.
In Python3 we can implement the Block class as following
import hashlib
from dataclasses import dataclass
@dataclass
class Block:
index: int
hash: str
prev_hash: str
timestamp: int
data: str
def calculate_block_hash(self) -> str:
return calculate_block_hash(
self.index,
self.prev_hash,
self.timestamp,
self.data
)
def calculate_block_hash(index: int, prev_hash: str, timestamp: int, data: str) -> str:
m = hashlib.sha256()
payload = "%s%s%s%s" % (
index,
prev_hash,
timestamp,
data
)
m.update(payload.encode("utf8"))
return m.hexdigest()
It should be noted that the block hash has not yet nothing to do with mining, as there is no proof-of-work problem to solve. We use block hashes to preserve integrity of the block and to explicitly reference the previous block.
A block chain simply contains list of blocks, it contains function to add blocks to the chain and verify chain status
from dataclasses import dataclass, field
from datetime import datetime
from . import Block, calculate_block_hash
@dataclass
class BlockChain:
blocks: list[Block] = field(default_factory=list)
to support block addition we can add the following function to the Blockchain class definition
def add_block(self, block: Block):
# Allow adding block only if Genesis Block or valid block
if len(self.blocks) == 0 or self.is_valid_block(block, self.get_latest_block()):
self.blocks.append(block)
At any given time we must be able to validate if a block or a chain of blocks are valid in terms of integrity. This is true especially when we receive new blocks from other nodes and must decide whether to accept them or not.
For a block to be valid the following must apply:
1.The index of the block must be one number larger than the previous 2.The prev_hash of the block match the hash of the previous block 3.The hash of the block itself must be valid
This can be done with the following code:
def is_valid_block(self, block: Block, previous_block: Block):
# Check block index
if previous_block.index + 1 != block.index:
return False
# Check previous block hash equls block hash
if previous_block.hash != block.prev_hash:
return False
# Check block hash
if block.calculate_block_hash() != block.hash:
return False
return True
to validate our chain we can always iterate over the nodes and confirm that each node's stored previous hash is equal to the the hash of the contents of the previous node. we can do this by validating each node with its previous one.
def is_valid_blockchain(self):
print("Checking integrity of Blockchain with length:", len(self.blocks))
# Blockchain is invalid if it doesn't have a Genesis block.
if len(self.blocks) == 0:
return False
# Validate chain
for idx in range(1, len(self.blocks)):
print("Checking integrity of Block Idx:", self.blocks[idx].index)
if not self.is_valid_block(self.blocks[idx], self.blocks[idx - 1]):
return False
# Blockchain is valid
return True
There should always be only one explicit set of blocks in the chain at a given time. In case of conflicts (e.g. two nodes both generate a block number) we choose the chain that has the longest number of blocks. In the below example, the data introduced in block 72: a350235b00 will not be included in the blockchain, since it will be overridden by the longer chain.

We implement this simple resolve implementation using the following function
def replace_chain(self, other_chain):
if self.get_genesis_block() != other_chain.get_genesis_block():
logging.error("Received blockchain with invalid Genesis block: %s", other_chain)
elif other_chain.is_valid_blockchain() and other_chain.length() > self.length():
logging.error("Received blockchain: %s is valid. Replacing current blockchain with received blockchain", other_chain)
self.blocks = other_chain.blocks
else:
logging.error("Received invalid blockchain: %s", other_chain)
We then a simple main function in a run.py file to test our blockchain
from blockchain import Block, calculate_block_hash
from blockchain.blockchain import BlockChain
def main():
#genesis_block = create_genesis_block("Test Block Data 1")
genesis_block = Block(
0,
'bc48c2c971c48f6b767b059885a51b4e753ae0928dd69b0ec0ce3ae4b6311d56',
None,
1638999821.017757,
"My Genesis Block!!"
)
blockchain = BlockChain(genesis_block)
blockchain.add_block(blockchain.generate_next_block("Test Block Data 1"))
blockchain.add_block(blockchain.generate_next_block("Test Block Data 2"))
blockchain.add_block(blockchain.generate_next_block("Test Block Data 3"))
o_blockchain = BlockChain(genesis_block)
o_blockchain.add_block(o_blockchain.generate_next_block("Test Block Data 1"))
o_blockchain.add_block(o_blockchain.generate_next_block("Test Block Data 2"))
o_blockchain.add_block(o_blockchain.generate_next_block("Test Block Data 3"))
o_blockchain.add_block(o_blockchain.generate_next_block("Test Block Data 4"))
blockchain.replace_chain(o_blockchain)
logging.info("Is Valid Blockchain: %s", blockchain.is_valid_blockchain())
we get the following output:
py-blockchain meally$ python3 run.py
INFO:root:Checking integrity of Blockchain: Blockchain[genesis[:8]=bc48c2c9, size=5]
INFO:root:Checking integrity of Block: Block[idx=1, contentSize=17, hash[:8]=bc5d6be6]
INFO:root:Checking integrity of Block: Block[idx=2, contentSize=17, hash[:8]=faf9af6d]
INFO:root:Checking integrity of Block: Block[idx=3, contentSize=17, hash[:8]=f4a5d425]
INFO:root:Checking integrity of Block: Block[idx=4, contentSize=17, hash[:8]=4c08e577]
INFO:root:Blockchain: Blockchain[genesis[:8]=bc48c2c9, size=5] is valid!
ERROR:root:Received blockchain: Blockchain[genesis[:8]=bc48c2c9, size=5] is valid. Replacing current blockchain with received blockchain
INFO:root:Checking integrity of Blockchain: Blockchain[genesis[:8]=bc48c2c9, size=5]
INFO:root:Checking integrity of Block: Block[idx=1, contentSize=17, hash[:8]=bc5d6be6]
INFO:root:Checking integrity of Block: Block[idx=2, contentSize=17, hash[:8]=faf9af6d]
INFO:root:Checking integrity of Block: Block[idx=3, contentSize=17, hash[:8]=f4a5d425]
INFO:root:Checking integrity of Block: Block[idx=4, contentSize=17, hash[:8]=4c08e577]
INFO:root:Blockchain: Blockchain[genesis[:8]=bc48c2c9, size=5] is valid!
INFO:root:Is Valid Blockchain: True
The full code that will be implemented in this chapter can be found here. version-1 only contains the empty project structure.
In the next blog post we will create a simple web server for our block chain and begin creating the peer to peer communication (distributed ledger) by using a mix between http server and web-sockets.