SHiNE-server/Как_устроены_каналы_в_блокчейне_SHiNE.md

7.5 KiB
Raw Permalink Blame History

Как устроены каналы в блокчейне SHiNE

1) Коротко: что такое “канал” в текущей реализации

В SHiNE канал — это не отдельная таблица сообщений, а линия блоков внутри блокчейна пользователя:

  • канал создается TECH-блоком CreateChannelBody (msg_type=0, msg_sub_type=1);
  • сообщения канала — это TEXT_POST (msg_type=1, msg_sub_type=10) с line_code = rootBlockNumber канала;
  • ответы (треды) — это TEXT_REPLY (msg_sub_type=20) с target-ссылкой на конкретный блок-сообщение.

То есть канал = “корневой блок канала” + все посты в его линии + связанные ответы.


2) Как канал появляется

Создание канала идет через AddBlock:

  1. UI собирает CreateChannelBody v2.
  2. UI подписывает блок приватным blockchain-ключом на устройстве.
  3. UI отправляет на сервер AddBlock с blockBytesB64 (полный бинарный блок: preimage + sigMarker + signature).
  4. Сервер:
    • проверяет цепочку (prevHash, blockNumber=last+1);
    • парсит body;
    • валидирует подпись;
    • валидирует имя канала;
    • сохраняет блок и обновляет state.

Дополнительно сервер поддерживает channel_names_state как нормализованное состояние названий каналов.


3) Правила имени и описания канала

Имя канала (ChannelNameRules)

  • длина: 3..32 символов (code points);
  • допустимые символы: только латиница A-Z a-z, цифры 0-9, _, -;
  • имя нормализуется как trim;
  • канонический slug: lower-case того же имени (без дополнительных преобразований).

Уникальность

Проверяется по slug. При конфликте сервер возвращает channel_name_already_exists.

Описание канала

В CreateChannelBody v2 описание хранится прямо в блоке (до 200 байт UTF-8). После создания описание в текущей реализации не редактируется (отдельного механизма обновления пока нет).


4) Канал “news” (root 0)

rootBlockNumber=0 — системный канал news (новостной канал по умолчанию).
Публикации TEXT_POST в news сейчас отключены (на сервере есть явный запрет записи в root 0).


5) Как идут сообщения в канале

Публикация поста

UI вызывает addBlockTextPost -> AddBlock с TEXT_POST.

Ограничения:

  • писать можно только в свой блокчейн и свои каналы;
  • для поста задается line_code канала;
  • пост в канале — это новый неизменяемый блок.

Ответы

Ответы (TEXT_REPLY) не обязаны лежать в той же линии.
Они ссылаются на целевой блок через target (to_bch_name, to_block_number, to_block_hash).

Это позволяет отвечать и из других блокчейнов (межпользовательский тред).


6) Редактирование и удаление сообщений

Редактирование

Поддержано на уровне протокола:

  • TEXT_EDIT_POST (11) — правка поста;
  • TEXT_EDIT_REPLY (21) — правка ответа.

Правка — это новый блок, ссылающийся на оригинал.
Оригинальный блок не меняется.

Серверные read-API уже собирают versions[] и versionsTotal.

Удаление

Сейчас отдельного subtype “delete post/reply” нет.
Физического удаления блоков из цепочки нет (блоки иммутабельны).

Итог:

  • изменить можно через edit-блок;
  • удалить “как в чате” сейчас нельзя.

7) Как UI получает канал

Основные read-API:

  • ListSubscriptionsFeed — список каналов/подписок;
  • GetChannelMessages — посты канала;
  • GetMessageThread — тред вокруг выбранного сообщения.

Важно: UI получает JSON-представление, собранное сервером из блоков БД, а не сырые блоки по умолчанию.

В JSON возвращаются:

  • messageRef (номер и hash блока),
  • автор,
  • текущий текст,
  • versions[] (оригинал + правки),
  • counters (likesCount, repliesCount).

8) Как строится тред

GetMessageThread:

  1. Находит focus-сообщение по (blockchainName, blockNumber).
  2. Строит ancestors вверх по target-ссылкам.
  3. Строит descendants вниз: replies, где target = focus.

Запросы в БД идут по to_bch_name + to_block_number + to_block_hash, поэтому ответы из других блокчейнов тоже связываются.


9) Что проверяется криптографически

При записи (AddBlock) сервер проверяет:

  • корректность формата блока;
  • непрерывность цепочки;
  • SHA-256(preimage) и Ed25519-подпись;
  • соответствие публичного blockchain-ключа пользователя.

На чтении (GetChannelMessages, GetMessageThread) сервер отдает уже сохраненные данные (JSON из БД).
Повторная верификация каждой записи при каждом чтении не делается.


10) UI-статус на сегодня (важно)

На момент этого документа:

  • в UI нет полноценного экрана истории правок сообщения (хотя versions уже приходят);
  • нет операции удаления сообщений (и на протоколе нет delete subtype);
  • канал читается как JSON-слой поверх блоков, а не как “сырой бинарный блок-объект”.

11) Практический вывод по модели данных

Каналы в SHiNE — это append-only модель:

  • каждое действие = новый подписанный блок;
  • “изменение” = добавление новой версии, не перезапись старой;
  • целостность и авторство обеспечиваются подписью и связностью цепочки;
  • UI может показывать удобный “чатовый” вид, но источник истины — блоки.