Подадреса
Сколько угодно несвязанных адресов из одной пары ключей
Подадрес с индексом (i, j) — это пара точек D = B + m·G и C = a·D, где m = Hs("SubAddr\0" ‖ a ‖ i ‖ j). Не зная ключа просмотра a, нельзя понять, что подадреса принадлежат одному кошельку.
Зачем
Если вы дали один адрес двум разным людям, они могут сравнить записи и понять, что платили одному и тому же получателю. Подадреса решают это: каждому плательщику — свой адрес, а кошелёк при этом один, и сканирование не становится медленнее.
Подадреса организованы в двухуровневую иерархию: аккаунт i (major) и индекс внутри аккаунта j (minor). Подадрес (0, 0) — это основной адрес.
Основной адрес у кошелька ровно один — (0,0), это просто B и A с префиксом 18. Любой другой индекс, включая «первый» адрес второго аккаунта (1,0), — это подадрес: его ключи вычисляются через m = Hs("SubAddr\0" ‖ a ‖ 1 ‖ 0), и он кодируется с префиксом 42, отсюда 8…. Аккаунт — лишь способ группировать подадреса, своего «основного» адреса у него нет.
Как вычисляется
D = B + m·G C = a·D i и j — 32-битные числа little-endian; "SubAddr\0" — 8 байт с нулевым байтом в конце
Подадрес кодируется так же, как обычный адрес, но с префиксом 42 (на mainnet начинается с 8): Base58(42 ‖ D ‖ C ‖ checksum).
Обратите внимание: публичный «ключ просмотра» подадреса C — это не a·G, а a·D. Эта хитрость нужна для отправки.
Отправка на подадрес
При отправке на обычный адрес транзакционный ключ R = r·G. При отправке на подадрес отправитель берёт R = r·D. Тогда получатель вычисляет общий секрет как обычно:
Отправитель знает r и C, получатель — a и R, и у обоих получается одна и та же точка.
Как кошелёк узнаёт свои подадреса
Кошелёк заранее вычисляет D для нескольких сотен индексов и хранит таблицу D → (i, j). Для каждого выхода он вычисляет кандидата
и ищет D' в таблице. Нашёл — выход наш, и известно, на какой подадрес он пришёл. Поэтому подадреса не замедляют сканирование: одно вычитание и поиск в хеш-таблице.
Если в одной транзакции есть выход на подадрес, кошелёк-отправитель использует отдельный транзакционный ключ для каждого выхода (дополнительные ключи в tx_extra). Иначе получатель смог бы проверить, принадлежит ли сдача отправителя какому-то адресу.