Exemple #1
0
 def add_block(self, block):
     transactions = [
         Transaction(tx['sender'], tx['recipient'], tx['signature'],
                     tx['amount']) for tx in block['transactions']
     ]
     proof_is_valid = Verification.valid_proof(transactions[:-1],
                                               block['previous_hash'],
                                               block['proof'])
     hashes_match = hash_block(self.chain[-1]) == block['previous_hash']
     if not proof_is_valid or not hashes_match:
         return False
     converted_block = Block(block['index'], block['previous_hash'],
                             transactions, block['proof'],
                             block['timestamp'])
     self.__chain.append(converted_block)
     stored_transactions = self.__open_transactions[:]
     for itx in block['transactions']:
         for opentx in stored_transactions:
             if opentx.sender == itx['sender'] and opentx.recipient == itx[
                     'recipient'] and opentx.amount == itx[
                         'amount'] and opentx.signature == itx['signature']:
                 try:
                     self.__open_transactions.remove(opentx)
                 except ValueError:
                     print('Item was already removed.')
     self.save_data()
     return True
Exemple #2
0
 def mine_block(self):
     """Create a new block and add open transactions to it."""
     if self.hosting_node == None:
         return None
     # grab the the last hashed block
     last_block = self.__chain[-1]
     # hash the last block inorder to use it in the stored hash value
     hashed_block = hash_block(
         last_block
     )  # pass in the last block to hash it and set to be passed to newly mined block
     proof = self.proof_of_work()
     reward_transaction = Transaction('Mining', self.hosting_node, '',
                                      MINING_REWARD)
     # Copy transaction instead of manipulating the original open_transactions list
     # This ensures that if for some reason the mining should fail, we don't have the reward transaction stored in the open transactions
     # create a shallow copy of the open transactions
     copied_transactions = self.__open_transactions[:]
     # verify all transactions during mining
     for tx in copied_transactions:
         if not Wallet.verify_transaction(tx):
             return None
     # append the mining reward transaction to all current open txns
     copied_transactions.append(reward_transaction)
     # create the new block object
     block = Block(len(self.__chain), hashed_block, copied_transactions,
                   proof)
     #append new block to the blockchain
     self.__chain.append(block)
     self.__open_transactions = []
     self.save_data()
     return block
Exemple #3
0
 def mine_block(self):
     if self.public_key == None:
         return None
     '''create a new block and add open transactions to it'''
     last_block = self.__chain[-1]
     hashed_block = hash_block(last_block)
     proof = self.proof_of_work()
     # miners are to be rewarded
     reward_transaction = Transaction('MINING', self.public_key, '',
                                      MINING_REWARD)
     copied_transactions = self.__open_transactions[:]
     for tx in copied_transactions:
         if not Wallet.verify_transaction(tx):
             return None
     copied_transactions.append(reward_transaction)
     block = Block(len(self.__chain), hashed_block, copied_transactions,
                   proof)
     self.__chain.append(block)
     self.__open_transactions = []
     self.save_data()
     for node in self.__peer_nodes:
         url = 'http://{}/broadcast-block'.format(node)
         converted_block = block.__dict__.copy()
         converted_block['transactions'] = [
             tx.__dict__ for tx in converted_block['transactions']
         ]
         try:
             response = requests.post(url, json={'block': converted_block})
             if response.status_code == 400 or response.status_code == 500:
                 print('Block declined, needs resolving')
             if response.status_code == 409:
                 self.resolve_conflicts = True
         except requests.exceptions.ConnectionError:
             continue
     return block
Exemple #4
0
 def proof_of_work(self):
     last_block = self.__chain[-1]
     last_hash = hash_block(last_block)
     proof = 0
     while not Verification.valid_proof(self.__open_transactions, last_hash,
                                        proof):
         proof += 1
     return proof
Exemple #5
0
 def proof_of_work(self):
     """Generate a proof of work for the open transactions, the hash of the previous block and a random number (which is guessed until it fits)."""
     last_block = self.__chain[-1]
     last_hash = hash_block(last_block)
     proof = 0
     # Try different PoW numbers and return the first valid one
     while not Verification.valid_proof(self.__open_transactions, last_hash,
                                        proof):
         proof += 1
     return proof
Exemple #6
0
 def verify_chain(cls, blockchain):
     '''Verify if chain is still valid'''
     for (index, block) in enumerate(blockchain):
         if index == 0:
             continue
         if block.previous_hash != hash_block(blockchain[index - 1]):
             return False
         if not cls.valid_proof(block.transactions[:-1],
                                block.previous_hash, block.proof):
             print('Proof of work is invalid')
             return False
     return True
Exemple #7
0
    def verify_chain(cls, blockchain):
        """ Verify the current blockchain and return True if it's valid, False otherwise."""
        # loop through each block and compare each available block
        for (index, block) in enumerate(
                blockchain
        ):  # Generate a destructured tuple with enumerate function
            if index == 0:
                continue  # skip the validation of the genesis block
            if block.previous_hash != hash_block(blockchain[index - 1]):
                return False

            if not cls.valid_proof(block.transactions[:-1],
                                   block.previous_hash, block.proof):
                print("Proof of work is invalid")
                return False

        return True  # return true to continue process if all blocks are valid