Hi, I woke up this morning and about an hour later I had an exam and the idea came to me to create a digital currency, but to create such a complex thing, I first needed a blockchain. I started coding and until I was coding at night when I came up with something like this :
This is the whole code that I wrote, but in my verify_poe function, even though the block hash is found and they are the same, the function does not confirm this hash, why please help me.
Python:
import numpy as np
import random
import time as tm
import psutil
import hashlib
from ecdsa import SigningKey, VerifyingKey
import codecs
import socket
import json
import os
import time
import base64
import binascii
import re
private_key = SigningKey.generate()
public_key = private_key.verifying_key
HOST = '127.0.0.1' # Replace with appropriate host address if needed
PORT = 65432
DATA_DIR = 'blockchain_data' # Directory to store block data
with open('config.json') as f:
config = json.load(f)
NODE_NAMES = config['node_names']
class Block:
def __init__(self, previous_hash=None):
self.key = random.randint(0, 10000000000000000000000000000000)
self.hash_of_block = hashlib.sha256(str(self.key).encode()).hexdigest()
self.address = random.randint(len(self.hash_of_block), 10000000000)
self.previous_hash = previous_hash
# Calculate and store the signature during initialization
data_to_sign = (str(self.key) + self.hash_of_block + str(self.address)).encode()
self.signature = private_key.sign(data_to_sign)
# Add PoE proof (timestamp)
self.poe_proof = time.time()
def verify_signature(self):
data_to_verify = (str(self.key) + self.hash_of_block + str(self.address)).encode()
try:
public_key.verify(self.signature, data_to_verify)
return True
except:
return False
def proof_of_existence(block):
# Store block hash for PoE verification
block_hash = str(block.hash_of_block)
with open(os.path.join(DATA_DIR, 'poe.txt'), 'a') as f:
f.write(block_hash + '\n')
f.close()
print(f"PoE: Storing block hash {block_hash} for verification")
def verify_poe(block, MAX_ALLOWED_TIMESTAMP_DIFF=10):
hash_to_timestamp = {}
try:
with open(os.path.join(DATA_DIR, 'poe.txt'), 'r') as f:
for line in f:
match = re.search(rf"({block.hash_of_block}) (.*?)", line)
if match:
timestamp_str = match.group(1)
if timestamp_str:
try:
timestamp = float(timestamp_str)
timestamp_diff = abs(timestamp - block.poe_proof)
if timestamp_diff <= MAX_ALLOWED_TIMESTAMP_DIFF:
print(f"PoE: hash '{block.hash_of_block}' found, PoE timestamp: '{timestamp}' is valid.")
else:
print(f"PoE: hash '{block.hash_of_block}' found, but timestamps differ significantly (diff: {timestamp_diff}).")
if timestamp_diff < MAX_ALLOWED_TIMESTAMP_DIFF * 1.1:
print("Warning: Timestamp difference is close to allowed limit.")
data_to_verify = hashlib.sha256((str(block.key) + block.hash_of_block + str(block.address)).encode()).hexdigest()
if block.verify_signature(data_to_verify):
print(f"PoE: Signature for block hash '{block.hash_of_block}' is valid.")
else:
print(f"PoE: Signature for block hash '{block.hash_of_block}' is invalid.")
except ValueError:
print(f"Warning: Invalid timestamp format for block hash '{block.hash_of_block}' in poe.txt")
else:
print(f"Warning: Missing timestamp for block hash '{block.hash_of_block}' in poe.txt")
if timestamp_diff > MAX_ALLOWED_TIMESTAMP_DIFF:
print(f"Error: PoE timestamp for block hash '{block.hash_of_block}' exceeds maximum allowed time (diff: {timestamp_diff})")
break
else:
print(f"Error: Block hash '{block.hash_of_block}' not found in poe.txt")
except Exception as e:
print(f"Error verifying PoE for hash '{block.hash_of_block}': {e}")
def save_block(block, filename):
with open(os.path.join(DATA_DIR, filename), 'wb') as f:
json_data = json.dumps({
'key': block.key,
'hash_of_block': str(block.hash_of_block), # Convert bytes to string
'address': block.address,
'previous_hash': str(block.previous_hash) if block.previous_hash else None,
'signature': str(block.signature) if block.signature else None,
'poe_proof': block.poe_proof
})
f.write(json_data.encode())
def load_block(filename):
if not os.path.exists(os.path.join(DATA_DIR, filename)):
return None
with open(os.path.join(DATA_DIR, filename), 'rb') as f:
data = f.read()
data_list = data.decode().strip().split(", ")
block_data = {}
for i in range(0, len(data_list), 2):
key = data_list[i]
# Check if the next index is within the list bounds
if i + 1 < len(data_list):
value = data_list[i + 1]
else:
value = None
block_data[key] = value
return Block(**block_data)
def broadcast_block(block):
# Convert block to JSON string
encoded = binascii.b2a_base64(block.hash_of_block.encode('utf-8'), newline=False)
block_json = json.dumps({
'key': block.key,
'hash_of_block': base64.b64encode(encoded).decode('utf-8'), # Convert bytes to base64 string
'address': block.address,
'previous_hash': base64.b64encode(block.previous_hash.encode('utf-8')).decode('utf-8') if block.previous_hash else None,
'signature': base64.b64encode(block.signature).decode('utf-8') if block.signature else None,
'poe_proof': block.poe_proof
}, indent=4)
NODE_NAME = "127.0.0.1"
for node_name in NODE_NAMES:
if node_name == NODE_NAME:
continue # Skip sending to itself
try:
# Create a TCP socket and connect to the node
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
sock.connect((NODE_NAMES[node_name], PORT))
# Send the JSON-encoded block data
sock.sendall(block_json.encode())
# Receive acknowledgement from the node
response = sock.recv(1024).decode()
if response:
print(f"Successfully broadcasted block to {node_name}")
else:
print(f"Failed to broadcast block to {node_name}: {response}")
except Exception as e:
print(f"Error broadcasting block to {node_name}: {e}")
def blockchain(k):
genesis_block = Block()
block_chain = [genesis_block]
for _ in range(k):
previous_block = block_chain[-1]
new_block = Block(previous_block.hash_of_block)
proof_of_existence(new_block)
verify_poe(new_block)
save_block(new_block, previous_block.hash_of_block + ".block")
broadcast_block(new_block)
block_chain.append(new_block)
for block in block_chain:
print(f"Key: {block.key}")
print(f"Block Hash: {block.hash_of_block}")
print(f"Address: {block.address}")
print(f"Previous Block Hash: {block.previous_hash}")
print(f"Signature: {block.signature}")
if block.verify_signature():
print("Signature is valid")
else:
print("Signature is invalid!")
print("-" * 50)
blockchain(10)
This is the whole code that I wrote, but in my verify_poe function, even though the block hash is found and they are the same, the function does not confirm this hash, why please help me.