Отключить репосты и добавить Solana-модуль

This commit is contained in:
AidarKC
2026-05-24 12:16:39 +03:00
parent abdce05136
commit 56cd90a197
95 changed files with 24261 additions and 64 deletions
+47
View File
@@ -0,0 +1,47 @@
# Движение Средств (Shine)
Документ описывает, как перемещаются средства между счетами в текущей схеме.
## 1) Регистрация и увеличение лимита (`shine_users`)
### Регистрация пользователя (`create_user_pda`)
1. Плательщик: кошелек `signer` (кто отправил транзакцию).
2. Получатель комиссии: `inflow_vault` (PDA в программе `shine_payments`).
3. Сумма перевода:
- `registration_fee_lamports` из economy-конфига `shine_users`;
- плюс комиссия за `additional_limit` (по формуле через `limit_step` и `lamports_per_limit_step`).
### Увеличение лимита (`update_user_pda`)
1. Плательщик: кошелек `signer`.
2. Получатель комиссии: `inflow_vault` (тот же PDA `shine_payments`).
3. Сумма перевода:
- только комиссия за `additional_limit` (без регистрационной части).
## 2) Покупка билета (`shine_payments`)
### Покупка (`buy_ticket`, `buy_ticket_usd`, `buy_ticket_sol`)
1. Плательщик: кошелек покупателя (`signer`).
2. Получатель: `dao_wallet` (казна DAO из `ConfigState`).
3. В `inflow_vault` на этом шаге средства не зачисляются.
## 3) Шаг выплат (`shine_payments::step_payout`)
Источник выплат: `inflow_vault` (`ConfigState.inflow_vault`).
При шаге выплаты:
1. Из `inflow_vault` переводится `ticket` получателю тикета.
2. Из `inflow_vault` переводится DAO-часть в `dao_wallet`.
3. Из `inflow_vault` переводится `call_reward_lamports` вызывающему шаг.
Если очереди пусты:
1. Весь доступный остаток `inflow_vault` переводится в `dao_wallet`.
## 4) Какие адреса задаются настройками
1. `dao_wallet` — хранится в `ConfigState` (`shine_payments`), задается при `init`.
2. `inflow_vault` — PDA `shine_payments`, вычисляется по seed и program id.
3. Для `shine_users` получатель комиссии не настраивается отдельно:
- всегда используется PDA `inflow_vault` программы `shine_payments`.
@@ -0,0 +1,225 @@
# SHINY USER FORMAT v1.0 (DRAFT)
Документ описывает целевой бинарный формат пользовательской записи в `user_pda` для программы `shine_users`.
## 1) Статус версии и цель
- Текущий on-chain формат: `v1.0`.
- Этот документ: `v1.0 (draft)` для текущего этапа.
- Цель текущей версии: зафиксировать рабочий формат и сразу оставить в нем поля для будущего расширения.
Новые статусные поля:
- `root_key_status`
- `blockchain_key_status`
- `device_key_status`
Текущее значение каждого статуса: `0` (ключ создан и не менялся).
## 2) Общие правила кодирования
- Числа: Little Endian (`LE`).
- Строки: `UTF-8` с префиксом длины `u8`.
- Публичные ключи: 32 байта (`Pubkey`).
- Подпись: 64 байта (Ed25519).
- Размер PDA фиксированный: `USER_PDA_SPACE` (сейчас 1024 байта).
- `record_len` хранит длину полезной записи от `magic` до `signature` включительно (без `padding`).
## 3) Единый список полей в порядке хранения
1. `magic`
Размер: 5 байт.
Значение: `"SHiNE"`.
Назначение: маркер формата записи.
2. `format_major`
Размер: 1 байт (`u8`).
Текущее значение: `1`.
Назначение: major-версия формата.
3. `format_minor`
Размер: 1 байт (`u8`).
Текущее значение: `0`.
Назначение: 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. `record_number` (`version`)
Размер: 4 байта (`u32`, LE).
Назначение: порядковый номер записи пользователя.
Правило обновления: новая запись должна иметь `last_record_number + 1`; проверяется программой.
8. `prev_record_hash` (`prev_hash`)
Размер: 32 байта.
Назначение: хэш unsigned-части предыдущей записи для связи истории.
9. `login_len`
Размер: 1 байт (`u8`).
Назначение: длина поля `login` в байтах.
10. `login`
Размер: `login_len` байт (UTF-8).
Назначение: логин пользователя.
Текущие ограничения: от 1 до 25 символов, только `a-z`, `0-9`, `_`.
11. `root_key_status`
Размер: 1 байт (`u8`).
Текущее значение: `0`.
Назначение: статус `root_key`.
Комментарий: будущие статусы ротации зарезервированы, смена root-ключа пока не реализована.
12. `root_key`
Размер: 32 байта (`Pubkey`).
Назначение: корневой ключ пользователя для подписи записи.
13. `blockchain_key_status`
Размер: 1 байт (`u8`).
Текущее значение: `0`.
Назначение: статус `blockchain_key`.
Комментарий: будущие статусы ротации зарезервированы.
14. `blockchain_key`
Размер: 32 байта (`Pubkey`).
Назначение: рабочий блокчейн-ключ пользователя.
15. `device_key_status`
Размер: 1 байт (`u8`).
Текущее значение: `0`.
Назначение: статус `device_key`.
Комментарий: будущие статусы ротации зарезервированы.
16. `device_key`
Размер: 32 байта (`Pubkey`).
Назначение: ключ устройства пользователя.
17. `chain_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. `sync_servers_count` (только если `is_server = 1`)
Размер: 1 байт (`u8`).
Назначение: количество серверов, с которыми сервер синхронизирует данные.
Ограничение: максимум `32`.
24. Повтор `sync_servers_count` раз (только если `is_server = 1`):
`server_login_len` — 1 байт (`u8`),
`server_login``server_login_len` байт (UTF-8).
Назначение: логины серверов синхронизации.
25. `access_servers_count`
Размер: 1 байт (`u8`).
Назначение: количество серверов доступа (relay), через которые можно достучаться до пользователя.
26. Повтор `access_servers_count` раз:
`server_login_len` — 1 байт (`u8`),
`server_login``server_login_len` байт (UTF-8).
Назначение: логины серверов доступа.
27. `trusted_count`
Размер: 1 байт (`u8`).
Назначение: текущее число trusted-контактов.
Текущее состояние: пока только счетчик, без отдельной trusted-логики.
28. `reserved`
Размер: 5 байт.
Текущее значение: `0x00 0x00 0x00 0x00 0x00`.
Назначение: резерв под будущие расширения.
29. `signature`
Размер: 64 байта.
Назначение: Ed25519-подпись хэша unsigned-части записи.
30. `padding`
Размер: до полного `USER_PDA_SPACE`.
Текущее значение: `0x00`.
Назначение: добивка до фиксированного размера PDA.
## 4) Что подписывается
Подписывается SHA-256 от unsigned-части записи:
- от `magic` до `reserved` включительно;
- без `signature`;
- без `padding`.
## 5) Что сейчас работает в логике
Сейчас в рабочем потоке используются 2 операции:
1. `create_user_pda` — регистрация пользователя.
2. `update_user_pda` — обновление записи пользователя.
Через `update_user_pda` сейчас можно:
- увеличить `balance` через `additional_limit`;
- обновить серверные поля (`is_server`, `server_key`, `server_address`, `sync_servers`, `access_servers`);
- увеличить `record_number` (`version`) на 1.
Оплата идет на адрес, заданный в `REGISTRATION_FEE_RECEIVER` (не в DAO по умолчанию).
## 6) Ограничения и отложенные расширения
Это функции и сценарии, которые предусмотрены структурой данных формата `v1.0`, но пока не реализованы программно.
1. Смена ключей пока недоступна
`root_key`, `blockchain_key`, `device_key` считаются без ротации; статусные поля пока фактически только `0`.
2. Multi-chain профили пока не реализованы
Пока используется один базовый профиль (`chain_number`), расширение до нескольких профилей/форков — отдельный этап.
3. Trusted-логика пока не реализована
Пока хранится только `trusted_count`; список trusted, очередь, таймеры и голосование будут добавляться отдельно.
4. Работа с несколькими серверами на уровне приложения ограничена
В записи можно хранить `sync_servers` и `access_servers`, но фактическая клиентская логика выбора/обхода серверов может быть ограничена.
## 7) Константы и фиксированные значения (точки будущего расширения)
Ниже перечислены места, где сейчас используются константы/фиксированные значения, а в будущем возможна доработка:
1. Версия формата: `format_major = 1`, `format_minor = 0`.
Расширение: переход на следующую минорную/мажорную версию при изменении бинарной схемы.
2. Размер PDA: `USER_PDA_SPACE = 1024`.
Расширение: увеличение размера или переход на иное хранение при росте структуры.
3. Статусы ключей: все три `*_key_status` пока равны `0`.
Расширение: добавить коды состояний для ротации/восстановления ключей.
4. `chain_number`: текущий рабочий сценарий с одним профилем (обычно `1`).
Расширение: поддержка нескольких блокчейн-форков.
5. `trusted_count`: пока только счетчик, обычно `0`.
Расширение: отдельные структуры trusted-списка, очередей и таймеров.
6. `reserved` (5 байт): сейчас всегда нули.
Расширение: использовать как флаги/дополнительные поля без слома общей схемы.
@@ -0,0 +1,55 @@
# Ключи и деплой (тестовое пояснение)
## 1) Какие адреса участвуют
В проекте есть **2 программы**, поэтому у них **2 разных Program ID**:
1. `shine_users` -> отдельный адрес программы
2. `shine_payments` -> отдельный адрес программы
Это нормальная схема Solana: одна программа = один Program ID.
Отдельно есть адрес кошелька-деплоера (upgrade authority), сейчас это:
- keypair: `~/.config/solana/id.json`
- адрес: `4yzHKs2zFXpyqqCETe8KpAs4xhEo4QhJ2ybyTgRZphZv`
Именно этот кошелек:
- платит комиссии/ренту при деплое;
- владеет правом апгрейда программ;
- получает обратно SOL при `solana program close`.
## 2) Почему раньше "плавали" адреса программ
`anchor deploy` берет адрес программы из program keypair файла (`target/deploy/*-keypair.json`).
Если keypair другой, Program ID тоже будет другой.
Чтобы этого не было, нужно держать синхронно:
1. `declare_id!` в `programs/*/src/lib.rs`
2. `[programs.devnet]` и `[programs.localnet]` в `Anchor.toml`
3. соответствующие `*-keypair.json` для программ
Сделано:
- выполнен `anchor keys sync`;
- keypair CLI по умолчанию переключен на `~/.config/solana/id.json`;
- сохранены копии program keypair в `shine/keys/`.
## 3) Сколько SOL занимали программы раньше (до закрытия)
Перед очисткой были закрыты 4 программы с такими возвратами:
1. `8Z3HQizFRhyVu5cNBwWNBXZHTpu89VMkn7Wuk1oCtkeJ` -> `3.38059032 SOL`
2. `qpgnAKhsXgPPaqQWfXhpme7UnG8GyStssuoSjF6Fzy3` -> `2.11208856 SOL`
3. `5dFcWDNp42Xn9Vv4oDMJzM4obBJ8hvDuAtPX54fT5L3t` -> `1.76425560 SOL`
4. `92sgkgx7KHpbhQu81mNGHaKa7skJB7esArVdPM7paDSW` -> `1.66820760 SOL`
Итого было занято программами:
- `8.92514208 SOL`
Из них "актуальная пара" (2 программы последнего деплоя) занимала:
- `3.38059032 + 2.11208856 = 5.49267888 SOL`