LCP

Blockchain for business has been the buzz term for quite some time now, and it has the potential to create great changes in business operations. Since its first introduction in 2008, the technology has gone through a series of improvements to make it what is today. However, what is blockchain? What are the building blocks of blockchain? What is Blockchain proof of work? How to program blockchain in Python? This blog will help you understand this new technology and also the core concepts. Programming blockchain can be done in many different languages, however, we’ll be programming blockchain in python for the concepts.

What is Blockchain?

Blockchain is a DLT technique of storing information such that it is nearly impossible to alter, hack or manipulate any data within the storage. The most popular use cases of the said technology are cryptocurrencies and NFTs. However, blockchain is not limited only to cryptos or NFTs and is used in various other fields like supply chain, logistics, anti-money laundering, artist royalty tracking, etc.

A blockchain is a digital ledger of transactions, generally shared among all the nodes in a network. It consists of a series of blocks that includes several transactions, and every time a new transaction entry is done in the system, a record of that transaction is added into the ledger of each participant. This form of decentralized database managed by multiple participants is known as Distributed Ledger Technology (DLT).

Blockchain is a type of Distributed Ledger Technology (DLT) in which blocks consist of all the transaction information within the chain of blocks secured by cryptographic signatures. These signatures are known as a hash of the respective blocks.

Let us take a sneak peek at some of the core concepts of blockchain:

1. Blocks

Blocks are the building blocks of a blockchain, and they consist of (a) transactions, (b) the hash of the previous block, and (c) a new hash of its own.

block = {
    "previous_hash": "21db2980f752de935c89ca175e7f5375fa8df0340721317a4d263aff19a0b997",
    "transactions": [{"sender": "A", "receiver": "B", "amount": 0.5}],
    "proof_of_work": 9,
    "new_hash": "6da1f66cd7a157dfacc5e802bfc4ccdb5224cdfdfe2e89659365fa3fe06d0119"
}

For this case, I have taken Python's dictionary as blocks consisting of a sender name, receiver name, proof of work, and the sent amount of token.

The very first block of a blockchain is known as Genesis Block. It lays the foundation of the blockchain since a new block that gets mined into the blockchain needs an existing block that it points to. A Genesis Block looks like this:

genesis_block = {
   "previous_hash": "",
   "transactions": [],
}

2. Hash

A hash is a fixed-length string providing a layer of encryption over a block, which makes it impossible to manipulate the blockchain. It is a mechanism that converts the given data of any arbitrary length into a fixed-length output.

A given data will always produce the same hash no matter what. However, even the slightest change in the data will alter the hash. As mentioned earlier, as a block contains the hash of the preceding block, we will apply our hashing technique to the data of the previous block to get the hash of the current block. Comparing thus obtained hash to the hash already stored in the current block will verify if a blockchain has been manipulated or not.


import hashlib
 
hash = hashlib.sha256(str(blockchain).encode()).hexdigest()
 
print(hash)
 
# Output
6da1f66cd7a157dfacc5e802bfc4ccdb5224cdfdfe2e89659365fa3fe06d0119

Here we have imported an in-built library of Python called hashlib, which we will be using for generating hashes for our blocks. To generate the hash, we will take the complete blockchain as a string, encode it, and pass it to the sha256 method of the hashlib library to have a 64 character hash.

Here is a code to hash a block


import hashlib
 
hash = hashlib.sha256(str(blockchain).encode()).hexdigest()
 
print(hash)
 
# Output
6da1f66cd7a157dfacc5e802bfc4ccdb5224cdfdfe2e89659365fa3fe06d0119

3. Proof of Work

Proof of Work blockchain is an algorithm that is native to the blockchain. It is the mechanism that controls how difficult it is to mine blocks to the blockchain. It is about the miners finding a number that satisfies a certain condition using a hash. This hash is different from the hash stored in the existing blocks as it takes some data of the block into account, typically considering the transactions and the hash of the previous block. A new hash is yielded by applying the hash function on this block data, along with this Proof of Work number. This newly generated hash must match certain criteria to be recognized as a Proof of Work number. Otherwise, the number gets incremented, and the process repeats until we find a valid number. The new valid number is then added to the block metadata as the Proof of Work.

Although finding a PoW number is a challenging task and requires a lot of guessing and resources, in contrast, verifying it is very easy.

In our case, we will start by taking this PoW number or nonce as 0 and start generating hashes by using the transactions and the previous hash of the current block. Repeat this process by incrementing the nonce until we get a hash that starts with 00. Please note that this condition can be anything, for example: Starting with ff or in the case of bitcoin hash starting with 0000000000000000000 (19 Zeroes). Adding more leading zeros means generating valid hashes will take more time, leading to a more secure and robust blockchain.

Core Blockchain Concepts: Illustration of blockchain's fundamental elements - blocks, hashes, and proof of work.

Now suppose there is an attack on the blockchain, and the transactions within a block get changed. Now, of course, the previous hash verification will fail in this case. Generating new hashes for the rest of the blockchain can be done in seconds. However, we already know that there is a PoW associated with all the blocks in the blockchain. Since a block has been manipulated, its PoW number got changed, and it needs to calculate a new PoW for the current block and all the succeeding blocks in the blockchain resulting in an extremely long process.

The genuine miners would have to calculate the PoW only for the new block to mine since all the previous blocks would have already been verified.

Proof of Work Difficulty: Graph showing the exponential relationship between block index and mining time.

Here is the python code to calculate a valid proof from a given set of transactions and the previous hash in a block.

def valid_proof(transactions, previous_hash, proof):
   guess = (str(transactions) + str(previous_hash) + str(proof)).encode()
   guess_hash = hashlib.sha256(guess)
   print(guess_hash)
   return guess_hash[:2] == "00"

To generate a valid PoW, we can repeat the valid_proof() method by incrementing the proof until it returns true.

def proof_of_work(transactions, blockchain):
   last_hash = hash_block(blockchain)
   proof = 0
   while not valid_proof(transactions, last_hash, proof):
       proof += 1
   return proof

The nonce, for which the valid_proof() has returned true, will be considered as the PoW number for the current block and this block will now be added to the blockchain.

4. Mining a Block

So far, we got to know what a block in a blockchain looks like and how we can add security measures by Proof of Work and Hashes. Once the block is created, the next step is to mine this block into the blockchain.

Mining is the process of adding new blocks in the blockchain after solving PoW respective to the chain.

Now we will write the code to add/mine a new block in the blockchain

def mine_block():
   """Create a new block and add open transactions to it."""
   last_block = blockchain[-1]
   hashed_block = hash_block(last_block)
   proof = proof_of_work()
   reward_transaction = OrderedDict(
       [("sender", "MINING"), ("recipient", owner), ("amount", MINING_REWARD)]
   )
   copied_transactions = open_transactions[:]
   copied_transactions.append(reward_transaction)
   block = {
       "previous_hash": hashed_block,
       "index": len(blockchain),
       "transactions": copied_transactions,
       "proof": proof,
   }
   blockchain.append(block)
   return True

Now, that we have learned the concepts of a blockchain and how it works, we can start building our blockchain in python. We can make a CLI (Command Line Interface) in which we will keep the sender fixed and take the recipient and amount from the user.

def get_user_choice():
   """Prompts the user for its choice and return it."""
   user_input = input("Your choice: ")
   return user_input
 
 
waiting_for_input = True
while waiting_for_input:
   print("Please choose")
   print("1: Add a new transaction value")
   print("2: Mine a new block")
   print("3: Output the blockchain blocks")
   print("4: Output participants")
   print("5: Check transaction validity")
   print("h: Manipulate the chain")
   print("q: Quit")
   user_choice = get_user_choice()
   if user_choice == "1":
       tx_data = get_transaction_value()
       recipient, amount = tx_data
       if add_transaction(recipient, amount=amount):
           print("Added transaction!")
       else:
           print("Transaction failed!")
       print(open_transactions)
   elif user_choice == "2":
       if mine_block():
           open_transactions = []
   elif user_choice == "3":
       print_blockchain_elements()
   elif user_choice == "4":
       print(participants)
   elif user_choice == "5":
       if verify_transactions():
           print("All transactions are valid")
       else:
           print("There are invalid transactions")
   elif user_choice == "h":
       if len(blockchain) undefined= 1:
           blockchain[0] = {
               "previous_hash": "",
               "index": 0,
               "transactions": [
                   {"sender": "Chris", "recipient": "Jay", "amount": 100.0}
               ],
           }
   elif user_choice == "q":
       waiting_for_input = False
   else:
       print("Input was invalid, please pick a value from the list!")
   if not verify_chain():
       print_blockchain_elements()
       print("Invalid blockchain!")
       break
   print("Balance of {}: {:6.2f}".format("Jay", get_balance("Jay")))

As we keep on adding new blocks, we get to know that it takes even more time to add a new block into the blockchain. The reason for this behaviour is that the PoW keeps on increasing exponentially.

This behaviour is graphically represented below:

Mining Process Flowchart: Steps involved in mining a new block in the blockchain.

Here's our GitHub link for the python code that we discussed in the blog.

This concludes our topic on what is blockchain and its basic concepts like proof of work blockchain, building blocks of blockchain, programming python using python as an analogy. Try it out on your own and help your colleagues understand blockchain technology. In case you're stuck somewhere, reach out to us and we'll assist you with any solution.

We, at Seaflux, are enthusiasts who are helping enterprises worldwide. Have a query or want to discuss Blockchain projects? Schedule a meeting with us here, we'll be happy to talk to you!

Jay Mehta - Director of Engineering
Jay Mehta

Director of Engineering

Contact Us