def getnewdestination(address_type='bech32m'): """Generate a random destination of the specified type and return the corresponding public key, scriptPubKey and address. Supported types are 'legacy', 'p2sh-segwit', 'bech32' and 'bech32m'. Can be used when a random destination is needed, but no compiled wallet is available (e.g. as replacement to the getnewaddress/getaddressinfo RPCs).""" key = ECKey() key.generate() pubkey = key.get_pubkey().get_bytes() if address_type == 'legacy': scriptpubkey = key_to_p2pkh_script(pubkey) address = key_to_p2pkh(pubkey) elif address_type == 'p2sh-segwit': scriptpubkey = key_to_p2sh_p2wpkh_script(pubkey) address = key_to_p2sh_p2wpkh(pubkey) elif address_type == 'bech32': scriptpubkey = key_to_p2wpkh_script(pubkey) address = key_to_p2wpkh(pubkey) elif address_type == 'bech32m': tap = taproot_construct(compute_xonly_pubkey(key.get_bytes())[0]) pubkey = tap.output_pubkey scriptpubkey = tap.scriptPubKey address = output_key_to_p2tr(pubkey) else: assert False return pubkey, scriptpubkey, address
def print_p2tr(tprv, path, start=0, end=2): root = tbtc.parse(tprv) for i in range(start, 1 + end): npath = path + f"/{i}" node = root.subkey_for_path(npath) pk = node.sec() p2tr = taproot_construct(pk[1:]) words = [1] + convertbits((list(p2tr.output_pubkey)), 8, 5) addr = bech32_encode(Encoding.BECH32M, 'tb', words) print(npath, addr)
def create_taproot_utxo(self, scripts=None, blind=False): # modify the transaction to add one output that should spend previous taproot # Create a taproot prevout addr = self.nodes[0].getnewaddress() sec = generate_privkey() pub = compute_xonly_pubkey(sec)[0] tap = taproot_construct(pub, scripts) spk = tap.scriptPubKey # No need to test blinding in this unit test unconf_addr = self.nodes[0].getaddressinfo(addr)['unconfidential'] raw_tx = self.nodes[0].createrawtransaction([], [{unconf_addr: 1.2}]) # edit spk directly, no way to get new address. # would need to implement bech32m in python tx = FromHex(CTransaction(), raw_tx) tx.vout[0].scriptPubKey = spk tx.vout[0].nValue = CTxOutValue(12 * 10**7) raw_hex = tx.serialize().hex() fund_tx = self.nodes[0].fundrawtransaction( raw_hex, False, )["hex"] fund_tx = FromHex(CTransaction(), fund_tx) # Createrawtransaction might rearrage txouts prev_vout = None for i, out in enumerate(fund_tx.vout): if spk == out.scriptPubKey: prev_vout = i tx = self.nodes[0].blindrawtransaction(fund_tx.serialize().hex()) signed_raw_tx = self.nodes[0].signrawtransactionwithwallet(tx) _txid = self.nodes[0].sendrawtransaction(signed_raw_tx['hex']) tx = FromHex(CTransaction(), signed_raw_tx['hex']) tx.rehash() self.nodes[0].generate(1) last_blk = self.nodes[0].getblock(self.nodes[0].getbestblockhash()) assert (tx.hash in last_blk['tx']) return tx, prev_vout, spk, sec, pub, tap
def compute_taproot_address(pubkey, scripts): """Compute the address for a taproot output with given inner key and scripts.""" tap = taproot_construct(pubkey, scripts) assert tap.scriptPubKey[0] == OP_1 assert tap.scriptPubKey[1] == 0x20 return encode_segwit_address("bcrt", 1, tap.scriptPubKey[2:])
def compute_taproot_address(pubkey, scripts): """Compute the address for a taproot output with given inner key and scripts.""" return output_key_to_p2tr(taproot_construct(pubkey, scripts).output_pubkey)