chainx-org / threshold_signature

GNU General Public License v3.0
4 stars 0 forks source link

Taproot test data #3

Open AAweidai opened 2 years ago

AAweidai commented 2 years ago

Test Data

Transaction sent to segwit v1 address

{
    "txid": "5d024151ba9fb4287946a5956621ed7ab45c4403314ff24ada0378d9c63c0d50",
    "hash": "d2afc56085644f26cdd0035cf4908e01b1d3622fcf708177f2da944b4cda5bf8",
    "version": 2,
    "size": 234,
    "vsize": 153,
    "weight": 609,
    "locktime": 61352,
    "vin": [
        {
            "txid": "4f705aabd1176921ae339819d5610e8ecd69458259b5f20bc747ff26fa39b718",
            "vout": 0,
            "scriptSig": {
                "asm": "",
                "hex": ""
            },
            "txinwitness": [
                "304402200178765ae00dbd169cdad7d2f3ce8262a7339ea789dd0de4a415348f1c8e27cc02207ea4b63334d378679d34453d4ef7a553db251732bb288801d176eb2026c372aa01",
                "03c8fa28c586bf6d15c5145ed5fccec1d4f2c4f48dc2f085ad1b0605c49eb84971"
            ],
            "sequence": 4294967294
        }
    ],
    "vout": [
        {
            "value": 69877.39451863,
            "n": 0,
            "scriptPubKey": {
                "asm": "0 4f99260782d93cdfff2dc4c108161d444dd47288",
                "hex": "00144f99260782d93cdfff2dc4c108161d444dd47288",
                "address": "tb1qf7vjvpuzmy7dlledcnqss9sag3xagu5gskm5nh",
                "type": "witness_v0_keyhash"
            }
        },
        {
            "value": 0.1,
            "n": 1,
            "scriptPubKey": {
                "asm": "1 52898a03a9f04bb83f8a48fb953089de10e6ee70658b059551ebf7c008b05b7a",
                "hex": "512052898a03a9f04bb83f8a48fb953089de10e6ee70658b059551ebf7c008b05b7a",
                "address": "tb1p22yc5qaf7p9ms0u2frae2vyfmcgwdmnsvk9st923a0muqz9stdaqn3h0p6",
                "type": "witness_v1_taproot"
            }
        }
    ],
    "hex": "0200000000010118b739fa26ff47c70bf2b559824569cd8e0e61d5199833ae216917d1ab5a704f0000000000feffffff02d751baf55a0600001600144f99260782d93cdfff2dc4c108161d444dd47288809698000000000022512052898a03a9f04bb83f8a48fb953089de10e6ee70658b059551ebf7c008b05b7a0247304402200178765ae00dbd169cdad7d2f3ce8262a7339ea789dd0de4a415348f1c8e27cc02207ea4b63334d378679d34453d4ef7a553db251732bb288801d176eb2026c372aa012103c8fa28c586bf6d15c5145ed5fccec1d4f2c4f48dc2f085ad1b0605c49eb84971a8ef0000",
    "blockhash": "00000021cc1545f4e10147c9ba1e512f4239819e376b658a66e21e22e515cfd0",
    "confirmations": 1,
    "time": 1635147919,
    "blocktime": 1635147919
}

Spend from segwit v1 address

{
    "txid": "295de683fadde77577d3a0e6b81b86d4e5dfd3611808e00a148d9295903f0d8a",
    "hash": "fb1857d2bbc249c85d6bc2a3715713aab30cd979231b2af42030f3a1cfe78a4c",
    "version": 2,
    "size": 205,
    "vsize": 154,
    "weight": 616,
    "locktime": 61353,
    "vin": [
        {
            "txid": "5d024151ba9fb4287946a5956621ed7ab45c4403314ff24ada0378d9c63c0d50",
            "vout": 1,
            "scriptSig": {
                "asm": "",
                "hex": ""
            },
            "txinwitness": [
                "a91efca1adb18ff64661028cfe97487bc8eb610fbe44aafdc7072de0bfe960a6524bb50e444c4a3bbc7055d70b9ec8c382aa8c0b08c0558641e725c12c80538f"
            ],
            "sequence": 4294967294
        }
    ],
    "vout": [
        {
            "value": 0.00099,
            "n": 0,
            "scriptPubKey": {
                "asm": "1 4a4f4c9c08dd137c6b43567f23b7d980be52e58d15c53e873ee43a4a99362be3",
                "hex": "51204a4f4c9c08dd137c6b43567f23b7d980be52e58d15c53e873ee43a4a99362be3",
                "address": "tb1pff85e8qgm5fhc66r2elj8d7eszl99evdzhznape7usay4xfk903srjt3y9",
                "type": "witness_v1_taproot"
            }
        },
        {
            "value": 0.099008,
            "n": 1,
            "scriptPubKey": {
                "asm": "1 23e3d60a762fe1e145b1b0b94e493474722b9ddeb5c29960a9670a4e49099f26",
                "hex": "512023e3d60a762fe1e145b1b0b94e493474722b9ddeb5c29960a9670a4e49099f26",
                "address": "tb1py03avznk9ls7z3d3kzu5ujf5w3ezh8w7khpfjc9fvu9yujgfnunqtjdwts",
                "type": "witness_v1_taproot"
            }
        }
    ],
    "hex": "02000000000101500d3cc6d97803da4af24f3103445cb47aed216695a5467928b49fba5141025d0100000000feffffff02b8820100000000002251204a4f4c9c08dd137c6b43567f23b7d980be52e58d15c53e873ee43a4a99362be3001397000000000022512023e3d60a762fe1e145b1b0b94e493474722b9ddeb5c29960a9670a4e49099f260140a91efca1adb18ff64661028cfe97487bc8eb610fbe44aafdc7072de0bfe960a6524bb50e444c4a3bbc7055d70b9ec8c382aa8c0b08c0558641e725c12c80538fa9ef0000",
    "blockhash": "0000015e0617eb67b4aa80ca774c5b5d3aa4d06861fa65df7f3d80babcc5503b",
    "confirmations": 1,
    "time": 1635149288,
    "blocktime": 1635149288
}
AAweidai commented 2 years ago

With taptweak. Cost by script path.

import util
from test_framework.address import program_to_witness, key_to_p2wpkh
from test_framework.key import ECKey
from test_framework.messages import CTxInWitness, COutPoint, CTransaction, CTxIn, CTxOut
from test_framework.script import TapTree, TapLeaf, TaprootSignatureHash, SIGHASH_ALL_TAPROOT, Tapbranch
from test_framework.musig import generate_musig_key
from pprint import pprint

def generate_bip340_key_pair(secret=None):
    """Convenience function to generate a BIP0340 private-public key pair."""
    if secret is None:
        d = ECKey()
        d.generate()
    else:
        d = ECKey().set(secret)
    P = d.get_pubkey()
    if P.get_y() % 2 != 0:
        d.negate()
        P.negate()
    return d, P

# generate alice bob charlie key
privkey_alice, pubkey_alice = generate_bip340_key_pair(
    secret=103910053441657220738925612114654039920823302334302261834756476233133311987138)
privkey_bob, pubkey_bob = generate_bip340_key_pair(
    secret=75573449985348711764142460376289265944117193680909672902170333608986796225238)
privkey_charlie, pubkey_charlie = generate_bip340_key_pair(
    secret=33705509085456474265534912245246680268484766969648186791871278745425848684352)

segwit_version = 1
pubkey_charlie_bytes = pubkey_charlie.get_bytes()
segwit_address_charlie = program_to_witness(segwit_version, pubkey_charlie_bytes)
segwit_address_script_pubkey_charlie = "5120" + pubkey_charlie_bytes.hex()
print("charlie Script pubkey: ", segwit_address_script_pubkey_charlie)
print("charlie Regtest address format: ", segwit_address_charlie)
print("charlie Mainnet address format: ", program_to_witness(segwit_version, pubkey_charlie_bytes, main=True), "\n")

# Start node
test = util.TestWrapper()
test.setup()
node = test.nodes[0]
tx = node.generate_and_send_coins(segwit_address_charlie)
tx_hex = tx.serialize().hex()
print("init tx: ", tx_hex, "\n")

c_map, pubkey_agg = generate_musig_key([pubkey_alice, pubkey_bob, pubkey_charlie])
if pubkey_agg.get_y() % 2 != 0:
    pubkey_agg.negate()
# Construct tapleaves
tapleafA = TapLeaf().construct_pk(pubkey_alice)
tapleafB = TapLeaf().construct_pk(pubkey_bob)
tapleafC = TapLeaf().construct_pk(pubkey_charlie)
# Construct taptree nodes.
tapbranchAB = Tapbranch(tapleafA, tapleafB)
tapbranchABC = Tapbranch(tapbranchAB, tapleafC)
# Construct the taptree.
taptree = TapTree(key=pubkey_agg, root=tapbranchABC)
segwit_v1_script, taptweak, control_map = taptree.construct()
# generate Taproot pubkey
taptweak_pubkey = pubkey_agg.tweak_add(taptweak)
# generate segwit address
taptweak_pubkey_b = taptweak_pubkey.get_bytes()
segwit_version = 1
segwit_address = program_to_witness(segwit_version, taptweak_pubkey_b)
segwit_address_script_pubkey = "5120" + taptweak_pubkey_b.hex()
print("Agg Script pubkey: ", segwit_address_script_pubkey)
print("Agg Regtest address format: ", segwit_address)
print("Agg Mainnet address format: ", program_to_witness(segwit_version, taptweak_pubkey_b, main=True), "\n")

spending_tx = test.create_spending_transaction(tx.hash, version=2)
output_script = bytes.fromhex(segwit_address_script_pubkey)
output_amount_sat = 10_000_000  # remove transaction fee from output amount
output = CTxOut(nValue=output_amount_sat, scriptPubKey=output_script)
remain_output_script = bytes.fromhex(segwit_address_script_pubkey_charlie)
remain_output = CTxOut(nValue=80_000_000, scriptPubKey=remain_output_script)
spending_tx.vout = [output, remain_output]
# Create sighash for ALL
sighashA = TaprootSignatureHash(spending_tx,
                                [tx.vout[0]],
                                SIGHASH_ALL_TAPROOT,
                                input_index=0)
signatureA = privkey_charlie.sign_schnorr(sighashA)
spending_tx.wit.vtxinwit.append(CTxInWitness([signatureA]))
print("send btc to segwit address, tx hex:", spending_tx.serialize().hex(), "\n")
assert node.test_transaction(spending_tx)
node.sendrawtransaction(spending_tx.serialize().hex(), 0)

# tx decode
tx = spending_tx
decode = node.decoderawtransaction(str(tx.serialize().hex()))
# print("\ndecode tx raw transaction:")
# pprint(decode)
spending_tx = test.create_spending_transaction(decode['txid'], version=2)
output_script = bytes.fromhex(segwit_address_script_pubkey_charlie)
output_amount_sat = 5_000_000  # remove transaction fee from output amount
output = CTxOut(nValue=output_amount_sat, scriptPubKey=output_script)
remain_output_script = bytes.fromhex(segwit_address_script_pubkey)
remain_output = CTxOut(nValue=4_000_000, scriptPubKey=remain_output_script)
spending_tx.vout = [output, remain_output]
# Create sighash for ALL
sighashA = TaprootSignatureHash(spending_tx,
                                [tx.vout[0]],
                                SIGHASH_ALL_TAPROOT,
                                input_index=0,
                                scriptpath=True,
                                script=tapleafA.script)
signatureA = privkey_alice.sign_schnorr(sighashA)
# print("Signature for TapLeafA: {}\n".format(signatureA.hex()))
# Add witness to transaction
# Tip: Witness stack for script path - [satisfying elements for tapscript] [TapLeaf.script] [controlblock]
# Tip: Controlblock for a tapscript in control_map[TapLeaf.script]
witness_elements = [signatureA, tapleafA.script, control_map[tapleafA.script]]
spending_tx.wit.vtxinwit.append(CTxInWitness(witness_elements))
assert node.test_transaction(spending_tx)
spending_tx_hex = spending_tx.serialize().hex()
print("\n", "send others from segwit address, spending_tx hex: ", spending_tx_hex, "\n")
# print("\ndecode spending_tx raw transaction:")
# pprint(node.decoderawtransaction(str(spending_tx_hex)))
test.shutdown()
AAweidai commented 2 years ago

With OpReturn. Cost by script path.

p2tr
import util
from test_framework.address import program_to_witness, key_to_p2wpkh
from test_framework.key import ECKey
from test_framework.messages import CTxInWitness, COutPoint, CTransaction, CTxIn, CTxOut
from test_framework.script import TapTree, TapLeaf, TaprootSignatureHash, SIGHASH_ALL_TAPROOT, Tapbranch, CScript, \
    OP_RETURN
from test_framework.musig import generate_musig_key
from pprint import pprint

def generate_bip340_key_pair(secret=None):
    """Convenience function to generate a BIP0340 private-public key pair."""
    if secret is None:
        d = ECKey()
        d.generate()
    else:
        d = ECKey().set(secret)
    P = d.get_pubkey()
    if P.get_y() % 2 != 0:
        d.negate()
        P.negate()
    return d, P

# generate alice bob charlie key
privkey_alice, pubkey_alice = generate_bip340_key_pair(
    secret=103910053441657220738925612114654039920823302334302261834756476233133311987138)
privkey_bob, pubkey_bob = generate_bip340_key_pair(
    secret=75573449985348711764142460376289265944117193680909672902170333608986796225238)
privkey_charlie, pubkey_charlie = generate_bip340_key_pair(
    secret=33705509085456474265534912245246680268484766969648186791871278745425848684352)

segwit_version = 1
pubkey_charlie_bytes = pubkey_charlie.get_bytes()
segwit_address_charlie = program_to_witness(segwit_version, pubkey_charlie_bytes)
segwit_address_script_pubkey_charlie = "5120" + pubkey_charlie_bytes.hex()
print("charlie Script pubkey: ", segwit_address_script_pubkey_charlie)
print("charlie Regtest address format: ", segwit_address_charlie)
print("charlie Mainnet address format: ", program_to_witness(segwit_version, pubkey_charlie_bytes, main=True), "\n")

# Start node
test = util.TestWrapper()
test.setup()
node = test.nodes[0]
tx = node.generate_and_send_coins(segwit_address_charlie)
tx_hex = tx.serialize().hex()
print("init tx: ", tx_hex, "\n")

c_map, pubkey_agg = generate_musig_key([pubkey_alice, pubkey_bob, pubkey_charlie])
if pubkey_agg.get_y() % 2 != 0:
    pubkey_agg.negate()
# Construct tapleaves
tapleafA = TapLeaf().construct_pk(pubkey_alice)
tapleafB = TapLeaf().construct_pk(pubkey_bob)
tapleafC = TapLeaf().construct_pk(pubkey_charlie)
# Construct taptree nodes.
tapbranchAB = Tapbranch(tapleafA, tapleafB)
tapbranchABC = Tapbranch(tapbranchAB, tapleafC)
# Construct the taptree.
taptree = TapTree(key=pubkey_agg, root=tapbranchABC)
segwit_v1_script, taptweak, control_map = taptree.construct()
# generate Taproot pubkey
taptweak_pubkey = pubkey_agg.tweak_add(taptweak)
# generate segwit address
taptweak_pubkey_b = taptweak_pubkey.get_bytes()
segwit_version = 1
segwit_address = program_to_witness(segwit_version, taptweak_pubkey_b)
segwit_address_script_pubkey = "5120" + taptweak_pubkey_b.hex()
print("Agg Script pubkey: ", segwit_address_script_pubkey)
print("Agg Regtest address format: ", segwit_address)
print("Agg Mainnet address format: ", program_to_witness(segwit_version, taptweak_pubkey_b, main=True), "\n")

spending_tx = test.create_spending_transaction(tx.hash, version=2)
output_script = bytes.fromhex(segwit_address_script_pubkey)
output_amount_sat = 10_000_000  # remove transaction fee from output amount
output = CTxOut(nValue=output_amount_sat, scriptPubKey=output_script)
# op return
commitment_bytes = bytes.fromhex("35516a706f3772516e7751657479736167477a6334526a376f737758534c6d4d7141754332416255364c464646476a38")
op_return_output_script = CScript([OP_RETURN, commitment_bytes])
op_return_output = CTxOut(nValue=0, scriptPubKey=op_return_output_script)
remain_output_script = bytes.fromhex(segwit_address_script_pubkey_charlie)
remain_output = CTxOut(nValue=80_000_000, scriptPubKey=remain_output_script)
spending_tx.vout = [output, op_return_output, remain_output]
# Create sighash for ALL
sighashA = TaprootSignatureHash(spending_tx,
                                [tx.vout[0]],
                                SIGHASH_ALL_TAPROOT,
                                input_index=0)
signatureA = privkey_charlie.sign_schnorr(sighashA)
spending_tx.wit.vtxinwit.append(CTxInWitness([signatureA]))
print("send btc to segwit address, tx hex:", spending_tx.serialize().hex(), "\n")
assert node.test_transaction(spending_tx)
node.sendrawtransaction(spending_tx.serialize().hex(), 0)

# tx decode
tx = spending_tx
decode = node.decoderawtransaction(str(tx.serialize().hex()))
# print("\ndecode tx raw transaction:")
# pprint(decode)
spending_tx = test.create_spending_transaction(decode['txid'], version=2)
output_script = bytes.fromhex(segwit_address_script_pubkey_charlie)
output_amount_sat = 5_000_000  # remove transaction fee from output amount
output = CTxOut(nValue=output_amount_sat, scriptPubKey=output_script)
remain_output_script = bytes.fromhex(segwit_address_script_pubkey)
remain_output = CTxOut(nValue=4_000_000, scriptPubKey=remain_output_script)
spending_tx.vout = [output, remain_output]
# Create sighash for ALL
sighashA = TaprootSignatureHash(spending_tx,
                                [tx.vout[0]],
                                SIGHASH_ALL_TAPROOT,
                                input_index=0,
                                scriptpath=True,
                                script=tapleafA.script)
signatureA = privkey_alice.sign_schnorr(sighashA)
# print("Signature for TapLeafA: {}\n".format(signatureA.hex()))
# Add witness to transaction
# Tip: Witness stack for script path - [satisfying elements for tapscript] [TapLeaf.script] [controlblock]
# Tip: Controlblock for a tapscript in control_map[TapLeaf.script]
witness_elements = [signatureA, tapleafA.script, control_map[tapleafA.script]]
spending_tx.wit.vtxinwit.append(CTxInWitness(witness_elements))
assert node.test_transaction(spending_tx)
spending_tx_hex = spending_tx.serialize().hex()
print("\n", "send others from segwit address, spending_tx hex: ", spending_tx_hex, "\n")
# print("\ndecode spending_tx raw transaction:")
# pprint(node.decoderawtransaction(str(spending_tx_hex)))
test.shutdown()
AAweidai commented 2 years ago

Hot to Cold. Cost by script path.

import util
from test_framework.address import program_to_witness, key_to_p2wpkh
from test_framework.key import ECKey
from test_framework.messages import CTxInWitness, COutPoint, CTransaction, CTxIn, CTxOut
from test_framework.script import TapTree, TapLeaf, TaprootSignatureHash, SIGHASH_ALL_TAPROOT, Tapbranch
from test_framework.musig import generate_musig_key
from pprint import pprint

def generate_bip340_key_pair(secret=None):
    """Convenience function to generate a BIP0340 private-public key pair."""
    if secret is None:
        d = ECKey()
        d.generate()
    else:
        d = ECKey().set(secret)
    P = d.get_pubkey()
    if P.get_y() % 2 != 0:
        d.negate()
        P.negate()
    return d, P

# generate alice bob charlie key
privkey_alice, pubkey_alice = generate_bip340_key_pair(
    secret=103910053441657220738925612114654039920823302334302261834756476233133311987138)
privkey_bob, pubkey_bob = generate_bip340_key_pair(
    secret=75573449985348711764142460376289265944117193680909672902170333608986796225238)
privkey_charlie, pubkey_charlie = generate_bip340_key_pair(
    secret=33705509085456474265534912245246680268484766969648186791871278745425848684352)

segwit_version = 1
pubkey_charlie_bytes = pubkey_charlie.get_bytes()
segwit_address_charlie = program_to_witness(segwit_version, pubkey_charlie_bytes)
segwit_address_script_pubkey_charlie = "5120" + pubkey_charlie_bytes.hex()
print("charlie Script pubkey: ", segwit_address_script_pubkey_charlie)
print("charlie Regtest address format: ", segwit_address_charlie)
print("charlie Mainnet address format: ", program_to_witness(segwit_version, pubkey_charlie_bytes, main=True), "\n")

# Start node
test = util.TestWrapper()
test.setup()
node = test.nodes[0]
tx = node.generate_and_send_coins(segwit_address_charlie)
tx_hex = tx.serialize().hex()
print("init tx: ", tx_hex, "\n")

c_map, pubkey_agg = generate_musig_key([pubkey_alice, pubkey_bob, pubkey_charlie])
if pubkey_agg.get_y() % 2 != 0:
    pubkey_agg.negate()
# Construct tapleaves
tapleafA = TapLeaf().construct_pk(pubkey_alice)
tapleafB = TapLeaf().construct_pk(pubkey_bob)
tapleafC = TapLeaf().construct_pk(pubkey_charlie)
# Construct taptree nodes.
tapbranchAB = Tapbranch(tapleafA, tapleafB)
tapbranchABC = Tapbranch(tapbranchAB, tapleafC)
# Construct the taptree.
taptree = TapTree(key=pubkey_agg, root=tapbranchABC)
segwit_v1_script, taptweak, control_map = taptree.construct()
# generate Taproot pubkey
taptweak_pubkey = pubkey_agg.tweak_add(taptweak)
# generate segwit address
taptweak_pubkey_b = taptweak_pubkey.get_bytes()
segwit_version = 1
segwit_address = program_to_witness(segwit_version, taptweak_pubkey_b)
segwit_address_script_pubkey = "5120" + taptweak_pubkey_b.hex()
print("Agg Script pubkey: ", segwit_address_script_pubkey)
print("Agg Regtest address format: ", segwit_address)
print("Agg Mainnet address format: ", program_to_witness(segwit_version, taptweak_pubkey_b, main=True), "\n")

spending_tx = test.create_spending_transaction(tx.hash, version=2)
output_script = bytes.fromhex(segwit_address_script_pubkey)
output_amount_sat = 10_000_000  # remove transaction fee from output amount
output = CTxOut(nValue=output_amount_sat, scriptPubKey=output_script)
remain_output_script = bytes.fromhex(segwit_address_script_pubkey_charlie)
remain_output = CTxOut(nValue=80_000_000, scriptPubKey=remain_output_script)
spending_tx.vout = [output, remain_output]
# Create sighash for ALL
sighashA = TaprootSignatureHash(spending_tx,
                                [tx.vout[0]],
                                SIGHASH_ALL_TAPROOT,
                                input_index=0)
signatureA = privkey_charlie.sign_schnorr(sighashA)
spending_tx.wit.vtxinwit.append(CTxInWitness([signatureA]))
print("send btc to segwit address(hot address), tx hex:", spending_tx.serialize().hex(), "\n")
assert node.test_transaction(spending_tx)
node.sendrawtransaction(spending_tx.serialize().hex(), 0)

# tx decode
tx = spending_tx
decode = node.decoderawtransaction(str(tx.serialize().hex()))
# print("\ndecode tx raw transaction:")
# pprint(decode)
# legacy p2sh address, mainnet
cold_addr = "3FLBhPfEqmw4Wn5EQMeUzPLrQtJMprgwnw"
cold_addr_script_pubkey = "a91495a12f1eba77d085711e9c837d04e4d8868a834387"
spending_tx = test.create_spending_transaction(decode['txid'], version=2)
output_script = bytes.fromhex(cold_addr_script_pubkey)
output_amount_sat = 5_000_000  # remove transaction fee from output amount
output = CTxOut(nValue=output_amount_sat, scriptPubKey=output_script)
remain_output_script = bytes.fromhex(segwit_address_script_pubkey)
remain_output = CTxOut(nValue=4_000_000, scriptPubKey=remain_output_script)
spending_tx.vout = [output, remain_output]
# Create sighash for ALL
sighashA = TaprootSignatureHash(spending_tx,
                                [tx.vout[0]],
                                SIGHASH_ALL_TAPROOT,
                                input_index=0,
                                scriptpath=True,
                                script=tapleafA.script)
signatureA = privkey_alice.sign_schnorr(sighashA)
# print("Signature for TapLeafA: {}\n".format(signatureA.hex()))
# Add witness to transaction
# Tip: Witness stack for script path - [satisfying elements for tapscript] [TapLeaf.script] [controlblock]
# Tip: Controlblock for a tapscript in control_map[TapLeaf.script]
witness_elements = [signatureA, tapleafA.script, control_map[tapleafA.script]]
spending_tx.wit.vtxinwit.append(CTxInWitness(witness_elements))
assert node.test_transaction(spending_tx)
spending_tx_hex = spending_tx.serialize().hex()
print("\n", "send cold address from segwit address, spending_tx hex: ", spending_tx_hex, "\n")
# print("\ndecode spending_tx raw transaction:")
# pprint(node.decoderawtransaction(str(spending_tx_hex)))
test.shutdown()
AAweidai commented 2 years ago

Cost by key path.

import util
from test_framework.address import program_to_witness, key_to_p2wpkh
from test_framework.key import ECKey
from test_framework.messages import CTxInWitness, COutPoint, CTransaction, CTxIn, CTxOut
from test_framework.script import TapTree, TapLeaf, TaprootSignatureHash, SIGHASH_ALL_TAPROOT, Tapbranch
from test_framework.musig import generate_musig_key
from pprint import pprint

def generate_bip340_key_pair(secret=None):
    """Convenience function to generate a BIP0340 private-public key pair."""
    if secret is None:
        d = ECKey()
        d.generate()
    else:
        d = ECKey().set(secret)
    P = d.get_pubkey()
    if P.get_y() % 2 != 0:
        d.negate()
        P.negate()
    return d, P

# generate alice bob charlie key
privkey_alice, pubkey_alice = generate_bip340_key_pair(
    secret=103910053441657220738925612114654039920823302334302261834756476233133311987138)
privkey_bob, pubkey_bob = generate_bip340_key_pair(
    secret=75573449985348711764142460376289265944117193680909672902170333608986796225238)
privkey_charlie, pubkey_charlie = generate_bip340_key_pair(
    secret=33705509085456474265534912245246680268484766969648186791871278745425848684352)

segwit_version = 1
pubkey_charlie_bytes = pubkey_charlie.get_bytes()
segwit_address_charlie = program_to_witness(segwit_version, pubkey_charlie_bytes)
segwit_address_script_pubkey_charlie = "5120" + pubkey_charlie_bytes.hex()
print("charlie Script pubkey: ", segwit_address_script_pubkey_charlie)
print("charlie Regtest address format: ", segwit_address_charlie)
print("charlie Mainnet address format: ", program_to_witness(segwit_version, pubkey_charlie_bytes, main=True), "\n")

# Start node
test = util.TestWrapper()
test.setup()
node = test.nodes[0]
tx = node.generate_and_send_coins(segwit_address_charlie)
tx_hex = tx.serialize().hex()
print("init tx: ", tx_hex, "\n")

c_map, pubkey_agg = generate_musig_key([pubkey_alice, pubkey_bob, pubkey_charlie])
privkey_alice_c = privkey_alice * c_map[pubkey_alice]
privkey_bob_c = privkey_bob * c_map[pubkey_bob]
privkey_charlie_c = privkey_charlie * c_map[pubkey_charlie]

if pubkey_agg.get_y() % 2 != 0:
    pubkey_agg.negate()
    privkey_alice_c.negate()
    privkey_bob_c.negate()
    privkey_charlie_c.negate()

# Construct tapleaves
tapleafA = TapLeaf().construct_pk(pubkey_alice)
tapleafB = TapLeaf().construct_pk(pubkey_bob)
tapleafC = TapLeaf().construct_pk(pubkey_charlie)
# Construct taptree nodes.
tapbranchAB = Tapbranch(tapleafA, tapleafB)
tapbranchABC = Tapbranch(tapbranchAB, tapleafC)
# Construct the taptree.
taptree = TapTree(key=pubkey_agg, root=tapbranchABC)
segwit_v1_script, taptweak, control_map = taptree.construct()
# generate Taproot pubkey
tweaked_privkey = privkey_alice_c.add(privkey_bob_c.get_bytes()).add(privkey_charlie_c.get_bytes()).add(
    taptweak)
taptweak_pubkey = pubkey_agg.tweak_add(taptweak)
if taptweak_pubkey.get_y() % 2 != 0:
    taptweak_pubkey.negate()
    tweaked_privkey.negate()

# generate segwit address
taptweak_pubkey_b = taptweak_pubkey.get_bytes()
segwit_version = 1
segwit_address = program_to_witness(segwit_version, taptweak_pubkey_b)
segwit_address_script_pubkey = "5120" + taptweak_pubkey_b.hex()
print("Agg Script pubkey: ", segwit_address_script_pubkey)
print("Agg Regtest address format: ", segwit_address)
print("Agg Mainnet address format: ", program_to_witness(segwit_version, taptweak_pubkey_b, main=True), "\n")

spending_tx = test.create_spending_transaction(tx.hash, version=2)
output_script = bytes.fromhex(segwit_address_script_pubkey)
output_amount_sat = 10_000_000  # remove transaction fee from output amount
output = CTxOut(nValue=output_amount_sat, scriptPubKey=output_script)
remain_output_script = bytes.fromhex(segwit_address_script_pubkey_charlie)
remain_output = CTxOut(nValue=80_000_000, scriptPubKey=remain_output_script)
spending_tx.vout = [output, remain_output]
# Create sighash for ALL
sighashA = TaprootSignatureHash(spending_tx,
                                [tx.vout[0]],
                                SIGHASH_ALL_TAPROOT,
                                input_index=0)
signatureA = privkey_charlie.sign_schnorr(sighashA)
spending_tx.wit.vtxinwit.append(CTxInWitness([signatureA]))
print("send btc to segwit address, tx hex:", spending_tx.serialize().hex(), "\n")
assert node.test_transaction(spending_tx)
node.sendrawtransaction(spending_tx.serialize().hex(), 0)

# tx decode
tx = spending_tx
decode = node.decoderawtransaction(str(tx.serialize().hex()))
# print("\ndecode tx raw transaction:")
# pprint(decode)
spending_tx = test.create_spending_transaction(decode['txid'], version=2)
output_script = bytes.fromhex(segwit_address_script_pubkey_charlie)
output_amount_sat = 5_000_000  # remove transaction fee from output amount
output = CTxOut(nValue=output_amount_sat, scriptPubKey=output_script)
remain_output_script = bytes.fromhex(segwit_address_script_pubkey)
remain_output = CTxOut(nValue=4_000_000, scriptPubKey=remain_output_script)
spending_tx.vout = [output, remain_output]
# Create sighash for ALL
sighashA = TaprootSignatureHash(spending_tx,
                                [tx.vout[0]],
                                SIGHASH_ALL_TAPROOT,
                                input_index=0)
signatureA = tweaked_privkey.sign_schnorr(sighashA)

assert taptweak_pubkey.verify_schnorr(signatureA, sighashA)
spending_tx.wit.vtxinwit.append(CTxInWitness([signatureA]))
spending_tx_hex = spending_tx.serialize().hex()
print("\n", "send others from segwit address, spending_tx hex: ", spending_tx_hex, "\n")
assert node.test_transaction(spending_tx)
# print("\ndecode spending_tx raw transaction:")
# pprint(node.decoderawtransaction(str(spending_tx_hex)))
test.shutdown()