[Python] Change Issue in Bitcoin Transactions Sent via Custom RPC Code

Discussão em 'Python' iniciado por Stack, Janeiro 24, 2025.

  1. Stack

    Stack Membro Participativo

    I've encountered an issue where all the change from transactions seems to be sent back to me when I use my custom RPC-based code. However, when I send transactions via Bitcoin Core, this issue does not occur. I also need the transaction fee to be exactly the amount specified by the user, with no deviation. Does anyone know what could cause this behavior or how to adjust the code to properly handle change outputs? Thank you in advance for any insights!

    `def send_data(self): try: with open('config.json') as config_file: rpc_data = json.load(config_file)

    rpc_user = rpc_data["rpc_user"]
    rpc_password = rpc_data["rpc_password"]
    rpc_port = rpc_data["rpc_port"]
    wallet_name = rpc_data["wallet_name"]

    rpc_connection = AuthServiceProxy(
    f'http://{rpc_user}:{rpc_password}@127.0.0.1:{rpc_port}/wallet/{wallet_name}')

    balance = rpc_connection.getbalance()
    if balance <= 0:
    QMessageBox.warning(self, 'Error', 'The wallet is empty.')
    return

    for transaction in self.transactions:
    address = transaction["address"]
    amount = Decimal(str(transaction["amount"]))

    utxos = rpc_connection.listunspent(0)
    if not utxos:
    QMessageBox.warning(self, 'Error', 'No available UTXOs.')
    return

    fee_rate = Decimal(str(self.total_fee))
    selected_inputs = []
    selected_amount = Decimal('0')
    required = amount

    for utxo in sorted(utxos, key=lambda x: x['amount'], reverse=True):
    selected_inputs.append({"txid": utxo["txid"], "vout": utxo["vout"]})
    selected_amount += Decimal(str(utxo['amount']))
    if selected_amount >= amount:
    break

    if selected_amount < amount:
    QMessageBox.warning(self, 'Error', f'Insufficient funds for {address}.')
    continue

    num_inputs = len(selected_inputs)
    actual_size = num_inputs * 68 + 31 + 10
    required_fee = fee_rate * Decimal(actual_size) / 1024

    if selected_amount < amount + required_fee:
    remaining_needed = amount + required_fee - selected_amount
    for utxo in utxos[len(selected_inputs):]:
    selected_inputs.append({"txid": utxo["txid"], "vout": utxo["vout"]})
    selected_amount += Decimal(str(utxo['amount']))
    num_inputs = len(selected_inputs)
    actual_size = num_inputs * 68 + 31 + 10
    required_fee = fee_rate * Decimal(actual_size) / 1024
    remaining_needed = amount + required_fee - selected_amount
    if remaining_needed <= 0:
    break

    if selected_amount < amount + required_fee:
    QMessageBox.warning(self, 'Error', f'Insufficient funds with fees for {address}.')
    continue

    outputs = {address: float(amount)}

    try:
    raw_tx = rpc_connection.createrawtransaction(selected_inputs, outputs)
    signed_tx = rpc_connection.signrawtransactionwithwallet(raw_tx)

    if signed_tx.get("complete"):
    txid = rpc_connection.sendrawtransaction(signed_tx["hex"])
    QMessageBox.information(self, 'Success', f'Transaction sent. TXID: {txid}')
    else:
    QMessageBox.warning(self, 'Error', 'Transaction signing failed.')
    except JSONRPCException as e:
    QMessageBox.critical(self, 'Error', f'RPC error: {e}')

    self.show_original_page()
    self.text_edit.clear()

    except Exception as e:
    QMessageBox.critical(self, 'Error', f'Error: {str(e)}')`


    I implemented custom transaction creation using the RPC API, where UTXOs are selected manually. I expected the change to be properly calculated and sent to the wallet's change address, similar to Bitcoin Core's behavior.

    Instead, all change appears to be sent back to the originating wallet address without explicitly setting it as a change output. Additionally, the fee calculation does not behave as expected when specifying a user-defined fee rate.

    I need the fee to match exactly what the user sets and ensure change is properly handled in the transaction outputs.

    Continue reading...

Compartilhe esta Página