1

I am trying to create a bitcoin transaction to send all of the funds from tb1qj6zz96g8xgrwpgmdlvmkrjlwzz54sf47086yc9 to tb1qxgm8j0cq7tnftef3t563psl56gtmzxanm5c9uy. tb1qj6zz96g8xgrwpgmdlvmkrjlwzz54sf47086yc9 has 0.00036698 btc as shown on this block explorer, https://blockstream.info/testnet/address/tb1qj6zz96g8xgrwpgmdlvmkrjlwzz54sf47086yc9.

I have this script to create a bitcoin transaction:

from bitcoinutils.utils import to_satoshis
from bitcoinutils.setup import setup
from bitcoinutils.transactions import Transaction, TxInput, TxOutput
from bitcoinutils.script import Script
from bitcoinutils.keys import PrivateKey as utilPrivKey
from bitcoinutils.constants import SIGHASH_ALL, SIGHASH_ANYONECANPAY

setup('testnet')

# private key for tb1qj6zz96g8xgrwpgmdlvmkrjlwzz54sf47086yc9
priv = utilPrivKey.from_wif('PRIVATE KEY FOR SENDING ADDRESS')

pub = priv.get_public_key().to_hex()
addrs_for_script = priv.get_public_key().get_address()

# private key for tb1qxgm8j0cq7tnftef3t563psl56gtmzxanm5c9uy
recPrivKey = utilPrivKey.from_wif('PRIVATE KEY FOR RECEIVING ADDRESS')

# This UTXO has 0.00009839 btc
txin1 = TxInput("102172a062da813c3aa8cc2fb3d523cf2db300e54cd680c2129c23c97db9dd8e", 0)

# This UTXO has 0.00026859 btc
txin2 = TxInput("b3fcae0b28b387475a123c056298aec0ba3759cd019f9d0975f5af0874f395ff", 1)

addr = recPrivKey.get_public_key().get_segwit_address()
addr_non_seg = recPrivKey.get_public_key().get_address()

# the script code required for signing for p2wpkh is the same as p2pkh
script_code = Script(['OP_DUP', 'OP_HASH160', addrs_for_script.to_hash160(),
                        'OP_EQUALVERIFY', 'OP_CHECKSIG'])

# remaining 0.00005 is tx fees
txout = TxOutput(to_satoshis(0.00031698), addr.to_script_pub_key())

# create transaction from inputs/outputs -- default locktime is used
tx = Transaction([txin1, txin2], [txout], has_segwit=True)

txsign1 = priv.sign_segwit_input(tx, 0, script_code, to_satoshis(0.00009839), SIGHASH_ALL | SIGHASH_ANYONECANPAY)
tx.witnesses = [ Script([txsign1, pub]) ]

txsign2 = priv.sign_segwit_input(tx, 1, script_code, to_satoshis(0.00026859), SIGHASH_ALL)
tx.witnesses.append( Script([txsign2, pub]) )

signed_tx = tx.serialize()
print("raw tx below this line")
print(signed_tx)
print("raw tx above this line")

So why is my script not working? Below is the signed transaction that my code spits out:

020000000001028eddb97dc9239c12c280d64ce500b32dcf23d5b32fcca83a3c81da62a07221100000000000ffffffffff95f37408aff575099d9f01cd5937bac0ae9862053c125a4787b3280baefcb30100000000ffffffff01d27b0000000000001600143236793f00f2e695e5315d3510c3f4d217b11bb302473044022079fd0fe64aef8599bbac5283058c0c1cf1964ef28a40caf3c26ee809d00b82f30220678e83dc39f6cd219159a4d289353be66ef7b18a00ff6f4a77f466991ca13e3e81210279b144f9caaea4f7619baf6a431caa5939db1d8894fa85c721829e1d4ac31d8d0247304402202857ee846e750dc6aea5b326c22e570a495e255e1b67511d5a2981205da69a0b02201980773e1fa733495f605eba9151a10e194ff8dfe8155f93ac8140fcac6ac43c01210279b144f9caaea4f7619baf6a431caa5939db1d8894fa85c721829e1d4ac31d8d00000000

But when I put it into https://blockstream.info/testnet/tx/push to broadcast it, I get sendrawtransaction RPC error: {"code":-25,"message":"bad-txns-inputs-missingorspent"}

1 Answer 1

0

This error message bad-txns-inputs-missingorspent mean that one of your transaction input are either spent or not found in the UTXO set, but there is a few error in your code, you are using the same private key for both inputs, use the correct one for both input, you used priv each time, and also since you are using P2WPKH you dont need SIGHASH_ANYONECANPAY.

Here would be a corrected version of your code:

from bitcoinutils.utils import to_satoshis
from bitcoinutils.setup import setup
from bitcoinutils.transactions import Transaction, TxInput, TxOutput
from bitcoinutils.script import Script
from bitcoinutils.keys import PrivateKey as utilPrivKey
from bitcoinutils.constants import SIGHASH_ALL, SIGHASH_ANYONECANPAY

setup('testnet')

# private key for tb1qj6zz96g8xgrwpgmdlvmkrjlwzz54sf47086yc9
priv = utilPrivKey.from_wif('SENDING WALLET PRIV KEY')

pub = priv.get_public_key().to_hex()
addrs_for_script = priv.get_public_key().get_address()

# private key for tb1qxgm8j0cq7tnftef3t563psl56gtmzxanm5c9uy
recPrivKey = utilPrivKey.from_wif('RECEIVING WALLET PRIV KEY')

# This UTXO has 0.00009839 btc
txin1 = TxInput("102172a062da813c3aa8cc2fb3d523cf2db300e54cd680c2129c23c97db9dd8e", 0)

# This UTXO has 0.00026859 btc
txin2 = TxInput("b3fcae0b28b387475a123c056298aec0ba3759cd019f9d0975f5af0874f395ff", 0)

addr = recPrivKey.get_public_key().get_segwit_address()
addr_non_seg = recPrivKey.get_public_key().get_address()

# the script code required for signing for p2wpkh is the same as p2pkh
script_code = Script(['OP_DUP', 'OP_HASH160', addrs_for_script.to_hash160(),
                        'OP_EQUALVERIFY', 'OP_CHECKSIG'])

# remaining 0.00005 is tx fees
txout = TxOutput(to_satoshis(0.00031698), addr.to_script_pub_key())

# create transaction from inputs/outputs -- default locktime is used
tx = Transaction([txin1, txin2], [txout], has_segwit=True)

txsign1 = priv.sign_segwit_input(tx, 0, script_code, to_satoshis(0.00009839), SIGHASH_ALL | SIGHASH_ANYONECANPAY)
tx.witnesses = [ Script([txsign1, pub]) ]

txsign2 = priv.sign_segwit_input(tx, 1, script_code, to_satoshis(0.00026859), SIGHASH_ALL)
tx.witnesses.append( Script([txsign2, pub]) )

signed_tx = tx.serialize()
print("raw tx below this line")
print(signed_tx)
print("raw tx above this line")
2
  • Awww so close. I think you're misunderstanding what the second private key is being used for. The first private key is using 2 UTXOs to send to the address of the second private key. I could have used an address instead of a second private key. Anyway this is my code that worked in the end. You can incorporate this into your answer and maybe improve the code if you want and I'll mark it accepted gist.github.com/ChristianOConnor/…. Apr 16 at 0:47
  • Alright, I modified my answer with your code
    – Saxtheowl
    Apr 16 at 13:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.