I’m trying to use the P2TR output using one of the scripts used to generate the current address. Below is some Python code that attempts to construct a raw transaction to use UTXOs. The address you want to move the testnet coins to is tb1pnnr3jysdew9gma9ac9k3pzdy5xp69fka3jh9vkga5ak28yjak0ws3hw834.
from bitcoinlib import transactions
from bitcoinutils.setup import setup
from bitcoinutils.script import Script
from bitcoinutils.utils import *
from bitcoinutils.transactions import Transaction, TxInput, TxOutput, TxWitnessInput
from bitcoinutils.keys import *
utxos = ('txid': "4390635a95c7e3538dda7c4690f38fbfaa5d93eaf04e1f4f63fb811a884428e2", "vout": 0)
priv1 = PrivateKey(wif="secret for obvious reason 1")
priv2 = PrivateKey(wif="secret for obvious reason 2")
priv3 = PrivateKey(wif="secret for obvious reason 3")
priv4 = PrivateKey(wif="secret for obvious reason 4")
pub1 = priv1.get_public_key()
pub2 = priv2.get_public_key()
pub3 = priv3.get_public_key()
pub4 = priv4.get_public_key()
def main():
setup("testnet")
input_amounts = (79800)
output_amounts = (79650)
# taproot script 2 is a simple P2PK with key 2
tr_script_p2pk2 = Script((pub2.to_x_only_hex(), "OP_CHECKSIG"))
# taproot script 3 is a simple P2PK with key 3
tr_script_p2pk3 = Script((pub3.to_x_only_hex(), "OP_CHECKSIG"))
# taproot script 4 is a simple P2PK with key 4
tr_script_p2pk4 = Script((pub4.to_x_only_hex(), "OP_CHECKSIG"))
all_leafs = ((tr_script_p2pk2, tr_script_p2pk3), tr_script_p2pk4)
input_address = pub1.get_taproot_address(all_leafs)
input_1 = TxInput(txid=utxos(4)('txid'), txout_index=utxos(4)('vout'))
output_address = P2pkhAddress(address="moHfMJHAP3LE2aYTp4Q6g5GxnnfTK9muAJ")
output_1 = TxOutput(amount=output_amounts(0), script_pubkey=output_address.to_script_pub_key())
tx1 = Transaction(inputs=(input_1), outputs=(output_1), has_segwit=True)
sig1 = priv3.sign_taproot_input(tx=tx1, txin_index=0, utxo_scripts=(input_address.to_script_pub_key()),
amounts=input_amounts, script_path=True,
tapleaf_script=tr_script_p2pk3, tweak=False)
# tagged hashes of leafs
leaf2 = tapleaf_tagged_hash(tr_script_p2pk2)
leaf3 = tapleaf_tagged_hash(tr_script_p2pk3)
leaf4 = tapleaf_tagged_hash(tr_script_p2pk4)
# If using get_tag_hashed_merkle_root
merkleroot1 = get_tag_hashed_merkle_root(scripts=all_leafs)
# If manually constructing the tree
branch_23 = tapbranch_tagged_hash(leaf2, leaf3)
merkleroot2 = tapbranch_tagged_hash(branch_23, leaf4)
assert(merkleroot1.hex() == merkleroot2.hex())
control_block = ControlBlock(pubkey=pub1, script_to_spend=tr_script_p2pk3, scripts=leaf2+leaf4)
tx1.witnesses.append(TxWitnessInput((sig1, tr_script_p2pk3.to_hex(), control_block.to_hex())))
print("\nRaw signed transaction:\n" + tx1.serialize())
Among the three scripts used to generate addresses, we are trying to use UTXO using tr_script_p2pk3. The raw transaction obtained by running this code is:
02000000 => version
0001 => marker and flag
01 => input count
e22844881a81fb634f1f4ef0ea935daabf8ff390467cda8d53e3c7955a639043 => input txid
00000000 => input vout
00 => scriptSig
ffffffff => nSequence
01 => output count
2237010000000000 => output amount
1976a914553d745f650e2faba231590931c3561e3ab7cb7888ac => scriptPubKey
03 => witness stack count
4060f3d6d5e5782977b53d6f7025ff8c7f70e1cb6a1b1de96117aa499713fcd701fed99f27d0922e58a8a8d731af9f3f9b36d5389e694b23513dd0b0eea6264fa7 => schnorr signature
222030a1dfffabb677eb2d8aa45bc7e24cbc31d67731680fe5be4b524e3359445f37ac => tr_script_p2pk3
61 => control block length
c0 => default leaf version tapscript
cded16e0e749cb161694b20f5bd7737ebc22b40805a415941b3fcc26df30dbb1 => internal key (in this example, pub1)
dff122122208c96d11efdd99a987150f7c422eeb2f9076f40804382dbc95c7b78cbca50495d9c133a60cf93e502e84b421b5640258f549c2bdb6e538eae16e7d => Merkle path (in this case, leaf2 + leaf4)
00000000 => nLocktime
The transaction failed and I received the following message: