Ich habe dem Python-Blockchain-Programm, das ich zuvor in [diesem Artikel] geschrieben habe, einen Manipulationserkennungstest hinzugefügt (https://qiita.com/sssssssiiiiinnn/items/e1022667026b942b2d7d).
In der Blockchain enthält jeder Block den Hash-Wert des vorherigen Blocks. Wenn er manipuliert wird, wird der Hash-Wert inkonsistent. Ich werde es sofort umsetzen. Das Verhalten ist einfach. Vergleichen Sie einfach den Hash-Wert des Blocks, den Sie wissen möchten, wenn er mit dem previous_hash des nächsten Blocks manipuliert wurde. Ich wollte eine Funktion wie is_same () in der if-Anweisung verwenden, konnte mir aber keinen guten Variablennamen vorstellen und stoppte. Führen Sie am Ende des Programms die folgende Funktion aus.
    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')
Die obige Funktion wird wie folgt implementiert.
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()
========================================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
Es gibt keine Fälschung ← Keine Manipulation
Als nächstes manipulieren wir es. Angenommen, Dave manipuliert den Wert einer Block 2-Transaktion, um sein Vermögen zu erhöhen. Fügen Sie kurz vor blockchain.print_chain Folgendes hinzu.
    blockchain.chain[2]['transaction'][0]['value'] = 10000
Was passiert, wenn Sie check_falsification in diesem Zustand ausführen?
==============================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 ← Manipulationen
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!!← Manipulationserkennung
Manipulationen wurden in [Block 2] festgestellt.
Diesmal habe ich versucht, von Manipulation bis Erkennung zu implementieren. Normalerweise sollten die Variablen in der Blockchain gekapselt und nicht funktionsfähig sein.
Recommended Posts