3

I am trying to unlock the P2WSH output of the following transaction:

https://blockstream.info/testnet/tx/b435b180c936564cc902ce3d7011643836a74d671159d494f59536e70d977cd2

The script that I'm paying to is a non-standard script, which can be unlocked by pushing OP_5 OP_0 before evaluation.

Here's the Python code I use to assemble the unlocking transaction:

from bitcoinutils.setup import setup
from bitcoinutils.utils import to_satoshis
from bitcoinutils.transactions import Transaction, TxInput, TxOutput
from bitcoinutils.keys import PrivateKey, P2wshAddress, P2wpkhAddress
from bitcoinutils.script import Script


def main():
    # always remember to setup the network
    setup('testnet')

    p2wsh_witness_script = Script.from_raw('0000018257615179547a75537a537a537a0079537a75527a527a7575615279008763537952795279615179517993517a75517a75619c77777777675279518763537952795279949c7777777767006868')

    fromAddress = P2wshAddress.from_script(p2wsh_witness_script)
    #print(fromAddress.to_string())

    toAddress = P2wpkhAddress.from_address("tb1qelplgcx5q7lj4mgk4sg8tlnq6njvamurvntwha")

    # set values
    txid = 'b435b180c936564cc902ce3d7011643836a74d671159d494f59536e70d977cd2'
    vout = 0
    amount = 0.00001400
    fee = 0.00000200


    # create transaction input from tx id of UTXO
    txin = TxInput(txid, vout)

    txOut1 = TxOutput(to_satoshis(amount - fee), toAddress.to_script_pub_key())

    tx = Transaction([txin], [txOut1], has_segwit=True)

    tx.witnesses.append(Script(['OP_5', 'OP_0', p2wsh_witness_script.to_hex()]))

    # print raw signed transaction ready to be broadcasted
    print("\nRaw signed transaction:\n" + tx.serialize())
    print("\nTxId:", tx.get_txid())


if __name__ == "__main__":
    main()

It produces the following serialized transaction:

02000000000101d27c970de73695f594d45911674da736386411703dce02c94c5636c980b135b40000000000ffffffff01b004000000000000160014cfc3f460d407bf2aed16ac1075fe60d4e4ceef83035500500000018257615179547a75537a537a537a0079537a75527a527a7575615279008763537952795279615179517993517a75517a75619c77777777675279518763537952795279949c777777776700686800000000

Unfortunately, while broadcasting, I get the following error:

sendrawtransaction RPC error: {"code":-22,"message":"TX decode failed. Make sure the tx has at least one input."}

I am not sure what I'm missing. Does the library serialize something wrong? Is the redeeming script too large?

1 Answer 1

4

The problem is this line:

tx.witnesses.append(Script(['OP_5', 'OP_0', p2wsh_witness_script.to_hex()]))

Perhaps confusingly, bitcoinutils uses the same API for scripts as it does for witness stacks (also known as "input witnesses" or just "witnesses" here), but they aren't scripts. They don't contain any opcodes, only byte arrays, some of which might be scripts.

In P2WSH the last witness item is the script and the preceding items form the initial stack for script execution, which means you shouldn't use opcodes but the result of running those opcodes:

tx.witnesses.append(Script(['05', '', p2wsh_witness_script.to_hex()]))

It might be a good idea to open an issue in the bitcoinutils repo because it probably shouldn't output an invalid transaction serialization without any warning. (Edit: The issue has since been opened and fixed.)

1

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