Example #1
0
def pycoin_sec2addr(sec):
	coin = ci.external_tests['testnet']['pycoin'][g.coin] if g.testnet else g.coin
	key = pcku.parse_key(sec,[network_for_netcode(coin)],secp256k1_generator)[1]
	if key is None: die(1,"can't parse {}".format(sec))
	o = pcku.create_output(sec,key,network_for_netcode(coin))[0]
	suf = ('_uncompressed','')[addr_type.compressed]
	wif = o['wif{}'.format(suf)]
	addr = o['p2sh_segwit' if addr_type.name == 'segwit' else '{}_address{}'.format(coin,suf)]
	return wif,addr
Example #2
0
def pycoin_sec2addr(sec):
	coin = ci.external_tests['testnet']['pycoin'][g.coin] if g.testnet else g.coin
	key = pcku.parse_key(sec,[network_for_netcode(coin)])[1]
	if key is None: die(1,"can't parse {}".format(sec))
	d = {
		'legacy':     ('wif_uncompressed','address_uncompressed'),
		'compressed': ('wif','address'),
		'segwit':     ('wif','p2sh_segwit'),
	}[addr_type.name]
	return [pcku.create_output(sec,key,network_for_netcode(coin),d[i])[0][d[i]] for i in (0,1)]
Example #3
0
File: ku.py Project: ctengiz/pycoin
def ku(args, parser):
    fallback_network = network_for_netcode(args.network
                                           or get_current_netcode())
    parse_networks = [fallback_network] + [
        network_for_netcode(netcode) for netcode in network_codes()
    ]
    if args.network:
        parse_networks = [network_for_netcode(args.network)]

    override_network = None
    if args.override_network:
        # Override the network value, so we can take the same xpubkey and view what
        # the values would be on each other network type.
        override_network = network_for_netcode(args.override_network)

    def parse_stdin():
        return [
            item for item in sys.stdin.readline().strip().split(' ')
            if len(item) > 0
        ]

    output_key_set = set(args.brief or [])
    if args.wallet:
        output_key_set.add("wallet_key")
    elif args.wif:
        output_key_set.add("wif_uncompressed" if args.uncompressed else "wif")
    elif args.address:
        output_key_set.add("address" +
                           ("_uncompressed" if args.uncompressed else ""))

    items = args.item if len(args.item) > 0 else parse_stdin()

    for item in items:
        key = parse_key(item, parse_networks)
        if key is None:
            print("can't parse %s" % item, file=sys.stderr)
            continue

        if override_network:
            key = key.override_network(override_network)

        display_network = override_network or key._network or fallback_network

        if hasattr(key, "subkeys"):
            key_iter = key.subkeys(args.subkey)
        else:
            key_iter = [key]
        for key in key_iter:
            if args.public:
                key = key.public_copy()

            output_dict, output_order = create_output(item, key,
                                                      output_key_set)

            generate_output(args, output_dict, output_order)
Example #4
0
def pycoin_sec2addr(sec):
    coin = ci.external_tests['testnet']['pycoin'][
        g.coin] if g.testnet else g.coin
    key = pcku.parse_key(sec, [network_for_netcode(coin)])[1]
    if key is None: die(1, "can't parse {}".format(sec))
    d = {
        'legacy': ('wif_uncompressed', 'address_uncompressed'),
        'compressed': ('wif', 'address'),
        'segwit': ('wif', 'p2sh_segwit'),
    }[addr_type.name]
    return [
        pcku.create_output(sec, key, network_for_netcode(coin), d[i])[0][d[i]]
        for i in (0, 1)
    ]
Example #5
0
def keychain(args, parser):
    network = network_for_netcode(args.netcode)

    parse = network.ui.parse

    keychain = Keychain(sqlite3.connect(args.keychain))

    keys = []
    for _ in args.key:
        key = parse(_, types=["electrum", "bip32"])
        if not key:
            raise ValueError("can't parse %s" % _)
        keys.append(key)

    subkey_paths = args.subkey_paths

    m = args.multisig
    if m and m > len(keys):
        raise ValueError("not enough keys for %d signatures" % m)

    total_paths = 0

    script_for_multisig = network.ui._script_info.script_for_multisig
    for path in subpaths_for_path_range(subkey_paths):
        if m:
            secs = sorted([_.subkey_for_path(path).sec() for _ in keys])
            script = script_for_multisig(m, secs)
            keychain.add_p2s_script(script)
            print(network.ui.address_for_p2s(script))
        total_paths += keychain.add_keys_path(keys, path)
    keychain.commit()
    print("%d total paths" % total_paths, file=sys.stderr)
Example #6
0
    def test_is_wif_valid(self):
        WIFS = [
            "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn",
            "5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf",
            "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU74NMTptX4",
            "5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAvUcVfH"
        ]

        for wif in WIFS:
            self.assertEqual(is_wif_valid(wif), "BTC")
            a = wif[:-1] + chr(ord(wif[-1]) + 1)
            self.assertEqual(is_wif_valid(a), None)

        from pycoin.networks.registry import network_for_netcode
        NETWORK_NAMES = network_codes()
        for netcode in NETWORK_NAMES:
            network = network_for_netcode(netcode)
            if not getattr(network, "key", None):
                continue
            for se in range(1, 10):
                key = network.key(secret_exponent=se,
                                  generator=secp256k1_generator)
                for tv in [True, False]:
                    wif = key.wif(use_uncompressed=tv)
                    self.assertEqual(
                        is_wif_valid(wif, allowable_netcodes=[netcode]),
                        netcode)
                    a = wif[:-1] + chr(ord(wif[-1]) + 1)
                    self.assertEqual(
                        is_wif_valid(a, allowable_netcodes=[netcode]), None)
Example #7
0
def create_parser():
    codes = network_codes()
    parser = argparse.ArgumentParser(
        description=(
            'Cache look-up information into a Keychain for use with tx. '
            'Useful for hiearchical keys with many children.'),
        epilog=('Known networks codes:\n  ' + ', '.join([
            '%s (%s)' % (i, network_for_netcode(i).full_name()) for i in codes
        ])))
    parser.add_argument('-n',
                        "--netcode",
                        help='specify network by netcode',
                        choices=codes,
                        default="BTC")
    parser.add_argument(
        '-m',
        "--multisig",
        metavar="sigcount",
        type=int,
        help='multisig, with this many signatures need to unencumber the funds'
    )
    parser.add_argument('keychain',
                        help='the keychain file (SQLite3 formatted)')
    parser.add_argument('subkey_paths',
                        help='subkey paths (example: 0H/2/15-20)')
    parser.add_argument(
        'key',
        nargs="+",
        help='a hierarchical wallet key string (public suffices)')
    return parser
Example #8
0
def keychain(args, parser):
    network = network_for_netcode(args.netcode)

    parse = network.ui.parse

    keychain = network.keychain(sqlite3.connect(args.keychain))

    keys = []
    for _ in args.key:
        key = parse(_, types=["electrum", "bip32"])
        if not key:
            raise ValueError("can't parse %s" % _)
        keys.append(key)

    subkey_paths = args.subkey_paths

    m = args.multisig
    if m and m > len(keys):
        raise ValueError("not enough keys for %d signatures" % m)

    total_paths = 0

    for path in subpaths_for_path_range(subkey_paths):
        if m:
            secs = sorted([_.subkey_for_path(path).sec() for _ in keys])
            script = network.contract.for_multisig(m, secs)
            keychain.add_p2s_script(script)
            print(network.ui.address_for_p2s(script))
        total_paths += keychain.add_keys_path(keys, path)
    keychain.commit()
    print("%d total paths" % total_paths, file=sys.stderr)
Example #9
0
def create_parser():
    codes = network_codes()
    parser = argparse.ArgumentParser(
        description='Create or verify a text signature using bitcoin standards',
        epilog=('Known networks codes:\n  ' + ', '.join([
            '%s (%s)' % (i, network_for_netcode(i).full_name()) for i in codes
        ])))
    parser.add_argument('-n',
                        "--network",
                        help='specify network (default: BTC = Bitcoin)',
                        default='BTC',
                        choices=codes)

    subparsers = parser.add_subparsers(dest="command")

    sign = subparsers.add_parser('sign',
                                 help='sign a message with a private key')
    sign.add_argument('WIF', help='the WIF to sign the message with')
    add_read_msg_arguments(sign, "signed")

    verify = subparsers.add_parser('verify')
    verify.add_argument('signature', help='the signature to verify')
    verify.add_argument('address',
                        nargs="?",
                        help='the address to verify against')
    add_read_msg_arguments(verify, "verified")

    return parser
Example #10
0
    def test_is_wif_valid(self):
        WIFS = [
            "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn",
            "5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf",
            "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU74NMTptX4",
            "5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAvUcVfH"
        ]

        for wif in WIFS:
            self.assertEqual(BTC.parse.wif(wif).wif(), wif)
            a = wif[:-1] + chr(ord(wif[-1]) + 1)
            self.assertIsNone(BTC.parse.wif(a))

        NETWORK_NAMES = network_codes()
        for netcode in NETWORK_NAMES:
            network = network_for_netcode(netcode)
            if not getattr(network, "Key", None):
                continue
            for se in range(1, 10):
                key = network.Key(secret_exponent=se)
                for tv in [True, False]:
                    wif = key.wif(is_compressed=tv)
                    self.assertEqual(network.parse.wif(wif).wif(), wif)
                    a = wif[:-1] + chr(ord(wif[-1]) + 1)
                    self.assertIsNone(network.parse.wif(a))
Example #11
0
def parse_context(args, parser):
    network = network_for_netcode(args.network)
    tx_class = network.tx

    # we create the tx_db lazily
    tx_db = None

    if args.db:
        try:
            txs = [tx_class.from_hex(tx_hex) for tx_hex in args.db]
        except Exception:
            parser.error("can't parse ")
        the_ram_tx_db = dict((tx.hash(), tx) for tx in txs)
        if tx_db is None:
            tx_db = create_tx_db(network)
        tx_db.lookup_methods.append(the_ram_tx_db.get)

    # defaults

    txs = []
    spendables = []
    payables = []

    key_iters = []

    # there are a few warnings we might optionally print out, but only if
    # they are relevant. We don't want to print them out multiple times, so we
    # collect them here and print them at the end if they ever kick in.

    warning_spendables = None

    for arg in args.argument:
        tx, tx_db = parse_tx(tx_class, arg, parser, tx_db, network)
        if tx:
            txs.append(tx)
            continue

        if key_found(arg, payables, key_iters, network):
            continue

        if parse_parts(tx_class, arg, spendables, payables, network):
            continue

        payable = script_for_address_or_opcodes(network, arg)
        if payable is not None:
            payables.append((payable, 0))
            continue

        parser.error("can't parse %s" % arg)

    parse_private_key_file(args, key_iters)

    if args.fetch_spendables:
        warning_spendables = message_about_spendables_for_address_env(args.network)
        for address in args.fetch_spendables:
            spendables.extend(spendables_for_address(address, args.network))

    return (network, txs, spendables, payables, key_iters, tx_db, warning_spendables)
Example #12
0
def coinc(args, parser):
    network = network_for_netcode(args.network)

    for arg in args.argument:
        info = info_for_arg(arg, network)
        for k in ("compiled_script_hex address_p2s preimage_p2s_hex "
                  "address_p2s_wit underlying_script disassembled_script"
                  ).split():
            print(info[k])
Example #13
0
def msg_sign(args, parser):
    network = network_for_netcode(args.network)
    message_signer = network.msg
    message_hash = get_message_hash(args, message_signer)
    network, key = parse_key(args.WIF, [network])
    is_compressed = key.is_compressed()
    sig = message_signer.signature_for_message_hash(
        key.secret_exponent(), msg_hash=message_hash, is_compressed=is_compressed)
    print(sig)
Example #14
0
def ku(args, parser):
    fallback_network = network_for_netcode(args.network or get_current_netcode())
    parse_networks = [fallback_network] + [network_for_netcode(netcode) for netcode in network_codes()]
    if args.network:
        parse_networks = [network_for_netcode(args.network)]

    override_network = None
    if args.override_network:
        # Override the network value, so we can take the same xpubkey and view what
        # the values would be on each other network type.
        override_network = network_for_netcode(args.override_network)

    def parse_stdin():
        return [item for item in sys.stdin.readline().strip().split(' ') if len(item) > 0]

    output_key_set = set(args.brief or [])
    if args.wallet:
        output_key_set.add("wallet_key")
    elif args.wif:
        output_key_set.add("wif_uncompressed" if args.uncompressed else "wif")
    elif args.address:
        output_key_set.add("address" + ("_uncompressed" if args.uncompressed else ""))

    items = args.item if len(args.item) > 0 else parse_stdin()

    for item in items:
        key_network, key = parse_key(item, parse_networks)
        if key is None:
            print("can't parse %s" % item, file=sys.stderr)
            continue

        display_network = override_network or key_network or fallback_network

        if hasattr(key, "subkeys"):
            key_iter = key.subkeys(args.subkey)
        else:
            key_iter = [key]
        for key in key_iter:
            if args.public:
                key = key.public_copy()

            output_dict, output_order = create_output(item, key, display_network, output_key_set)

            generate_output(args, output_dict, output_order)
Example #15
0
def mnemonic_to_bip32_node(mnemonic, passphrase='', net_code='BTC'):
    """
    mnemonic sentence to bip32 node
    :param mnemonic: mnemonic sentence
    :param passphrase: used for PBKDF2 salt('mnemonic' + passphrase)
    :param net_code: 'BTC' => "mainnet", 'XTN' => "testnet3"
    """
    master_seed = Mnemonic.to_seed(mnemonic, passphrase=passphrase)
    network = network_for_netcode(net_code)
    return network.keys.bip32_seed(master_seed)
Example #16
0
def external_key_from_account_hwif(hwif, key_idx=0, net_code='BTC'):
    """
    path 0 / {key_idx}
    :param hwif: bip32 private key format
    :param key_idx: 0 as first key
    :param net_code: hwif corresponding net code
    """
    network = network_for_netcode(net_code)
    node = network.parse.bip32(hwif)
    return node.subkey_for_path(f'0/{key_idx}')
Example #17
0
def mnemonic_to_bip32_hwif(mnemonic, passphrase='', net_code='BTC'):
    """
    mnemonic sentence to bip32 private key format which starts with 'xprv'
    :param mnemonic: mnemonic sentence
    :param passphrase: used for PBKDF2 salt('mnemonic' + passphrase)
    :param net_code: BTC or XTN(test net)
    """
    master_seed = Mnemonic.to_seed(mnemonic, passphrase=passphrase)
    network = network_for_netcode(net_code)
    master = network.keys.bip32_seed(master_seed)
    return master.hwif(as_private=True)
Example #18
0
def msg_sign(args, parser):
    network = network_for_netcode(args.network)
    message_signer = network.msg
    message_hash = get_message_hash(args, message_signer)
    network, key = parse_key(args.WIF, [network])
    is_compressed = key.is_compressed()
    sig = message_signer.signature_for_message_hash(
        key.secret_exponent(),
        msg_hash=message_hash,
        is_compressed=is_compressed)
    print(sig)
Example #19
0
def ku(args, parser):
    generator = secp256k1_generator

    fallback_network = network_for_netcode(args.network
                                           or get_current_netcode())
    parse_networks = [
        network_for_netcode(netcode) for netcode in network_codes()
    ]
    if args.network:
        parse_networks = [network_for_netcode(args.network)]

    override_network = None
    if args.override_network:
        # Override the network value, so we can take the same xpubkey and view what
        # the values would be on each other network type.
        override_network = network_for_netcode(args.override_network)

    def parse_stdin():
        return [
            item for item in sys.stdin.readline().strip().split(' ')
            if len(item) > 0
        ]

    items = args.item if len(args.item) > 0 else parse_stdin()

    for item in items:
        key_network, key = parse_key(item, parse_networks, generator)
        if key is None:
            print("can't parse %s" % item, file=sys.stderr)
            continue

        display_network = override_network or key_network or fallback_network

        for key in key.subkeys(args.subkey or ""):
            if args.public:
                key = key.public_copy()

            output_dict, output_order = create_output(item, key,
                                                      display_network)

            generate_output(args, output_dict, output_order)
Example #20
0
def bip44_btc_account(mnemonic, account=0, passphrase=''):
    """
    bip44 btc format m / 44' / 0' / {account}'
    account can generate related address/key pairs
    :param mnemonic: mnemonic sentence
    :param account: 0 as first account
    :param passphrase: used for PBKDF2 salt('mnemonic' + passphrase)
    """
    master_seed = Mnemonic.to_seed(mnemonic, passphrase=passphrase)
    network = network_for_netcode('BTC')
    master = network.keys.bip32_seed(master_seed)
    return master.subkey_for_path(f'44H/0H/{account}H')
Example #21
0
def msg_sign(args, parser):
    network = network_for_netcode(args.network)
    message_signer = MessageSigner(network.network_name, network.ui,
                                   secp256k1_generator)
    message_hash = get_message_hash(args, message_signer)
    network, key = parse_key(args.WIF, [network], secp256k1_generator)
    is_compressed = not key._use_uncompressed()
    sig = message_signer.signature_for_message_hash(
        key.secret_exponent(),
        msg_hash=message_hash,
        is_compressed=is_compressed)
    print(sig)
Example #22
0
def bip44_test_external_key(mnemonic, account=0, key_idx=0, passphrase=''):
    """
    bip44 testnet format m / 44' / 1' / {account}' / 0 / {key_idx}
    :param mnemonic: mnemonic sentence
    :param account: 0 as first account
    :param key_idx: 0 as first key
    :param passphrase: used for PBKDF2 salt('mnemonic' + passphrase)
    """
    master_seed = Mnemonic.to_seed(mnemonic, passphrase=passphrase)
    network = network_for_netcode('XTN')
    master = network.keys.bip32_seed(master_seed)
    return master.subkey_for_path(f'44H/1H/{account}H/0/{key_idx}')
Example #23
0
def bip44_eth_account(mnemonic, account=0, passphrase=''):
    """
    bip44 eth format m / 44' / 0' / {account}'
    account can generate related address/key pairs
    :param mnemonic: mnemonic sentence
    :param account: 0 as first account
    :param passphrase: used for PBKDF2 salt('mnemonic' + passphrase)
    """
    master_seed = Mnemonic.to_seed(mnemonic, passphrase=passphrase)
    # we just need the private key, BTC symbol will not used to generate address for ETH
    network = network_for_netcode('BTC')
    master = network.keys.bip32_seed(master_seed)
    return master.subkey_for_path(f'44H/60H/{account}H')
Example #24
0
def create_parser():
    codes = network_codes()
    parser = argparse.ArgumentParser(
        description=(
            'Cache look-up information into a Keychain for use with tx. '
            'Useful for hiearchical keys with many children.'),
        epilog=('Known networks codes:\n  ' +
                ', '.join(['%s (%s)' % (i, network_for_netcode(i).full_name()) for i in codes]))
    )
    parser.add_argument('-n', "--netcode", help='specify network by netcode', choices=codes, default="BTC")
    parser.add_argument('-m', "--multisig", metavar="sigcount", type=int,
                        help='multisig, with this many signatures need to unencumber the funds')
    parser.add_argument('keychain', help='the keychain file (SQLite3 formatted)')
    parser.add_argument('subkey_paths', help='subkey paths (example: 0H/2/15-20)')
    parser.add_argument('key', nargs="+", help='a hierarchical wallet key string (public suffices)')
    return parser
Example #25
0
 def test_keychain(self):
     netcode = "BTC"
     network = network_for_netcode(netcode)
     BIP32 = network.ui._bip32node_class
     keychain = Keychain()
     bip32_list = [BIP32.from_master_secret(_) for _ in [b"foo", b"bar"]]
     for bip32 in bip32_list:
         keychain.add_key_paths(bip32.public_copy(), subpaths_for_path_range("0-1/0-10"))
     keychain.add_secrets(bip32_list)
     for bip32 in bip32_list:
         for path in ["0/5", "1/2", "0/9"]:
             subkey = bip32.subkey_for_path("0/5")
             v = keychain.get(subkey.hash160())
             self.assertEqual(v[0], subkey.secret_exponent())
     v = keychain.get(b'0' * 32)
     self.assertEqual(v, None)
Example #26
0
    def test_is_public_private_bip32_valid(self):
        from pycoin.networks.registry import network_for_netcode
        NETWORK_NAMES = network_codes()
        WALLET_KEYS = ["foo", "1", "2", "3", "4", "5"]

        # not all networks support BIP32 yet
        for netcode in "BTC XTN DOGE".split():
            network = network_for_netcode(netcode)
            BIP32Node = network.ui._bip32node_class
            for wk in WALLET_KEYS:
                wallet = BIP32Node.from_master_secret(secp256k1_generator,
                                                      wk.encode("utf8"))
                text = wallet.wallet_key(as_private=True)
                self.assertEqual(
                    is_private_bip32_valid(text,
                                           allowable_netcodes=NETWORK_NAMES),
                    netcode)
                self.assertEqual(
                    is_public_bip32_valid(text,
                                          allowable_netcodes=NETWORK_NAMES),
                    None)
                a = text[:-1] + chr(ord(text[-1]) + 1)
                self.assertEqual(
                    is_private_bip32_valid(a,
                                           allowable_netcodes=NETWORK_NAMES),
                    None)
                self.assertEqual(
                    is_public_bip32_valid(a, allowable_netcodes=NETWORK_NAMES),
                    None)
                text = wallet.wallet_key(as_private=False)
                self.assertEqual(
                    is_private_bip32_valid(text,
                                           allowable_netcodes=NETWORK_NAMES),
                    None)
                self.assertEqual(
                    is_public_bip32_valid(text,
                                          allowable_netcodes=NETWORK_NAMES),
                    netcode)
                a = text[:-1] + chr(ord(text[-1]) + 1)
                self.assertEqual(
                    is_private_bip32_valid(a,
                                           allowable_netcodes=NETWORK_NAMES),
                    None)
                self.assertEqual(
                    is_public_bip32_valid(a, allowable_netcodes=NETWORK_NAMES),
                    None)
Example #27
0
    def test_repr(self):
        BitcoinTestnet = network_for_netcode("XTN")
        Key = BitcoinTestnet.ui._key_class
        key = Key(secret_exponent=273)
        wallet = XTNBIP32Node.from_master_secret(
            bytes(key.wif().encode('ascii')))

        address = wallet.address()
        pub_k = key_from_text(address, networks=[BitcoinTestnet])
        self.assertEqual(repr(pub_k), '<myb5gZNXePNf2E2ksrjnHRFCwyuvt7oEay>')

        wif = wallet.wif()
        priv_k = key_from_text(wif, networks=[BitcoinTestnet])
        self.assertEqual(
            repr(priv_k),
            'private_for <XTNSEC:03ad094b1dc9fdce5d3648ca359b4e210a89d049532fdd39d9ccdd8ca393ac82f4>'
        )
Example #28
0
def coinc(args, parser):
    network = network_for_netcode(args.network)
    script_tools = network.extras.ScriptTools

    for arg in args.argument:
        compiled_script = script_tools.compile(arg)
        print(b2h(compiled_script))

        address_p2s = network.ui.address_for_p2s(compiled_script)
        print(address_p2s)
        print(b2h(network.ui.script_for_address(address_p2s)))

        address_p2s_wit = network.ui.address_for_p2s_wit(compiled_script)
        print(address_p2s_wit)
        print(b2h(network.ui.script_for_address(address_p2s_wit)))

        print(script_tools.disassemble(compiled_script))
Example #29
0
def msg_verify(args, parser):
    network = network_for_netcode(args.network)
    message_signer = network.msg
    message_hash = get_message_hash(args, message_signer)
    try:
        pair, is_compressed = message_signer.pair_for_message_hash(args.signature, msg_hash=message_hash)
    except EncodingError:
        pass
    ta = network.address.for_p2pkh(public_pair_to_hash160_sec(pair, compressed=is_compressed))
    if args.address:
        if ta == args.address:
            print("signature ok")
            return 0
        else:
            print("bad signature, matches %s" % ta)
            return 1
    else:
        print(ta)
Example #30
0
def make_tests_for_netcode(netcode):

    network = network_for_netcode(netcode)

    class KuTest(ToolTest):

        @classmethod
        def setUpClass(cls):
            cls.parser = ku.create_parser()
            cls.tool_name = "ku"

        def test_ku_create(self):
            output = self.launch_tool("ku create -w -n %s" % netcode).split("\n")
            bip32 = network.parse.bip32_prv(output[0])
            bip32_as_text = bip32.hwif(as_private=True)
            self.assertEqual(output[0], bip32_as_text)

    return KuTest
Example #31
0
def msg_verify(args, parser):
    network = network_for_netcode(args.network)
    message_signer = network.msg
    message_hash = get_message_hash(args, message_signer)
    try:
        pair, is_compressed = message_signer.pair_for_message_hash(
            args.signature, msg_hash=message_hash)
    except EncodingError:
        pass
    ta = network.address.for_p2pkh(
        public_pair_to_hash160_sec(pair, compressed=is_compressed))
    if args.address:
        if ta == args.address:
            print("signature ok")
            return 0
        else:
            print("bad signature, matches %s" % ta)
            return 1
    else:
        print(ta)
Example #32
0
    def test_is_public_private_bip32_valid(self):
        from pycoin.networks.registry import network_for_netcode
        WALLET_KEYS = ["foo", "1", "2", "3", "4", "5"]

        # not all networks support BIP32 yet
        for netcode in NETCODES:
            network = network_for_netcode(netcode)
            for wk in WALLET_KEYS:
                wallet = network.keys.bip32_seed(wk.encode("utf8"))
                text = wallet.hwif(as_private=True)
                self.assertEqual(network.parse.bip32_prv(text).hwif(as_private=True), text)
                self.assertIsNone(network.parse.bip32_pub(text))
                a = text[:-1] + chr(ord(text[-1])+1)
                self.assertIsNone(network.parse.bip32_prv(a))
                self.assertIsNone(network.parse.bip32_pub(a))
                text = wallet.hwif(as_private=False)
                self.assertIsNone(network.parse.bip32_prv(text))
                self.assertEqual(network.parse.bip32_pub(text).hwif(), text)
                a = text[:-1] + chr(ord(text[-1])+1)
                self.assertIsNone(network.parse.bip32_prv(a))
                self.assertIsNone(network.parse.bip32_pub(a))
Example #33
0
def create_parser():
    codes = network_codes()
    EPILOG = ('Known networks codes:\n  ' + ', '.join(
        ['%s (%s)' % (i, network_for_netcode(i).full_name()) for i in codes]))

    parser = argparse.ArgumentParser(
        description="Compile or disassemble scripts.", epilog=EPILOG)

    parser.add_argument(
        '-n',
        "--network",
        default=get_current_netcode(),
        choices=codes,
        help=('Network code (environment variable PYCOIN_DEFAULT_NETCODE '
              'or "BTC"=Bitcoin mainnet if unset)'))

    parser.add_argument("argument",
                        nargs="+",
                        help='script to compile. To dump hex, prefix with 0x')

    return parser
Example #34
0
    def test_is_public_private_bip32_valid(self):
        from pycoin.networks.registry import network_for_netcode
        WALLET_KEYS = ["foo", "1", "2", "3", "4", "5"]

        # not all networks support BIP32 yet
        for netcode in NETCODES:
            network = network_for_netcode(netcode)
            for wk in WALLET_KEYS:
                wallet = network.keys.bip32_seed(wk.encode("utf8"))
                text = wallet.hwif(as_private=True)
                self.assertEqual(
                    network.parse.bip32_prv(text).hwif(as_private=True), text)
                self.assertIsNone(network.parse.bip32_pub(text))
                a = text[:-1] + chr(ord(text[-1]) + 1)
                self.assertIsNone(network.parse.bip32_prv(a))
                self.assertIsNone(network.parse.bip32_pub(a))
                text = wallet.hwif(as_private=False)
                self.assertIsNone(network.parse.bip32_prv(text))
                self.assertEqual(network.parse.bip32_pub(text).hwif(), text)
                a = text[:-1] + chr(ord(text[-1]) + 1)
                self.assertIsNone(network.parse.bip32_prv(a))
                self.assertIsNone(network.parse.bip32_pub(a))
Example #35
0
    def test_is_public_private_bip32_valid(self):
        from pycoin.networks.registry import network_for_netcode
        WALLET_KEYS = ["foo", "1", "2", "3", "4", "5"]

        # not all networks support BIP32 yet
        for netcode in NETCODES:
            network = network_for_netcode(netcode)
            BIP32Node = network.ui._bip32node_class
            for wk in WALLET_KEYS:
                wallet = BIP32Node.from_master_secret(wk.encode("utf8"))
                text = wallet.hwif(as_private=True)
                self.assertEqual(is_private_bip32_valid(text, allowable_netcodes=NETCODES), netcode)
                self.assertEqual(is_public_bip32_valid(text, allowable_netcodes=NETCODES), None)
                a = text[:-1] + chr(ord(text[-1])+1)
                self.assertEqual(is_private_bip32_valid(a, allowable_netcodes=NETCODES), None)
                self.assertEqual(is_public_bip32_valid(a, allowable_netcodes=NETCODES), None)
                text = wallet.hwif(as_private=False)
                self.assertEqual(is_private_bip32_valid(text, allowable_netcodes=NETCODES), None)
                self.assertEqual(is_public_bip32_valid(text, allowable_netcodes=NETCODES), netcode)
                a = text[:-1] + chr(ord(text[-1])+1)
                self.assertEqual(is_private_bip32_valid(a, allowable_netcodes=NETCODES), None)
                self.assertEqual(is_public_bip32_valid(a, allowable_netcodes=NETCODES), None)
Example #36
0
def create_parser():
    codes = network_codes()
    parser = argparse.ArgumentParser(
        description='Create or verify a text signature using bitcoin standards',
        epilog=('Known networks codes:\n  ' +
                ', '.join(['%s (%s)' % (i, network_for_netcode(i).full_name()) for i in codes]))
    )
    parser.add_argument('-n', "--network", help='specify network (default: BTC = Bitcoin)',
                        default='BTC', choices=codes)

    subparsers = parser.add_subparsers(dest="command")

    sign = subparsers.add_parser('sign', help='sign a message with a private key')
    sign.add_argument('WIF', help='the WIF to sign the message with')
    add_read_msg_arguments(sign, "signed")

    verify = subparsers.add_parser('verify')
    verify.add_argument('signature', help='the signature to verify')
    verify.add_argument('address', nargs="?", help='the address to verify against')
    add_read_msg_arguments(verify, "verified")

    return parser
Example #37
0
def create_parser():
    codes = network_codes()
    parser = argparse.ArgumentParser(
        description='Crypto coin utility ku ("key utility") to show'
        ' information about Bitcoin or other cryptocoin data structures.',
        epilog=('Known networks codes:\n  ' +
                ', '.join(['%s (%s)' % (i, network_for_netcode(i).full_name()) for i in codes]))
    )
    parser.add_argument('-w', "--wallet", help='show just Bitcoin wallet key', action='store_true')
    parser.add_argument('-W', "--wif", help='show just Bitcoin WIF', action='store_true')
    parser.add_argument('-a', "--address", help='show just Bitcoin address', action='store_true')
    parser.add_argument(
        '-u', "--uncompressed", help='show output in uncompressed form', action='store_true')
    parser.add_argument(
        '-P', "--public", help='only show public version of wallet keys', action='store_true')

    parser.add_argument('-j', "--json", help='output as JSON', action='store_true')

    parser.add_argument('-b', "--brief", nargs="*", help='brief output; display a single field')

    parser.add_argument('-s', "--subkey", help='subkey path (example: 0H/2/15-20)', default="")
    parser.add_argument('-n', "--network", help='specify network', choices=codes)
    parser.add_argument(
        "--override-network", help='override detected network type', default=None, choices=codes)

    parser.add_argument(
        'item', nargs="*", help='a BIP0032 wallet key string;'
        ' a WIF;'
        ' a bitcoin address;'
        ' an SEC (ie. a 66 hex chars starting with 02, 03 or a 130 hex chars starting with 04);'
        ' the literal string "create" to create a new wallet key using strong entropy sources;'
        ' P:wallet passphrase (NOT RECOMMENDED);'
        ' H:wallet passphrase in hex (NOT RECOMMENDED);'
        ' E:electrum value (either a master public, master private, or initial data);'
        ' secret_exponent (in decimal or hex);'
        ' x,y where x,y form a public pair (y is a number or one of the strings "even" or "odd");'
        ' hash160 (as 40 hex characters).'
        ' If this argument is missing, input data will be read from stdin.')
    return parser
Example #38
0
    def test_is_public_private_bip32_valid(self):
        from pycoin.networks.registry import network_for_netcode
        WALLET_KEYS = ["foo", "1", "2", "3", "4", "5"]

        # not all networks support BIP32 yet
        for netcode in NETCODES:
            network = network_for_netcode(netcode)
            BIP32Node = network.ui._bip32node_class
            for wk in WALLET_KEYS:
                wallet = BIP32Node.from_master_secret(wk.encode("utf8"))
                text = wallet.hwif(as_private=True)
                self.assertEqual(
                    is_private_bip32_valid(text, allowable_netcodes=NETCODES),
                    netcode)
                self.assertEqual(
                    is_public_bip32_valid(text, allowable_netcodes=NETCODES),
                    None)
                a = text[:-1] + chr(ord(text[-1]) + 1)
                self.assertEqual(
                    is_private_bip32_valid(a, allowable_netcodes=NETCODES),
                    None)
                self.assertEqual(
                    is_public_bip32_valid(a, allowable_netcodes=NETCODES),
                    None)
                text = wallet.hwif(as_private=False)
                self.assertEqual(
                    is_private_bip32_valid(text, allowable_netcodes=NETCODES),
                    None)
                self.assertEqual(
                    is_public_bip32_valid(text, allowable_netcodes=NETCODES),
                    netcode)
                a = text[:-1] + chr(ord(text[-1]) + 1)
                self.assertEqual(
                    is_private_bip32_valid(a, allowable_netcodes=NETCODES),
                    None)
                self.assertEqual(
                    is_public_bip32_valid(a, allowable_netcodes=NETCODES),
                    None)
Example #39
0
    def test_is_wif_valid(self):
        WIFS = ["KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn",
                "5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf",
                "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU74NMTptX4",
                "5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAvUcVfH"]

        for wif in WIFS:
            self.assertEqual(BTC.parse.wif(wif).wif(), wif)
            a = wif[:-1] + chr(ord(wif[-1])+1)
            self.assertIsNone(BTC.parse.wif(a))

        NETWORK_NAMES = network_codes()
        for netcode in NETWORK_NAMES:
            network = network_for_netcode(netcode)
            if not getattr(network, "Key", None):
                continue
            for se in range(1, 10):
                key = network.Key(secret_exponent=se)
                for tv in [True, False]:
                    wif = key.wif(is_compressed=tv)
                    self.assertEqual(network.parse.wif(wif).wif(), wif)
                    a = wif[:-1] + chr(ord(wif[-1])+1)
                    self.assertIsNone(network.parse.wif(a))
Example #40
0
    def _manually_initialize(self):
        """ Create words (if is None) and start seed and master node
            Then we generate the first addresses, so we can check if we already have transactions
        """
        self.mnemonic = Mnemonic(self.language)

        if not self.words:
            # Initialized but still locked
            return

        # Validate words first
        self.validate_words()

        assert isinstance(self.passphrase,
                          bytes), 'Passphrase must be in bytes'

        # Master seed
        seed = self.mnemonic.to_seed(self.words,
                                     self.passphrase.decode('utf-8'))

        # Master node
        from pycoin.networks.registry import network_for_netcode
        _register_pycoin_networks()
        network = network_for_netcode('htr')
        key = network.keys.bip32_seed(seed)

        # Until account key should be hardened
        # Chain path = 44'/0'/0'/0
        # 44' (hardened) -> BIP44
        # 280' (hardened) -> Coin type (280 = hathor)
        # 0' (hardened) -> Account
        # 0 -> Chain
        self.chain_key = key.subkey_for_path('44H/280H/0H/0')

        for key in self.chain_key.children(self.initial_key_generation, 0,
                                           False):
            self._key_generated(key, key.child_index())
Example #41
0
    def test_is_wif_valid(self):
        WIFS = ["KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sVHnoWn",
                "5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAnchuDf",
                "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU74NMTptX4",
                "5HpHagT65TZzG1PH3CSu63k8DbpvD8s5ip4nEB3kEsreAvUcVfH"]

        for wif in WIFS:
            self.assertEqual(is_wif_valid(wif, allowable_netcodes=NETCODES), "BTC")
            a = wif[:-1] + chr(ord(wif[-1])+1)
            self.assertEqual(is_wif_valid(a), None)

        from pycoin.networks.registry import network_for_netcode
        NETWORK_NAMES = network_codes()
        for netcode in NETWORK_NAMES:
            network = network_for_netcode(netcode)
            if not getattr(network, "key", None):
                continue
            for se in range(1, 10):
                key = network.key(secret_exponent=se)
                for tv in [True, False]:
                    wif = key.wif(use_uncompressed=tv)
                    self.assertEqual(is_wif_valid(wif, allowable_netcodes=[netcode]), netcode)
                    a = wif[:-1] + chr(ord(wif[-1])+1)
                    self.assertEqual(is_wif_valid(a, allowable_netcodes=[netcode]), None)
Example #42
0
valid_private_key = False
while not valid_private_key:
    my_secret = 1 #util.randrange(ecdsa.generator_secp256k1.order())
    valid_private_key = 0 < my_secret < ecdsa.generator_secp256k1.order()

print("")
my_prng = util.PRNG(util.randrange(ecdsa.generator_secp256k1.order()))
print("PRNG (random generator) 32 bytes: ", b2h(my_prng.__call__(32)))

my_netcode = "BTC" # mainnet: BTC, testnet3: XTN

my_key = Key(secret_exponent=my_secret, is_compressed=True, netcode=my_netcode)
## netcode list: pycoin.networks.all.py

pp = pprint.PrettyPrinter(indent=2)
my_network = registry.network_for_netcode(my_netcode)
my_addr_prefix = registry._lookup(my_netcode, "address")
getattr(my_network, "address")
pp.pprint(my_network.__dict__)
pprint.pprint(my_network.__dict__.keys(), width=60, depth=2)

privkey_hex = b2h(encoding.to_bytes_32(my_key.secret_exponent()))
assert(len(privkey_hex) == 64)

print("\npycoin.key.Key example - ", my_netcode)

#print("Private Key (dec): ", eval('0x' + privkey_hex))
print("Private Key (dec): ", int(privkey_hex, 16))
print("Private Key (hex): ", privkey_hex)
privkey_bytes = unhexlify(privkey_hex)
# use CBitcoinSecret to compress private key
Example #43
0
def make_tests_for_netcode(netcode):
    network = network_for_netcode(netcode)

    Tx = network.tx
    annotate_scripts = network.annotate.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.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
Example #44
0
 def test_sighash_single(self):
     for netcode in ["BTC", "XTN"]:
         self._test_sighash_single(network_for_netcode(netcode))
def make_tests_for_netcode(netcode):
    network = network_for_netcode(netcode)

    address_for_script = network.address.for_script
    script_for_p2pkh = network.contract.for_p2pkh
    script_for_p2pk = network.contract.for_p2pk
    script_for_nulldata = network.contract.for_nulldata

    Tx = network.tx

    class AddressForScriptTest(unittest.TestCase):

        def test_script_type_pay_to_address(self):
            for se in range(1, 100):
                key = network.keys.private(secret_exponent=se)
                for b in [True, False]:
                    addr = key.address(is_compressed=b)
                    sc = script_for_p2pkh(key.hash160(is_compressed=b))
                    afs_address = address_for_script(sc)
                    self.assertEqual(afs_address, addr)

        def test_solve_pay_to_address(self):
            for se in range(1, 10):
                key = network.keys.private(secret_exponent=se)
                for b in [True, False]:
                    addr = key.address(is_compressed=b)
                    script = script_for_p2pkh(key.hash160(is_compressed=b))
                    afs_address = address_for_script(script)
                    self.assertEqual(afs_address, addr)
                    hl = network.tx.solve.build_hash160_lookup([se])
                    tx = Tx(1, [], [Tx.TxOut(100, script)])
                    tx.sign(hash160_lookup=hl)
                    afs_address = address_for_script(tx.txs_out[0].puzzle_script())
                    self.assertEqual(afs_address, addr)

        def test_script_type_pay_to_public_pair(self):
            for se in range(1, 100):
                key = network.keys.private(secret_exponent=se)
                for b in [True, False]:
                    addr = key.address(is_compressed=b)
                    sc = script_for_p2pk(key.sec(is_compressed=b))
                    afs_address = address_for_script(sc)
                    self.assertEqual(afs_address, addr)

        def test_solve_pay_to_public_pair(self):
            for se in range(1, 10):
                key = network.keys.private(secret_exponent=se)
                for b in [True, False]:
                    addr = key.address(is_compressed=b)
                    script = script_for_p2pk(key.sec(is_compressed=b))
                    afs_address = address_for_script(script)
                    self.assertEqual(afs_address, addr)
                    hl = network.tx.solve.build_hash160_lookup([se])
                    tx = Tx(1, [], [Tx.TxOut(100, script)])
                    tx.sign(hash160_lookup=hl)
                    afs_address = address_for_script(tx.txs_out[0].puzzle_script())
                    self.assertEqual(afs_address, addr)

        def test_weird_tx(self):
            # this is from tx 12a8d1d62d12307eac6e62f2f14d7e826604e53c320a154593845aa7c8e59fbf
            afs_address = address_for_script(b'Q')
            self.assertNotEqual(afs_address, None)
            self.assertEqual(afs_address, "???")

        def test_issue_225(self):
            script = script_for_nulldata(b"foobar")
            tx_out = Tx.TxOut(1, script)
            address = address_for_script(tx_out.puzzle_script())
            self.assertEqual(address, "(nulldata 666f6f626172)")

    return AddressForScriptTest
Example #46
0
import unittest

from pycoin.networks.registry import network_for_netcode
from pycoin.ui.key_from_text import key_from_text


NETWORKS = [network_for_netcode(_) for _ in ["BTC", "XTN"]]


class KeyParserTest(unittest.TestCase):

    def test_parse_bip32_prv(self):
        key = key_from_text("xprv9s21ZrQH143K31AgNK5pyVvW23gHnkBq2wh5aEk6g1s496M8ZMjx"
                            "ncCKZKgb5jZoY5eSJMJ2Vbyvi2hbmQnCuHBujZ2WXGTux1X2k9Krdtq", networks=NETWORKS)
        self.assertEqual(
            key.secret_exponent(), 0x91880b0e3017ba586b735fe7d04f1790f3c46b818a2151fb2def5f14dd2fd9c3)
        self.assertEqual(key.address(), "19Vqc8uLTfUonmxUEZac7fz1M5c5ZZbAii")
        self.assertEqual(key.address(use_uncompressed=True), "1MwkRkogzBRMehBntgcq2aJhXCXStJTXHT")
        subkey = key.subkey_for_path("0")
        self.assertEqual(subkey.address(), "1NV3j6NgeAkWBytXiQkWxMFLBtTdbef1rp")

    def test_parse_bip32_prv_xtn(self):
        key = key_from_text("tprv8ZgxMBicQKsPdpQD2swL99YVLB6W2GDqNVcCSfAZ9zMXvh6DYj5iJMZmUVrF66"
                            "x7uXBDJSunexZjAtFLtd89iLTWGCEpBdBxs7GTBnEksxV", networks=NETWORKS)
        self.assertEqual(
            key.secret_exponent(), 0x91880b0e3017ba586b735fe7d04f1790f3c46b818a2151fb2def5f14dd2fd9c3)
        self.assertEqual(key.address(), "mp1nuBzKGgv4ZtS5x8YywbCLD5CnVfT7hV")
        self.assertEqual(key.address(use_uncompressed=True), "n2ThiotfoCrcRofQcFbCrVX2PC89s2KUjh")
        subkey = key.subkey_for_path("0")
        self.assertEqual(subkey.address(), "n31129TfTCBky6N9RyitnGTf3t4LYwCV6A")
Example #47
0
def create_parser():
    codes = network_codes()
    EPILOG = ('Files are binary by default unless they end with the suffix ".hex". ' +
              'Known networks codes:\n  ' +
              ', '.join(['%s (%s)' % (i, network_for_netcode(i).full_name()) for i in codes]))

    parser = argparse.ArgumentParser(
        description="Manipulate bitcoin (or alt coin) transactions.",
        epilog=EPILOG)

    parser.add_argument('-t', "--transaction-version", type=range_int(0, 255, "version"),
                        help='Transaction version, either 1 (default) or 3 (not yet supported).')

    parser.add_argument('-l', "--lock-time", type=parse_locktime, help='Lock time; either a block'
                        'index, or a date/time (example: "2014-01-01T15:00:00"')

    parser.add_argument('-n', "--network", default=get_current_netcode(), choices=codes,
                        help=('Default network code (environment variable PYCOIN_DEFAULT_NETCODE '
                              'or "BTC"=Bitcoin mainnet if unset'))

    parser.add_argument('-a', "--augment", action='store_true',
                        help='augment tx by adding any missing spendable metadata by fetching'
                             ' inputs from cache and/or web services')

    parser.add_argument('-s', "--verbose-signature", action='store_true',
                        help='Display technical signature details.')

    parser.add_argument("-i", "--fetch-spendables", metavar="address", action="append",
                        help='Add all unspent spendables for the given bitcoin address. This information'
                        ' is fetched from web services. With no outputs, incoming spendables will be printed.')

    parser.add_argument("-I", "--dump-inputs", action='store_true', help='Dump inputs to this transaction.')

    parser.add_argument(
        "-k", "--keychain", default=":memory:",
        help="path to keychain file for hierarchical key hints (SQLite3 file created with keychain tool)")

    parser.add_argument(
        "-K", "--key-paths", default="",
        help="Key path hints to search hiearachical private keys (example: 0/0H/0-20)")

    parser.add_argument('-f', "--private-key-file", metavar="path-to-private-keys", action="append", default=[],
                        help='file containing WIF or BIP0032 private keys. If file name ends with .gpg, '
                        '"gpg -d" will be invoked automatically. File is read one line at a time, and if '
                        'the file contains only one WIF per line, it will also be scanned for a bitcoin '
                        'address, and any addresses found will be assumed to be public keys for the given'
                        ' private key.',
                        type=argparse.FileType('r'))

    parser.add_argument('-g', "--gpg-argument", help='argument to pass to gpg (besides -d).', default='')

    parser.add_argument("--remove-tx-in", metavar="tx_in_index_to_delete", action="append", type=int,
                        help='remove a tx_in')

    parser.add_argument("--remove-tx-out", metavar="tx_out_index_to_delete", action="append", type=int,
                        help='remove a tx_out')

    parser.add_argument("--replace-input-script", metavar="tx_in_script_slash_hex", action="append", default=[],
                        type=parse_script_index_hex, help='replace an input script: arg looks like "1/796a"')

    parser.add_argument('-F', "--fee", help='fee, in satoshis, to pay on transaction, or '
                        '"standard" to auto-calculate. This is only useful if the "split pool" '
                        'is used; otherwise, the fee is automatically set to the unclaimed funds.',
                        default="standard", metavar="transaction-fee", type=parse_fee)

    parser.add_argument('-C', "--cache", help='force the resultant transaction into the transaction cache.'
                        ' Mostly for testing.', action='store_true'),

    parser.add_argument("--db", help='force the transaction expressed by the given hex '
                        'into a RAM-based transaction cache. Mostly for testing.', action="append"),

    parser.add_argument('-u', "--show-unspents", action='store_true',
                        help='show TxOut items for this transaction in Spendable form.')

    parser.add_argument('-b', "--bitcoind-url",
                        help='URL to bitcoind instance to validate against (http://user:pass@host:port).')

    parser.add_argument('-o', "--output-file", metavar="path-to-output-file", type=argparse.FileType('wb'),
                        help='file to write transaction to. This supresses most other output.')

    parser.add_argument('-d', "--disassemble", action='store_true',
                        help='Disassemble scripts.')

    parser.add_argument("--pdb", action="store_true", help='Enter PDB debugger on each script instruction.')

    parser.add_argument("--trace", action='store_true', help='Trace scripts.')

    parser.add_argument('-p', "--pay-to-script", metavar="pay-to-script", action="append",
                        help='a hex version of a script required for a pay-to-script'
                        'input (a bitcoin address that starts with 3)')

    parser.add_argument("--signature", metavar="known-good-signature", action="append",
                        help='a hex version of a signature that will be used if useful')

    parser.add_argument("--sec", metavar="known-sec", action="append",
                        help='a hex version of an SEC that will be used if useful')

    parser.add_argument('-P', "--pay-to-script-file", metavar="pay-to-script-file", nargs=1,
                        type=argparse.FileType('r'), help='a file containing hex scripts '
                        '(one per line) corresponding to pay-to-script inputs')

    parser.add_argument("--dump-signatures", action="store_true",
                        help="print signatures (for use with --signature)")

    parser.add_argument("--dump-secs", action="store_true",
                        help="print secs (for use with --sec)")

    parser.add_argument("--coinbase", type=str, help="add an input as a coinbase from the given address")

    parser.add_argument("argument", nargs="*", help='generic argument: can be a hex transaction id '
                        '(exactly 64 characters) to be fetched from cache or a web service;'
                        ' a transaction as a hex string; a path name to a transaction to be loaded;'
                        ' a spendable 4-tuple of the form tx_id/tx_out_idx/script_hex/satoshi_count '
                        'to be added to TxIn list; an address/satoshi_count to be added to the TxOut '
                        'list; an address or script to be added to the TxOut list and placed in the '
                        '"split pool".')

    return parser
Example #48
0
def parse_context(args, parser):
    network = network_for_netcode(args.network)
    tx_class = network.tx

    # defaults

    spendables = []
    payables = []

    # we create the tx_db lazily
    tx_db = None

    if args.db:

        try:
            txs = [tx_class.from_hex(tx_hex) for tx_hex in args.db or []]
        except Exception:
            parser.error("can't parse ")

        the_ram_tx_db = dict((tx.hash(), tx) for tx in txs)
        if tx_db is None:
            tx_db = create_tx_db(network)
        tx_db.lookup_methods.append(the_ram_tx_db.get)

    txs = []

    if args.coinbase:
        coinbase_tx = build_coinbase_tx(network, args.coinbase)
        txs.append(coinbase_tx)

    keychain = network.keychain(sqlite3.connect(args.keychain))

    # there are a few warnings we might optionally print out, but only if
    # they are relevant. We don't want to print them out multiple times, so we
    # collect them here and print them at the end if they ever kick in.

    warning_spendables = None

    for arg in args.argument:
        tx, tx_db = parse_tx(tx_class, arg, parser, tx_db, network)
        if tx:
            txs.append(tx)
            continue

        if key_found(arg, keychain, args.key_paths, network):
            continue

        if parse_parts(tx_class, arg, spendables, payables, network):
            continue

        payable = script_for_address_or_opcodes(network, arg)
        if payable is not None:
            payables.append((payable, 0))
            continue

        parser.error("can't parse %s" % arg)

    parse_private_key_file(args, keychain, network)

    if args.fetch_spendables:
        warning_spendables = message_about_spendables_for_address_env(args.network)
        for address in args.fetch_spendables:
            spendables.extend(spendables_for_address(address, args.network))

    return (network, txs, spendables, payables, keychain, tx_db, warning_spendables)