Example #1
0
def test_bitcoin_multisig(test_obj):
    btc_rpc = test_obj.conn.get_rpc()
    # create tx (output multisig)
    txouts = [
        TxOut(100000000, str(test_obj.addr_dic['p2sh'])),
        TxOut(100000000, str(test_obj.addr_dic['p2wsh'])),
        TxOut(100000000, str(test_obj.addr_dic['p2sh-p2wsh'])),
    ]
    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=20.0,
                            knapsack_min_change=1)
    # 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 multisig tx1-3)
    txid = tx.txid
    txin_list = []
    txin_utxo_list = []
    for index, txout in enumerate(tx.txout_list):
        temp_addr = str(txout.get_address(network=NETWORK))
        if temp_addr == fee_addr:
            continue
        txin_list.append(TxIn(txid=txid, vout=index))
        if temp_addr not in test_obj.desc_dic:
            test_obj.assertTrue(
                False, 'addr not found. [{}]:[{}]'.format(index, temp_addr))
        desc = test_obj.desc_dic[temp_addr]
        txin_utxo_list.append(
            UtxoData(txid=txid,
                     vout=index,
                     amount=txout.amount,
                     descriptor=desc))
    txouts2 = [
        TxOut(300000000, 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

    def multisig_sign(tx_obj, utxo, path_list):
        sighash = tx_obj.get_sighash(
            outpoint=utxo.outpoint,
            hash_type=utxo.descriptor.data.hash_type,
            amount=utxo.amount,
            redeem_script=utxo.descriptor.data.redeem_script)
        signature_list = []
        for path in path_list:
            sk = test_obj.hdwallet.get_privkey(path=path).privkey
            sig = sk.calculate_ec_signature(sighash)
            sig.related_pubkey = sk.pubkey
            signature_list.append(sig)
            if len(signature_list) == 2:
                break
        tx_obj.add_multisig_sign(utxo.outpoint, utxo.descriptor.data.hash_type,
                                 utxo.descriptor.data.redeem_script,
                                 signature_list)

    join_utxo_list = []
    join_utxo_list[len(join_utxo_list):len(join_utxo_list)] = utxo_list
    join_utxo_list[len(join_utxo_list):len(join_utxo_list)] = txin_utxo_list
    for index, txin in enumerate(tx2.txin_list):
        utxo = search_utxos(test_obj, join_utxo_list, txin.outpoint)
        if not utxo.descriptor.data.redeem_script:
            path = test_obj.path_dic[str(utxo.descriptor.data.address)]
            sk = test_obj.hdwallet.get_privkey(path=path).privkey
            tx2.sign_with_privkey(txin.outpoint,
                                  utxo.descriptor.data.hash_type,
                                  sk,
                                  amount=utxo.amount,
                                  sighashtype=SigHashType.ALL)
        else:
            path_list = test_obj.path_dic[str(utxo.descriptor.data.address)]
            multisig_sign(tx2, utxo, path_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_create_raw_transaction(self):
        privkey = ExtPrivkey(
            'xprv9zt1onyw8BdEf7SQ6wUVH3bQQdGD9iy9QzXveQQRhX7i5iUN7jZgLbqFEe491LfjozztYa6bJAGZ65GmDCNcbjMdjZcgmdisPJwVjcfcDhV'
        )  # noqa: E501
        addr1 = AddressUtil.p2wpkh(
            privkey.derive_pubkey(number=1).pubkey, Network.REGTEST)
        addr2 = AddressUtil.p2wpkh(
            privkey.derive_pubkey(number=2).pubkey, Network.REGTEST)
        addr3 = AddressUtil.p2wpkh(
            privkey.derive_pubkey(number=3).pubkey, Network.REGTEST)

        outpoint1 = OutPoint(
            '0000000000000000000000000000000000000000000000000000000000000001',
            2)
        outpoint2 = OutPoint(
            '0000000000000000000000000000000000000000000000000000000000000001',
            3)
        txin1 = TxIn(outpoint=outpoint1)
        txout1 = TxOut(amount=10000, locking_script=addr1.locking_script)
        txout2 = TxOut(amount=10000, address=addr2)
        self.assertEqual(str(outpoint1), str(txin1))
        self.assertEqual(str(addr1.locking_script), str(txout1))
        self.assertEqual(str(addr2), str(txout2))
        self.assertEqual(str(addr1), str(txout1.get_address(Network.REGTEST)))

        tx = Transaction.create(version=2,
                                locktime=0,
                                txins=[
                                    txin1,
                                    TxIn(outpoint=outpoint2),
                                ],
                                txouts=[
                                    txout1,
                                    txout2,
                                ])
        tx.add_txout(amount=50000, address=addr3)
        self.assertEqual(
            "020000000201000000000000000000000000000000000000000000000000000000000000000200000000ffffffff01000000000000000000000000000000000000000000000000000000000000000300000000ffffffff0310270000000000001600148b756cbd98f4f55e985f80437a619d47f0732a941027000000000000160014c0a3dd0b7c1b3281be91112e16ce931dbac2a97950c3000000000000160014ad3abd3c325e40e20d89aa054dd980b97494f16c00000000",  # noqa: E501
            tx.hex)

        privkey1 = privkey.derive(number=11).privkey
        pubkey1 = privkey1.pubkey
        sighash_type = SigHashType.ALL
        sighash = tx.get_sighash(outpoint=outpoint1,
                                 hash_type=HashType.P2WPKH,
                                 pubkey=pubkey1,
                                 amount=50000,
                                 sighashtype=sighash_type)
        signature = privkey1.calculate_ec_signature(sighash)
        tx.add_sign(outpoint=outpoint1,
                    hash_type=HashType.P2WPKH,
                    sign_data=signature,
                    clear_stack=True,
                    use_der_encode=True,
                    sighashtype=sighash_type)
        tx.add_sign(outpoint=outpoint1,
                    hash_type=HashType.P2WPKH,
                    sign_data=pubkey1)
        self.assertEqual(
            "0200000000010201000000000000000000000000000000000000000000000000000000000000000200000000ffffffff01000000000000000000000000000000000000000000000000000000000000000300000000ffffffff0310270000000000001600148b756cbd98f4f55e985f80437a619d47f0732a941027000000000000160014c0a3dd0b7c1b3281be91112e16ce931dbac2a97950c3000000000000160014ad3abd3c325e40e20d89aa054dd980b97494f16c02473044022034db802aad655cd9be589075fc8ef325b6ffb8c24e5b27eb87bde8ad38f5fd7a0220364c916c8e8fc0adf714d7148cd1c6dc6f3e67d55471e57233b1870c65ec2727012103782f0ea892d7000e5f0f82b6ff283382a76500137a542bb0a616530094a8f54c0000000000",  # noqa: E501
            tx.hex)
 def test_empty_input(self):
     txout = TxOut(1000)
     self.assertEqual('', str(txout.locking_script))
Example #4
0
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_transaction_func1(obj, name, case, req, exp, error):
    try:
        resp = None
        if 'tx' in req:
            resp = Transaction.from_hex(req['tx'])
        txins, txouts = [], []
        for input in req.get('txins', []):
            txins.append(
                TxIn(txid=input['txid'],
                     vout=input['vout'],
                     sequence=input.get('sequence', TxIn.SEQUENCE_DISABLE)))
        for output in req.get('txouts', []):
            txouts.append(
                TxOut(output['amount'],
                      address=output.get('address', ''),
                      locking_script=output.get('directLockingScript', '')))

        if name == 'Transaction.Create':
            resp = Transaction.create(req['version'], req['locktime'], txins,
                                      txouts)
        elif name == 'Transaction.Add':
            if len(txins) + len(txouts) == 1:
                for input in req.get('txins', []):
                    resp.add_txin(txid=input['txid'],
                                  vout=input['vout'],
                                  sequence=input.get('sequence',
                                                     TxIn.SEQUENCE_DISABLE))
                for output in req.get('txouts', []):
                    resp.add_txout(output['amount'],
                                   address=output.get('address', ''),
Example #6
0
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))
Example #7
0
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))
Example #8
0
def test_psbt(test_obj: 'TestBitcoin'):
    btc_rpc = test_obj.conn.get_rpc()
    fee_addr = str(test_obj.addr_dic['fee'])
    fee_sk = test_obj.hdwallet.get_privkey(path=FEE_PATH).privkey
    main_addr = test_obj.addr_dic['main']
    utxos = get_utxo(btc_rpc, [str(fee_addr)])  # listunspent
    utxo_list = convert_bitcoin_utxos(test_obj, utxos)
    txouts = [
        PsbtAppendOutputData(100000000,
                             address=test_obj.addr_dic['p2pkh'],
                             descriptor=test_obj.desc_dic[str(
                                 test_obj.addr_dic['p2pkh'])]),
        PsbtAppendOutputData(100000000,
                             address=str(test_obj.addr_dic['p2wpkh']),
                             descriptor=test_obj.desc_dic[str(
                                 test_obj.addr_dic['p2wpkh'])]),
        PsbtAppendOutputData(
            100000000,
            address=str(test_obj.addr_dic['p2sh-p2wpkh']),
            descriptor=test_obj.desc_dic[str(
                test_obj.addr_dic['p2sh-p2wpkh'])],
        ),
    ]
    psbt = Psbt.create(tx_version=2, network=NETWORK)
    psbt.add(outputs=txouts)
    psbt.fund(utxo_list=utxo_list,
              reserved_address_descriptor=test_obj.desc_dic[str(fee_addr)],
              effective_fee_rate=2.0,
              long_term_fee_rate=2.0,
              knapsack_min_change=0)
    psbt.sign(fee_sk)
    # bitcoinrpc: finalize extract
    ret = btc_rpc.finalizepsbt(str(psbt), True)
    tx_hex = ret['hex'] if 'hex' in ret else ''
    if not ret.get('complete', True):
        raise AssertionError("finalizepsbt not complete.")
    print(Transaction.parse_to_json(tx_hex, network=NETWORK))
    txid = btc_rpc.sendrawtransaction(tx_hex)
    tx = Transaction(tx_hex)
    # generate block
    btc_rpc.generatetoaddress(2, fee_addr)
    time.sleep(2)
    utxos = get_utxo(btc_rpc, [str(main_addr)])
    print('UTXO: {}'.format(utxos))

    txid = tx.txid
    txin_list = []
    key_list = []
    for index, _ in enumerate(txouts):
        txout = tx.txout_list[index]
        addr = txout.get_address(network=NETWORK)
        desc = test_obj.desc_dic[str(addr)]
        txin_list.append(
            PsbtAppendInputData(outpoint=OutPoint(txid, index),
                                utxo=txout,
                                descriptor=str(desc),
                                utxo_tx=tx_hex))
        path = str(test_obj.path_dic[str(addr)])
        key_list.append(test_obj.hdwallet.get_privkey(path=path).privkey)
    txouts2 = [
        TxOut(300000000, str(test_obj.addr_dic['main'])),
    ]
    tx2 = Transaction.create(2, 0, [], txouts2)
    psbt2 = Psbt.from_transaction(transaction=tx2, network=NETWORK)
    psbt2.set_output_bip32_key(0,
                               pubkey=str(test_obj.desc_dic[str(
                                   txouts2[0].address)]))
    psbt2.add(inputs=txin_list)
    utxos = get_utxo(btc_rpc, [str(fee_addr)])  # listunspent
    utxo_list2 = convert_bitcoin_utxos(test_obj, utxos)
    psbt2.fund(utxo_list=utxo_list2,
               reserved_address_descriptor=test_obj.desc_dic[str(fee_addr)],
               effective_fee_rate=2.0,
               long_term_fee_rate=2.0,
               knapsack_min_change=0)
    psbt21 = Psbt(str(psbt2), network=NETWORK)
    psbt22 = Psbt(str(psbt2), network=NETWORK)
    psbt21.sign(fee_sk)
    for key in key_list:
        psbt22.sign(key)
    # psbt2_str = btc_rpc.combinepsbt([str(psbt21), str(psbt22)])
    # psbt2 = Psbt(psbt2_str, network=NETWORK)
    psbt2 = Psbt.combine_psbts([str(psbt21), psbt22])
    tx2 = psbt2.extract(True)
    print(Transaction.parse_to_json(str(tx2), network=NETWORK))
    txid = 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))
Example #9
0
def test_bitcoin_pkh(test_obj: 'TestBitcoin'):
    btc_rpc = test_obj.conn.get_rpc()
    # create tx (output wpkh, p2sh-segwit, pkh)
    txouts = [
        TxOut(100000000, str(test_obj.addr_dic['p2pkh'])),
        TxOut(100000000, str(test_obj.addr_dic['p2wpkh'])),
        TxOut(100000000, str(test_obj.addr_dic['p2sh-p2wpkh'])),
    ]
    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=20.0,
                            knapsack_min_change=1)
    # 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 = []
    for index, txout in enumerate(tx.txout_list):
        temp_addr = str(txout.get_address(network=NETWORK))
        if temp_addr == fee_addr:
            continue
        txin_list.append(TxIn(txid=txid, vout=index))
        if temp_addr not in test_obj.desc_dic:
            test_obj.assertTrue(
                False, 'addr not found. [{}]:[{}]'.format(index, temp_addr))
        desc = test_obj.desc_dic[temp_addr]
        txin_utxo_list.append(
            UtxoData(txid=txid,
                     vout=index,
                     amount=txout.amount,
                     descriptor=desc))
    txouts2 = [
        TxOut(300000000, 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)] = utxo_list
    join_utxo_list[len(join_utxo_list):len(join_utxo_list)] = txin_utxo_list
    for txin in tx2.txin_list:
        utxo = search_utxos(test_obj, join_utxo_list, txin.outpoint)
        path = str(test_obj.path_dic[str(utxo.descriptor.data.address)])
        sk = test_obj.hdwallet.get_privkey(path=path).privkey
        tx2.sign_with_privkey(txin.outpoint,
                              utxo.descriptor.data.hash_type,
                              sk,
                              amount=utxo.amount,
                              sighashtype=SigHashType.ALL)
    # 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))
Example #10
0
         'network', Network.MAINNET))
     psbt.finalize()
     resp = psbt
 elif name == 'Psbt.SignPsbt':
     psbt = Psbt(req['psbt'], network=req.get(
         'network', Network.MAINNET))
     psbt.sign(privkey=req['privkey'],
               has_grind_r=req.get('hasGrindR', True))
     resp = psbt
 elif name == 'Psbt.AddPsbtData':
     net_type = Network.get(req.get('network', Network.MAINNET))
     psbt = Psbt(req['psbt'], network=net_type)
     for input_data in req.get('inputs', []):
         txin = input_data['txin']
         input = input_data['input']
         utxo = TxOut(0)
         if 'witnessUtxo' in input:
             addr = ''
             if 'address' in input['witnessUtxo']:
                 addr = AddressUtil.parse(
                     input['witnessUtxo']['address'])
             utxo = TxOut(
                 input['witnessUtxo']['amount'],
                 address=addr,
                 locking_script=input['witnessUtxo'].get(
                     'directLockingScript',
                     ''))
         script = '' if 'redeemScript' not in input else Script(
             input['redeemScript'])
         tx = '' if 'utxoFullTx' not in input else Transaction(
             input['utxoFullTx'])