Технический › Ключи и адреса

Адрес

95 символов: префикс сети, два публичных ключа и контрольная сумма в особом Base58

Коротко

Стандартный адрес Monero = Base58( префикс ‖ B ‖ A ‖ checksum ). Префикс говорит, какая это сеть и тип адреса, B и A — публичные ключи траты и просмотра, checksum — первые 4 байта Keccak-256 от всего предыдущего.

Устройство

12 B — публичный ключ траты A — публичный ключ просмотра чек 1 байт 32 байта 32 байта 4 байта 69 байт → Monero-Base58 → 95 символов

Префикс сети

Префикс записывается как varint (для маленьких чисел — один байт). Из-за того как работает Base58, префикс определяет первый символ адреса:

СетьСтандартныйИнтегрированныйПодадрес
mainnet18 → 4…19 → 4…42 → 8…
stagenet24 → 5…25 → 5…36 → 7…
testnet53 → 9…/A…54 → A…63 → B…

Контрольная сумма

checksum = Keccak256( префикс ‖ B ‖ A )[0..4]

Если в адресе опечатка, контрольная сумма не сойдётся, и кошелёк откажется отправлять деньги.

Monero-Base58 — не такой, как в Bitcoin

Алфавит тот же (без 0 O I l), но кодирование другое. Bitcoin превращает всё сообщение в одно большое число и переводит его в 58-ричную систему. Monero режет данные на блоки по 8 байт и кодирует каждый блок отдельно ровно в 11 символов (последний неполный блок — в меньшее число символов по таблице).

байт в блоке12345678
символов2356791011

69 байт = 8 полных блоков (88 символов) + 5 байт (7 символов) = 95 символов. Плюс такого подхода — длина адреса всегда одинаковая и кодирование работает за линейное время.

const ENC_BLOCK = [0, 2, 3, 5, 6, 7, 9, 10, 11];
function encodeBlock(block) {
  let n = 0n;
  for (const x of block) n = (n << 8n) | BigInt(x);       // big-endian внутри блока
  let s = '';
  while (n > 0n) { s = ALPHABET[Number(n % 58n)] + s; n /= 58n; }
  return s.padStart(ENC_BLOCK[block.length], '1');
}

Интегрированный адрес

Интегрированный адрес (префикс 19) = стандартный адрес + 8-байтный payment ID (106 символов). Payment ID шифруется внутри транзакции и помогает магазину понять, какой заказ оплачен. Сегодня вместо него рекомендуют подадреса: новый подадрес на каждый заказ.

Чего в адресе нет

Важно: адрес никогда не записывается в блокчейн. Отправитель использует A и B, чтобы построить одноразовый адрес, и в блокчейн попадает только он.