def __init__(self):

        self.genesis_transaction = Transaction(
            [TxIn('', 0, '')], [TxOut(get_public_from_wallet(), 50)])
        self._blockchain = [self.get_genesis_block()]
        self.difficulty_bits = 15
        self.unspent_tx_outs = process_transactions([self.genesis_transaction],
                                                    [], 0)
Beispiel #2
0
    def construct_next_block_with_transaction(self, receiver_address, amount):
        if not is_valid_address(receiver_address):
            print('invalid address')
            return
        if not isinstance(amount, int):
            print('invalid amount')
            return

        coinbase_tx = get_coinbase_transaction(get_public_from_wallet(), self.blocks[-1].index + 1)
        tx = create_transaction(receiver_address, amount, get_private_from_wallet(),
                                self.get_unspent_tx_outs(), get_transaction_pool())
        if not tx:
            return False
        block_data = [coinbase_tx, tx]
        return self.generate_next_block(block_data)
Beispiel #3
0
 def construct_next_block(self):
     coinbase_tx = get_coinbase_transaction(get_public_from_wallet(), self.blocks[-1].index + 1)
     block_data = [coinbase_tx] + get_transaction_pool()
     return self.generate_next_block(block_data)
Beispiel #4
0
 def get_my_utxos(self):
     return find_unspent_tx_outs(get_public_from_wallet(), self.get_unspent_tx_outs())
Beispiel #5
0
 def get_account_balance(self):
     print(self.get_unspent_tx_outs())
     return get_balance(get_public_from_wallet(), self.get_unspent_tx_outs())
class Blockchain(object):

    def __init__(self):

        self._blockchain = [self.get_genesis_block()]
        self.difficulty_bits = 15
        self.unspent_tx_outs = process_transactions([self.genesis_transaction], [], 0)

    @property
    def blocks(self):
        return self._blockchain


    def get_unspent_tx_outs(self):
        return self.unspent_tx_outs

    def set_unspent_tx_outs(self, new_utxo):
        print('replacing unspent_tx_outs with: %s' % new_utxo)
        self.unspent_tx_outs = new_utxo

    @blocks.setter
    def blocks(self, blocks):
        self._blockchain = blocks

    # genesis_transaction = {'tx_ins': [{'signature': '', 'tx_out_id': '', 'tx_out_index': 0}],
    #     'tx_outs': [{
    #         'address': getPublicFromWallet(),
    #         'amount': 50
    #     }]
        # 'id': 'e655f6a5f26dc9b4cac6e46f52336428287759cf81ef5ff10854f69d68f43fa3'
    # }

    genesis_transaction = Transaction([TxIn('', 0, '')], [TxOut(get_public_from_wallet(), 50)])

    @classmethod
    def get_genesis_block(cls):

        # SHA256.new(data=(str(0) + "0"+ str(1465154705) +"my genesis block!!").encode()).hexdigest()

        return Block(0, "0", 1465154705, cls.genesis_transaction, 0, 0,
                     "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7")

    def generate_next_block(self, block_data):

        previous_block = self.get_latest_block()
        next_index = previous_block.index + 1
        next_timestamp = datetime.now().strftime("%s")
        next_hash, next_nonce = self.calculate_hash(next_index, previous_block.hash, next_timestamp, block_data)
        new_block = Block(next_index, previous_block.hash, next_timestamp, block_data,
                     self.difficulty_bits, next_nonce, next_hash)

        if self.add_block(new_block):
            # broadcastLatest();
            return new_block


    # gets the unspent transaction outputs owned by the wallet
    def get_my_utxos(self):
        return find_unspent_tx_outs(get_public_from_wallet(), self.get_unspent_tx_outs())

    def construct_next_block(self):
        coinbase_tx = get_coinbase_transaction(get_public_from_wallet(), self.blocks[-1].index + 1)
        block_data = [coinbase_tx] + get_transaction_pool()
        return self.generate_next_block(block_data)

    def construct_next_block_with_transaction(self, receiver_address, amount):
        if not is_valid_address(receiver_address):
            print('invalid address')
            return
        if not isinstance(amount, int):
            print('invalid amount')
            return

        coinbase_tx = get_coinbase_transaction(get_public_from_wallet(), self.blocks[-1].index + 1)
        tx = create_transaction(receiver_address, amount, get_private_from_wallet(),
                                self.get_unspent_tx_outs(), get_transaction_pool())
        if not tx:
            return False
        block_data = [coinbase_tx, tx]
        return self.generate_next_block(block_data)

    def get_account_balance(self):
        return get_balance(get_public_from_wallet(), self.get_unspent_tx_outs())

    def send_transaction(self, address, amount):
        tx = create_transaction(address, amount, get_private_from_wallet(),
                                self.get_unspent_tx_outs(), get_transaction_pool())
        add_to_transaction_pool(tx, self.get_unspent_tx_outs())
        # broadCastTransactionPool()
        return tx

    def get_latest_block(self):

        try:
            return self._blockchain[-1]
        except IndexError as e:
            return None

    def calculate_hash_for_block(self, block):

        return self.calculate_hash(block.index, block.previous_hash, block.timestamp, block.data, block.nonce)

    def calculate_hash(self, index, previous_hash, timestamp, data, nonce=None):

        if not nonce:
            header = str(index) + previous_hash + str(timestamp) + str(data) + str(self.difficulty_bits)
            return self.proof_of_work(header)
        else:
            hash_object = SHA256.new(data=(str(index) + previous_hash + str(timestamp)
                                           + str(data) + str(self.difficulty_bits) + str(nonce)).encode())
            return hash_object.hexdigest()

    def proof_of_work(self, header):
        """Calculates nonce for the block based on the difficulty bits set"""

        print("Computing nonce for the block...")
        target = 2 ** (256 - self.difficulty_bits)

        for nonce in range(max_nonce):
            hash_result = SHA256.new(data=(str(header) + str(nonce)).encode()).hexdigest()

            if int(hash_result, 16) < target:
                print("Success with nonce %d" % nonce)
                print("Hash is %s" % hash_result)
                return (hash_result, nonce)

        print("Failed after %d (max_nonce) tries" % nonce)
        return nonce

    def add_block(self, new_block):

        if self.is_valid_new_block(new_block, self.get_latest_block()):
            ret_val = process_transactions(new_block.data, self.get_unspent_tx_outs(), new_block.index)
            if ret_val is None:
                print('block is not valid in terms of transactions')
                return False
            else:
                self._blockchain.append(new_block)
                self.set_unspent_tx_outs(ret_val)
                update_transaction_pool(self.get_unspent_tx_outs())
                return True

    def is_valid_new_block(self, new_block, previous_block):

        if previous_block.index + 1 != new_block.index:
            logger.warning('invalid index')
            return False
        if previous_block.hash != new_block.previous_hash:
            logger.warning('invalid previous hash')
            return False
        if self.calculate_hash_for_block(new_block) != new_block.hash:
            logger.info(str(type(new_block.hash)) + ' ' + str(type(self.calculate_hash_for_block(new_block))))
            logger.warning('invalid hash: ' + self.calculate_hash_for_block(new_block) + ' ' + new_block.hash)
            return False

        return True

    def is_valid_chain(self, blockchain_to_validate):

        # if self.calculate_hash_for_block(Block(**blockchain_to_validate[0])) != self.get_genesis_block().hash:
        #     return False

        temp_blocks = [Block(**blockchain_to_validate[0])]
        for currentBlock in blockchain_to_validate[1:]:
            if self.is_valid_new_block(Block(**currentBlock), temp_blocks[-1]):
                temp_blocks.append(Block(**currentBlock))
            else:
                return False
        return True
 async def address(self, request):
     return json({'address': get_public_from_wallet()})