<p>Since it is a segwit address you should use</p>
<pre><code>fromAddress2 = pub2.get_segwit_address()
</code></pre>
<p>Also, while taproot (segwit v1) requires the scriptPubKey when signing, segwit v0 requires the script code; i.e. a template that corresponds to the non-segwit equivalent. For example, for p2wpkh you would use as script code the p2pkh scriptPubKey.</p>
<p>So when signing the segwit input you shouldn't use the scriptPubKey but the p2pkh equivalent for that address. Example <a href="https://github.com/karask/python-bitcoin-utils/blob/master/examples/spend_p2wpkh_transaction.py" rel="nofollow noreferrer">https://github.com/karask/python-bitcoin-utils/blob/master/examples/spend_p2wpkh_transaction.py</a> demonstrates this.</p>
<p>I haven't tried these changes to your code yet, but will do with the first opportunity.</p>
<p>EDIT: Just tried the suggested changes it works.</p>
<p>PS. In the meantime, if you try it out yourself please use <code>testmempoolaccept</code> to test tx validity instead of just sending the tx to a node for processing. That will test tx validity without spending the outputs. If there is still an issue I can then test using the same UTXOs.</p>

CC BY-SA 4.0
2023-08-25T13:00:02.590Z
2023-08-25T13:57:23.417Z
2023-08-25T13:57:23.417Z
karask
<p>I'm constructing a script to spend multiple distinct UTXOs in a single transaction. I've successfully combined all UTXOs except for two.</p>
<p>Succeeding in spending a <code>P2TR</code> with <code>P2PKH</code> UTXO.</p>
<p>I encountered a problem when attempting to spend a <code>P2TR</code> with one of them <code>P2SH, P2WSH, P2WPKH</code>.</p>
<pre><code>accompanied by a 'non-mandatory-script-verify-flag (Invalid Schnorr signature).
</code></pre>
<p>While I managed to dispatch these transactions via an alternative node, none of them have been confirmed as of yet.</p>
<p>tx ids: (bitcoin-testnet)</p>
<p><a href="https://live.blockcypher.com/btc-testnet/tx/88558b495f28ff4799a4dacf40ee5cd1666850fed4847b8315256a5ae22527f8/" rel="nofollow noreferrer">88558b495f28ff4799a4dacf40ee5cd1666850fed4847b8315256a5ae22527f8</a>
<a href="https://live.blockcypher.com/btc-testnet/tx/88558b495f28ff4799a4dacf40ee5cd1666850fed4847b8315256a5ae22527f8/" rel="nofollow noreferrer">02429ffe2f82f587d8e7a6e925201d3e7f219ac3af3688f2bc5c2770204e5d5c</a></p>
<p>What could be the cause?
thanks</p>
<p><code>P2TR</code>,<code>P2WPKH</code> to <code>P2PKH</code></p>
<pre><code>&quot;hex&quot;: &quot;02000000000102f80b4d99b2489228e23a25f1a458feefc1129b8ee030dc53d7ad0f112e278bd10000000000fffffffff80b4d99b2489228e23a25f1a458feefc1129b8ee030dc53d7ad0f112e278bd10100000000ffffffff01dc000000000000001976a91451283c275c76d14f0a1b010fa3430f0ade37781c88ac0140d7ac7111d6a732e655ebdf62fe224b1572803b47eb0c70aeb2b4f1a8f287fa20008b9145143f4cd0302ac1420f9602f5728a74d7c91b6c491ca44323d045f0af024730440220608f9ba4da7daa2d70aa24e7aabbf2c47d78ed39c331f40caf7aba7c07aa14750220467cf13de308c0633624fbcc6b41f9a1ef4f4f8568db9ac13ab7f1002e12912c01210220e57408d8f6726a81747f7507f7cdb7b86c502882d8a3bce5c62d39fddf38b100000000&quot;,
  &quot;addresses&quot;: [
    &quot;mnv5EAfPMTbfatz5ZbT6uUKpK7E5MftBAv&quot;,
    &quot;tb1ps7gfq0h0hwu2cql9azz0wcf8rphr6xxeeyenrugd6yf263pxg9tq0fcjvz&quot;,
    &quot;tb1qgt0w9wnw9wrs5qxtw7ptpfdz579889t2lcwcsy&quot;
  ],
  &quot;total&quot;: 220,
  &quot;fees&quot;: 199780,
  &quot;size&quot;: 301,
  &quot;vsize&quot;: 170,
  &quot;ver&quot;: 2,
  &quot;vin_sz&quot;: 2,
  &quot;vout_sz&quot;: 1,
  &quot;confirmations&quot;: 0,
  &quot;inputs&quot;: [
    {
      &quot;prev_hash&quot;: &quot;d18b272e110fadd753dc30e08e9b12c1effe58a4f1253ae2289248b2994d0bf8&quot;,
      &quot;output_index&quot;: 0,
      &quot;output_value&quot;: 100000,
      &quot;sequence&quot;: 4294967295,
      &quot;addresses&quot;: [
        &quot;tb1ps7gfq0h0hwu2cql9azz0wcf8rphr6xxeeyenrugd6yf263pxg9tq0fcjvz&quot;
      ],
      &quot;script_type&quot;: &quot;pay-to-taproot&quot;,
      &quot;age&quot;: 2474244,
      &quot;witness&quot;: [
        &quot;d7ac7111d6a732e655ebdf62fe224b1572803b47eb0c70aeb2b4f1a8f287fa20008b9145143f4cd0302ac1420f9602f5728a74d7c91b6c491ca44323d045f0af&quot;
      ]
    },
    {
      &quot;prev_hash&quot;: &quot;d18b272e110fadd753dc30e08e9b12c1effe58a4f1253ae2289248b2994d0bf8&quot;,
      &quot;output_index&quot;: 1,
      &quot;output_value&quot;: 100000,
      &quot;sequence&quot;: 4294967295,
      &quot;addresses&quot;: [
        &quot;tb1qgt0w9wnw9wrs5qxtw7ptpfdz579889t2lcwcsy&quot;
      ],
      &quot;script_type&quot;: &quot;pay-to-witness-pubkey-hash&quot;,
      &quot;age&quot;: 2474244,
      &quot;witness&quot;: [
        &quot;30440220608f9ba4da7daa2d70aa24e7aabbf2c47d78ed39c331f40caf7aba7c07aa14750220467cf13de308c0633624fbcc6b41f9a1ef4f4f8568db9ac13ab7f1002e12912c01&quot;,
        &quot;0220e57408d8f6726a81747f7507f7cdb7b86c502882d8a3bce5c62d39fddf38b1&quot;
      ]
    }
  ],
  &quot;outputs&quot;: [
    {
      &quot;value&quot;: 220,
      &quot;script&quot;: &quot;76a91451283c275c76d14f0a1b010fa3430f0ade37781c88ac&quot;,
      &quot;addresses&quot;: [
        &quot;mnv5EAfPMTbfatz5ZbT6uUKpK7E5MftBAv&quot;
      ],
      &quot;script_type&quot;: &quot;pay-to-pubkey-hash&quot;
    }
  ]
</code></pre>
<p>I used <a href="https://github.com/karask/python-bitcoin-utils" rel="nofollow noreferrer">python-bitcoin-utils</a> Python tool to generate the following code related to the transaction ID <code>88558b495f28ff4799a4dacf40ee5cd1666850fed4847b8315256a5ae22527f8</code> which involves inputs from both P2TR and P2WPKH scripts.</p>
<pre><code>def main():
    print(to_satoshis(0.0000022))

    setup('testnet')
    priv1 = PrivateKey(&quot;cV3R88re3AZSBnWhBBNdiCKTfwpMKkYYjdiR13HQzsU7zoRNX7JL&quot;)
    priv2 = PrivateKey(&quot;cSfna7riKJdNU7skpRUx17WYANNsyHTA2FmuzLpFzpp37xpytgob&quot;)
    pub1 = priv1.get_public_key()
    pub2 = priv2.get_public_key()
    fromAddress1 = pub1.get_taproot_address()
    fromAddress2 = pub2.get_address()
    # p2tr utxo
    txid1 = 'd18b272e110fadd753dc30e08e9b12c1effe58a4f1253ae2289248b2994d0bf8'
    vout1 = 0
    # P2wpkh UTXO
    txid2 = 'd18b272e110fadd753dc30e08e9b12c1effe58a4f1253ae2289248b2994d0bf8'
    vout2 = 1
    amount1 = 100000
    amount2 = 100000
    amounts = [amount1, amount2]
    script_pubkey1 = fromAddress1.to_script_pub_key()
    script_pubkey2 = fromAddress2.to_script_pub_key()
    utxos_script_pubkeys = [script_pubkey1, script_pubkey2]

    toAddress = P2pkhAddress('mnv5EAfPMTbfatz5ZbT6uUKpK7E5MftBAv')
    txin1 = TxInput(txid1, vout1)
    txin2 = TxInput(txid2, vout2)
    txOut = TxOutput(to_satoshis(0.0000022), toAddress.to_script_pub_key())

    tx = Transaction([txin1, txin2], [txOut], has_segwit=True)
    sig1 = priv1.sign_taproot_input(tx, 0, utxos_script_pubkeys, amounts)
    sig2 = priv2.sign_segwit_input(tx, 1, script=script_pubkey2, amount=amount1)

    tx.witnesses.append(TxWitnessInput([sig1]))
    tx.witnesses.append(TxWitnessInput([sig2, pub2.to_hex()]))
    print(&quot;\nRaw signed transaction:\n&quot; + tx.serialize())
</code></pre>

CC BY-SA 4.0
2023-08-22T14:01:14.737Z
Instead of posting the one that worked, could you post the transaction that failed? My first guess would be that you forgot to add the (empty) witness stack for the non-segwit input.
Murch
CC BY-SA 4.0
2023-08-22T14:02:07.963Z
@Murch I added an empty witness for the UTXO P2SH at the specified index. I didn't modify the transaction; this is the same failed transaction that got confirmed on another node provider.
Mohsen Haydari
CC BY-SA 4.0
2023-08-22T14:04:45.113Z
Okay, cool. Could you still post the failed transaction rather than one that succeeded? It’s hard to diagnose the issue without seeing the transaction that caused the problem.
Murch
CC BY-SA 4.0
2023-08-22T14:06:11.960Z
@Murch  I didn't modify the transaction; this is the same failed transaction that got confirmed on another node provider
Mohsen Haydari
CC BY-SA 4.0
2023-08-22T14:09:17.187Z
Oh, my bad. I thought that the second input was P2PKH, instead of P2WPKH.
Murch
CC BY-SA 4.0
2023-08-22T14:40:17.053Z
It looks like your signature is invalid. You said that you managed to send other transactions with P2TR inputs, right? Most likely your issue stems from incorrectly calculating the sighash for the P2TR input now that there is another input.
Murch
CC BY-SA 4.0
2023-08-22T14:42:09.903Z
There is nothing special about P2TR signatures in combination with specific other types of inputs. Can you post the sighash you used, and how you computed it?
Pieter Wuille
CC BY-SA 4.0
2023-08-22T14:43:02.370Z
Perhaps it would be helpful if you provided more information on how you construct the transaction. What tools do you use and which steps did you implement or perform manually?
Murch
CC BY-SA 4.0
2023-08-22T15:40:38.003Z
@Murch I am encountering an issue while sending a transaction with various inputs. If one of these inputs is P2TR, I have created two transactions previously. Unfortunately, neither of them has been confirmed yet. The first transaction involves a P2TR input and a P2SH input, while the second one includes P2TR and P2WPKH inputs. I updated the question
Mohsen Haydari
CC BY-SA 4.0
2023-08-22T15:55:35.130Z
@Murch Could you perform a test transaction with (P2TR +P2WPKH) inputs? I suspect the issue might lie with the test network's node or miners. Thanks
Mohsen Haydari
CC BY-SA 4.0
2023-08-22T16:47:34.103Z
I don’t think it’s the nodes. The error message “non-mandatory-script-verify-flag (Invalid Schnorr signature)” indicates that the node you tried to give the transaction to first found the signature to be invalid. Perhaps @karask has an idea, have you considered trying to ask him on his project in github?
Murch
CC BY-SA 4.0
2023-08-22T17:18:58.147Z
@Murch Now I received this answer from him https://github.com/karask/python-bitcoin-utils/issues/47#issuecomment-1688599637
Mohsen Haydari
CC BY-SA 4.0
2023-08-22T17:59:16.370Z
I would not be surprised is the testnet node of Blockcypher were still a pre-taproot node, but I cannot find either of your transactions on other popular testnet block explorers (e.g. Blockstream and Mempool.space).
Murch
CC BY-SA 4.0
2023-08-22T20:57:47.213Z
If the error is "Invalid Schnorr signature", it is definitely a taproot node.
Pieter Wuille
CC BY-SA 4.0
2023-08-23T03:07:51.753Z
It has now been deleted from Blockcypher. I tested many Taproot transactions, and I only encountered a problem with inputs involving (p2tr+ (None p2pkh) ).
Mohsen Haydari
<p2sh><p2tr><p2wpkh><spending><p2wsh>
How can I spend a mix of UTXOs (p2sh, p2wpkh, p2wsh) along with a p2tr UTXO?
Mohsen Haydari
# How can I spend a mix of UTXOs (p2sh, p2wpkh, p2wsh) along with a p2tr UTXO?

(Asked by: username_0 on 2023-08-22)

I'm constructing a script to spend multiple distinct UTXOs in a single transaction. I've successfully combined all UTXOs except for two.

Succeeding in spending a `P2TR` with `P2PKH` UTXO.

I encountered a problem when attempting to spend a `P2TR` with one of them `P2SH, P2WSH, P2WPKH`.

```
accompanied by a 'non-mandatory-script-verify-flag (Invalid Schnorr signature).

```

While I managed to dispatch these transactions via an alternative node, none of them have been confirmed as of yet.

tx ids: (bitcoin-testnet)

[88558b495f28ff4799a4dacf40ee5cd1666850fed4847b8315256a5ae22527f8](https://live.blockcypher.com/btc-testnet/tx/88558b495f28ff4799a4dacf40ee5cd1666850fed4847b8315256a5ae22527f8/)
[02429ffe2f82f587d8e7a6e925201d3e7f219ac3af3688f2bc5c2770204e5d5c](https://live.blockcypher.com/btc-testnet/tx/88558b495f28ff4799a4dacf40ee5cd1666850fed4847b8315256a5ae22527f8/)

What could be the cause?
thanks

`P2TR`,`P2WPKH` to `P2PKH`

```
"hex": "02000000000102f80b4d99b2489228e23a25f1a458feefc1129b8ee030dc53d7ad0f112e278bd10000000000fffffffff80b4d99b2489228e23a25f1a458feefc1129b8ee030dc53d7ad0f112e278bd10100000000ffffffff01dc000000000000001976a91451283c275c76d14f0a1b010fa3430f0ade37781c88ac0140d7ac7111d6a732e655ebdf62fe224b1572803b47eb0c70aeb2b4f1a8f287fa20008b9145143f4cd0302ac1420f9602f5728a74d7c91b6c491ca44323d045f0af024730440220608f9ba4da7daa2d70aa24e7aabbf2c47d78ed39c331f40caf7aba7c07aa14750220467cf13de308c0633624fbcc6b41f9a1ef4f4f8568db9ac13ab7f1002e12912c01210220e57408d8f6726a81747f7507f7cdb7b86c502882d8a3bce5c62d39fddf38b100000000",
  "addresses": [
    "mnv5EAfPMTbfatz5ZbT6uUKpK7E5MftBAv",
    "tb1ps7gfq0h0hwu2cql9azz0wcf8rphr6xxeeyenrugd6yf263pxg9tq0fcjvz",
    "tb1qgt0w9wnw9wrs5qxtw7ptpfdz579889t2lcwcsy"
  ],
  "total": 220,
  "fees": 199780,
  "size": 301,
  "vsize": 170,
  "ver": 2,
  "vin_sz": 2,
  "vout_sz": 1,
  "confirmations": 0,
  "inputs": [
    {
      "prev_hash": "d18b272e110fadd753dc30e08e9b12c1effe58a4f1253ae2289248b2994d0bf8",
      "output_index": 0,
      "output_value": 100000,
      "sequence": 4294967295,
      "addresses": [
        "tb1ps7gfq0h0hwu2cql9azz0wcf8rphr6xxeeyenrugd6yf263pxg9tq0fcjvz"
      ],
      "script_type": "pay-to-taproot",
      "age": 2474244,
      "witness": [
        "d7ac7111d6a732e655ebdf62fe224b1572803b47eb0c70aeb2b4f1a8f287fa20008b9145143f4cd0302ac1420f9602f5728a74d7c91b6c491ca44323d045f0af"
      ]
    },
    {
      "prev_hash": "d18b272e110fadd753dc30e08e9b12c1effe58a4f1253ae2289248b2994d0bf8",
      "output_index": 1,
      "output_value": 100000,
      "sequence": 4294967295,
      "addresses": [
        "tb1qgt0w9wnw9wrs5qxtw7ptpfdz579889t2lcwcsy"
      ],
      "script_type": "pay-to-witness-pubkey-hash",
      "age": 2474244,
      "witness": [
        "30440220608f9ba4da7daa2d70aa24e7aabbf2c47d78ed39c331f40caf7aba7c07aa14750220467cf13de308c0633624fbcc6b41f9a1ef4f4f8568db9ac13ab7f1002e12912c01",
        "0220e57408d8f6726a81747f7507f7cdb7b86c502882d8a3bce5c62d39fddf38b1"
      ]
    }
  ],
  "outputs": [
    {
      "value": 220,
      "script": "76a91451283c275c76d14f0a1b010fa3430f0ade37781c88ac",
      "addresses": [
        "mnv5EAfPMTbfatz5ZbT6uUKpK7E5MftBAv"
      ],
      "script_type": "pay-to-pubkey-hash"
    }
  ]

```

I used [python-bitcoin-utils](https://github.com/username_3/python-bitcoin-utils) Python tool to generate the following code related to the transaction ID `88558b495f28ff4799a4dacf40ee5cd1666850fed4847b8315256a5ae22527f8` which involves inputs from both P2TR and P2WPKH scripts.

```
def main():
    print(to_satoshis(0.0000022))

    setup('testnet')
    priv1 = PrivateKey("cV3R88re3AZSBnWhBBNdiCKTfwpMKkYYjdiR13HQzsU7zoRNX7JL")
    priv2 = PrivateKey("cSfna7riKJdNU7skpRUx17WYANNsyHTA2FmuzLpFzpp37xpytgob")
    pub1 = priv1.get_public_key()
    pub2 = priv2.get_public_key()
    fromAddress1 = pub1.get_taproot_address()
    fromAddress2 = pub2.get_address()
    # p2tr utxo
    txid1 = 'd18b272e110fadd753dc30e08e9b12c1effe58a4f1253ae2289248b2994d0bf8'
    vout1 = 0
    # P2wpkh UTXO
    txid2 = 'd18b272e110fadd753dc30e08e9b12c1effe58a4f1253ae2289248b2994d0bf8'
    vout2 = 1
    amount1 = 100000
    amount2 = 100000
    amounts = [amount1, amount2]
    script_pubkey1 = fromAddress1.to_script_pub_key()
    script_pubkey2 = fromAddress2.to_script_pub_key()
    utxos_script_pubkeys = [script_pubkey1, script_pubkey2]

    toAddress = P2pkhAddress('mnv5EAfPMTbfatz5ZbT6uUKpK7E5MftBAv')
    txin1 = TxInput(txid1, vout1)
    txin2 = TxInput(txid2, vout2)
    txOut = TxOutput(to_satoshis(0.0000022), toAddress.to_script_pub_key())

    tx = Transaction([txin1, txin2], [txOut], has_segwit=True)
    sig1 = priv1.sign_taproot_input(tx, 0, utxos_script_pubkeys, amounts)
    sig2 = priv2.sign_segwit_input(tx, 1, script=script_pubkey2, amount=amount1)

    tx.witnesses.append(TxWitnessInput([sig1]))
    tx.witnesses.append(TxWitnessInput([sig2, pub2.to_hex()]))
    print("\nRaw signed transaction:\n" + tx.serialize())

```

**Tags:** p2sh, p2tr, p2wpkh, spending, p2wsh

> **Comments:**
> **username_1**: Instead of posting the one that worked, could you post the transaction that failed? My first guess would be that you forgot to add the (empty) witness stack for the non-segwit input.  
> **username_0**: @username_1 I added an empty witness for the UTXO P2SH at the specified index. I didn't modify the transaction; this is the same failed transaction that got confirmed on another node provider.  
> **username_1**: Okay, cool. Could you still post the failed transaction rather than one that succeeded? It’s hard to diagnose the issue without seeing the transaction that caused the problem.  
> **username_0**: @username_1  I didn't modify the transaction; this is the same failed transaction that got confirmed on another node provider  
> **username_1**: Oh, my bad. I thought that the second input was P2PKH, instead of P2WPKH.  
> **username_1**: It looks like your signature is invalid. You said that you managed to send other transactions with P2TR inputs, right? Most likely your issue stems from incorrectly calculating the sighash for the P2TR input now that there is another input.  
> **username_2**: There is nothing special about P2TR signatures in combination with specific other types of inputs. Can you post the sighash you used, and how you computed it?  
> **username_1**: Perhaps it would be helpful if you provided more information on how you construct the transaction. What tools do you use and which steps did you implement or perform manually?  
> **username_0**: @username_1 I am encountering an issue while sending a transaction with various inputs. If one of these inputs is P2TR, I have created two transactions previously. Unfortunately, neither of them has been confirmed yet. The first transaction involves a P2TR input and a P2SH input, while the second one includes P2TR and P2WPKH inputs. I updated the question  
> **username_0**: @username_1 Could you perform a test transaction with (P2TR +P2WPKH) inputs? I suspect the issue might lie with the test network's node or miners. Thanks  
> **username_1**: I don’t think it’s the nodes. The error message “non-mandatory-script-verify-flag (Invalid Schnorr signature)” indicates that the node you tried to give the transaction to first found the signature to be invalid. Perhaps @username_3 has an idea, have you considered trying to ask him on his project in github?  
> **username_0**: @username_1 Now I received this answer from him https://github.com/username_3/python-bitcoin-utils/issues/47#issuecomment-1688599637  
> **username_1**: I would not be surprised is the testnet node of Blockcypher were still a pre-taproot node, but I cannot find either of your transactions on other popular testnet block explorers (e.g. Blockstream and Mempool.space).  
> **username_2**: If the error is "Invalid Schnorr signature", it is definitely a taproot node.  
> **username_0**: It has now been deleted from Blockcypher. I tested many Taproot transactions, and I only encountered a problem with inputs involving (p2tr+ (None p2pkh) ).  

---

## 1 answers

### Answer by username_3 on 2023-08-25. Score: 2 | Accepted answer

Since it is a segwit address you should use

```
fromAddress2 = pub2.get_segwit_address()

```

Also, while taproot (segwit v1) requires the scriptPubKey when signing, segwit v0 requires the script code; i.e. a template that corresponds to the non-segwit equivalent. For example, for p2wpkh you would use as script code the p2pkh scriptPubKey.

So when signing the segwit input you shouldn't use the scriptPubKey but the p2pkh equivalent for that address. Example <https://github.com/username_3/python-bitcoin-utils/blob/master/examples/spend_p2wpkh_transaction.py> demonstrates this.

I haven't tried these changes to your code yet, but will do with the first opportunity.

EDIT: Just tried the suggested changes it works.

PS. In the meantime, if you try it out yourself please use `testmempoolaccept` to test tx validity instead of just sending the tx to a node for processing. That will test tx validity without spending the outputs. If there is still an issue I can then test using the same UTXOs.


---

