Ключи и типы аккаунтов
Аккаунтом ZooBC управляет подпись, а не имя пользователя, пароль или ключ API. Какая именно подпись, зависит от типа аккаунта. Помимо нативных аккаунтов Ed25519, ZooBC принимает аккаунты, адреса которых записаны так, как их записывают Bitcoin, Ethereum, Solana, Polkadot, Cardano, Ripple, Tron и Tezos, и проверяет их подписи собственной схемой каждой цепочки. Поэтому ключ Bitcoin или Ethereum может управлять аккаунтом ZooBC с тем же адресом, что и в его родной цепочке. Этот аккаунт отдельный, он ведётся в собственном реестре ZooBC и хранит ZBC.
Адрес — это тип и данные
Адрес — это 4-байтовый номер типа (little-endian), за которым следуют данные, смысл и длину которых определяет тип (аккаунты и адреса). Для нативного аккаунта данные — это сам публичный ключ Ed25519; для аккаунта Ethereum — последние 20 байт хеша Keccak-256 от ключа; для аккаунта Bitcoin P2PKH — HASH160 от ключа.
| Тип | Аккаунт | Запись | Может подписывать |
|---|---|---|---|
| 0 | ZooBC, Ed25519 | ZBC_… | да |
| 1 | Bitcoin legacy (HASH160) | — | да |
| 2 | Empty («нет получателя») | — | нет |
| 3 | Estonia eID (зарезервирован) | — | нет |
| 4 | Ethereum | 0x… | да |
| 5 | Bitcoin P2PKH | 1… | да |
| 6 | Bitcoin P2SH, проверяется как P2SH-P2WPKH | 3… | да |
| 7 | Bitcoin P2WPKH | bc1q…, 42 символа | да |
| 8 | Bitcoin P2WSH (скрипт) | bc1q…, 62 символа | нет |
| 9 | Bitcoin Taproot | bc1p… | да |
| 10 | Объект набора данных | ZBS_… | нет |
| 11 | Solana | как в Solana | да |
| 12 | Polkadot | как в Polkadot | да |
| 13 | Cardano | addr1… | да |
| 14 | Ripple | r… | да |
| 15 | Tron | T… | да |
| 16 | Tezos | tz1… | да |
Бесключевые адреса тоже не могут подписывать: у пулов протокола, групп аккаунтов и мультиподписных аккаунтов ключа нет, поэтому их средства движутся только по правилам протокола.
Нативная текстовая форма — ZBC_, за которым следуют 56 символов base32 в семи группах по восемь: 32-байтовый ключ плюс 3-байтовая контрольная сумма SHA3-256, которая охватывает и префикс. При чтении разделители, пробелы и регистр букв игнорируются. Тот же 32-байтовый ключ можно также записать как ключ узла (ZNK_), ключ ретранслятора (ZBR_) или ключ шлюза (ZBG_).
Один дайджест для всех схем
Каждый тип аккаунта подписывает один и тот же дайджест, привязанный к цепочке:
digest = SHA3-256("ZBC-TX" ‖ genesis hash ‖ unsigned transaction bytes)
Принимается только этот дайджест; подпись над голыми байтами отклоняется. Хеш генезиса привязывает каждую подпись к одной цепочке (подписи, привязанные к цепочке). Некоторые схемы хешируют дайджест ещё раз, как того требует их родная цепочка.
Схемы
- Ed25519 над 32-байтовым дайджестом — для ZooBC (тип 0) и Solana (11). Cardano (13) и Tezos (16) тоже подписывают Ed25519, но их адреса — это хеши, поэтому поле подписи несёт ещё и ключ: 98 байт из 2-байтовой длины, ключа и подписи. Ключ привязывается к адресу через BLAKE2b-28 (Cardano) или BLAKE2b-20 (Tezos).
- secp256k1 ECDSA в стиле Bitcoin — для типов 1, 5, 6 и 7 и для Ripple (14). Поле подписи несёт ключ: 2-байтовую длину, 33- или 65-байтовый ключ, затем 64-байтовую подпись (r и s). HASH160 от ключа должен совпадать с адресом, подписываемое сообщение — двойной SHA-256 от дайджеста, и принимаются только подписи с малым s.
- secp256k1 ECDSA в стиле Ethereum — для Ethereum (4) и Tron (15): 65-байтовая подпись (r, s и v) над хешем Keccak-256 от дайджеста. Ключ восстанавливается из подписи, и его адрес сравнивается; подписи с большим s отклоняются.
- BIP-340 Schnorr — для Taproot (9), с выходным ключом только по координате x; кошелёк применяет твик Taproot.
- sr25519 — для Polkadot (12), в контексте подписания «substrate».
Аккаунты Taproot также могут получать ZBC через SendZBC во всех цепочках с генезиса.
Проверка ключа, который нигде не хранится
Адрес в стиле Ethereum — это лишь 20-байтовый хеш; публичный ключ нигде в цепочке не хранится. Подписи Ethereum восстанавливаемы: по подписанному сообщению и 65-байтовой подписи любой может вычислить тот единственный публичный ключ, который её создал. Узел именно это и делает: берёт последние 20 байт хеша Keccak-256 от восстановленного ключа и принимает подпись, только если они совпадают с адресом. Поскольку подписи с большим s отклоняются, подпись нельзя превратить во вторую действительную форму. Не нужны ни шаг регистрации, ни внешний поиск, и аккаунты 0x могут отправлять так же свободно, как и получать.
Чужие транзакции внутри
Отправитель с чужим аккаунтом может также поместить нативную транзакцию своей родной цепочки в поле сообщения транзакции ZooBC. На этом пути узел проверяет чужую транзакцию и её подпись вместо дайджеста ZooBC:
- Ethereum (тип 4): транзакция EIP-1559, EIP-2930 или legacy (EIP-155) с пустым списком доступа. Её восстановленный подписант должен быть отправителем, её
to— получателем, а её сумма в wei, делённая на 10^10, — суммой перевода (MetaMask и доступ в стиле Ethereum). - Solana (тип 11): перевод System, число лампортов которого равно сумме.
- Bitcoin (типы 7 и 5): один вход, один или два выхода и нулевая комиссия майнеру; выход 0 платит получателю, а выход 1, если он есть, возвращает сдачу отправителю.
Такое сообщение-носитель может занимать до 4 096 байт, и транзакция не может нести платёж survival (конверт транзакции).
Вывод нативных ключей
Нативный ключ выводится из фразы восстановления BIP-39: PBKDF2-HMAC-SHA512 с 2 048 раундами, затем SLIP-0010 Ed25519 по пути m/44'/883'/n', где каждый шаг усиленный (hardened). 883 — тип монеты ZooBC.