shine-solana/shine/doc/SHINE_USER_PDA_V1.md

4.7 KiB
Raw Blame History

SHiNE User PDA v1.0

1. Назначение

SHiNE User PDA v1.0 — бинарный формат пользовательской записи в PDA Solana.

Хранит:

  • логин;
  • ключи пользователя;
  • номер внутренней сети;
  • лимит (баланс);
  • серверные данные (опционально);
  • список серверов подключения;
  • данные восстановления;
  • связь с предыдущей версией через prev_hash;
  • подпись владельца root_key.

Размер PDA фиксированный:

768 bytes

Полезная длина записи указывается в record_len.

2. Общие правила кодирования

  • Числа: little-endian.
  • Строки: UTF-8 с префиксом длины u8.
  • Padding до 768 байт: нули 0x00.
  • Padding не входит в record_len.

3. Структура записи

  • magic (5): "SHiNE"
  • format_major (1): 1
  • format_minor (1): 0
  • record_len (2): длина от magic до signature включительно
  • created_at_ms (8)
  • updated_at_ms (8)
  • version (4)
  • prev_hash (32)
  • login_len (1)
  • login (N)
  • root_key (32)
  • blockchain_key (32)
  • device_key (32)
  • chain_number (2)
  • balance (8)
  • is_server (1)
  • если is_server=1:
    • server_key (32)
    • server_address_len (1)
    • server_address (N)
  • connection_servers_count (1)
  • повтор count раз:
    • server_login_len (1)
    • server_login (N)
  • trusted_count (1)
  • reserved (5) = 0x00 0x00 0x00 0x00 0x00
  • signature (64)
  • padding до 768

4. Подпись (v1.0)

В v1.0 подписывается не сырой блок полей напрямую, а его SHA-256.

  1. Формируется unsigned_bytes:
    • все поля от magic до reserved включительно;
    • поле signature не включается;
    • padding не включается.
  2. Считается msg_hash = SHA-256(unsigned_bytes).
  3. signature = Ed25519.sign(root_private_key, msg_hash).
  4. Проверка:
    • Ed25519.verify(root_key, msg_hash, signature).

5. Что входит в prev_hash

Для связи версий:

  • prev_hash = SHA-256(previous_unsigned_bytes)

Где previous_unsigned_bytes — предыдущая версия записи от magic до reserved включительно, без signature и без padding.

Для первой версии:

  • prev_hash = 32 нулевых байта.

6. Правила create/update в текущей реализации

Create

  • PDA: seed ["login=", login].
  • Создаётся запись версии 0.
  • updated_at_ms = created_at_ms.
  • Стартовый лимит:
    • START_BONUS_LIMIT + additional_limit.
  • Оплата:
    • регистрационная комиссия;
    • пополнение additional_limit по курсу;
    • рента PDA (плательщик транзакции).

Update

  • Проверка подписи новой записи по root_key.
  • Проверка:
    • magic, format_major, format_minor;
    • корректного record_len;
    • prev_hash на соответствие предыдущей версии;
    • version = old_version + 1;
    • неизменяемых полей: login, created_at_ms, root_key.
  • balance не уменьшается:
    • new_balance = old_balance + additional_limit.
  • При additional_limit > 0 берётся комиссия пополнения.

7. Параметры экономики/размера (settings)

См. programs/shine_users/src/settings.rs:

  • USER_PDA_SPACE = 768
  • REGISTRATION_FEE_RECEIVER
  • REGISTRATION_FEE_LAMPORTS
  • LIMIT_STEP
  • LAMPORTS_PER_LIMIT_STEP
  • START_BONUS_LIMIT

8. Root Key Rotation (пока не включено)

В v1.0 root_key неизменяем.

Варианты расширения:

  1. Dual-signature rotate tx:

    • отдельный флаг операции rotate;
    • запись подписывается и старым, и новым root key;
    • контракт проверяет обе подписи.
  2. Two-step commit/confirm:

    • шаг 1: proposal смены root (old root подпись);
    • шаг 2: confirm (new root подпись) в отдельной tx.
  3. Recovery guardians:

    • отдельная PDA для доверенных лиц;
    • пороговая схема (например m-of-n) для восстановления root.

Для v1.0 решение отложено, но изменение root_key в update запрещено.