def __init__(self, script_tools, ui): self.annotate = Annotate(script_tools, ui) self.Key = ui._key_class self.BIP32Node = ui._bip32node_class self.ElectrumKey = ui._electrum_class who_signed = WhoSigned(script_tools, self.Key._default_generator) self.who_signed_tx = who_signed.who_signed_tx self.public_pairs_signed = who_signed.public_pairs_signed self.extract_secs = who_signed.extract_secs self.extract_signatures = who_signed.extract_signatures self.public_pairs_for_script = who_signed.public_pairs_for_script
import unittest from pycoin.coins.bitcoin.ScriptTools import BitcoinScriptTools from pycoin.vm.annotate import Annotate from pycoin.symbols.btc import network as BitcoinMainnet Tx = BitcoinMainnet.tx annotate_scripts = Annotate(BitcoinScriptTools, BitcoinMainnet.ui).annotate_scripts class DisassembleTest(unittest.TestCase): def test_validate(self): input_tx = Tx.from_hex( "01000000019c97afdf6c9a31ffa86d71ea79a079001e2b59ee408fd418498219400639ac0a01" "0000008b4830450220363cffae09599397b21e6d8a8073fb1dfbe06b6acdd0f2f7d3fea86ca9" "c3f605022100fa255a6ed23fd825c759ef1a885a31cad0989606ca8a3a16657d50fe3cef5828" "014104ff444bac08308b9ec97f56a652ad8866e0ba804da97868909999566cb377f4a2c8f100" "0e83b496868f3a282e1a34df78565b65c15c3fa21a0763fd81a3dfbbb6ffffffff02c05eecde" "010000001976a914588554e6cc64e7343d77117da7e01357a6111b7988ac404b4c0000000000" "1976a914ca6eb218592f289999f13916ee32829ad587dbc588ac00000000") tx_to_validate = Tx.from_hex( "010000000165148d894d3922ef5ffda962be26016635c933d470c8b0ab7618e869e3f70e3c00" "0000008b48304502207f5779ebf4834feaeff4d250898324eb5c0833b16d7af4c1cb0f66f50f" "cf6e85022100b78a65377fd018281e77285efc31e5b9ba7cb7e20e015cf6b7fa3e4a466dd195" "014104072ad79e0aa38c05fa33dd185f84c17f611e58a8658ce996d8b04395b99c7be36529ca" "b7606900a0cd5a7aebc6b233ea8e0fe60943054c63620e05e5b85f0426ffffffff02404b4c00" "000000001976a914d4caa8447532ca8ee4c80a1ae1d230a01e22bfdb88ac8013a0de01000000" "1976a9149661a79ae1f6d487af3420c13e649d6df3747fc288ac00000000") tx_db = {tx.hash(): tx for tx in [input_tx]} tx_to_validate.unspents_from_db(tx_db)
def make_tests_for_netcode(netcode): network = network_for_netcode(netcode) Tx = network.tx annotate_scripts = Annotate(network.script_tools, network.ui).annotate_scripts class DisassembleTest(unittest.TestCase): def test_validate(self): input_tx = Tx.from_hex( "01000000019c97afdf6c9a31ffa86d71ea79a079001e2b59ee408fd418498219400639ac0a01" "0000008b4830450220363cffae09599397b21e6d8a8073fb1dfbe06b6acdd0f2f7d3fea86ca9" "c3f605022100fa255a6ed23fd825c759ef1a885a31cad0989606ca8a3a16657d50fe3cef5828" "014104ff444bac08308b9ec97f56a652ad8866e0ba804da97868909999566cb377f4a2c8f100" "0e83b496868f3a282e1a34df78565b65c15c3fa21a0763fd81a3dfbbb6ffffffff02c05eecde" "010000001976a914588554e6cc64e7343d77117da7e01357a6111b7988ac404b4c0000000000" "1976a914ca6eb218592f289999f13916ee32829ad587dbc588ac00000000") tx_to_validate = Tx.from_hex( "010000000165148d894d3922ef5ffda962be26016635c933d470c8b0ab7618e869e3f70e3c00" "0000008b48304502207f5779ebf4834feaeff4d250898324eb5c0833b16d7af4c1cb0f66f50f" "cf6e85022100b78a65377fd018281e77285efc31e5b9ba7cb7e20e015cf6b7fa3e4a466dd195" "014104072ad79e0aa38c05fa33dd185f84c17f611e58a8658ce996d8b04395b99c7be36529ca" "b7606900a0cd5a7aebc6b233ea8e0fe60943054c63620e05e5b85f0426ffffffff02404b4c00" "000000001976a914d4caa8447532ca8ee4c80a1ae1d230a01e22bfdb88ac8013a0de01000000" "1976a9149661a79ae1f6d487af3420c13e649d6df3747fc288ac00000000") tx_db = {tx.hash(): tx for tx in [input_tx]} tx_to_validate.unspents_from_db(tx_db) self.assertEqual("OP_DUP OP_HASH160 [d4caa8447532ca8ee4c80a1ae1d230a01e22bfdb] OP_EQUALVERIFY OP_CHECKSIG", network.script_tools.disassemble(tx_to_validate.txs_out[0].script)) self.assertEqual(tx_to_validate.id(), "7c4f5385050c18aa8df2ba50da566bbab68635999cc99b75124863da1594195b") annotate_scripts(tx_to_validate, 0) def test_disassemble(self): input_tx = Tx.from_hex( "01000000010000000000000000000000000000000000000000000000000000000000000000" "ffffffff0704ffff001d0134ffffffff0100f2052a0100000043410411db93e1dcdb8a016b" "49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0eaddfb84ccf9744464f82e16" "0bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000") tx_db = {tx.hash(): tx for tx in [input_tx]} tx_to_validate = Tx.from_hex( "0100000001c997a5e56e104102fa209c6a852dd90660a20b2d9c352423edce25857fcd3704000000004847304402" "204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220181522ec8eca07de4860a4" "acdd12909d831cc56cbbac4622082221a8768d1d0901ffffffff0200ca9a3b00000000434104ae1a62fe09c5f51b" "13905f07f06b99a2f7159b2225f374cd378d71302fa28414e7aab37397f554a7df5f142c21c1b7303b8a0626f1ba" "ded5c72a704f7e6cd84cac00286bee0000000043410411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482e" "cad7b148a6909a5cb2e0eaddfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3ac00000000") tx_to_validate.unspents_from_db(tx_db) self.assertEqual(tx_to_validate.id(), "f4184fc596403b9d638783cf57adfe4c75c605f6356fbc91338530e9831e9e16") r = annotate_scripts(tx_to_validate, 0) EXPECTED = [ ( ['--- SIGNATURE SCRIPT START'], 0, 0x47, ('[PUSH_71] 304402204e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd410220' '181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d0901'), [ 'r: 0x4e45e16932b8af514961a1d3a1a25fdf3f4f7732e9d624c6c61548ab5fb8cd41', 's: 0x181522ec8eca07de4860a4acdd12909d831cc56cbbac4622082221a8768d1d09', 'z: 0x7a05c6145f10101e9d6325494245adf1297d80f8f38d4d576d57cdba220bcb19', 'signature type SIGHASH_ALL', (' sig for 1M6HTkQf7RhsrDLDX7Q6GJkxXbTz8VWxMx 1E5CDVQrLjSqTeqfN5zT2X2DoeYS7od2Mi ' '13KiMqUJ7xD6MhUD2k7mKEoZMHDP9HdWwW 12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S') ] ), ( ['--- PUBLIC KEY SCRIPT START'], 0, 0x41, ('[PUSH_65] 0411db93e1dcdb8a016b49840f8c53bc1eb68a382e97b1482ecad7b148a6909a5cb2e0ead' 'dfb84ccf9744464f82e160bfa9b8b64f9d4c03f999b8643f656b412a3'), ['SEC for uncompressed 12cbQLTFMXRnSzktFkuoG3eHoMeFtpTu3S'] ), ([], 0x42, 0xac, 'OP_CHECKSIG', [])] self.assertEqual(r, EXPECTED) return DisassembleTest
def create_bitcoinish_network(symbol, network_name, subnet_name, **kwargs): # potential kwargs: # tx, block, magic_header_hex, default_port, dns_bootstrap, # wif_prefix_hex, address_prefix_hex, pay_to_script_prefix_hex # bip32_prv_prefix_hex, bip32_pub_prefix_hex, sec_prefix, script_tools # bip49_prv_prefix, bip49_pub_prefix, bip84_prv_prefix, bip84_pub_prefix network = Network(symbol, network_name, subnet_name) generator = kwargs.get("generator", secp256k1_generator) kwargs.setdefault("sec_prefix", "%sSEC" % symbol.upper()) KEYS_TO_H2B = ( "bip32_prv_prefix bip32_pub_prefix bip49_prv_prefix bip49_pub_prefix " "bip84_prv_prefix bip84_pub_prefix wif_prefix address_prefix " "pay_to_script_prefix sec_prefix magic_header").split() for k in KEYS_TO_H2B: k_hex = "%s_hex" % k if k_hex in kwargs: kwargs[k] = h2b(kwargs[k_hex]) script_tools = kwargs.get("script_tools", BitcoinScriptTools) UI_KEYS = ( "bip32_prv_prefix bip32_pub_prefix bip49_prv_prefix bip49_pub_prefix " "bip84_prv_prefix bip84_pub_prefix wif_prefix sec_prefix " "address_prefix pay_to_script_prefix bech32_hrp").split() ui_kwargs = {k: kwargs[k] for k in UI_KEYS if k in kwargs} _bip32_prv_prefix = ui_kwargs.get("bip32_prv_prefix") _bip32_pub_prefix = ui_kwargs.get("bip32_pub_prefix") _wif_prefix = ui_kwargs.get("wif_prefix") _sec_prefix = ui_kwargs.get("sec_prefix") def bip32_as_string(blob, as_private): prefix = ui_kwargs.get("bip32_%s_prefix" % ("prv" if as_private else "pub")) return b2a_hashed_base58(prefix + blob) def bip49_as_string(blob, as_private): prefix = ui_kwargs.get("bip49_%s_prefix" % ("prv" if as_private else "pub")) return b2a_hashed_base58(prefix + blob) def bip84_as_string(blob, as_private): prefix = ui_kwargs.get("bip84_%s_prefix" % ("prv" if as_private else "pub")) return b2a_hashed_base58(prefix + blob) def wif_for_blob(blob): return b2a_hashed_base58(_wif_prefix + blob) def sec_text_for_blob(blob): return _sec_prefix + b2h(blob) NetworkKey = Key.make_subclass(symbol, network=network, generator=generator) NetworkElectrumKey = ElectrumWallet.make_subclass(symbol, network=network, generator=generator) NetworkBIP32Node = BIP32Node.make_subclass(symbol, network=network, generator=generator) NetworkBIP49Node = BIP49Node.make_subclass(symbol, network=network, generator=generator) NetworkBIP84Node = BIP84Node.make_subclass(symbol, network=network, generator=generator) NETWORK_KEYS = "network_name subnet_name dns_bootstrap default_port magic_header".split( ) for k in NETWORK_KEYS: if k in kwargs: setattr(network, k, kwargs[k]) network.Tx = network.tx = kwargs.get("tx") or Tx network.Block = network.block = kwargs.get("block") or Block.make_subclass( symbol, network.tx) streamer = standard_streamer( standard_parsing_functions(network.block, network.tx)) network.message = API() network.message.parse, network.message.pack = make_parser_and_packer( streamer, standard_messages(), standard_message_post_unpacks(streamer)) network.output_for_secret_exponent = make_output_for_secret_exponent( NetworkKey) network.output_for_public_pair = make_output_for_public_pair( NetworkKey, network) network.keychain = Keychain parse_api_class = kwargs.get("parse_api_class", ParseAPI) network.parse = parse_api_class(network, **ui_kwargs) network.contract = ContractAPI(network, script_tools) network.address = make_address_api(network.contract, **ui_kwargs) def keys_private(secret_exponent, is_compressed=True): return NetworkKey(secret_exponent=secret_exponent, is_compressed=is_compressed) def keys_public(item, is_compressed=None): if isinstance(item, tuple): if is_compressed is None: is_compressed = True # it's a public pair return NetworkKey(public_pair=item, is_compressed=is_compressed) if is_compressed is not None: raise ValueError("can't set is_compressed from sec") return NetworkKey.from_sec(item) network.keys = API() network.keys.private = keys_private network.keys.public = keys_public def electrum_seed(seed): return NetworkElectrumKey(initial_key=seed) def electrum_private(master_private_key): return NetworkElectrumKey(master_private_key=master_private_key) def electrum_public(master_public_key): return NetworkElectrumKey(master_public_key=master_public_key) network.keys.bip32_seed = NetworkBIP32Node.from_master_secret network.keys.bip32_deserialize = NetworkBIP32Node.deserialize network.keys.bip49_deserialize = NetworkBIP49Node.deserialize network.keys.bip84_deserialize = NetworkBIP84Node.deserialize network.keys.electrum_seed = electrum_seed network.keys.electrum_private = electrum_private network.keys.electrum_public = electrum_public network.keys.InvalidSecretExponentError = InvalidSecretExponentError network.keys.InvalidPublicPairError = InvalidPublicPairError network.msg = API() message_signer = MessageSigner(network, generator) network.msg.sign = message_signer.sign_message network.msg.verify = message_signer.verify_message network.msg.parse_signed = message_signer.parse_signed_message network.msg.hash_for_signing = message_signer.hash_for_signing network.msg.signature_for_message_hash = message_signer.signature_for_message_hash network.msg.pair_for_message_hash = message_signer.pair_for_message_hash network.script = script_tools network.bip32_as_string = bip32_as_string network.bip49_as_string = bip49_as_string network.sec_text_for_blob = sec_text_for_blob network.wif_for_blob = wif_for_blob def network_build_hash160_lookup(iter): return build_hash160_lookup(iter, [generator]) network.tx.solve = API() network.tx.solve.build_hash160_lookup = network_build_hash160_lookup network.tx.solve.build_p2sh_lookup = build_p2sh_lookup network.tx.solve.build_sec_lookup = build_sec_lookup network.validator = API() network.validator.ScriptError = ScriptError network.validator.ValidationFailureError = ValidationFailureError network.validator.errno = errno network.validator.flags = flags def my_create_tx(*args, **kwargs): return create_tx(network, *args, **kwargs) def my_sign_tx(*args, **kwargs): return sign_tx(network, *args, **kwargs) def my_create_signed_tx(*args, **kwargs): return create_signed_tx(network, *args, **kwargs) def my_split_with_remainder(*args, **kwargs): return split_with_remainder(network, *args, **kwargs) network.tx_utils = API() network.tx_utils.create_tx = my_create_tx network.tx_utils.sign_tx = my_sign_tx network.tx_utils.create_signed_tx = my_create_signed_tx network.tx_utils.split_with_remainder = my_split_with_remainder network.tx_utils.distribute_from_split_pool = distribute_from_split_pool network.annotate = Annotate(script_tools, network.address) network.who_signed = WhoSigned(script_tools, network.address, generator) network.str = parseable_str network.generator = generator return network