0

I've been struggling to figure out how to spend a particular script path using buidl python lib. Currently I assume the problem lies in how I construct p2tr address or there's a bug (very unlikely) in how the control block is calculated.

The error I'm receiving when broadcasting a spending transaction is: Witness program hash mismatch

You can find my code in the gist or below:

from buidl.hd import HDPrivateKey
from buidl.ecc import PrivateKey
from buidl.taproot import TapLeaf, TapBranch, TapScript
from buidl.script import Script
from buidl.op import *
from buidl.tx import Tx, TxIn, TxOut
from buidl.taproot import ControlBlock
from buidl.witness import Witness
from buidl.script import P2WPKHScriptPubKey, ScriptPubKey, decode_bech32

pvt_key = PrivateKey(12345, network="regtest")
internal_pvtkey = PrivateKey(3333, network="regtest")
internal_pubkey = internal_pvtkey.point

# leaf_a = Script([op_1, op_add, op_2, op_equal])
# leaf_b = Script([op_2, op_add, op_4, op_equal])
# leaf_b = Script([op_1, op_add, op_5, op_equal])
script_a = TapScript([81, 147, 82, 135])
script_b = TapScript([82, 147, 84, 135])
script_c = TapScript([81, 147, 85, 135])

leaf_a = TapLeaf(script_a)
leaf_b = TapLeaf(script_b)
leaf_c = TapLeaf(script_c)

branch_ab = TapBranch(leaf_a, leaf_b)
branch_abc = TapBranch(branch_ab, leaf_c)

address = branch_abc.external_pubkey(internal_pubkey).p2tr_address(network="regtest")
print("Deposit funds to:", address)

# SPEND PATH B
amount = 1_000_000
cb = branch_abc.control_block(internal_pubkey, leaf_b)

tx_in = TxIn(bytes.fromhex("07fdfaf3541c26d5fc18f644f338d8ac4e47f7bcc83c41192741990d150b8d19"), 1)
tx_in.witness.items = [encode_num(2), leaf_b.tap_script.raw_serialize(), cb.serialize()]
tx_ins = [tx_in]
tx_outs = [TxOut(998000, P2TRScriptPubKey(decode_bech32("bcrt1py7e8e0q7pdkxwyp2tjn65k4kd5kgch0aqe03jzjczn96xat6nwjswsu892")[2]))]
tx = Tx(2, tx_ins, tx_outs, network="regtest", segwit=True)
tx.serialize().hex()
# 02000000000101941ea2c9c9236e92e0d94530d0de3694012f0d3902399dc680294ef2e82a0e780100000000ffffffff01301b0f0000000000160014904946363de1f2cb5ce439e5ed038492051b2785030101045293538841c04cecb33a915e2c3b189eb6ee45fa4eb3eddeff09729945c600f893bd4381b294c95c39c9307263577e8ed45b4d6ad91cf6f47f42476e0e40676b1f028be1360600000000
# I always get: `non-mandatory-script-verify-flag (Witness program hash mismatch)`

Please not that I was able to successfully create and spend a p2tr address (using same tapscripts) with bitcointx library, hence why I assume I'm most likely not using the buidl library correctly or am misunderstanding something.

1 Answer 1

0

I'm happy to report that I was finally able to construct an address in a way that I was also able to spend a script path!

This is how I constructed an address before:

address = branch_abc.external_pubkey(internal_pubkey).p2tr_address(network="regtest")

This is how I constructed it now:

internal_pubkey = S256Point.parse_xonly(unhexlify("f006a18d5653c4edf5391ff23a61f03ff83d237e880ee61187fa9f379a028e0a"))
internal_pubkey.p2tr_address(branch_abc.hash(), network="regtest")

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