Source code for blockchain.blockchain.block

import logging

from time import time

from ..utils.utils import colorize
from ..blockchain.data import Data


logger = logging.getLogger(__name__)


[docs]class Block(object): def __init__(self, index: int, data: Data, proof: int, previous_hash: str) -> None: """ Constructor for ``Block`` objects. Constraints: - ``index`` has to be int and positiv - ``data`` has to be a object of class ``Data`` - ``proof`` has to be int - ``prevoius_hash`` has to be string and of length 64 (64 hex digits hash). Args: index (int): If of the new Block. data (Data): Data that is attached to this block. proof (int): The ``proof`` value for this block. previous_hash (str): Hash value of previous block in chain. """ logger.debug(f"Arguments - index: {index}, data.id: {data.id if isinstance(data, Data) else None}, data.message: {data.message if isinstance(data, Data) else None}, proof: {proof}, previous_hash: {previous_hash}") logger.debug("Init parent Class.") super().__init__() if index == 0 and proof == None and previous_hash == None: # Genesis Block is ok. For all others check constraints. logger.debug("Genesis Block -> no type checks ...") else: logger.debug(f"Type checks: 'index' ...") if not isinstance(index, int) or index < 0: raise ValueError("Index has incorrect type or value!") logger.debug(f"Type checks: 'data' ...") if not isinstance(data, Data): raise ValueError("Data is not a object of class 'Data'.") logger.debug(f"Type checks: 'proof' ...") if not isinstance(proof, int): raise ValueError("Proof has incorrect type!") logger.debug(f"Type checks: 'previous_hash' ...") if not isinstance(previous_hash, str) or len(previous_hash) != 64: raise ValueError("Previous hash has incorrect type or wrong length!") logger.debug(f"Type checks done: all valid.") self._index = index self._timestamp = time() self._data = data self._proof = proof self._previous_hash = previous_hash logger.info("Created 'Block' object.") logger.debug(f"'Block' object created.")
[docs] def __eq__(self, other: object) -> bool: """ Method for comparing two ``Block`` objects. Args: other (Block): ``Block`` object to compare with ``self``. Returns: bool: ``True`` if blocks are equal. ``False`` otherwise. """ if not isinstance(other, Block): return False # if all attributes are equal => block1 = block2 return self.__dict__ == other.__dict__
[docs] def __repr__(self) -> str: """ String representation of ``Block`` object. Returns: str: String representation of ``Block`` object. """ block_representation = f"\n| {'=' * 80}\n" block_representation += f"| {colorize('index', 'bold')}: \t {str(self.index)} \n" block_representation += f"| {colorize('time', 'bold')}: \t {str(self.timestamp)} \n" block_representation += f"| {colorize('proof', 'bold')}: \t {str(self.proof)} \n" block_representation += f"| {colorize('prev. hash', 'bold')}: \t {str(self.previous_hash)} \n" block_representation += f"{str(self.data)}\n" block_representation += f"| {'=' * 80}\n" return block_representation
[docs] def __bytes__(self) -> bytes: """ Uses the encoded string representation of this ``Block`` object as ``bytes`` representation. Returns: bytes: ``byte`` representation of ``Block`` object. """ return self.__repr__().encode("utf-8")
@property def index(self) -> int: return self._index @property def timestamp(self) -> float: return self._timestamp @property def data(self) -> Data: return self._data @property def proof(self) -> int: return self._proof @property def previous_hash(self) -> str: return self._previous_hash