Creating a blockchain

Now that we have defined all the required functionalities of a simple blockchain linker, we'll emulate one by creating both a few blocks and a blockchain:

new_chain = Blockchain() 
new_chain.add_block(data="first block data") 
new_chain.add_block(data="second block data") 
new_chain.add_block(data="third block data") 
 
print(json.dumps(new_chain.chain))
 
new_chain.reset() 
 
new_chain.add_block(data="first block data") 
new_chain.add_block(data="second block data") 
new_chain.add_block(data="third block data") 
 
print(json.dumps(new_chain.chain))

The preceding code snippet creates a Blockchain object and adds three blocks to it, along with an existing genesis block. This operation is performed again after resetting the blockchain. An important observation here is that both outputs of new_chain.chain will produce a list of blocks containing the block hashes shown in the following output. This is due to the fact that all the attributes contributing to the creation of the hash value are the same during execution. The hash function always produces the same hash value if fed with the same input.

The timestamp is hardcoded in the genesis block and is intentionally kept constant for all the blocks to show that hash values computed with the similar data will generate the same value every time:

[ 
  { 
    "index": 0, 
    "data": "my genesis block!!", 
    "hash": "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7", 
    "previous_hash": "0", 
    "timestamp": 1465154705 
  }, 
  { 
    "index": 1, 
    "data": "first block data", 
    "hash": "c8028a8a867a639fec693243f88a4e04f0ab5872f6913da53210316bd97d6ebb", 
    "previous_hash": "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7", 
    "timestamp": "1521059029" 
  }, 
  { 
    "index": 2, 
    "data": "second block data", 
    "hash": "aba71ef94fdc7d70bd39e5aa3eeef6fd53ac8e7fc102c2f638126c8a74d5cefe", 
    "previous_hash": "c8028a8a867a639fec693243f88a4e04f0ab5872f6913da53210316bd97d6ebb", 
    "timestamp": "1521059029" 
  }, 
  { 
    "index": 3, 
    "data": "third block data", 
    "hash": "f208c8375036ad785c9226d09585bd50a2b3993300f75e041dc3f2f0b6cfdd2b", 
    "previous_hash": "aba71ef94fdc7d70bd39e5aa3eeef6fd53ac8e7fc102c2f638126c8a74d5cefe", 
    "timestamp": "1521059029" 
  } 
] 

The preceding output will be generated two times during the actual execution. The output shows how the blocks in our blockchain are linked using cryptographic hashes. Each block in the blockchain has a previous_hash value that matches the hash value of the previous block. Index 0 is the hardcoded genesis block with no previous_hash, and index 1 has a previous_hash value that matches the genesis block's hash. All the other blocks are linked in the same manner.

Let's try to alter the data in a block and insert the rest of the blocks in the chain:

new_chain.reset() 
new_chain.add_block(data="modified first block data") 
new_chain.add_block(data="second block data") 
new_chain.add_block(data="third block data") 
 
print(json.dumps(new_chain.chain)) 

This would produce the following list of blocks in the blockchain:

[ 
  { 
    "hash": "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7", 
    "data": "my genesis block!!", 
    "index": 0, 
    "timestamp": 1465154705, 
    "previous_hash": "0" 
  }, 
  { 
    "hash": "06045fb547175c5cd32b3ba326ce9768c22771c3e128f801bbec19ea1eb20052", 
    "data": "modified first block data", 
    "index": 1, 
    "timestamp": "1521086845", 
    "previous_hash": "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7" 
  }, 
  { 
    "hash": "40c54c31afda040d037dae637ab1ec6e5eb9b132c761b9eadda21e68c0897a65", 
    "data": "second block data", 
    "index": 2, 
    "timestamp": "1521086845", 
    "previous_hash": "06045fb547175c5cd32b3ba326ce9768c22771c3e128f801bbec19ea1eb20052" 
  }, 
  { 
    "hash": "466083f34143e7f99196de01cd7777c52b0763624acd2895f0d28047c670eb41", 
    "data": "third block data", 
    "index": 3, 
    "timestamp": "1521086845", 
    "previous_hash": "40c54c31afda040d037dae637ab1ec6e5eb9b132c761b9eadda21e68c0897a65" 
  } 
] 

The preceding list of blocks shows similar block link properties to the earlier blockchain, but an interesting observation is that although only the block data of index 1 has been modified, the hash values of all the other blocks are different to the previous block output. This is due to the chaining or ripple effect. Because each block stores the hash value of the previous block, each block is affected by this modification. This leads to the creation of a new blockchain. This is the reason why blockchains are secure: A single block cannot be modified without affecting the other blocks in the ledger.

The complete script of the preceding sample blockchain application can be found in the GitHub repository of the book ( https://github.com/PacktPublishing/Foundations-of-Blockchain), along with Python packaging.