def generate_transaction(receiver, amount, commission): publicKey = Key._publicKey privateKey = Key._privateKey publicKey_ser = publicKey.serialize(compressed=False) total = 0 in_counter = 0 out_counter = 0 vin = [] vout = [] tmpUTXO = [] # Temporary UTXOset for resulting transaction # Check if amount or commission is negative if amount <= 0 or commission < 0: print('Invalid input value') return False # Check if balance is sufficient for key, value in UTXOset._myUTXOset.iterator(): d_value = json.loads(value) address_ser = base64.b64decode(d_value["address"]) if address_ser != publicKey_ser: UTXOset.Pop_myUTXO(key, d_value["index"]) continue tmpUTXO.append( UTXO(key, d_value["index"], d_value["address"], d_value["amount"])) total += d_value["amount"] if total > amount + commission: break # Insufficient balance if total < amount + commission: print('Insufficient BTC balance') return False # Generate inputs for output in tmpUTXO: total += output.amount in_counter += 1 # Generate signatures unlockSig = privateKey.generate_sign(output.txOutid) unlock = privateKey.ecdsa_serialize(unlockSig) vin.append(Vin(output.txOutid, output.index, unlock)) # Generate outputs vout.append(Vout(amount, receiver)) change = total - commission - amount if change > 0: vout.append(Vout(change, publicKey_ser)) # Generate tx_id SumString = str(in_counter) for input in vin: SumString = SumString + str(input.tx_id) + str(input.index) + str( input.unlock) SumString = SumString + str(out_counter) for output in vout: SumString = SumString + str(output.value) + str(output.lock) keccak_hash = keccak.new(digest_bits=256) keccak_hash.update(SumString.encode( 'ascii')) # keccak_hash == tx_id of current transaction # Add to UTXOset and myUTXOset address = base64.b64encode(receiver).decode('utf-8') UTXOset.Insert_UTXO(keccak_hash.hexdigest().encode(), 0, address, float(amount)) if (change > 0): address = base64.b64encode(publicKey_ser).decode('utf-8') UTXOset.Insert_UTXO(keccak_hash.hexdigest().encode(), 1, address, float(amount)) UTXOset.Insert_myUTXO(keccak_hash.hexdigest().encode(), 1, address, float(amount)) # Delete from UTXOset and myUTXOset for otuput in tmpUTXO: UTXOset.Pop_UTXO(output.txOutid, output.index) UTXOset.Pop_myUTXO(output.txOutid, output.index) # Add to memoryPool Transaction.Insert_MemoryPool(keccak_hash.hexdigest().encode(), in_counter, vin, out_counter, vout) return True