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
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()
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
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]