"""Block class representing a single record in the blockchain. Each block stores transaction information (owner, amount, operation type) and a cryptographic hash linking it to the previous block. Provides serialization methods for computing hashes and maintaining blockchain integrity. Authors: Andre Grassi de Jesus, Ricardo Faria Last Modified: Nov. 14 2025 """ import json from typing import Optional from models.operation import Operation class Block: """A register in the block chain. Attributes: owner_name (str): The name of the client that did the operation registered. amount (float): The amount of minicoins involved in the operation. operation (Operation): The action that the client did. hash_b (bytes): The hash of the block. It's initialized as None and must be computed and set by the server with Hash class. """ def __init__( self, owner_name: str, amount: float, operation: Operation, ): if amount <= 0: raise ValueError("amount must be positive.") if owner_name is None: raise ValueError("owner_name can't be None") self.owner_name = owner_name self.amount = amount self.operation = operation self.hash_b: bytes = None def serialize(self) -> bytes: """Transforms the Block in a JSON object for hashing.""" json_s = json.dumps(self.to_dict(), sort_keys=True) return json_s.encode("utf-8") def to_dict(self) -> dict: """Transforms the Block into a dictionary for serialization.""" return { "owner_name": self.owner_name, "amount": self.amount, "operation": self.operation.value, } def __repr__(self): if self.hash_b is None: hash_hex = "None" else: hash_hex = self.hash_b.hex()[:3] return f"Block {self.owner_name} {self.operation.value} {self.amount} hash={hash_hex}"