I hope you’ll be able to assist me to resolve this concern. I am utilizing the library python-bitcoin-utils developed by Karask and I might to execute a transaction the place the UTXO has 2 P2TR (Taproot) addresses and the ship output to a different 2 P2TR (Taproot) addresses.
Earlier than to succeed in this aim, I might attempt to use the https://github.com/karask/python-bitcoin-utils/blob/grasp/examples/spend_multi_input_p2tr_and_p2pkh.py to execute the enter UTXO from 2 P2TR to 1 P2TR. I compiled the code and produce the rawtransaction nevertheless it get the error non-mandatory-script-verify-flag (Invalid Schnorr signature) (code -26).
I attempted to look the BIP340 guidelines however I am probably not understanding what I’ve to do to resolve it.
Right here the code that i am utilizing:
# Copyright (C) 2018-2024 The python-bitcoin-utils builders
#
# This file is a part of python-bitcoin-utils
#
# It's topic to the license phrases within the LICENSE file discovered within the top-level
# listing of this distribution.
#
# No a part of python-bitcoin-utils, together with this file, could also be copied,
# modified, propagated, or distributed besides based on the phrases contained
# within the LICENSE file.
from bitcoinutils.setup import setup
from bitcoinutils.utils import to_satoshis
from bitcoinutils.transactions import Transaction, TxInput, TxOutput, TxWitnessInput
from bitcoinutils.keys import P2pkhAddress, PrivateKey, P2trAddress
from bitcoinutils.script import Script
def major():
# at all times keep in mind to setup the community
setup("testnet")
# the important thing that corresponds to the P2WPKH tackle
priv1 = PrivateKey("cMrLFqBmVQgQpkpf6Q6YqR6KC7gmUuQGbQtXtyJV9PR3rf1PAoF4")
#priv2 = PrivateKey("cSfna7riKJdNU7skpRUx17WYANNsyHTA2FmuzLpFzpp37xpytgob")
priv3 = PrivateKey("cRhBdjfJqGVKkdcBeiTSdkiDGnmfntD4yyfeHHTDQwhtueQYDLZC")
pub1 = priv1.get_public_key()
#pub2 = priv2.get_public_key()
pub3 = priv3.get_public_key()
fromAddress1 = pub1.get_taproot_address()
#fromAddress2 = pub2.get_address()
fromAddress3 = pub3.get_taproot_address()
print(fromAddress1.to_string())
#print(fromAddress2.to_string())
print(fromAddress3.to_string())
# UTXO of fromAddress's respectively
txid1 = "c7cc326c838699a5c62c13af85877512cf76c803504dbc3de82fe295ba94cfbe"
vout1 = 0
#txid2 = "99fb66cbc26a2d1a5a03c3d00118fd370a37a29fb368817dde3b8b50920cd4dc"
#vout2 = 1
txid3 = "c7cc326c838699a5c62c13af85877512cf76c803504dbc3de82fe295ba94cfbe"
vout3 = 1
# all quantities are wanted to signal a taproot enter
# (relying on sighash)
amount1 = to_satoshis(0.00005000)
#amount2 = to_satoshis(0.0001312)
amount3 = to_satoshis(0.00009114)
#quantities = [amount1, amount2, amount3]
quantities = [amount1, amount3]
# all scriptPubKeys are wanted to signal a taproot enter
# (relying on sighash) however at all times of the spend enter
script_pubkey1 = fromAddress1.to_script_pub_key()
#script_pubkey2 = fromAddress2.to_script_pub_key()
script_pubkey3 = fromAddress3.to_script_pub_key()
#utxos_script_pubkeys = [script_pubkey1, script_pubkey2, script_pubkey3]
utxos_script_pubkeys = [script_pubkey1, script_pubkey3]
#toAddress = P2pkhAddress("mtVHHCqCECGwiMbMoZe8ayhJHuTdDbYWdJ")
toAddress = P2trAddress("tb1ph76fd3w923rfc025hwfhpqf5p9gslqzsent43p4ah2g9nklelr3q5gzzuy")
# create transaction enter from tx id of UTXO
txin1 = TxInput(txid1, vout1)
#txin2 = TxInput(txid2, vout2)
txin3 = TxInput(txid3, vout3)
# create transaction output
txOut = TxOutput(to_satoshis(0.00010), toAddress.to_script_pub_key())
# create transaction with out change output - if no less than a single enter is
# segwit we have to set has_segwit=True
#tx = Transaction([txin1, txin2, txin3], [txOut], has_segwit=True)
tx = Transaction([txin1, txin3], [txOut], has_segwit=True)
print("nRaw transaction:n" + tx.serialize())
print("ntxid: " + tx.get_txid())
print("ntxwid: " + tx.get_wtxid())
# signal taproot enter
# to create the digest message to register taproot we have to
# cross all of the utxos' scriptPubKeys and their quantities
sig1 = priv1.sign_taproot_input(tx, 0, utxos_script_pubkeys, quantities)
#sig2 = priv2.sign_input(tx, 1, utxos_script_pubkeys[1])
sig3 = priv3.sign_taproot_input(tx, 2, utxos_script_pubkeys, quantities)
print("Signature1: ", sig1)
print("nSignature3: ", sig3)
tx.witnesses.append(TxWitnessInput([sig1]))
#txin2.script_sig = Script([sig2, pub2.to_hex()])
# the second enter is just not segwit however we nonetheless want so as to add an empty
# witness enter script
#tx.witnesses.append(TxWitnessInput([]))
tx.witnesses.append(TxWitnessInput([sig3]))
# print uncooked signed transaction able to be broadcasted
print("nRaw signed transaction:n" + tx.serialize())
print("nTxId:", tx.get_txid())
print("nTxwId:", tx.get_wtxid())
print("nSize:", tx.get_size())
print("nvSize:", tx.get_vsize())
# print("nCore vSize:", 160)
if __name__ == "__main__":
major()
That is the uncooked signed transaction end result
02000000000102becf94ba95e22fe83dbc4d5003c876cf12758785af132cc6a59986836c32ccc70000000000ffffffffbecf94ba95e22fe83dbc4d5003c876cf12758785af132cc6a59986836c32ccc70100000000ffffffff011027000000000000225120bfb496c5c554469c3d54bb9370813409510f8050ccd75886bdba9059dbf9f8e20140dba380daaadc08f4968390dfd6ec376879c065ddd512f9109c3b61ff6465c5dd1593ad5347f57ed1ddf049e03fa9d49fcb42ac4e1ded888a59c1b66d1cca5ef50140786e666be0e3cf1f316a697a2eaf5056007665537ff9f5b619ba073973cc4a510098f37a4a5d182e9db87df126f1aab24eb0f12ddc0eae4973917ae3a7b3db2900000000
Thanks on your assist.