90 lines
3.5 KiB
Python
90 lines
3.5 KiB
Python
import json
|
||
import os
|
||
from dotenv import load_dotenv
|
||
from nonce_finder import NonceFinder
|
||
|
||
|
||
class Block:
|
||
def __init__(
|
||
self,
|
||
name,
|
||
amount,
|
||
to_whom_name,
|
||
nonce=0,
|
||
prev_hash='00000000000000000000000000000000'
|
||
):
|
||
self.name = name
|
||
self.amount = amount
|
||
self.to_whom_name = to_whom_name
|
||
self.nonce = nonce
|
||
self.prev_hash = prev_hash
|
||
self.standard_path = 'blockchain_blocks/'
|
||
dotenv_path = os.path.join(os.path.dirname(__file__), '.env')
|
||
if os.path.exists(dotenv_path):
|
||
load_dotenv(dotenv_path)
|
||
self.key = os.environ.get('KEY')
|
||
|
||
def get_last_block(self):
|
||
""" Получение номера последнего блока """
|
||
try:
|
||
files = [int(f.split('.')[0])
|
||
for f in os.listdir(self.standard_path) if f.endswith('.txt')]
|
||
return max(files, default=0)
|
||
except ValueError:
|
||
return 0
|
||
|
||
def data_creator(self):
|
||
""" Создание данных блока """
|
||
return [
|
||
{'nonce': self.nonce},
|
||
{'from': self.name, 'amount': self.amount, 'to_whom': self.to_whom_name},
|
||
{'preview_hash': self.prev_hash}
|
||
]
|
||
|
||
def get_last_block_hash(self, filename):
|
||
""" Получение хэша последнего блока """
|
||
with open(
|
||
os.path.join(self.standard_path, str(int(filename) - 1) + '.txt'),
|
||
'r'
|
||
) as file:
|
||
return json.load(file)[1]
|
||
|
||
def block_creator(self):
|
||
""" Создание нового блока """
|
||
last_file = self.get_last_block()
|
||
filename = str(last_file + 1)
|
||
data = self.data_creator()
|
||
if last_file != 0:
|
||
data[2]['preview_hash'] = self.get_last_block_hash(filename)
|
||
block_hash = NonceFinder(data, 4, self.key).create_pow()[1]
|
||
result_dump_data = [data, block_hash]
|
||
with open(os.path.join(self.standard_path, filename + '.txt'), 'w') as file:
|
||
json.dump(result_dump_data, file, indent=4, ensure_ascii=False)
|
||
if last_file == 0:
|
||
print('[+] Создан первый блок')
|
||
else:
|
||
print(f'[+] Блок {filename} создан')
|
||
|
||
def blockchain_checker(self):
|
||
""" Проверка целостности блокчейна """
|
||
files = sorted([f for f in os.listdir(self.standard_path) if f.endswith('.txt')],
|
||
key=lambda x: int(x.split('.')[0]))
|
||
for file in files[1:]:
|
||
with open(os.path.join(self.standard_path, file), 'r') as current_file:
|
||
current_block = json.load(current_file)
|
||
prev_hash = current_block[0][2]['preview_hash']
|
||
prev_file = str(int(file.split('.')[0]) - 1) + ".txt"
|
||
with open(os.path.join(self.standard_path, prev_file), 'r') as _file:
|
||
prev_block_data = json.load(_file)[0]
|
||
real_prev_block_hash = NonceFinder(
|
||
prev_block_data,
|
||
4,
|
||
self.key
|
||
).create_pow()[1]
|
||
if prev_hash == real_prev_block_hash:
|
||
print(f'[+] Блок {prev_file} верен')
|
||
else:
|
||
print(f'[-] В блоке {prev_file} допущена ошибка!')
|
||
if len(files) <= 1:
|
||
print('[+] Для начала проверки цепочки блоков, создайте больше блоков!')
|