<p>The problem is this line:</p>
<pre class="lang-py prettyprint-override"><code>tx.witnesses.append(Script(['OP_5', 'OP_0', p2wsh_witness_script.to_hex()]))
</code></pre>
<p>Perhaps confusingly, bitcoinutils uses the same API for scripts as it does for witness stacks (also known as &quot;input witnesses&quot; or just &quot;witnesses&quot; here), but they aren't scripts. They don't contain any opcodes, only byte arrays, some of which might be scripts.</p>
<p>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:</p>
<pre class="lang-py prettyprint-override"><code>tx.witnesses.append(Script(['05', '', p2wsh_witness_script.to_hex()]))
</code></pre>
<p>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 <a href="https://github.com/karask/python-bitcoin-utils/issues/39" rel="nofollow noreferrer">opened</a> and <a href="https://github.com/karask/python-bitcoin-utils/commit/fc382d670f8267d097d972f15bd956f72dfc8cfd" rel="nofollow noreferrer">fixed</a>.)</p>

CC BY-SA 4.0
2023-05-10T18:24:37.903Z
Yep, this was it. Thanks! Managed to broadcast it now: https://blockstream.info/testnet/tx/5e5c4ebde652c06adde980687926a0f91aa261bdeed3e1e18fd045dd1e766e22
msinkec
CC BY-SA 4.0
2023-05-10T15:51:34.643Z
2024-01-03T15:53:39.730Z
2024-01-03T15:53:39.730Z
Vojtěch Strnad
<p>I am trying to unlock the P2WSH output of the following transaction:</p>
<p><a href="https://blockstream.info/testnet/tx/b435b180c936564cc902ce3d7011643836a74d671159d494f59536e70d977cd2" rel="nofollow noreferrer">https://blockstream.info/testnet/tx/b435b180c936564cc902ce3d7011643836a74d671159d494f59536e70d977cd2</a></p>
<p>The script that I'm paying to is a non-standard script, which can be unlocked by pushing OP_5 OP_0 before evaluation.</p>
<p>Here's the Python code I use to assemble the unlocking transaction:</p>
<pre class="lang-py prettyprint-override"><code>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(&quot;tb1qelplgcx5q7lj4mgk4sg8tlnq6njvamurvntwha&quot;)

    # 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(&quot;\nRaw signed transaction:\n&quot; + tx.serialize())
    print(&quot;\nTxId:&quot;, tx.get_txid())


if __name__ == &quot;__main__&quot;:
    main()
</code></pre>
<p>It produces the following serialized transaction:</p>
<pre><code>02000000000101d27c970de73695f594d45911674da736386411703dce02c94c5636c980b135b40000000000ffffffff01b004000000000000160014cfc3f460d407bf2aed16ac1075fe60d4e4ceef83035500500000018257615179547a75537a537a537a0079537a75527a527a7575615279008763537952795279615179517993517a75517a75619c77777777675279518763537952795279949c777777776700686800000000
</code></pre>
<p>Unfortunately, while broadcasting, I get the following error:</p>
<pre><code>sendrawtransaction RPC error: {&quot;code&quot;:-22,&quot;message&quot;:&quot;TX decode failed. Make sure the tx has at least one input.&quot;}
</code></pre>
<p>I am not sure what I'm missing. Does the library serialize something wrong? Is the redeeming script too large?</p>

<python><non-standard-transaction><p2wsh><serialization>
Failing to construct transaction that unlocks P2WSH
msinkec
# Failing to construct transaction that unlocks P2WSH

(Asked by: username_0 on 2023-05-10)

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:

```py
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?

**Tags:** python, non-standard-transaction, p2wsh, serialization


---

## 1 answers

### Answer by username_1 on 2023-05-10. Score: 4 | Accepted answer

The problem is this line:

```py
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:

```py
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](https://github.com/karask/python-bitcoin-utils/issues/39) and [fixed](https://github.com/karask/python-bitcoin-utils/commit/fc382d670f8267d097d972f15bd956f72dfc8cfd).)

> **Comments:**
> **username_0**: Yep, this was it. Thanks! Managed to broadcast it now: https://blockstream.info/testnet/tx/5e5c4ebde652c06adde980687926a0f91aa261bdeed3e1e18fd045dd1e766e22  

---

