5.1 KiB
shine-server-blockchain — это библиотека, которая задаёт формат блока, правила парсинга/валидации тела, крипто-проверку (hash+Ed25519) и безопасную работу с файлами блокчейна (data/.bch через временный .tmp_bch).
Как устроена структура и логика работы
-
“Блок” как центральный объект (ядро) BchBlockEntry — единая модель блока “как лежит на диске/в сети”: читает/собирает байты в формате RAW + signature64 + hash32 сразу парсит body через BodyRecordParser сразу проверяет что lineIndex совпадает с тем, что ожидает конкретный тип body (expectedLineIndex()) То есть: всё, что считается “блоком”, обязано быть самодостаточно валидным уже на этапе создания объекта.
-
“Body” как плагины по типам (расширяемая часть) ! <-- Новые типы записей добавлть сюда ! BodyRecord — интерфейс контракта для всех тел: type/version — идентификаторы формата expectedLineIndex() — жёсткое правило “в какой линии может жить” check() — логическая валидация содержимого toBytes() — сериализация обратно в бинарь
BodyRecordParser — диспетчер: читает первые 4 байта (type+ver) и выбирает нужный класс: HeaderBody (lineIndex=0) TextBody (lineIndex=1) ReactionBody (lineIndex=2)
Добавление нового типа = добавить новый класс XxxBody + кейс в BodyRecordParser.
-
Криптография как отдельный слой проверки BchCryptoVerifier отвечает за “как получить хэш и как проверить подпись”: строит preimage = "SHiNE" + login + prevGlobalHash32 + prevLineHash32 + rawBytes считает sha256(preimage) и сравнивает с hash32 внутри блока проверяет Ed25519 подпись над hash32 Важно: BchBlockEntry не проверяет подпись — он проверяет структуру блока и правильность body/lineIndex, а криптопроверка вынесена отдельно.
-
Утилиты вокруг имени и файлов
BlockchainNameUtil — извлекает login из blockchainName (отрезает 3 символа суффикса). FileStoreUtil — безопасное файловое хранилище:
- Объяснение структуры работы
Типичный сценарий: пришёл блок → проверить → принять Шаг 0. Контекст (что у нас уже есть снаружи)
Снаружи библиотеки (в сервере) у тебя уже известны: userLogin — владелец блокчейна publicKey32 — публичный ключ пользователя prevGlobalHash32 — хэш предыдущего блока по глобальной цепи prevLineHash32 — хэш предыдущего блока по текущей линии
Библиотека не хранит это сама, она ожидает, что сервер это передаст.
Шаг 1. Парсинг блока (структура + логика) BchBlockEntry block = new BchBlockEntry(fullBytes);
Что происходит здесь автоматически: проверяется длина блока проверяется recordSize парсится RAW-заголовок парсится body через BodyRecordParser проверяется, что lineIndex соответствует типу body (HEADER → line 0, TEXT → line 1, REACTION → line 2 и т.д.) ❗ На этом шаге никакой криптографии ещё нет — только структура и логика формата.
Если тут не упало исключение → блок структурно корректен.
Шаг 2. Подготовка данных для криптопроверки (они получаются просто из частей байтов полного блокас подписью) byte[] rawBytes = block.getRawBytes(); byte[] signature64 = block.getSignature64(); byte[] hash32FromTail = block.getHash32();
Важно: rawBytes — это ровно те байты, которые участвовали в хэшировании hash32FromTail — это то, что автор блока положил внутрь блока
Шаг 3. Криптографическая проверка (ключевой вызов) boolean ok = BchCryptoVerifier.verifyAll( userLogin, prevGlobalHash32, prevLineHash32, rawBytes, signature64, publicKey32, hash32FromTail );