# SHINY USER FORMAT v1.1 (DRAFT) Документ описывает единый бинарный формат пользовательской записи в `user_pda` для программы `shine_users`. Цель версии `v1.1`: сохранить текущую рабочую логику регистрации/обновления и добавить задел под будущую смену ключей через 3 статус-байта: - `root_key_status` - `blockchain_key_status` - `device_key_status` Сейчас во всех трех полях используется значение `0` (ключ создан и ни разу не менялся). ## 1) Общие правила кодирования - Числа: Little Endian (`LE`). - Строки: `UTF-8` с префиксом длины `u8`. - Публичные ключи: 32 байта (`Pubkey`). - Подпись: 64 байта (Ed25519). - Размер PDA фиксированный: `USER_PDA_SPACE` (сейчас 768 байт). - `record_len` хранит длину полезной записи от `magic` до `signature` включительно (без `padding`). ## 2) Единый список полей в порядке хранения 1. `magic` - Размер: 5 байт - Значение: `"SHiNE"` - Назначение: маркер формата записи. 2. `format_major` - Размер: 1 байт (`u8`) - Назначение: major-версия формата. 3. `format_minor` - Размер: 1 байт (`u8`) - Назначение: minor-версия формата. 4. `record_len` - Размер: 2 байта (`u16`, LE) - Назначение: длина полезных данных записи (без `padding`). 5. `created_at_ms` - Размер: 8 байт (`u64`, LE) - Назначение: время создания записи (Unix time, ms). 6. `updated_at_ms` - Размер: 8 байт (`u64`, LE) - Назначение: время последнего обновления записи (Unix time, ms). 7. `version` - Размер: 4 байта (`u32`, LE) - Назначение: номер версии записи. - Правило: при обновлении должен быть строго `old_version + 1`; это проверяется программой. 8. `prev_hash` - Размер: 32 байта - Назначение: хэш unsigned-предыдущей версии для связывания истории. 9. `login_len` - Размер: 1 байт (`u8`) - Назначение: длина поля `login` в байтах. 10. `login` - Размер: `login_len` байт (UTF-8) - Назначение: логин пользователя. - Текущие ограничения: от 1 до 30 символов, только `a-z`, `0-9`, `_`. 11. `root_key_status` - Размер: 1 байт (`u8`) - Текущее значение: `0` - Назначение: статус `root_key`. - Комментарий: `0` = ключ создан и не менялся; другие статусы зарезервированы на будущее, сейчас ротация root-ключа не реализована. 12. `root_key` - Размер: 32 байта (`Pubkey`) - Назначение: корневой ключ пользователя для подписи записи. 13. `blockchain_key_status` - Размер: 1 байт (`u8`) - Текущее значение: `0` - Назначение: статус `blockchain_key`. - Комментарий: `0` = ключ создан и не менялся; другие статусы зарезервированы на будущее. 14. `blockchain_key` - Размер: 32 байта (`Pubkey`) - Назначение: рабочий блокчейн-ключ пользователя. 15. `device_key_status` - Размер: 1 байт (`u8`) - Текущее значение: `0` - Назначение: статус `device_key`. - Комментарий: `0` = ключ создан и не менялся; другие статусы зарезервированы на будущее. 16. `device_key` - Размер: 32 байта (`Pubkey`) - Назначение: ключ устройства пользователя. 17. `blockchain_number` - Размер: 2 байта (`u16`, LE) - Назначение: номер/версия пользовательского блокчейн-профиля. - Текущее использование: базовый сценарий с одним профилем; обычно значение `1` (только основной блокчейн-профиль без форков). 18. `balance` - Размер: 8 байт (`u64`, LE) - Назначение: лимит/баланс пользователя. 19. `is_server` - Размер: 1 байт (`u8`) - Значения: `0` или `1` - Назначение: флаг серверного профиля. 20. `server_key` (только если `is_server = 1`) - Размер: 32 байта (`Pubkey`) - Назначение: публичный ключ сервера. 21. `server_address_len` (только если `is_server = 1`) - Размер: 1 байт (`u8`) - Назначение: длина строки `server_address`. 22. `server_address` (только если `is_server = 1`) - Размер: `server_address_len` байт (UTF-8) - Назначение: адрес сервера. 23. `connection_servers_count` - Размер: 1 байт (`u8`) - Назначение: количество серверов в списке подключения. 24. Повтор `connection_servers_count` раз: - `server_login_len` — 1 байт (`u8`) - `server_login` — `server_login_len` байт (UTF-8) - Назначение: логины серверов подключения. 25. `trusted_count` - Размер: 1 байт (`u8`) - Назначение: текущее число trusted-контактов. - Текущее состояние: пока только счетчик; в текущем рабочем потоке обычно `0`, расширенная trusted-логика еще не включена. 26. `reserved` - Размер: 5 байт - Текущее значение: все `0x00` - Назначение: резерв под будущие расширения. 27. `signature` - Размер: 64 байта - Назначение: Ed25519 подпись хэша unsigned-части записи. 28. `padding` - Размер: до полного `USER_PDA_SPACE` - Текущее значение: `0x00` - Назначение: добивка до фиксированного размера PDA. ## 3) Что подписывается Подписывается SHA-256 от unsigned-части записи: - от `magic` до `reserved` включительно; - без `signature`; - без `padding`. ## 4) Что сейчас ограничено и зарезервировано на будущее 1. Статусы ключей (`root_key_status`, `blockchain_key_status`, `device_key_status`) Сейчас только значение `0`; будущие значения для ротации ключей пока не введены. 2. Trusted-часть (`trusted_count`) Пока хранится только счетчик. Полная логика trusted-пользователей (список, очередь, таймауты) еще не реализована. 3. `reserved` (5 байт) Полностью нулевой резерв под будущие поля/флаги. 4. Блокчейн-профили Сейчас рабочая модель ориентирована на один базовый профиль; расширение до нескольких профилей/форков будет отдельным этапом. 5. Версия формата Текущий документ описывает `v1.1 (DRAFT)`. В тестовой разработке формат можно не повышать до момента внедрения новой on-chain логики. 6. Текущие рабочие операции Сейчас по факту поддерживаются: - регистрация пользователя (`create_user_pda`); - обновление записи (`update_user_pda`) с увеличением `balance` через `additional_limit`; - инкремент `version` на каждом успешном update; - оплата уходит на адрес, заданный в `REGISTRATION_FEE_RECEIVER` (а не в DAO по умолчанию).