"""placeholder module for compilation""" from __future__ import annotations import datetime import hashlib import struct import time import dopt_basics.datetime def float_to_bytes(num: float): return struct.pack(">d", num) class Block: __slots__ = ( "_index", "_timestamp", "_data", "_prev_hash", "_nonce", "_hash", ) def __init__( self, index: int, data: str, previous_hash: str, nonce: int, ): self._index = index self._timestamp = datetime.datetime(2025, 12, 1, 12, 0, 0).timestamp() # self._timestamp = dopt_basics.datetime.current_time_tz().timestamp() self._data = data self._prev_hash = previous_hash self._nonce = nonce self._hash = "" def _perform_hash(self): parts = bytearray() parts.extend(self._index.to_bytes(8, "big")) parts.extend(float_to_bytes(self._timestamp)) parts.extend(self._data.encode("UTF-8")) parts.extend(self._prev_hash.encode("UTF-8")) parts.extend(self._nonce.to_bytes(8, "big")) return hashlib.sha256(parts) def compute_hash_bytes(self): return self._perform_hash().digest() def compute_hash(self): return self._perform_hash().hexdigest() # Python public API @property def index(self) -> int: return self._index @property def timestamp(self) -> datetime.datetime: return datetime.datetime.fromtimestamp(self._timestamp) @property def data(self) -> str: return self._data @property def prev_hash(self) -> str: return self._prev_hash @property def nonce(self): return self._nonce @nonce.setter def nonce(self, value: int): self._nonce = value @property def hash(self) -> str: return self._hash @hash.setter def hash(self, value: str) -> None: if not isinstance(value, str): raise TypeError("No string") self._hash = value class Blockchain: def __init__( self, difficulty: int = 1, ) -> None: self.chain: list[Block] = [] # self.difficulty = difficulty.to_bytes(8, "big") self.difficulty = difficulty def create_genesis_block(self): genesis = Block( index=0, data="Genesis Block", previous_hash="0", nonce=0, ) genesis.hash = genesis.compute_hash() self.chain.append(genesis) def proof_of_work( self, block: Block, ) -> str: prefix = "0" * self.difficulty while True: block_hash = block.compute_hash() if block_hash.startswith(prefix): return block_hash block.nonce += 1 def add_block(self, data: str) -> Block: new_block = Block( index=len(self.chain), data=data, previous_hash=self.chain[-1].hash, nonce=0, ) start = time.perf_counter() new_block.hash = self.proof_of_work(new_block) elapsed = time.perf_counter() - start self.chain.append(new_block) print(f"Mined block {new_block.index} in {elapsed:.3f}s with nonce={new_block.nonce}") return new_block