From 5a8ea0af2175a02a3357a7c8a207fd1f548839ea Mon Sep 17 00:00:00 2001 From: Ouziel Slama Date: Thu, 3 Oct 2024 14:41:07 +0000 Subject: [PATCH] Migrate to 'bitcoinutils' which supports taproot addresses --- .../counterpartycore/lib/composer.py | 59 ++-- .../fixtures/contract_vectors/composer.py | 273 +++++++++--------- .../counterpartycore/test/util_test.py | 9 +- counterparty-core/requirements.txt | 1 + 4 files changed, 172 insertions(+), 170 deletions(-) diff --git a/counterparty-core/counterpartycore/lib/composer.py b/counterparty-core/counterpartycore/lib/composer.py index 88e85727d..35e05c779 100644 --- a/counterparty-core/counterpartycore/lib/composer.py +++ b/counterparty-core/counterpartycore/lib/composer.py @@ -1,21 +1,8 @@ import binascii -from bitcoin.core import ( - CTransaction, - CTxIn, - CTxOut, -) -from bitcoin.core.script import ( - OP_CHECKMULTISIG, - OP_RETURN, - CScript, -) -from bitcoin.wallet import ( - CBitcoinAddress, - CBitcoinAddressError, - P2PKHBitcoinAddress, - P2WPKHBitcoinAddress, -) +from bitcoinutils.keys import P2pkhAddress, P2wpkhAddress, PublicKey +from bitcoinutils.script import Script, b_to_h +from bitcoinutils.transactions import Transaction, TxInput, TxOutput from counterpartycore.lib import arc4, backend, config, exceptions, script, transaction, util from counterpartycore.lib.transaction_helper.common_serializer import make_fully_valid @@ -31,9 +18,15 @@ def search_pubkey(address, provides_pubkeys=None): try: if not pubkey: raise exceptions.ComposeError(f"invalid pubkey: {pubkey}") - if str(P2PKHBitcoinAddress.from_pubkey(bytes.fromhex(pubkey))) == address: + check_address = PublicKey.from_hex(pubkey).get_address(compressed=True).to_string() + print(check_address) + if check_address == address: return pubkey - except (ValueError, CBitcoinAddressError) as e: + check_address = PublicKey.from_hex(pubkey).get_address(compressed=False).to_string() + print(check_address) + if check_address == address: + return pubkey + except ValueError as e: raise exceptions.ComposeError(f"invalid pubkey: {pubkey}") from e raise exceptions.ComposeError(f"`{address}` pubkey not found in provided pubkeys") @@ -42,11 +35,12 @@ def get_script(address, pubkeys=None): if script.is_multisig(address): signatures_required, addresses, signatures_possible = script.extract_array(address) pubkeys = [search_pubkey(address, pubkeys) for address in addresses] - pubkeys = [bytes.fromhex(pubkey) for pubkey in pubkeys] - return CScript([signatures_required] + pubkeys + [signatures_possible] + [OP_CHECKMULTISIG]) + return Script( + [signatures_required] + pubkeys + [signatures_possible] + ["OP_CHECKMULTISIG"] + ) if script.is_bech32(address): - return P2WPKHBitcoinAddress(address).to_scriptPubKey() - return CBitcoinAddress(address).to_scriptPubKey() + return P2wpkhAddress(address).to_script_pub_key() + return P2pkhAddress(address).to_script_pub_key() def get_default_value(address): @@ -59,7 +53,7 @@ def perpare_non_data_outputs(destinations, pubkeys=None): outputs = [] for address, value in destinations: output_value = value or get_default_value(address) - outputs.append(CTxOut(output_value, get_script(address, pubkeys))) + outputs.append(TxOutput(output_value, get_script(address, pubkeys))) return outputs @@ -86,7 +80,7 @@ def prepare_opreturn_output(data, arc4_key=None): opreturn_data = config.PREFIX + data if arc4_key: opreturn_data = encrypt_data(opreturn_data, arc4_key) - return [CTxOut(0, CScript([OP_RETURN, opreturn_data]))] + return [TxOutput(0, Script(["OP_RETURN", b_to_h(opreturn_data)]))] def data_to_pubkey_pairs(data, arc4_key=None): @@ -104,20 +98,19 @@ def data_to_pubkey_pairs(data, arc4_key=None): output_data = encrypt_data(output_data, arc4_key) data_pubkey_1 = make_fully_valid(output_data[:31]) data_pubkey_2 = make_fully_valid(output_data[31:]) - pubkey_pairs.append((data_pubkey_1, data_pubkey_2)) + pubkey_pairs.append((b_to_h(data_pubkey_1), b_to_h(data_pubkey_2))) return pubkey_pairs def prepare_multisig_output(data, source, pubkeys, arc4_key=None): source_pubkey = search_pubkey(source, pubkeys) - dust_return_pubkey = binascii.unhexlify(source_pubkey) pubkey_pairs = data_to_pubkey_pairs(data, arc4_key) outputs = [] for pubkey_pair in pubkey_pairs: - output_script = CScript( - [1, pubkey_pair[0], pubkey_pair[1], dust_return_pubkey, 3, OP_CHECKMULTISIG] + output_script = Script( + [1, pubkey_pair[0], pubkey_pair[1], source_pubkey, 3, "OP_CHECKMULTISIG"] ) - outputs.append(CTxOut(config.DEFAULT_MULTISIG_DUST_SIZE, output_script)) + outputs.append(TxOutput(config.DEFAULT_MULTISIG_DUST_SIZE, output_script)) return outputs @@ -179,7 +172,7 @@ def select_utxos(unspent_list, target_amount): def utxos_to_txins(utxos: list): inputs = [] for utxo in utxos: - inputs.append(CTxIn(CScript([bytes.fromhex(utxo["txid"]), utxo["vout"]]))) + inputs.append(TxInput(utxo["txid"], utxo["vout"])) return inputs @@ -210,7 +203,7 @@ def prepare_transaction(source, outputs, pubkeys, unspent_list, desired_fee): change = input_total - target_amount change_outputs = [] if change > get_minimum_change(source): - change_outputs.append(CTxOut(change, get_script(source, pubkeys))) + change_outputs.append(TxOutput(change, get_script(source, pubkeys))) else: change = 0 return inputs, change_outputs, input_total @@ -220,7 +213,7 @@ def construct_transaction(source, outputs, pubkeys, unspent_list, desired_fee): inputs, change_outputs, _input_total = prepare_transaction( source, outputs, pubkeys, unspent_list, desired_fee ) - tx = CTransaction(inputs, outputs + change_outputs) + tx = Transaction(inputs, outputs + change_outputs) return tx @@ -255,7 +248,7 @@ def compose_transaction( outputs = prepare_outputs( source, destinations, data, pubkeys, encoding, arc4_key=inputs[0]["txid"] ) - tx = CTransaction(inputs, outputs + change_outputs) + tx = Transaction(inputs, outputs + change_outputs) btc_out = sum(output.nValue for output in outputs) btc_change = sum(change_output.nValue for change_output in change_outputs) diff --git a/counterparty-core/counterpartycore/test/fixtures/contract_vectors/composer.py b/counterparty-core/counterpartycore/test/fixtures/contract_vectors/composer.py index 2208443aa..6845d78fa 100644 --- a/counterparty-core/counterpartycore/test/fixtures/contract_vectors/composer.py +++ b/counterparty-core/counterpartycore/test/fixtures/contract_vectors/composer.py @@ -1,7 +1,6 @@ -from bitcoin import SelectParams -from bitcoin.core import CTxOut -from bitcoin.core.script import OP_CHECKMULTISIG, OP_RETURN, CScript -from bitcoin.wallet import CBitcoinAddress, P2WPKHBitcoinAddress +from bitcoinutils.keys import P2pkhAddress, P2wpkhAddress +from bitcoinutils.script import Script, b_to_h +from bitcoinutils.transactions import TxOutput from counterpartycore.lib import config, exceptions @@ -12,8 +11,6 @@ P2WPKH_ADDR, ) -SelectParams("testnet") - PROVIDED_PUBKEYS = [DEFAULT_PARAMS["pubkey"][ADDR[0]], DEFAULT_PARAMS["pubkey"][ADDR[1]]] ARC4_KEY = "0000000000000000000000000000000000000000000000000000000000000000" UTXO_1 = "344dcc8909ca3a137630726d0071dfd2df4f7c855bac150c7d3a8367835c90bc:1" @@ -26,23 +23,23 @@ { "comment": "P2PKH address", "in": (ADDR[0],), - "out": CBitcoinAddress(ADDR[0]).to_scriptPubKey(), + "out": P2pkhAddress(ADDR[0]).to_script_pub_key(), }, { "comment": "P2WPKH address", "in": (P2WPKH_ADDR[0],), - "out": P2WPKHBitcoinAddress(P2WPKH_ADDR[0]).to_scriptPubKey(), + "out": P2wpkhAddress(P2WPKH_ADDR[0]).to_script_pub_key(), }, { "comment": "multisig address", "in": (MULTISIGADDR[0], PROVIDED_PUBKEYS), - "out": CScript( + "out": Script( [ 1, - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[1]]), + DEFAULT_PARAMS["pubkey"][ADDR[0]], + DEFAULT_PARAMS["pubkey"][ADDR[1]], 2, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), }, @@ -50,20 +47,20 @@ "perpare_non_data_outputs": [ { "in": ([(ADDR[0], 0)],), - "out": [CTxOut(546, CBitcoinAddress(ADDR[0]).to_scriptPubKey())], + "out": [TxOutput(546, P2pkhAddress(ADDR[0]).to_script_pub_key())], }, { "in": ([(MULTISIGADDR[0], 0)], PROVIDED_PUBKEYS), "out": [ - CTxOut( + TxOutput( 1000, - CScript( + Script( [ 1, - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[1]]), + DEFAULT_PARAMS["pubkey"][ADDR[0]], + DEFAULT_PARAMS["pubkey"][ADDR[1]], 2, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), ) @@ -71,7 +68,7 @@ }, { "in": ([(ADDR[0], 2024)],), - "out": [CTxOut(2024, CBitcoinAddress(ADDR[0]).to_scriptPubKey())], + "out": [TxOutput(2024, P2pkhAddress(ADDR[0]).to_script_pub_key())], }, ], "determine_encoding": [ @@ -102,12 +99,14 @@ { "in": (b"Hello, World!", ARC4_KEY), "out": [ - CTxOut( + TxOutput( 0, - CScript( + Script( [ - OP_RETURN, - b"\x8a]\xda\x15\xfbo\x05b\xc2cr\x0b8B\xb2:\xa8h\x13\xc7\xd1", + "OP_RETURN", + b_to_h( + b"\x8a]\xda\x15\xfbo\x05b\xc2cr\x0b8B\xb2:\xa8h\x13\xc7\xd1" + ), ] ), ) @@ -115,7 +114,7 @@ }, { "in": (b"Hello, World!",), - "out": [CTxOut(0, CScript([OP_RETURN, b"TESTXXXXHello, World!"]))], + "out": [TxOutput(0, Script(["OP_RETURN", b_to_h(b"TESTXXXXHello, World!")]))], }, ], "data_to_pubkey_pairs": [ @@ -123,16 +122,16 @@ "in": (b"Hello, World!" * 10,), "out": [ ( - b"\x025Hello, World!Hello, World!Hell\x9b", - b"\x03o, World!Hello, World!H\x00\x00\x00\x00\x00\x00\x00\x00\x94", + "023548656c6c6f2c20576f726c642148656c6c6f2c20576f726c642148656c6c9b", + "036f2c20576f726c642148656c6c6f2c20576f726c642148000000000000000094", ), ( - b"\x025ello, World!Hello, World!Hello<", - b"\x03, World!Hello, World!He\x00\x00\x00\x00\x00\x00\x00\x00\t", + "0235656c6c6f2c20576f726c642148656c6c6f2c20576f726c642148656c6c6f3c", + "032c20576f726c642148656c6c6f2c20576f726c64214865000000000000000009", ), ( - b"\x02\x18llo, World!Hello, World!\x00\x00\x00\x00\x00\x00G", - b"\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c", + "02186c6c6f2c20576f726c642148656c6c6f2c20576f726c642100000000000047", + "03000000000000000000000000000000000000000000000000000000000000000c", ), ], }, @@ -140,16 +139,16 @@ "in": (b"Hello, World!" * 10, ARC4_KEY), "out": [ ( - b"\x03\xebP\xec-\xcfXq\x1a\xddil\x0b3O\xda\x08\xabv\x10\x8f\xd0\x9b\x84\xe5)OlzB\xfa33", - b'\x02\xf1\x84\xec"h\x1f\xf3\xdd\xe4\t\x1f\xc9\xa7_\xd0\x02N\xe4F\xf4I\x9a*\x9e\xc0KO\x8b\x05\xa0q\xda', + "03eb50ec2dcf58711add696c0b334fda08ab76108fd09b84e5294f6c7a42fa3333", + "02f184ec22681ff3dde4091fc9a75fd0024ee446f4499a2a9ec04b4f8b05a071da", ), ( - b"\x02\xeb}\xe5-\xcc\x1b}m\xe5tr\x03v&\xf7\x01\xabuS\x83\xa7\xa3\x99\xfb!\n\x05WK\xfa0\r", - b"\x02\xb2\x88\x9b\x1au\x01\xfb\x98\x8d$\x16\xc9\xa4\x1c\xdcuv\xf9X\xfc\x0c\xf3\x07\x9e\xc0KO\x8b\x05\xa0q\xa2", + "02eb7de52dcc1b7d6de57472037626f701ab755383a7a399fb210a05574bfa300d", + "02b2889b1a7501fb988d2416c9a41cdc7576f958fc0cf3079ec04b4f8b05a071a2", ), ( - b"\x03\xc6t\xe5.\x8f\x17\nU\xf8jzF\x1f\x0b\xfe\x01\xa86_\xf4\x9f\xbe\x87\xf3d+M2'\x96_\x81", - b'\x02\x9e\xa8\xccu\x07m\x9f\xb9\xc5Az\xa5\xcb0\xfc"\x19\x8b4\x98-\xbbb\x9e\xc0KO\x8b\x05\xa0q4', + "03c674e52e8f170a55f86a7a461f0bfe01a8365ff49fbe87f3642b4d3227965f81", + "029ea8cc75076d9fb9c5417aa5cb30fc22198b34982dbb629ec04b4f8b05a07134", ), ], }, @@ -159,42 +158,42 @@ "comment": "No encryption", "in": (b"Hello, World!" * 10, ADDR[0], PROVIDED_PUBKEYS), "out": [ - CTxOut( + TxOutput( config.DEFAULT_MULTISIG_DUST_SIZE, - CScript( + Script( [ 1, - b"\x025Hello, World!Hello, World!Hell\x9b", - b"\x03o, World!Hello, World!H\x00\x00\x00\x00\x00\x00\x00\x00\x94", - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), + "023548656c6c6f2c20576f726c642148656c6c6f2c20576f726c642148656c6c9b", + "036f2c20576f726c642148656c6c6f2c20576f726c642148000000000000000094", + DEFAULT_PARAMS["pubkey"][ADDR[0]], 3, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), ), - CTxOut( + TxOutput( config.DEFAULT_MULTISIG_DUST_SIZE, - CScript( + Script( [ 1, - b"\x025ello, World!Hello, World!Hello<", - b"\x03, World!Hello, World!He\x00\x00\x00\x00\x00\x00\x00\x00\t", - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), + "0235656c6c6f2c20576f726c642148656c6c6f2c20576f726c642148656c6c6f3c", + "032c20576f726c642148656c6c6f2c20576f726c64214865000000000000000009", + DEFAULT_PARAMS["pubkey"][ADDR[0]], 3, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), ), - CTxOut( + TxOutput( config.DEFAULT_MULTISIG_DUST_SIZE, - CScript( + Script( [ 1, - b"\x02\x18llo, World!Hello, World!\x00\x00\x00\x00\x00\x00G", - b"\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c", - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), + "02186c6c6f2c20576f726c642148656c6c6f2c20576f726c642100000000000047", + "03000000000000000000000000000000000000000000000000000000000000000c", + DEFAULT_PARAMS["pubkey"][ADDR[0]], 3, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), ), @@ -204,42 +203,42 @@ "comment": "Encrypted", "in": (b"Hello, World!" * 10, ADDR[0], PROVIDED_PUBKEYS, ARC4_KEY), "out": [ - CTxOut( + TxOutput( config.DEFAULT_MULTISIG_DUST_SIZE, - CScript( + Script( [ 1, - b"\x03\xebP\xec-\xcfXq\x1a\xddil\x0b3O\xda\x08\xabv\x10\x8f\xd0\x9b\x84\xe5)OlzB\xfa33", - b'\x02\xf1\x84\xec"h\x1f\xf3\xdd\xe4\t\x1f\xc9\xa7_\xd0\x02N\xe4F\xf4I\x9a*\x9e\xc0KO\x8b\x05\xa0q\xda', - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), + "03eb50ec2dcf58711add696c0b334fda08ab76108fd09b84e5294f6c7a42fa3333", + "02f184ec22681ff3dde4091fc9a75fd0024ee446f4499a2a9ec04b4f8b05a071da", + DEFAULT_PARAMS["pubkey"][ADDR[0]], 3, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), ), - CTxOut( + TxOutput( config.DEFAULT_MULTISIG_DUST_SIZE, - CScript( + Script( [ 1, - b"\x02\xeb}\xe5-\xcc\x1b}m\xe5tr\x03v&\xf7\x01\xabuS\x83\xa7\xa3\x99\xfb!\n\x05WK\xfa0\r", - b"\x02\xb2\x88\x9b\x1au\x01\xfb\x98\x8d$\x16\xc9\xa4\x1c\xdcuv\xf9X\xfc\x0c\xf3\x07\x9e\xc0KO\x8b\x05\xa0q\xa2", - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), + "02eb7de52dcc1b7d6de57472037626f701ab755383a7a399fb210a05574bfa300d", + "02b2889b1a7501fb988d2416c9a41cdc7576f958fc0cf3079ec04b4f8b05a071a2", + DEFAULT_PARAMS["pubkey"][ADDR[0]], 3, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), ), - CTxOut( + TxOutput( config.DEFAULT_MULTISIG_DUST_SIZE, - CScript( + Script( [ 1, - b"\x03\xc6t\xe5.\x8f\x17\nU\xf8jzF\x1f\x0b\xfe\x01\xa86_\xf4\x9f\xbe\x87\xf3d+M2'\x96_\x81", - b'\x02\x9e\xa8\xccu\x07m\x9f\xb9\xc5Az\xa5\xcb0\xfc"\x19\x8b4\x98-\xbbb\x9e\xc0KO\x8b\x05\xa0q4', - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), + "03c674e52e8f170a55f86a7a461f0bfe01a8365ff49fbe87f3642b4d3227965f81", + "029ea8cc75076d9fb9c5417aa5cb30fc22198b34982dbb629ec04b4f8b05a07134", + DEFAULT_PARAMS["pubkey"][ADDR[0]], 3, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), ), @@ -249,7 +248,7 @@ "prepare_data_outputs": [ { "in": ("opreturn", b"Hello, World!", ADDR[0], None), - "out": [CTxOut(0, CScript([OP_RETURN, b"TESTXXXXHello, World!"]))], + "out": [TxOutput(0, Script(["OP_RETURN", b_to_h(b"TESTXXXXHello, World!")]))], }, { "in": ("opreturn", b"Hello, World!" * 10, ADDR[0], PROVIDED_PUBKEYS), @@ -258,42 +257,42 @@ { "in": ("multisig", b"Hello, World!" * 10, ADDR[0], PROVIDED_PUBKEYS), "out": [ - CTxOut( + TxOutput( config.DEFAULT_MULTISIG_DUST_SIZE, - CScript( + Script( [ 1, - b"\x025Hello, World!Hello, World!Hell\x9b", - b"\x03o, World!Hello, World!H\x00\x00\x00\x00\x00\x00\x00\x00\x94", - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), + "023548656c6c6f2c20576f726c642148656c6c6f2c20576f726c642148656c6c9b", + "036f2c20576f726c642148656c6c6f2c20576f726c642148000000000000000094", + DEFAULT_PARAMS["pubkey"][ADDR[0]], 3, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), ), - CTxOut( + TxOutput( config.DEFAULT_MULTISIG_DUST_SIZE, - CScript( + Script( [ 1, - b"\x025ello, World!Hello, World!Hello<", - b"\x03, World!Hello, World!He\x00\x00\x00\x00\x00\x00\x00\x00\t", - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), + "0235656c6c6f2c20576f726c642148656c6c6f2c20576f726c642148656c6c6f3c", + "032c20576f726c642148656c6c6f2c20576f726c64214865000000000000000009", + DEFAULT_PARAMS["pubkey"][ADDR[0]], 3, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), ), - CTxOut( + TxOutput( config.DEFAULT_MULTISIG_DUST_SIZE, - CScript( + Script( [ 1, - b"\x02\x18llo, World!Hello, World!\x00\x00\x00\x00\x00\x00G", - b"\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c", - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), + "02186c6c6f2c20576f726c642148656c6c6f2c20576f726c642100000000000047", + "03000000000000000000000000000000000000000000000000000000000000000c", + DEFAULT_PARAMS["pubkey"][ADDR[0]], 3, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), ), @@ -308,20 +307,22 @@ { "in": (ADDR[0], [(ADDR[0], 9999)], b"Hello, World!", None, "opreturn"), "out": [ - CTxOut(9999, CBitcoinAddress(ADDR[0]).to_scriptPubKey()), - CTxOut(0, CScript([OP_RETURN, b"TESTXXXXHello, World!"])), + TxOutput(9999, P2pkhAddress(ADDR[0]).to_script_pub_key()), + TxOutput(0, Script(["OP_RETURN", b_to_h(b"TESTXXXXHello, World!")])), ], }, { "in": (ADDR[0], [(ADDR[0], 9999)], b"Hello, World!", None, "opreturn", ARC4_KEY), "out": [ - CTxOut(9999, CBitcoinAddress(ADDR[0]).to_scriptPubKey()), - CTxOut( + TxOutput(9999, P2pkhAddress(ADDR[0]).to_script_pub_key()), + TxOutput( 0, - CScript( + Script( [ - OP_RETURN, - b"\x8a]\xda\x15\xfbo\x05b\xc2cr\x0b8B\xb2:\xa8h\x13\xc7\xd1", + "OP_RETURN", + b_to_h( + b"\x8a]\xda\x15\xfbo\x05b\xc2cr\x0b8B\xb2:\xa8h\x13\xc7\xd1" + ), ] ), ), @@ -336,43 +337,43 @@ "multisig", ), "out": [ - CTxOut(9999, CBitcoinAddress(ADDR[0]).to_scriptPubKey()), - CTxOut( + TxOutput(9999, P2pkhAddress(ADDR[0]).to_script_pub_key()), + TxOutput( config.DEFAULT_MULTISIG_DUST_SIZE, - CScript( + Script( [ 1, - b"\x025Hello, World!Hello, World!Hell\x9b", - b"\x03o, World!Hello, World!H\x00\x00\x00\x00\x00\x00\x00\x00\x94", - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), + "023548656c6c6f2c20576f726c642148656c6c6f2c20576f726c642148656c6c9b", + "036f2c20576f726c642148656c6c6f2c20576f726c642148000000000000000094", + DEFAULT_PARAMS["pubkey"][ADDR[0]], 3, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), ), - CTxOut( + TxOutput( config.DEFAULT_MULTISIG_DUST_SIZE, - CScript( + Script( [ 1, - b"\x025ello, World!Hello, World!Hello<", - b"\x03, World!Hello, World!He\x00\x00\x00\x00\x00\x00\x00\x00\t", - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), + "0235656c6c6f2c20576f726c642148656c6c6f2c20576f726c642148656c6c6f3c", + "032c20576f726c642148656c6c6f2c20576f726c64214865000000000000000009", + DEFAULT_PARAMS["pubkey"][ADDR[0]], 3, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), ), - CTxOut( + TxOutput( config.DEFAULT_MULTISIG_DUST_SIZE, - CScript( + Script( [ 1, - b"\x02\x18llo, World!Hello, World!\x00\x00\x00\x00\x00\x00G", - b"\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0c", - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), + "02186c6c6f2c20576f726c642148656c6c6f2c20576f726c642100000000000047", + "03000000000000000000000000000000000000000000000000000000000000000c", + DEFAULT_PARAMS["pubkey"][ADDR[0]], 3, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), ), @@ -388,43 +389,43 @@ ARC4_KEY, ), "out": [ - CTxOut(9999, CBitcoinAddress(ADDR[0]).to_scriptPubKey()), - CTxOut( + TxOutput(9999, P2pkhAddress(ADDR[0]).to_script_pub_key()), + TxOutput( config.DEFAULT_MULTISIG_DUST_SIZE, - CScript( + Script( [ 1, - b"\x03\xebP\xec-\xcfXq\x1a\xddil\x0b3O\xda\x08\xabv\x10\x8f\xd0\x9b\x84\xe5)OlzB\xfa33", - b'\x02\xf1\x84\xec"h\x1f\xf3\xdd\xe4\t\x1f\xc9\xa7_\xd0\x02N\xe4F\xf4I\x9a*\x9e\xc0KO\x8b\x05\xa0q\xda', - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), + "03eb50ec2dcf58711add696c0b334fda08ab76108fd09b84e5294f6c7a42fa3333", + "02f184ec22681ff3dde4091fc9a75fd0024ee446f4499a2a9ec04b4f8b05a071da", + DEFAULT_PARAMS["pubkey"][ADDR[0]], 3, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), ), - CTxOut( + TxOutput( config.DEFAULT_MULTISIG_DUST_SIZE, - CScript( + Script( [ 1, - b"\x02\xeb}\xe5-\xcc\x1b}m\xe5tr\x03v&\xf7\x01\xabuS\x83\xa7\xa3\x99\xfb!\n\x05WK\xfa0\r", - b"\x02\xb2\x88\x9b\x1au\x01\xfb\x98\x8d$\x16\xc9\xa4\x1c\xdcuv\xf9X\xfc\x0c\xf3\x07\x9e\xc0KO\x8b\x05\xa0q\xa2", - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), + "02eb7de52dcc1b7d6de57472037626f701ab755383a7a399fb210a05574bfa300d", + "02b2889b1a7501fb988d2416c9a41cdc7576f958fc0cf3079ec04b4f8b05a071a2", + DEFAULT_PARAMS["pubkey"][ADDR[0]], 3, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), ), - CTxOut( + TxOutput( config.DEFAULT_MULTISIG_DUST_SIZE, - CScript( + Script( [ 1, - b"\x03\xc6t\xe5.\x8f\x17\nU\xf8jzF\x1f\x0b\xfe\x01\xa86_\xf4\x9f\xbe\x87\xf3d+M2'\x96_\x81", - b'\x02\x9e\xa8\xccu\x07m\x9f\xb9\xc5Az\xa5\xcb0\xfc"\x19\x8b4\x98-\xbbb\x9e\xc0KO\x8b\x05\xa0q4', - bytes.fromhex(DEFAULT_PARAMS["pubkey"][ADDR[0]]), + "03c674e52e8f170a55f86a7a461f0bfe01a8365ff49fbe87f3642b4d3227965f81", + "029ea8cc75076d9fb9c5417aa5cb30fc22198b34982dbb629ec04b4f8b05a07134", + DEFAULT_PARAMS["pubkey"][ADDR[0]], 3, - OP_CHECKMULTISIG, + "OP_CHECKMULTISIG", ] ), ), diff --git a/counterparty-core/counterpartycore/test/util_test.py b/counterparty-core/counterpartycore/test/util_test.py index bbd27a672..5edbb48c7 100644 --- a/counterparty-core/counterpartycore/test/util_test.py +++ b/counterparty-core/counterpartycore/test/util_test.py @@ -22,6 +22,7 @@ import bitcoin as bitcoinlib import pycoin import pytest +from bitcoinutils.transactions import TxOutput from pycoin.coins.bitcoin import Tx # noqa: F401 CURR_DIR = os.path.dirname( @@ -904,7 +905,13 @@ def check_outputs( if outputs is not None: try: - assert outputs == test_outputs + if isinstance(outputs, TxOutput): + assert outputs.to_bytes() == test_outputs.to_bytes() + elif isinstance(outputs, list) and isinstance(outputs[0], TxOutput): + for i, output in enumerate(outputs): + assert output.to_bytes() == test_outputs[i].to_bytes() + else: + assert outputs == test_outputs except AssertionError: if pytest_config.getoption("verbose") >= 2: msg = ( diff --git a/counterparty-core/requirements.txt b/counterparty-core/requirements.txt index 80452ba25..5011d3745 100644 --- a/counterparty-core/requirements.txt +++ b/counterparty-core/requirements.txt @@ -32,4 +32,5 @@ python-gnupg==0.5.2 pyzmq==26.0.3 JSON-log-formatter==1.0 yoyo-migrations==8.2.0 +bitcoin-utils==0.7.1 counterparty-rs==10.4.2