J'ai ajouté un test de détection de sabotage au programme Python blockchain que j'ai écrit plus tôt dans cet article.
Dans la blockchain, chaque bloc contient la valeur de hachage du bloc précédent, et s'il est falsifié, la valeur de hachage deviendra incohérente. Je vais le mettre en œuvre immédiatement. Le comportement est simple, comparez simplement la valeur de hachage du bloc dont vous voulez savoir s'il a été falsifié avec le previous_hash du bloc suivant. Je voulais utiliser une fonction comme is_same () dans l'instruction if, mais je ne pouvais pas penser à un bon nom de variable et je me suis arrêté. Exécutez la fonction suivante à la fin du programme.
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')
La fonction ci-dessus est implémentée comme suit.
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
Il n'y a pas de falsification ← Pas de falsification
Ensuite, trafiquons-le. Supposons que Dave altère la valeur d'une transaction du bloc 2 dans le but d'augmenter sa richesse. Ajoutez ce qui suit juste avant blockchain.print_chain.
blockchain.chain[2]['transaction'][0]['value'] = 10000
Que se passe-t-il si vous exécutez check_falsification dans cet état?
==============================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 ← Falsification
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!!← Détection de sabotage
Une falsification a été détectée dans [Bloc 2].
Cette fois, j'ai essayé de mettre en œuvre de la falsification à la détection. Normalement, les variables à l'intérieur de la blockchain devraient être encapsulées et inopérantes.
Recommended Posts