def create_transaction(receiver_public_keys: List[str], amounts: List[int], sender_public_key, message="") -> Transaction: vout = {} vin = {} current_amount = 0 total_amount = sum(amounts) i = 0 for so, utxo_list in BLOCKCHAIN.active_chain.utxo.utxo.items(): tx_out = utxo_list[0] if current_amount >= total_amount: break if tx_out.address == sender_public_key: current_amount += tx_out.amount vin[i] = TxIn(payout=SingleOutput.from_json(so), pub_key=sender_public_key, sig="") i += 1 for i, address in enumerate(receiver_public_keys): vout[i] = TxOut(amount=amounts[i], address=address) change = (current_amount - total_amount) if change > 0: vout[i + 1] = TxOut(amount=change, address=sender_public_key) tx = Transaction(version=consts.MINER_VERSION, locktime=0, timestamp=int(time.time()), vin=vin, vout=vout, message=message) return tx
def __mine(self, mempool: Set[Transaction], chain: Chain, payout_addr: str) -> Block: c_pool = list(copy.deepcopy(mempool)) mlist, fees = self.__calculate_best_transactions(c_pool) # logger.debug(f"Miner: Will mine {len(mlist)} transactions and get {fees} scoins in fees") coinbase_tx_in = { 0: TxIn(payout=None, sig="Receiving some Money", pub_key="Does it matter?") } coinbase_tx_out = { 0: TxOut(amount=chain.current_block_reward(), address=payout_addr), 1: TxOut(amount=fees, address=payout_addr), } coinbase_tx = Transaction( is_coinbase=True, version=consts.MINER_VERSION, fees=0, timestamp=int(time.time()), locktime=-1, vin=coinbase_tx_in, vout=coinbase_tx_out, ) mlist.insert(0, coinbase_tx) block_header = BlockHeader( version=consts.MINER_VERSION, height=chain.length, prev_block_hash=dhash(chain.header_list[-1]), merkle_root=merkle_hash(mlist), timestamp=int(time.time()), target_difficulty=chain.target_difficulty, nonce=0, ) DONE = False for n in range(2**64): block_header.nonce = n bhash = dhash(block_header) if chain.is_proper_difficulty(bhash): block = Block(header=block_header, transactions=mlist) requests.post("http://0.0.0.0:" + str(consts.MINER_SERVER_PORT) + "/newblock", data=compress(block.to_json())) logger.info( f"Miner: Mined Block with {len(mlist)} transactions, Got {fees} in fees and {chain.current_block_reward()} as reward" ) DONE = True break if not DONE: logger.error( "Miner: Exhausted all 2 ** 64 values without finding proper hash" )
def calculate_transaction_fees(tx: Transaction, w: Wallet, bounty: int, fees: int): current_amount = 0 i = 0 for so, utxo_list in BLOCKCHAIN.active_chain.utxo.utxo.items(): tx_out = utxo_list[0] if utxo_list[2]: # check for coinbase TxIn Maturity if not (BLOCKCHAIN.active_chain.length - utxo_list[1].height) >= consts.COINBASE_MATURITY: continue if current_amount >= bounty + fees: break if tx_out.address == w.public_key: current_amount += tx_out.amount tx.vin[i] = TxIn(payout=SingleOutput.from_json(so), pub_key=w.public_key, sig="") i += 1 tx.vout[1].amount = current_amount - bounty - fees tx.fees = fees tx.sign(w)
def get_peer_url(peer: Dict[str, Any]) -> str: return "http://" + str(peer["ip"]) + ":" + str(peer["port"]) if __name__ == "__main__": # The singleOutput for first coinbase transaction in genesis block so = SingleOutput(txid=dhash(first_block_transaction[0]), vout=0) first_transaction = Transaction( version=1, locktime=0, timestamp=3, is_coinbase=False, fees=4000000000, vin={0: TxIn(payout=so, sig="", pub_key=consts.WALLET_PUBLIC)}, vout={0: TxOut(amount=1000000000, address=consts.WALLET_PUBLIC)} ) sign_copy_of_tx = copy.deepcopy(first_transaction) sign_copy_of_tx.vin = {} w = Wallet() w.public_key = consts.WALLET_PUBLIC w.private_key = consts.WALLET_PRIVATE sig = w.sign(sign_copy_of_tx.to_json()) first_transaction.vin[0].sig = sig peer_list = fetch_peer_list() print(peer_list) for peer in peer_list: try: