7.5 KiB
Как устроены каналы в блокчейне 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:
- UI собирает
CreateChannelBody v2. - UI подписывает блок приватным blockchain-ключом на устройстве.
- UI отправляет на сервер
AddBlockсblockBytesB64(полный бинарный блок: preimage + sigMarker + signature). - Сервер:
- проверяет цепочку (
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:
- Находит focus-сообщение по
(blockchainName, blockNumber). - Строит
ancestorsвверх по target-ссылкам. - Строит
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 может показывать удобный “чатовый” вид, но источник истины — блоки.