Source code for nano.accounts

"""
Accounts module

``nano.accounts.KNOWN_ACCOUNT_IDS``: dict of account ids => names eg.

>>> KNOWN_ACCOUNT_IDS['xrb_1ipx847tk8o46pwxt5qjdbncjqcbwcc1rrmqnkztrfjy5k7z4imsrata9est']
'Developer Fund'

``nano.accounts.KNOWN_ACCOUNT_NAMES``: dict of names => account ids

>>> KNOWN_ACCOUNT_NAMES['Burn']
'xrb_1111111111111111111111111111111111111111111111111111hifc8npp'

"""

import random
from binascii import hexlify, unhexlify
from .crypto import (
    b32xrb_encode, b32xrb_decode, address_checksum, keypair_from_seed)


KNOWN_ACCOUNT_IDS = {
    'xrb_3t6k35gi95xu6tergt6p69ck76ogmitsa8mnijtpxm9fkcm736xtoncuohr3': 'Genesis',
    'xrb_13ezf4od79h1tgj9aiu4djzcmmguendtjfuhwfukhuucboua8cpoihmh8byo': 'Landing',
    'xrb_35jjmmmh81kydepzeuf9oec8hzkay7msr6yxagzxpcht7thwa5bus5tomgz9': 'Faucet',
    'xrb_1111111111111111111111111111111111111111111111111111hifc8npp': 'Burn',
    'xrb_3wm37qz19zhei7nzscjcopbrbnnachs4p1gnwo5oroi3qonw6inwgoeuufdp': 'Developer Donations',
    'xrb_1ipx847tk8o46pwxt5qjdbncjqcbwcc1rrmqnkztrfjy5k7z4imsrata9est': 'Developer Fund',
    'xrb_3arg3asgtigae3xckabaaewkx3bzsh7nwz7jkmjos79ihyaxwphhm6qgjps4': 'Official representative #1',
    'xrb_1stofnrxuz3cai7ze75o174bpm7scwj9jn3nxsn8ntzg784jf1gzn1jjdkou': 'Official representative #2',
    'xrb_1q3hqecaw15cjt7thbtxu3pbzr1eihtzzpzxguoc37bj1wc5ffoh7w74gi6p': 'Official representative #3',
    'xrb_3dmtrrws3pocycmbqwawk6xs7446qxa36fcncush4s1pejk16ksbmakis78m': 'Official representative #4',
    'xrb_3hd4ezdgsp15iemx7h81in7xz5tpxi43b6b41zn3qmwiuypankocw3awes5k': 'Official representative #5',
    'xrb_1awsn43we17c1oshdru4azeqjz9wii41dy8npubm4rg11so7dx3jtqgoeahy': 'Official representative #6',
    'xrb_1anrzcuwe64rwxzcco8dkhpyxpi8kd7zsjc1oeimpc3ppca4mrjtwnqposrs': 'Official representative #7',
    'xrb_1hza3f7wiiqa7ig3jczyxj5yo86yegcmqk3criaz838j91sxcckpfhbhhra1': 'Official representative #8',
    'xrb_3wu7h5in34ntmbiremyxtszx7ufgkceb3jx8orkuncyytcxwzrawuf3dy3sh': 'RaiWalletBot',
    'xrb_16k5pimotz9zehjk795wa4qcx54mtusk8hc5mdsjgy57gnhbj3hj6zaib4ic': 'RaiWalletBot representative',
    'xrb_39ymww61tksoddjh1e43mprw5r8uu1318it9z3agm7e6f96kg4ndqg9tuds4': 'BitGrail Representative 1',
    'xrb_31a51k53fdzam7bhrgi4b67py9o7wp33rec1hi7k6z1wsgh8oagqs7bui9p1': 'BitGrail Representative 2',
    'xrb_3decyj8e1kpzrthikh79x6dwhn8ei81grennibmt43mcm9o8fgxqd8t46whj': 'Mercatox Representative',
    'xrb_369dmjiipkuwar1zxxiuixaqq1kfmyp9rwsttksxdbf8zi3qwit1kxiujpdo': 'RaiBlocks Community',
    'xrb_1niabkx3gbxit5j5yyqcpas71dkffggbr6zpd3heui8rpoocm5xqbdwq44oh': 'KuCoin Representative',
}


KNOWN_ACCOUNT_NAMES = dict(
    (name, account) for account, name in KNOWN_ACCOUNT_IDS.items())


[docs]def public_key_to_xrb_address(public_key): """ Convert `public_key` (bytes) to an xrb address >>> public_key_to_xrb_address(b'00000000000000000000000000000000') 'xrb_1e3i81r51e3i81r51e3i81r51e3i81r51e3i81r51e3i81r51e3imxssakuq' :param public_key: public key in bytes :type public_key: bytes :return: xrb address :rtype: str """ if not len(public_key) == 32: raise ValueError('public key must be 32 chars') padded = b'000' + public_key address = b32xrb_encode(padded)[4:] checksum = b32xrb_encode(address_checksum(public_key)) return 'xrb_' + address.decode('ascii') + checksum.decode('ascii')
[docs]def xrb_address_to_public_key(address): """ Convert an xrb address to public key in bytes >>> xrb_address_to_public_key('xrb_1e3i81r51e3i81r51e3i81r51e3i'\ '81r51e3i81r51e3i81r51e3imxssakuq') b'00000000000000000000000000000000' :param address: xrb address :type address: bytes :return: public key in bytes :rtype: bytes :raises ValueError: """ address = bytearray(address, 'ascii') if not address.startswith(b'xrb_'): raise ValueError('address does not start with xrb_: %s' % address) if len(address) != 64: raise ValueError('address must be 64 chars long: %s' % address) address = bytes(address) key_b32xrb = b'1111' + address[4:56] key_bytes = b32xrb_decode(key_b32xrb)[3:] checksum = address[56:] if b32xrb_encode(address_checksum(key_bytes)) != checksum: raise ValueError('invalid address, invalid checksum: %s' % address) return key_bytes
[docs]def generate_account(seed=None, index=0): """ Generates an adhoc account and keypair >>> account = generate_account(seed=unhexlify('0'*64)) {'address': u'xrb_3i1aq1cchnmbn9x5rsbap8b15akfh7wj7pwskuzi7ahz8oq6cobd99d4r3b7', 'private_key_bytes': '\x9f\x0eDLi\xf7zI\xbd\x0b\xe8\x9d\xb9,8\xfeq>\tc\x16\\\xca\x12\xfa\xf5q-vW\x12\x0f', 'private_key_hex': '9f0e444c69f77a49bd0be89db92c38fe713e0963165cca12faf5712d7657120f', 'public_key_bytes': '\xc0\x08\xb8\x14\xa7\xd2i\xa1\xfa<e(\xb1\x92\x01\xa2Myy\x12\xdb\x99\x96\xff\x02\xa1\xff5nEU+', 'public_key_hex': 'c008b814a7d269a1fa3c6528b19201a24d797912db9996ff02a1ff356e45552b'} :param seed: the seed in bytes to use to generate the account, if not provided one is generated randomly :type seed: bytes :param index: the index offset for deterministic account generation :type index: int :return: dict containing the account address and pub/priv keys in hex/bytes :rtype: dict """ if not seed: seed = unhexlify( ''.join(random.choice('0123456789ABCDEF') for i in range(64))) pair = keypair_from_seed(seed, index=index) result = { 'address': public_key_to_xrb_address(pair['public']), 'private_key_bytes': pair['private'], 'public_key_bytes': pair['public'], } result['private_key_hex'] = hexlify(pair['private']) result['public_key_hex'] = hexlify(pair['public']) return result