resp = AddressUtil.p2wpkh(req['keyData']['hex'], network=_network) elif _hash_type == HashType.P2SH_P2WPKH: resp = AddressUtil.p2sh_p2wpkh(req['keyData']['hex'], network=_network) elif _hash_type == HashType.P2SH: resp = AddressUtil.p2sh(req['keyData']['hex'], network=_network) elif _hash_type == HashType.P2WSH: resp = AddressUtil.p2wsh(req['keyData']['hex'], network=_network) elif _hash_type == HashType.P2SH_P2WSH: resp = AddressUtil.p2sh_p2wsh(req['keyData']['hex'], network=_network) elif _hash_type == HashType.TAPROOT: resp = AddressUtil.taproot(req['keyData']['hex'], network=_network) elif name == 'Address.GetInfo': resp = AddressUtil.parse(req['address']) elif name == 'Address.MultisigAddresses': resp = AddressUtil.get_multisig_address_list(req['redeemScript'], req['hashType'], network=_network) elif name == 'Address.CreateMultisig': resp = AddressUtil.multisig(req['nrequired'], req['keys'], req['hashType'], network=_network) elif name == 'Address.FromLockingScript': resp = AddressUtil.from_locking_script(req['lockingScript'], network=_network)
def test_taproot_tapscript(test_obj: 'TestBitcoin'): btc_rpc = test_obj.conn.get_rpc() main_addr = test_obj.addr_dic['main'] main_pk, _ = SchnorrPubkey.from_pubkey(str(main_addr.pubkey)) pkh_addr = test_obj.addr_dic['p2pkh'] spk1, _ = SchnorrPubkey.from_pubkey(str(pkh_addr.pubkey)) wpkh_addr = test_obj.addr_dic['p2wpkh'] spk2, _ = SchnorrPubkey.from_pubkey(str(wpkh_addr.pubkey)) main_path = str(test_obj.path_dic[str(main_addr)]) main_sk = test_obj.hdwallet.get_privkey(path=main_path).privkey pkh_path = str(test_obj.path_dic[str(pkh_addr)]) sk1 = test_obj.hdwallet.get_privkey(path=pkh_path).privkey # wpkh_path = str(test_obj.path_dic[str(wpkh_addr)]) # sk2 = test_obj.hdwallet.get_privkey(path=wpkh_path).privkey script1 = Script.from_asm([str(spk1), 'OP_CHECKSIG']) script2 = Script.from_asm([str(spk2), 'OP_CHECKSIG']) op_true_script = Script('51') op_true_sub_tree1 = TaprootScriptTree(op_true_script) op_true_sub_tree1.add_branch(script1) script1_tree = TaprootScriptTree(script1) script1_tree.add_branches([op_true_script, script2]) script1_tree.internal_pubkey = main_pk op_true_tree = TaprootScriptTree(op_true_script) op_true_tree.add_branches([script1, script2]) op_true_tree.internal_pubkey = main_pk script2_tree = TaprootScriptTree(script2) script2_tree.add_branch(op_true_sub_tree1) script2_tree.internal_pubkey = main_pk tr_addr1 = AddressUtil.taproot(script1_tree, network=NETWORK) tr_addr2 = AddressUtil.taproot(op_true_tree, network=NETWORK) tr_addr3 = AddressUtil.taproot(script2_tree, network=NETWORK) txouts = [ TxOut(100000, str(tr_addr1)), TxOut(150000, str(tr_addr2)), TxOut(200000, str(tr_addr3)), ] tx = Transaction.create(2, 0, [], txouts) # fundrawtransaction fee_addr = str(test_obj.addr_dic['fee']) fee_desc = test_obj.desc_dic[fee_addr] fee_sk = test_obj.hdwallet.get_privkey(path=FEE_PATH).privkey utxos = get_utxo(btc_rpc, [fee_addr]) utxo_list = convert_bitcoin_utxos(test_obj, utxos) tx.fund_raw_transaction([], utxo_list, fee_addr, target_amount=0, effective_fee_rate=2.0, knapsack_min_change=0) # add sign for txin in tx.txin_list: utxo = search_utxos(test_obj, utxo_list, txin.outpoint) tx.sign_with_privkey(txin.outpoint, fee_desc.data.hash_type, fee_sk, amount=utxo.amount, sighashtype=SigHashType.ALL) # broadcast print(Transaction.parse_to_json(str(tx), network=NETWORK)) btc_rpc.sendrawtransaction(str(tx)) # generate block btc_rpc.generatetoaddress(2, fee_addr) time.sleep(2) txid = tx.txid utxo1 = UtxoData(txid=txid, vout=0, amount=txouts[0].amount, descriptor=f'raw({str(tr_addr1.locking_script)})') utxo2 = UtxoData(txid=txid, vout=1, amount=txouts[1].amount, descriptor=f'raw({str(tr_addr2.locking_script)})') utxo3 = UtxoData(txid=txid, vout=2, amount=txouts[2].amount, descriptor=f'raw({str(tr_addr3.locking_script)})') # send tapscript script1 txin_list = [] txin_utxo_list = [] txin_list.append(TxIn(txid=txid, vout=0)) txin_utxo_list.append(utxo1) txouts2 = [ TxOut(txouts[0].amount, str(test_obj.addr_dic['main'])), ] tx2 = Transaction.create(2, 0, txin_list, txouts2) main_addr = test_obj.addr_dic['main'] utxos = get_utxo(btc_rpc, [fee_addr]) utxo_list = convert_bitcoin_utxos(test_obj, utxos) tx2.fund_raw_transaction(txin_utxo_list, utxo_list, fee_addr, target_amount=0, effective_fee_rate=2.0, knapsack_min_change=0) # add sign join_utxo_list: List['UtxoData'] = [] join_utxo_list[len(join_utxo_list):len(join_utxo_list)] = txin_utxo_list for txin in tx2.txin_list: for utxo in utxo_list: if utxo.outpoint == txin.outpoint: join_utxo_list.append(utxo) for index, txin in enumerate(tx2.txin_list): utxo = search_utxos(test_obj, join_utxo_list, txin.outpoint) if index == 0: sk = sk1 sighash = tx2.get_sighash(txin.outpoint, HashType.TAPROOT, redeem_script=script1, sighashtype=SigHashType.DEFAULT, utxos=join_utxo_list) sig = SchnorrUtil.sign(sighash, sk1) sign_param = SignParameter(sig, sighashtype=SigHashType.DEFAULT) _, _, _, control_block = script1_tree.get_taproot_data() tx2.add_tapscript_sign(txin.outpoint, [sign_param], script1, control_block) else: path = str(test_obj.path_dic[str(utxo.descriptor.data.address)]) sk = test_obj.hdwallet.get_privkey(path=path).privkey hash_type = utxo.descriptor.data.hash_type tx2.sign_with_privkey(txin.outpoint, hash_type, sk, amount=utxo.amount, sighashtype=SigHashType.ALL, utxos=join_utxo_list) # broadcast print(Transaction.parse_to_json(str(tx2), network=NETWORK)) btc_rpc.sendrawtransaction(str(tx2)) # generate block btc_rpc.generatetoaddress(2, fee_addr) time.sleep(2) # send tapscript OP_TRUE txin_list = [] txin_utxo_list = [] txin_list.append(TxIn(txid=txid, vout=1)) txin_utxo_list.append(utxo2) txouts2 = [ TxOut(txouts[1].amount, str(test_obj.addr_dic['main'])), ] tx2 = Transaction.create(2, 0, txin_list, txouts2) main_addr = test_obj.addr_dic['main'] utxos = get_utxo(btc_rpc, [fee_addr]) utxo_list = convert_bitcoin_utxos(test_obj, utxos) tx2.fund_raw_transaction(txin_utxo_list, utxo_list, fee_addr, target_amount=0, effective_fee_rate=2.0, knapsack_min_change=0) # add sign join_utxo_list = [] join_utxo_list[len(join_utxo_list):len(join_utxo_list)] = txin_utxo_list for txin in tx2.txin_list: for utxo in utxo_list: if utxo.outpoint == txin.outpoint: join_utxo_list.append(utxo) for index, txin in enumerate(tx2.txin_list): utxo = search_utxos(test_obj, join_utxo_list, txin.outpoint) if index == 0: _, _, _, control_block = op_true_tree.get_taproot_data() tx2.add_tapscript_sign(txin.outpoint, [], op_true_script, control_block) else: path = str(test_obj.path_dic[str(utxo.descriptor.data.address)]) sk = test_obj.hdwallet.get_privkey(path=path).privkey hash_type = utxo.descriptor.data.hash_type tx2.sign_with_privkey(txin.outpoint, hash_type, sk, amount=utxo.amount, sighashtype=SigHashType.ALL, utxos=join_utxo_list) # broadcast print(Transaction.parse_to_json(str(tx2), network=NETWORK)) btc_rpc.sendrawtransaction(str(tx2)) # generate block btc_rpc.generatetoaddress(2, fee_addr) time.sleep(2) # send tapscript internal_pubkey txin_list = [] txin_utxo_list = [] txin_list.append(TxIn(txid=txid, vout=2)) txin_utxo_list.append(utxo3) txouts2 = [ TxOut(txouts[2].amount, str(test_obj.addr_dic['main'])), ] tx2 = Transaction.create(2, 0, txin_list, txouts2) main_addr = test_obj.addr_dic['main'] utxos = get_utxo(btc_rpc, [fee_addr]) utxo_list = convert_bitcoin_utxos(test_obj, utxos) tx2.fund_raw_transaction(txin_utxo_list, utxo_list, fee_addr, target_amount=0, effective_fee_rate=2.0, knapsack_min_change=0) # add sign join_utxo_list = [] join_utxo_list[len(join_utxo_list):len(join_utxo_list)] = txin_utxo_list for txin in tx2.txin_list: for utxo in utxo_list: if utxo.outpoint == txin.outpoint: join_utxo_list.append(utxo) for index, txin in enumerate(tx2.txin_list): utxo = search_utxos(test_obj, join_utxo_list, txin.outpoint) if index == 0: sk = script2_tree.get_privkey(main_sk) hash_type = tr_addr3.hash_type else: path = str(test_obj.path_dic[str(utxo.descriptor.data.address)]) sk = test_obj.hdwallet.get_privkey(path=path).privkey hash_type = utxo.descriptor.data.hash_type tx2.sign_with_privkey(txin.outpoint, hash_type, sk, amount=utxo.amount, sighashtype=SigHashType.ALL, utxos=join_utxo_list) # broadcast print(Transaction.parse_to_json(str(tx2), network=NETWORK)) btc_rpc.sendrawtransaction(str(tx2)) # generate block btc_rpc.generatetoaddress(2, fee_addr) time.sleep(2) utxos = get_utxo(btc_rpc, [str(main_addr)]) print('UTXO: {}'.format(utxos))
def test_taproot_single_key(test_obj: 'TestBitcoin'): btc_rpc = test_obj.conn.get_rpc() main_addr = test_obj.addr_dic['main'] main_pk, _ = SchnorrPubkey.from_pubkey(str(main_addr.pubkey)) pkh_addr = test_obj.addr_dic['p2pkh'] spk1, _ = SchnorrPubkey.from_pubkey(str(pkh_addr.pubkey)) wpkh_addr = test_obj.addr_dic['p2wpkh'] spk2, _ = SchnorrPubkey.from_pubkey(str(wpkh_addr.pubkey)) main_path = str(test_obj.path_dic[str(main_addr)]) main_sk = test_obj.hdwallet.get_privkey(path=main_path).privkey pkh_path = str(test_obj.path_dic[str(pkh_addr)]) sk1 = test_obj.hdwallet.get_privkey(path=pkh_path).privkey wpkh_path = str(test_obj.path_dic[str(wpkh_addr)]) sk2 = test_obj.hdwallet.get_privkey(path=wpkh_path).privkey branch = TapBranch() tr_addr1 = AddressUtil.taproot(main_pk, script_tree=branch, network=NETWORK) tr_sk1 = branch.get_privkey(main_sk) tr_addr2 = AddressUtil.taproot(spk1, script_tree=branch, network=NETWORK) tr_sk2 = branch.get_privkey(sk1) tr_addr3 = AddressUtil.taproot(spk2, script_tree=branch, network=NETWORK) tr_sk3 = branch.get_privkey(sk2) txouts = [ TxOut(100000, str(tr_addr1)), TxOut(150000, str(tr_addr2)), TxOut(200000, str(tr_addr3)), ] tx = Transaction.create(2, 0, [], txouts) # fundrawtransaction fee_addr = str(test_obj.addr_dic['fee']) fee_desc = test_obj.desc_dic[fee_addr] fee_sk = test_obj.hdwallet.get_privkey(path=FEE_PATH).privkey utxos = get_utxo(btc_rpc, [fee_addr]) utxo_list = convert_bitcoin_utxos(test_obj, utxos) tx.fund_raw_transaction([], utxo_list, fee_addr, target_amount=0, effective_fee_rate=2.0, knapsack_min_change=0) # add sign for txin in tx.txin_list: utxo = search_utxos(test_obj, utxo_list, txin.outpoint) tx.sign_with_privkey(txin.outpoint, fee_desc.data.hash_type, fee_sk, amount=utxo.amount, sighashtype=SigHashType.ALL) # broadcast print(Transaction.parse_to_json(str(tx), network=NETWORK)) btc_rpc.sendrawtransaction(str(tx)) # generate block btc_rpc.generatetoaddress(2, fee_addr) time.sleep(2) txid = tx.txid utxo1 = UtxoData(txid=txid, vout=0, amount=txouts[0].amount, descriptor=f'raw({str(tr_addr1.locking_script)})') utxo2 = UtxoData(txid=txid, vout=1, amount=txouts[1].amount, descriptor=f'raw({str(tr_addr2.locking_script)})') utxo3 = UtxoData(txid=txid, vout=2, amount=txouts[2].amount, descriptor=f'raw({str(tr_addr3.locking_script)})') # send taproot singleKey1 txin_list = [] txin_utxo_list = [] txin_list.append(TxIn(txid=txid, vout=0)) txin_utxo_list.append(utxo1) txouts2 = [ TxOut(txouts[0].amount, str(test_obj.addr_dic['main'])), ] tx2 = Transaction.create(2, 0, txin_list, txouts2) main_addr = test_obj.addr_dic['main'] utxos = get_utxo(btc_rpc, [fee_addr]) utxo_list = convert_bitcoin_utxos(test_obj, utxos) tx2.fund_raw_transaction(txin_utxo_list, utxo_list, fee_addr, target_amount=0, effective_fee_rate=2.0, knapsack_min_change=0) # add sign join_utxo_list: List['UtxoData'] = [] join_utxo_list[len(join_utxo_list):len(join_utxo_list)] = txin_utxo_list for txin in tx2.txin_list: for utxo in utxo_list: if utxo.outpoint == txin.outpoint: join_utxo_list.append(utxo) for index, txin in enumerate(tx2.txin_list): utxo = search_utxos(test_obj, join_utxo_list, txin.outpoint) if index == 0: sighash = tx2.get_sighash(txin.outpoint, HashType.TAPROOT, pubkey=tr_addr1.pubkey, sighashtype=SigHashType.DEFAULT, utxos=join_utxo_list) sig = SchnorrUtil.sign(sighash, tr_sk1) sign_param = SignParameter(sig, sighashtype=SigHashType.DEFAULT) tx2.add_taproot_sign(txin.outpoint, sign_param) else: path = str(test_obj.path_dic[str(utxo.descriptor.data.address)]) sk = test_obj.hdwallet.get_privkey(path=path).privkey hash_type = utxo.descriptor.data.hash_type tx2.sign_with_privkey(txin.outpoint, hash_type, sk, amount=utxo.amount, sighashtype=SigHashType.ALL, utxos=join_utxo_list) # broadcast print(Transaction.parse_to_json(str(tx2), network=NETWORK)) btc_rpc.sendrawtransaction(str(tx2)) # generate block btc_rpc.generatetoaddress(2, fee_addr) time.sleep(2) # send taproot singleKey2 txin_list = [] txin_utxo_list = [] txin_list.append(TxIn(txid=txid, vout=1)) txin_utxo_list.append(utxo2) txouts2 = [ TxOut(txouts[1].amount, str(test_obj.addr_dic['main'])), ] tx2 = Transaction.create(2, 0, txin_list, txouts2) main_addr = test_obj.addr_dic['main'] utxos = get_utxo(btc_rpc, [fee_addr]) utxo_list = convert_bitcoin_utxos(test_obj, utxos) tx2.fund_raw_transaction(txin_utxo_list, utxo_list, fee_addr, target_amount=0, effective_fee_rate=2.0, knapsack_min_change=0) # add sign join_utxo_list = [] join_utxo_list[len(join_utxo_list):len(join_utxo_list)] = txin_utxo_list for txin in tx2.txin_list: for utxo in utxo_list: if utxo.outpoint == txin.outpoint: join_utxo_list.append(utxo) for index, txin in enumerate(tx2.txin_list): utxo = search_utxos(test_obj, join_utxo_list, txin.outpoint) if index == 0: sighash = tx2.get_sighash(txin.outpoint, HashType.TAPROOT, pubkey=tr_addr2.pubkey, sighashtype=SigHashType.DEFAULT, utxos=join_utxo_list) sig = SchnorrUtil.sign(sighash, tr_sk2) sign_param = SignParameter(sig, sighashtype=SigHashType.DEFAULT) tx2.add_taproot_sign(txin.outpoint, sign_param) else: path = str(test_obj.path_dic[str(utxo.descriptor.data.address)]) sk = test_obj.hdwallet.get_privkey(path=path).privkey hash_type = utxo.descriptor.data.hash_type tx2.sign_with_privkey(txin.outpoint, hash_type, sk, amount=utxo.amount, sighashtype=SigHashType.ALL, utxos=join_utxo_list) # broadcast print(Transaction.parse_to_json(str(tx2), network=NETWORK)) btc_rpc.sendrawtransaction(str(tx2)) # generate block btc_rpc.generatetoaddress(2, fee_addr) time.sleep(2) # send taproot singleKey3 txin_list = [] txin_utxo_list = [] txin_list.append(TxIn(txid=txid, vout=2)) txin_utxo_list.append(utxo3) txouts2 = [ TxOut(txouts[2].amount, str(test_obj.addr_dic['main'])), ] tx2 = Transaction.create(2, 0, txin_list, txouts2) main_addr = test_obj.addr_dic['main'] utxos = get_utxo(btc_rpc, [fee_addr]) utxo_list = convert_bitcoin_utxos(test_obj, utxos) tx2.fund_raw_transaction(txin_utxo_list, utxo_list, fee_addr, target_amount=0, effective_fee_rate=2.0, knapsack_min_change=0) # add sign join_utxo_list = [] join_utxo_list[len(join_utxo_list):len(join_utxo_list)] = txin_utxo_list for txin in tx2.txin_list: for utxo in utxo_list: if utxo.outpoint == txin.outpoint: join_utxo_list.append(utxo) for index, txin in enumerate(tx2.txin_list): utxo = search_utxos(test_obj, join_utxo_list, txin.outpoint) if index == 0: sighash = tx2.get_sighash(txin.outpoint, HashType.TAPROOT, pubkey=tr_addr3.pubkey, sighashtype=SigHashType.DEFAULT, utxos=join_utxo_list) sig = SchnorrUtil.sign(sighash, tr_sk3) sign_param = SignParameter(sig, sighashtype=SigHashType.DEFAULT) tx2.add_taproot_sign(txin.outpoint, sign_param) else: path = str(test_obj.path_dic[str(utxo.descriptor.data.address)]) sk = test_obj.hdwallet.get_privkey(path=path).privkey hash_type = utxo.descriptor.data.hash_type tx2.sign_with_privkey(txin.outpoint, hash_type, sk, amount=utxo.amount, sighashtype=SigHashType.ALL, utxos=join_utxo_list) # broadcast print(Transaction.parse_to_json(str(tx2), network=NETWORK)) btc_rpc.sendrawtransaction(str(tx2)) # generate block btc_rpc.generatetoaddress(2, fee_addr) time.sleep(2) utxos = get_utxo(btc_rpc, [str(main_addr)]) print('UTXO: {}'.format(utxos))
def test_taproot_schnorr(test_obj: 'TestBitcoin'): btc_rpc = test_obj.conn.get_rpc() main_addr = test_obj.addr_dic['main'] main_pk, _ = SchnorrPubkey.from_pubkey(str(main_addr.pubkey)) tr_addr = AddressUtil.taproot(main_pk, network=NETWORK) main_path = str(test_obj.path_dic[str(main_addr)]) main_sk = test_obj.hdwallet.get_privkey(path=main_path).privkey txouts = [ TxOut(100000000, str(tr_addr)), ] tx = Transaction.create(2, 0, [], txouts) # fundrawtransaction fee_addr = str(test_obj.addr_dic['fee']) fee_desc = test_obj.desc_dic[fee_addr] fee_sk = test_obj.hdwallet.get_privkey(path=FEE_PATH).privkey utxos = get_utxo(btc_rpc, [fee_addr]) utxo_list = convert_bitcoin_utxos(test_obj, utxos) tx.fund_raw_transaction([], utxo_list, fee_addr, target_amount=0, effective_fee_rate=2.0, knapsack_min_change=0) # add sign for txin in tx.txin_list: utxo = search_utxos(test_obj, utxo_list, txin.outpoint) tx.sign_with_privkey(txin.outpoint, fee_desc.data.hash_type, fee_sk, amount=utxo.amount, sighashtype=SigHashType.ALL) # broadcast print(Transaction.parse_to_json(str(tx), network=NETWORK)) btc_rpc.sendrawtransaction(str(tx)) # generate block btc_rpc.generatetoaddress(2, fee_addr) time.sleep(2) # create tx (output wpkh only, input tx1-3) txid = tx.txid txin_list = [] txin_utxo_list = [] txin_list.append(TxIn(txid=txid, vout=0)) desc = f'raw({str(tr_addr.locking_script)})' txin_utxo_list.append( UtxoData(txid=txid, vout=0, amount=txouts[0].amount, descriptor=desc)) txouts2 = [ TxOut(100000000, str(test_obj.addr_dic['main'])), ] tx2 = Transaction.create(2, 0, txin_list, txouts2) main_addr = test_obj.addr_dic['main'] utxos = get_utxo(btc_rpc, [fee_addr]) utxo_list = convert_bitcoin_utxos(test_obj, utxos) tx2.fund_raw_transaction(txin_utxo_list, utxo_list, fee_addr, target_amount=0, effective_fee_rate=20.0, knapsack_min_change=1) # add sign join_utxo_list: List['UtxoData'] = [] join_utxo_list[len(join_utxo_list):len(join_utxo_list)] = txin_utxo_list for txin in tx2.txin_list: for utxo in utxo_list: if utxo.outpoint == txin.outpoint: join_utxo_list.append(utxo) for index, txin in enumerate(tx2.txin_list): utxo = search_utxos(test_obj, join_utxo_list, txin.outpoint) if index == 0: sk = main_sk hash_type = main_addr.hash_type else: path = str(test_obj.path_dic[str(utxo.descriptor.data.address)]) sk = test_obj.hdwallet.get_privkey(path=path).privkey hash_type = utxo.descriptor.data.hash_type tx2.sign_with_privkey(txin.outpoint, hash_type, sk, amount=utxo.amount, sighashtype=SigHashType.ALL, utxos=join_utxo_list) # broadcast print(Transaction.parse_to_json(str(tx2), network=NETWORK)) btc_rpc.sendrawtransaction(str(tx2)) # generate block btc_rpc.generatetoaddress(2, fee_addr) time.sleep(2) utxos = get_utxo(btc_rpc, [str(main_addr)]) print('UTXO: {}'.format(utxos))