1

Goal is to archive the following logic:

$alice = A;
$bob = B;

pk($bob) || (pk($alice) && older(10))

I went through The Taproot Workshop and came up with the following code:

from io import BytesIO
import random
import util
from test_framework.key import generate_key_pair, generate_bip340_key_pair, generate_schnorr_nonce, ECKey, ECPubKey, SECP256K1_FIELD_SIZE, SECP256K1, SECP256K1_ORDER
from test_framework.musig import aggregate_musig_signatures, aggregate_schnorr_nonces, generate_musig_key, musig_digest, sign_musig
from test_framework.script import TapLeaf, TapTree, TaprootSignatureHash, SIGHASH_ALL_TAPROOT
from test_framework.address import program_to_witness
from test_framework.messages import CTransaction, COutPoint, CTxIn, CTxOut, CTxInWitness
from test_framework.util import assert_equal




my_privkey, my_pubkey = generate_bip340_key_pair()
delay_privkey, delay_pubkey = generate_bip340_key_pair()


tapscript_res = TapLeaf().construct_pk_delay(delay_pubkey, 10)
taptree = TapTree(key=my_pubkey)
taptree.huffman_constructor([(1, tapscript_res)])

taproot_script, tweak, control_map = taptree.construct()
taproot_pubkey = my_pubkey.tweak_add(tweak) 
program = taproot_pubkey.get_bytes()
address = program_to_witness(1, program)
print("Segwit Address:", address)


test = util.TestWrapper()
test.setup()
node = test.nodes[0]

tx = node.generate_and_send_coins(address)
node.generate(2)
print("Transaction {}, output 0\nsent to {}\n".format(tx.hash, address))
spending_tx = test.create_spending_transaction(tx.hash, version=2)

print("Spending transaction:\n{}".format(spending_tx))
sighashA = TaprootSignatureHash(spending_tx,
                               [tx.vout[0]],
                               SIGHASH_ALL_TAPROOT,
                               input_index=0,
                               scriptpath=True,
                               script=tapscript_res.script)

signatureA = delay_privkey.sign_schnorr(sighashA)

print("Signature for TapLeafA: {}\n".format(signatureA.hex()))
witness_elements = [signatureA, tapscript_res.script, control_map[tapscript_res.script]]
spending_tx.wit.vtxinwit.append(CTxInWitness(witness_elements))

# Test mempool acceptance
assert not node.test_transaction(spending_tx)
node.generate(21)
assert node.test_transaction(spending_tx)
print("Success!")
test.shutdown()

I tried numerous changes to the spending process, however the output I get is always:

Segwit Address: bcrt1p0jh5l700aqtnxtn97vhf3vqf6w700dzj5h9vahx5aqhrklu8glgqtwgnn0

Client version is /Satoshi:22.99.0(testnode0)/

Balance: 50.00000000

Transaction 78f7017342f86f03af0e27e127ce7578311f967b950f1dc65b9b928653766117, output 0
sent to bcrt1p0jh5l700aqtnxtn97vhf3vqf6w700dzj5h9vahx5aqhrklu8glgqtwgnn0

Spending transaction:
CTransaction(nVersion=2 vin=[CTxIn(prevout=COutPoint(hash=78f7017342f86f03af0e27e127ce7578311f967b950f1dc65b9b928653766117 n=0) scriptSig= nSequence=0)] vout=[CTxOut(nValue=0.50000000 scriptPubKey=001415d2012d191dbad6cf7881b1cad4af4bb72b6a57)] wit=CTxWitness() nLockTime=0)
Signature for TapLeafA: bbad433804dcdc1070894abe58e52fe38ebc87c9b337187aee0d77ca0299e78f6f212131f6bd19dbc3d7655304322b43b99ecadb64c84d3f9fcceebcc25184c6

{'txid': 'b462759670cbca3c6449fa18f0a0a45044317dadd13a58521549fc1e42219c6f', 'wtxid': '17e532c0447fe3cf6ef52b6e23f69d744e745ba7c6ccd5d53689fe3da968aa18', 'allowed': False, 'reject-reason': 'non-mandatory-script-verify-flag (Data push larger than necessary)'}
{'txid': 'b462759670cbca3c6449fa18f0a0a45044317dadd13a58521549fc1e42219c6f', 'wtxid': '17e532c0447fe3cf6ef52b6e23f69d744e745ba7c6ccd5d53689fe3da968aa18', 'allowed': False, 'reject-reason': 'non-mandatory-script-verify-flag (Data push larger than necessary)'}

Depending on how I change the code, the reject-reason varies.

Any ideas what is faulty in my code?

If there is an existing way to approach this using other languages/libraries, I am happy for hints.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.