Example #1
0
    def create_block(cls):
        last_block = Block.last()
        previous_hash = last_block.block_id
        proof_of_work = ProofOfWork(previous_hash, 10)
        proof_result = proof_of_work.prove()

        if not proof_result.isValid():
            raise Exception('fail proof')

        transactions = UnconfirmedTransactionPool.transactions.copy()
        UnconfirmedTransactionPool.transactions.clear()
        block_number = len(Block.list()) + 1

        block = Block.build(
            block_number = block_number,
            version = "1",
            previous_block_hash = previous_hash,
            timestamp = datetime.now().timestamp(),
            merkle_root = "",  # TODO
            difficulty_target = 10,
            nonce = proof_result.nonce,
            transactions = transactions
        )

        for tx in transactions:
            tx.block_id = block.block_id

        Block.create_block(block)

        db.session.commit()

        transaction = cls._create_transaction_to_miner()

        return block, proof_result, transaction
Example #2
0
 def seed(cls):
     timestamp = 0
     block = Block.build(block_number=1,
                         version='1',
                         previous_block_hash='1',
                         timestamp=1,
                         merkle_root='',
                         difficulty_target=10,
                         nonce=1)
     transaction = Transaction.build(block_id='1',
                                     locktime=0,
                                     timestamp=timestamp)
     transaction_output = TransactionOutput.build(
         transaction_id='1',
         amount=10000000000000000000,
         sender_address='coinbase',
         recipient_address=
         '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAznjoHvzCJtQcIYd3yj7v\ngwaPlyiG6U/Qlw1G89n0bNt5anvRe+e2eKzvpy98aj6ShGu7hARE9SxAFA9bIHCB\nqdAyPnrUaw7qGkeZNPHBByHe9prJSn0ZwBtfySOSbzdetO5aAwvLj5qMudW2PDz1\n5mP2taGOvXqNnbcH78ZHQLvF6G+SbwuLHU5LEDSZlcy+CnvPqD67cg+QmJLneVmQ\nfOBtbFHz3yDQghNrHWa+UCspUMHVGsDG6OEK7MSpPieY6TzBEYQWsikosQ+V0zBN\nrSCADe3GBcJ7XzafM/gb+gzJ1eP78F1sA6Ja4ZtqInqN406PwerAXaUJa2twW652\n9wIDAQAB\n-----END PUBLIC KEY-----',
         timestamp=timestamp)
     db.session.add(block)
     db.session.add(transaction)
     db.session.add(transaction_output)
     db.session.commit()
Example #3
0
    def _create_block(cls):
        last_block = Blockchain.fetch_last_block()

        previous_hash = last_block.block_id
        block_number = Blockchain.fetch_block_count() + 1

        proof_of_work = ProofOfWork(previous_hash,
                                    last_block.difficulty_target)
        proof_result = proof_of_work.prove()

        proof_result.assert_valid()

        transactions = UnconfirmedTxPool.transactions.copy()
        UnconfirmedTxPool.transactions.clear()

        target_transactions = Blockchain.search_new_transactions(transactions)

        block = Block.build(
            block_number=block_number,
            previous_block_hash=previous_hash,
            timestamp=datetime.now().timestamp(),
            merkle_root="",  # TODO
            difficulty_target=last_block.difficulty_target,
            nonce=proof_result.nonce,
            transactions=target_transactions)

        last_block = Blockchain.fetch_last_block()
        if last_block.block_id != block.previous_block_hash:
            print('lost mining', block.block_id)
            raise LoseMiningException()

        Blockchain.create_block(block)
        print('block created', block.block_id)
        print('current block number', block.block_number)

        return block, proof_result
Example #4
0
class Blockchain:
    blocks = [
        Block.build(
            block_number=1,
            previous_block_hash="1",
            timestamp=0,
            merkle_root="",
            difficulty_target=20,
            nonce=0,
            transactions=[
                Transaction.build(
                    timestamp=1,
                    tx_inputs=[],
                    tx_outputs=[
                        TransactionOutput.build(
                            amount=1000000000,
                            sender_address=COINBASE_ADDRESS,
                            recipient_address=
                            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAznjoHvzCJtQcIYd3yj7vgwaPlyiG6U/Qlw1G89n0bNt5anvRe+e2eKzvpy98aj6ShGu7hARE9SxAFA9bIHCBqdAyPnrUaw7qGkeZNPHBByHe9prJSn0ZwBtfySOSbzdetO5aAwvLj5qMudW2PDz15mP2taGOvXqNnbcH78ZHQLvF6G+SbwuLHU5LEDSZlcy+CnvPqD67cg+QmJLneVmQfOBtbFHz3yDQghNrHWa+UCspUMHVGsDG6OEK7MSpPieY6TzBEYQWsikosQ+V0zBNrSCADe3GBcJ7XzafM/gb+gzJ1eP78F1sA6Ja4ZtqInqN406PwerAXaUJa2twW6529wIDAQAB",
                            timestamp=1)
                    ]),
                Transaction.build(
                    timestamp=1,
                    tx_inputs=[],
                    tx_outputs=[
                        TransactionOutput.build(
                            amount=200000000,
                            sender_address=COINBASE_ADDRESS,
                            recipient_address=
                            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAznjoHvzCJtQcIYd3yj7vgwaPlyiG6U/Qlw1G89n0bNt5anvRe+e2eKzvpy98aj6ShGu7hARE9SxAFA9bIHCBqdAyPnrUaw7qGkeZNPHBByHe9prJSn0ZwBtfySOSbzdetO5aAwvLj5qMudW2PDz15mP2taGOvXqNnbcH78ZHQLvF6G+SbwuLHU5LEDSZlcy+CnvPqD67cg+QmJLneVmQfOBtbFHz3yDQghNrHWa+UCspUMHVGsDG6OEK7MSpPieY6TzBEYQWsikosQ+V0zBNrSCADe3GBcJ7XzafM/gb+gzJ1eP78F1sA6Ja4ZtqInqN406PwerAXaUJa2twW6529wIDAQAB",
                            timestamp=1)
                    ]),
                Transaction.build(
                    timestamp=1,
                    tx_inputs=[],
                    tx_outputs=[
                        TransactionOutput.build(
                            amount=300003,
                            sender_address=COINBASE_ADDRESS,
                            recipient_address=
                            "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAznjoHvzCJtQcIYd3yj7vgwaPlyiG6U/Qlw1G89n0bNt5anvRe+e2eKzvpy98aj6ShGu7hARE9SxAFA9bIHCBqdAyPnrUaw7qGkeZNPHBByHe9prJSn0ZwBtfySOSbzdetO5aAwvLj5qMudW2PDz15mP2taGOvXqNnbcH78ZHQLvF6G+SbwuLHU5LEDSZlcy+CnvPqD67cg+QmJLneVmQfOBtbFHz3yDQghNrHWa+UCspUMHVGsDG6OEK7MSpPieY6TzBEYQWsikosQ+V0zBNrSCADe3GBcJ7XzafM/gb+gzJ1eP78F1sA6Ja4ZtqInqN406PwerAXaUJa2twW6529wIDAQAB",
                            timestamp=1)
                    ]),
            ])
    ]

    @classmethod
    def fetch_all_blocks(cls):
        return cls.blocks

    @classmethod
    def fetch_block_count(cls):
        return len(cls.blocks)

    @classmethod
    def fetch_last_block(cls):
        return cls.blocks[-1]

    @classmethod
    def fetch_unspent_tx_outputs_by_tx_output_ids(cls, tx_output_ids):
        blocks = cls.blocks
        if len(blocks) == 0:
            return []

        transactions = reduce(
            add, list(map(lambda block: block.transactions, blocks)))
        if len(transactions) == 0:
            return []

        tx_outputs = reduce(add,
                            list(map(lambda tx: tx.tx_outputs, transactions)))

        tx_inputs = reduce(add, list(map(lambda tx: tx.tx_inputs,
                                         transactions)))
        spent_tx_output_ids = list(
            map(lambda tx_i: tx_i.transaction_output_id, tx_inputs))

        unspent_tx_outputs = list(
            filter(
                lambda tx_o: tx_o.transaction_output_id not in
                spent_tx_output_ids, tx_outputs))
        return list(
            filter(lambda tx_o: tx_o.transaction_output_id in tx_output_ids,
                   unspent_tx_outputs))

    @classmethod
    def fetch_unspent_tx_outputs_by_address(cls, address):
        blocks = cls.blocks
        if len(blocks) == 0:
            return []

        transactions = reduce(
            add, list(map(lambda block: block.transactions, blocks)))
        if len(transactions) == 0:
            return []

        tx_outputs = reduce(add,
                            list(map(lambda tx: tx.tx_outputs, transactions)))
        tx_inputs = reduce(add, list(map(lambda tx: tx.tx_inputs,
                                         transactions)))
        spent_tx_output_ids = list(
            map(lambda tx_i: tx_i.transaction_output_id, tx_inputs))

        return list(
            filter(
                lambda tx_o: tx_o.recipient_address == address and tx_o.
                transaction_output_id not in spent_tx_output_ids, tx_outputs))

    @classmethod
    def create_block(cls, block):
        cls.blocks.append(block)

    @classmethod
    def search_new_transactions(cls, transactions):
        transactions_in_chain = reduce(
            add, list(map(lambda block: block.transactions, cls.blocks)))
        return list(
            filter(lambda tx: tx not in transactions_in_chain, transactions))

    @classmethod
    def delete_block(cls, deleting_block):
        cls.blocks.remove(deleting_block)

    @classmethod
    def find_block(cls, block_id):
        blocks = list(
            filter(lambda block: block.block_id == block_id, cls.blocks))
        if len(blocks) == 0:
            return None
        return blocks[0]