Blockchain tampering detection with Python

Introduction

I added a tamper detection test to the Python blockchain program I wrote earlier in this article.

Tampering detection mechanism

In the blockchain, each block holds the hash value of the previous block, and if it is tampered with, the hash value will become inconsistent. I will implement it immediately. The behavior is simple: just compare the hash value of the block you want to know if it has been tampered with with the previous_hash of the next block. I wanted to use a function like is_same () in the if statement, but I couldn't think of a good variable name and stopped. Execute the following function at the end of the program.

    def check_falsification(self):
      print('=' * 30 + 'Check falsification')
      for chain_index, block in enumerate(self.chain):
        if chain_index == 0:
          continue
        else:
          if block['previous_hash'] != self.make_hash(self.chain[chain_index-1]):
            print(f'[Block {chain_index-1}]Falsification is detected!!')
            return
      print('There is no falsification')

Source code

The implementation of the above function is as follows.

import hashlib
import time
import json


class BlockChain(object):

    def __init__(self):
        self.chain = []
        self.transaction_pool = []
        self.create_block(previous_hash='Initialize')

    def make_hash(self, block):
        json_block = json.dumps(block)
        return hashlib.sha256(json_block.encode()).hexdigest()
    
    def create_block(self, previous_hash=None, nonce=0, transaction=None, timestamp=time.time()):
        block = {
            'previous_hash': previous_hash,
            'nonce': nonce,
            'transaction': transaction,
            'timestamp': timestamp
          }
        self.add_block_to_chain(block)
    
    def add_block_to_chain(self, block):
        self.chain.append(block)

    def mining(self):
        previous_hash = self.make_hash(self.chain[-1])
        nonce = 0
        transaction = self.transaction_pool
        self.transaction_pool = []
        while True:
            if self.proof_of_work(previous_hash, nonce, transaction):
                break
            else:
                nonce += 1
        timestamp = time.time()
        self.create_block(previous_hash, nonce, transaction, timestamp)

    def proof_of_work(self, previous_hash, nonce, transaction):
        guess_block = {
          'previous_hash': previous_hash,
          'nonce': nonce,
          'transaction': transaction
        }
        guess_hash = self.make_hash(guess_block)
        return guess_hash.startswith('0'*2)

    def add_transaction(self, sender_name, reciever_name, value):
        transaction = {
            'sender_name': sender_name,
            'reciever_name': reciever_name,
            'value': value
        }
        self.transaction_pool.append(transaction)

    def print_chain(self):
        for chain_index, block in enumerate(self.chain):
            print(f'{"="*40}Block {chain_index:3}')
            if block['transaction'] is None:
                print('Initialize')
                continue
            else:
                for key, value in block.items():
                    if key == 'transaction':
                        for transaction in value:
                            print(f'{"transaction":15}:')
                            for kk, vv in transaction.items():
                                print(f'\t{kk:15}:{vv}')
                    else:
                        print(f'{key:15}:{value}')

    def check_falsification(self):
      print('=' * 30 + 'Check falsification')
      for chain_index, block in enumerate(self.chain):
        if chain_index == 0:
          continue
        else:
          if block['previous_hash'] != self.make_hash(self.chain[chain_index-1]):
            print(f'[Block {chain_index-1}]Falsification is detected!!')
            return
      print('There is no falsification')


if __name__ == '__main__':
    # print('='*30 + 'Start' + '='*30)
    blockchain = BlockChain()
    blockchain.add_transaction(sender_name='Alice', reciever_name='Bob', value=100)
    blockchain.add_transaction(sender_name='Alice', reciever_name='Chris', value=1)
    blockchain.mining()
    blockchain.add_transaction(sender_name='Bob', reciever_name='Dave', value=100)
    blockchain.mining()
    blockchain.add_transaction(sender_name='Chris', reciever_name='Dave', value=100)
    blockchain.mining()
    blockchain.print_chain()
    blockchain.check_falsification()

Execution result

========================================Block   0
Initialize
========================================Block   1
previous_hash  :f904f9ea034f3e38ca26d52b5274b1d1159472ac12063194ee5c8b7f692e2adc
nonce          :33
transaction    :
        sender_name    :Alice
        reciever_name  :Bob
        value          :100
transaction    :
        sender_name    :Alice
        reciever_name  :Chris
        value          :1
timestamp      :1579064814.8078277
========================================Block   2
previous_hash  :75fd5621af68c8f2d8700f4585c6a05bf4f0ff781a9bef0924ad31c7ac3066b0
nonce          :220
transaction    :
        sender_name    :Bob
        reciever_name  :Dave
        value          :100
timestamp      :1579064814.815833
========================================Block   3
previous_hash  :5aa74c98450873ce6485a92a932cecbd72f542d961cb1cc3c2fd9129f15eebf2
nonce          :243
transaction    :
        sender_name    :Chris
        reciever_name  :Dave
        value          :100
timestamp      :1579064814.8278437
==============================Check falsification
There is no falsification ← No tampering

Tampering and detection

Next, let's tamper with it. Suppose Dave tampers with the value of a Block 2 transaction in an attempt to increase his wealth. Add the following just before blockchain.print_chain.

    blockchain.chain[2]['transaction'][0]['value'] = 10000

What happens if you run check_falsification in this state?

Execution result

==============================Make falsification
========================================Block   0
Initialize
========================================Block   1
previous_hash  :3697444272d45bb529d559f0ac13cd287a310303cae0db0e27c644d32d371c27
nonce          :105
transaction    :
        sender_name    :Alice
        reciever_name  :Bob
        value          :100
transaction    :
        sender_name    :Alice
        reciever_name  :Chris
        value          :1
timestamp      :1579064861.3724322
========================================Block   2
previous_hash  :e6cdee32c283131e191a97113887172fba2f61c49eae031d271162545c345bec
nonce          :146
transaction    :
        sender_name    :Bob
        reciever_name  :Dave
        value          :10000 ← Tampering
timestamp      :1579064861.3824363
========================================Block   3
previous_hash  :7810a72e38652124bff69c1436669e873a01d7d4b392107d210e33c3c841ca0c
nonce          :162
transaction    :
        sender_name    :Chris
        reciever_name  :Dave
        value          :100
timestamp      :1579064861.391444
==============================Check falsification
[Block 2]Falsification is detected!!← Tampering detection

Tampering was detected in [Block 2].

Summary

This time I tried to implement from tampering to detection. Normally, the variables inside the blockchain should be encapsulated and inoperable.

Recommended Posts

Blockchain tampering detection with Python
Face detection with Python + dlib
Face detection with Python + OpenCV
Face detection with YOLO Face (Windows10, Python3.6)
Face detection with Lambda (Python) + Rekognition
[Python] Using OpenCV with Python (Edge Detection)
Face detection with Python + OpenCV (rotation invariant)
FizzBuzz with Python3
Scraping with Python
Statistics with python
Build a blockchain with Python ① Create a class
Scraping with Python
Python with Go
Twilio with Python
Integrate with Python
Play with 2016-Python
AES256 with python
Tested with Python
python starts with ()
with syntax (Python)
Zundokokiyoshi with python
Excel with Python
Microcomputer with Python
[Python] Real-time object detection with iPad camera
Cast with python
Hello World and face detection with OpenCV 4.3 + Python
Serial communication with Python
Zip, unzip with python
Django 1.11 started with Python3.6
Primality test with Python
Python with eclipse + PyDev.
Socket communication with Python
Data analysis with python 2
Scraping with Python (preparation)
Learning Python with ChemTHEATER 03
Sequential search with Python
Run Python with VBA
Handling yaml with python
Solve AtCoder 167 with python
Serial communication with python
[Python] Use JSON with Python
Learning Python with ChemTHEATER 05-1
Learn Python with ChemTHEATER
Run prepDE.py with python3
1.1 Getting Started with Python
Collecting tweets with Python
Binarization with OpenCV / Python
3. 3. AI programming with Python
Kernel Method with Python
Non-blocking with Python + uWSGI
Scraping with Python + PhantomJS
Posting tweets with python
Use mecab with Python3
[Python] Redirect with CGIHTTPServer
Operate Kinesis with Python
Getting Started with Python
Use DynamoDB with Python
Zundko getter with python
Handle Excel with python
Ohm's Law with Python
Primality test with python