Exemplo n.º 1
0
def validate_address(addr):
    try:
        assert len(addr) > 2
        if addr[:2].lower() in ['bc', 'tb']:
            # Regtest special case
            if addr[:4] == 'bcrt':
                if btc.bech32addr_decode('bcrt', addr)[1]:
                    return True, 'address validated'
                return False, 'Invalid bech32 regtest address'
            #Else, enforce testnet/mainnet per config
            if get_network() == "testnet":
                hrpreq = 'tb'
            else:
                hrpreq = 'bc'
            if btc.bech32addr_decode(hrpreq, addr)[1]:
                return True, 'address validated'
            return False, 'Invalid bech32 address'
        #Not bech32; assume b58 from here
        ver = btc.get_version_byte(addr)
    except AssertionError:
        return False, 'Checksum wrong. Typo in address?'
    except Exception:
        return False, "Invalid bitcoin address"
    if ver != get_p2pk_vbyte() and ver != get_p2sh_vbyte():
        return False, 'Wrong address version. Testnet/mainnet confused?'
    if len(btc.b58check_to_bin(addr)) != 20:
        return False, "Address has correct checksum but wrong length."
    return True, 'address validated'
Exemplo n.º 2
0
def test_wif_privkeys_valid():
    with open(os.path.join(testdir, "base58_keys_valid.json"), "r") as f:
        json_data = f.read()
    valid_keys_list = json.loads(json_data)
    for a in valid_keys_list:
        key, hex_key, prop_dict = a
        if prop_dict["isPrivkey"]:
            netval = "testnet" if prop_dict["isTestnet"] else "mainnet"
            print 'testing this key: ' + key
            assert chr(btc.get_version_byte(
                key)) in '\x80\xef', "not valid network byte"
            comp = prop_dict["isCompressed"]
            from_wif_key = btc.from_wif_privkey(
                key, compressed=comp, vbyte=btc.get_version_byte(key) - 128)
            expected_key = hex_key
            if comp: expected_key += '01'
            assert from_wif_key == expected_key, "Incorrect key decoding: " + \
                   str(from_wif_key) + ", should be: " + str(expected_key)
Exemplo n.º 3
0
    def wif_to_privkey(cls, wif):
        raw = btc.b58check_to_bin(wif)
        vbyte = struct.unpack('B', btc.get_version_byte(wif))[0]

        if (struct.unpack('B', btc.BTC_P2PK_VBYTE[get_network()])[0] + struct.unpack('B', cls.WIF_PREFIX)[0]) & 0xff == vbyte:
            key_type = TYPE_P2PKH
        elif (struct.unpack('B', btc.BTC_P2SH_VBYTE[get_network()])[0] + struct.unpack('B', cls.WIF_PREFIX)[0]) & 0xff == vbyte:
            key_type = TYPE_P2SH_P2WPKH
        else:
            key_type = None

        return raw, key_type
Exemplo n.º 4
0
def test_wif_privkeys_invalid():
    #first try to create wif privkey from key of wrong length
    bad_privs = [b'\x01\x02' * 17]  #some silly private key but > 33 bytes

    #next try to create wif with correct length but wrong compression byte
    bad_privs.append(b'\x07' * 32 + b'\x02')

    for priv in bad_privs:
        with pytest.raises(Exception) as e_info:
            fake_wif = btc.wif_compressed_privkey(
                binascii.hexlify(priv).decode('ascii'))

    #Create a wif with wrong length
    bad_wif1 = btc.bin_to_b58check(b'\x01\x02' * 34, b'\x80')
    #Create a wif with wrong compression byte
    bad_wif2 = btc.bin_to_b58check(b'\x07' * 33, b'\x80')
    for bw in [bad_wif1, bad_wif2]:
        with pytest.raises(Exception) as e_info:
            fake_priv = btc.from_wif_privkey(bw)

    #Some invalid b58 from bitcoin repo;
    #none of these are valid as any kind of key or address
    with open(os.path.join(testdir, "base58_keys_invalid.json"), "r") as f:
        json_data = f.read()
    invalid_key_list = json.loads(json_data)
    for k in invalid_key_list:
        bad_key = k[0]
        for netval in ["mainnet", "testnet"]:
            #if using pytest -s ; sanity check to see what's actually being tested
            print('testing this key: ' + bad_key)
            #should throw exception
            with pytest.raises(Exception) as e_info:
                from_wif_key = btc.from_wif_privkey(
                    bad_key, btc.get_version_byte(bad_key))
                #in case the b58 check encoding is valid, we should
                #also check if the leading version byte is in the
                #expected set, and throw an error if not.
                if chr(btc.get_version_byte(bad_key)) not in b'\x80\xef':
                    raise Exception("Invalid version byte")
def validate_address(addr, nettype):
    """A mock of jmclient.validate_address
    """
    BTC_P2PK_VBYTE = {"mainnet": b'\x00', "testnet": b'\x6f'}
    BTC_P2SH_VBYTE = {"mainnet": b'\x05', "testnet": b'\xc4'}
    try:
        ver = btc.get_version_byte(addr)
    except AssertionError as e:
        return False, 'Checksum wrong. Typo in address?'
    except Exception as e:
        return False, "Invalid bitcoin address"
    if ver not in [BTC_P2PK_VBYTE[nettype], BTC_P2SH_VBYTE[nettype]]:
        return False, 'Wrong address version. Testnet/mainnet confused?'
    if len(btc.b58check_to_bin(addr)) != 20:
        return False, "Address has correct checksum but wrong length."
    return True, 'address validated'
Exemplo n.º 6
0
    def wif_to_privkey(cls, wif):
        raw = btc.b58check_to_bin(wif)[1]
        # see note to `privkey_to_wif`; same applies here.
        # We only handle valid private keys, not any byte string.
        btc.read_privkey(raw)

        vbyte = struct.unpack('B', btc.get_version_byte(wif))[0]

        if (struct.unpack('B', btc.BTC_P2PK_VBYTE[get_network()])[0] + \
            struct.unpack('B', cls.WIF_PREFIX)[0]) & 0xff == vbyte:
            key_type = TYPE_P2PKH
        elif (struct.unpack('B', btc.BTC_P2SH_VBYTE[get_network()])[0] + \
              struct.unpack('B', cls.WIF_PREFIX)[0]) & 0xff == vbyte:
            key_type = TYPE_P2SH_P2WPKH
        else:
            key_type = None
        return raw, key_type
Exemplo n.º 7
0
    def wif_to_privkey(cls, wif):
        """ Note July 2020: the `key_type` construction below is
        custom and is not currently used. Future code should
        not use this returned `key_type` variable.
        """
        raw = btc.b58check_to_bin(wif)[1]
        # see note to `privkey_to_wif`; same applies here.
        # We only handle valid private keys, not any byte string.
        btc.read_privkey(raw)

        vbyte = struct.unpack('B', btc.get_version_byte(wif))[0]

        if (struct.unpack('B', btc.BTC_P2PK_VBYTE[get_network()])[0] + \
            struct.unpack('B', cls.WIF_PREFIX)[0]) & 0xff == vbyte:
            key_type = TYPE_P2PKH
        elif (struct.unpack('B', btc.BTC_P2SH_VBYTE[get_network()])[0] + \
              struct.unpack('B', cls.WIF_PREFIX)[0]) & 0xff == vbyte:
            key_type = TYPE_P2SH_P2WPKH
        else:
            key_type = None
        return raw, key_type
Exemplo n.º 8
0
def test_wif_privkeys_valid(setup_keys):
    with open(os.path.join(testdir, "base58_keys_valid.json"), "r") as f:
        json_data = f.read()
    valid_keys_list = json.loads(json_data)
    for a in valid_keys_list:
        key, hex_key, prop_dict = a
        if prop_dict["isPrivkey"]:
            netval = "testnet" if prop_dict["isTestnet"] else "mainnet"
            jm_single().config.set("BLOCKCHAIN", "network", netval)
            print('testing this key: ' + key)
            assert btc.get_version_byte(
                key) in b'\x80\xef', "not valid network byte"
            comp = prop_dict["isCompressed"]
            if not comp:
                # we only handle compressed keys
                continue
            from_wif_key, keytype = BTCEngine.wif_to_privkey(key)
            expected_key = hextobin(hex_key) + b"\x01"
            assert from_wif_key == expected_key, "Incorrect key decoding: " + \
                   str(from_wif_key) + ", should be: " + str(expected_key)
    jm_single().config.set("BLOCKCHAIN", "network", "testnet")