from BlockChain import CBlock from Signature import generate_keys, sign, verify from cryptography.hazmat.primitives import hashes from cryptography.hazmat.backends import default_backend import random reward = 25.0 leading_zeros = 2 next_char_limit = 20 class TxBlock (CBlock): nonce = "A random nonce" def __init__(self, previousBlock): super(TxBlock, self).__init__([], previousBlock) def addTx(self, Tx_in): self.data.append(Tx_in) def count_totals(self): total_in = 0 total_out = 0 for tx in self.data: for addr, amt in tx.inputs: total_in = total_in + amt for addr, amt in tx.outputs: total_out = total_out + amt return total_in, total_out def is_valid(self): if not super(TxBlock, self).is_valid(): return False for tx in self.data: if not tx.is_valid(): return False total_in, total_out = self.count_totals() if total_out - total_in - reward > 0.000000000001: return False return True def good_nonce(self): digest = hashes.Hash(hashes.SHA256(), backend=default_backend()) digest.update(bytes(str(self.data), 'utf8')) digest.update(bytes(str(self.previousHash), 'utf8')) digest.update(bytes(str(self.nonce), 'utf8')) this_hash = digest.finalize() if this_hash[:leading_zeros] != bytes(''.join(['\x4f' for i in range(leading_zeros)]), 'utf8'): return False return int(this_hash[leading_zeros]) < next_char_limit def find_nonce(self): for i in range(1000000): self.nonce = ''.join([ chr(random.randint(0, 255)) for i in range(10*leading_zeros)]) if self.good_nonce(): return self.nonce return None # count_total() needs to be public to be used in Miner