コード例 #1
0
    def test_address_creation(self):
        """
        Test address creation
        https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses
        """
        self.assertEqual(
            PublicKey.from_hex(
                '0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352'
            ).to_address('P2PKH', ), '1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs')

        self.assertNotEqual(
            PublicKey.from_hex(
                '0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352'
            ).to_address('P2PKH', compressed=False),
            '1PMycacnJaSqwwJqjawXBErnLsZ7RkXUAs')

        self.assertEqual(
            PublicKey.from_hex(
                '03b82761f2482254b93fdf45f26c5d00bd51883fb7cd143080318c5be9746a5f5f'
            ).to_address('P2WPKH-P2SH'), '33x3UHfxVvJNqd275WG9XprVfepEUeASoj')

        self.assertEqual(
            PublicKey.from_hex(
                '03727fcbaff7eadb840b13bfd5b3d258530f0c1208bf02d8537606d096f069d2b5'
            ).to_address('P2WPKH'),
            'bc1qsxe29au72mvjf7vsfhmlcdd5seuslnnkmgw4ws')
コード例 #2
0
def legacy_address(public_key: PublicKey, version_byte: bytes) -> str:
    """https://en.bitcoin.it/wiki/Technical_background_of_version_1_Bitcoin_addresses"""
    bts = public_key.encode(
        compressed=False) if isinstance(public_key, PublicKey) else public_key
    hashed = hash160(bts)
    payload = version_byte + hashed
    return hashed_payload_to_address(payload)
コード例 #3
0
    def deserialize(cls, bts: bytes, network='btc'):
        def read(n):
            nonlocal bts
            data, bts = bts[:n], bts[n:]
            return data

        net = read(4)
        is_private = net in get_network_attr('extended_prv', network).values()
        is_public = net in get_network_attr('extended_pub', network).values()
        assert is_public ^ is_private, f'Invalid network bytes : {bytes_to_hex(net)}'
        address_lookup = {val: key for key, val in (
            get_network_attr('extended_prv', network) if is_private else get_network_attr('extended_pub',
                                                                                          network)).items()}
        constructor = XPrv if is_private else XPub
        depth = bytes_to_int(read(1))
        assert depth in range(256), f'Invalid depth : {depth}'
        fingerprint = read(4)
        i = bytes_to_int(read(4))
        if depth == 0:
            i = None
            path = None
        else:
            ih = f'{i}' if i < 2 ** 31 else f"{i - 2 ** 31}h"
            path = '/'.join([constructor.root_path] + ['x' for _ in range(depth - 1)] + [ih])

        code = read(32)
        key = read(33)
        key = PrivateKey(key, network=network) if is_private else PublicKey.decode(key, network=network)
        assert not bts, 'Leftover bytes'
        return constructor(key, code, depth=depth, i=i, parent=fingerprint, path=path, address_type=address_lookup[net])
コード例 #4
0
    def child(self, i: int) -> 'XPub':
        hardened = i >= 1 << 31

        if hardened:
            raise KeyDerivationError('Cannot derive a hardened key from an extended public key')

        I = hmac.new(key=self.code, msg=self.key_data() + int_to_bytes(i).rjust(4, b'\x00'),
                     digestmod=hashlib.sha512).digest()

        I_L, I_R = I[:32], I[32:]

        key = PrivateKey(I_L).to_public().point + self.key.point
        ret_code = I_R
        path = self.path + f'/{i}'

        # TODO add point at infinity check
        return XPub(
            PublicKey(key, network=self.key.network),
            ret_code,
            depth=self.depth + 1,
            i=i,
            parent=self.fingerprint(),
            path=path,
            address_type=self.type.value
        )
コード例 #5
0
 def test_private_to_public(self):
     private = PrivateKey.from_wif(
         'L2AnMo4KYaNTKFwgd2ZSsgcxAo8QSwJ9QYSiBSm44a4WZrwPKTum')
     self.assertEqual(
         private.to_public(),
         PublicKey.from_hex(
             '03b82761f2482254b93fdf45f26c5d00bd51883fb7cd143080318c5be9746a5f5f'
         ))
コード例 #6
0
 def to_p2wpkh_p2sh(public_key: PublicKey) -> 'str':
     return legacy_address(
         witness_byte(witver=0) +
         push(hash160(public_key.encode(compressed=True))),
         version_byte=get_network_attr('scripthash', public_key.network))
コード例 #7
0
 def to_p2pkh(public_key: PublicKey, compressed=False) -> 'str':
     return legacy_address(
         public_key.encode(compressed=True) if compressed else public_key,
         version_byte=get_network_attr('keyhash', public_key.network))
コード例 #8
0
def pubkey_to_bech32(public_key: PublicKey, witver: int) -> str:
    """https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki#witness-program"""
    witprog = hash160(public_key.encode(compressed=True))
    return bech32.encode(get_network_attr('hrp', public_key.network), witver,
                         witprog)