85 lines
5.1 KiB
Markdown
85 lines
5.1 KiB
Markdown
shine-server-blockchain — это библиотека, которая задаёт формат блока, правила парсинга/валидации тела, крипто-проверку (hash+Ed25519) и безопасную работу с файлами блокчейна (data/<name>.bch через временный .tmp_bch).
|
||
|
||
Как устроена структура и логика работы
|
||
|
||
1) “Блок” как центральный объект (ядро)
|
||
BchBlockEntry — единая модель блока “как лежит на диске/в сети”:
|
||
читает/собирает байты в формате RAW + signature64 + hash32
|
||
сразу парсит body через BodyRecordParser
|
||
сразу проверяет что lineIndex совпадает с тем, что ожидает конкретный тип body (expectedLineIndex())
|
||
То есть: всё, что считается “блоком”, обязано быть самодостаточно валидным уже на этапе создания объекта.
|
||
|
||
2) “Body” как плагины по типам (расширяемая часть) ! <-- Новые типы записей добавлть сюда !
|
||
BodyRecord — интерфейс контракта для всех тел:
|
||
type/version — идентификаторы формата
|
||
expectedLineIndex() — жёсткое правило “в какой линии может жить”
|
||
check() — логическая валидация содержимого
|
||
toBytes() — сериализация обратно в бинарь
|
||
|
||
BodyRecordParser — диспетчер: читает первые 4 байта (type+ver) и выбирает нужный класс:
|
||
HeaderBody (lineIndex=0)
|
||
TextBody (lineIndex=1)
|
||
ReactionBody (lineIndex=2)
|
||
|
||
Добавление нового типа = добавить новый класс XxxBody + кейс в BodyRecordParser.
|
||
|
||
3) Криптография как отдельный слой проверки
|
||
BchCryptoVerifier отвечает за “как получить хэш и как проверить подпись”:
|
||
строит preimage = "SHiNE" + login + prevGlobalHash32 + prevLineHash32 + rawBytes
|
||
считает sha256(preimage) и сравнивает с hash32 внутри блока
|
||
проверяет Ed25519 подпись над hash32
|
||
Важно: BchBlockEntry не проверяет подпись — он проверяет структуру блока и правильность body/lineIndex, а криптопроверка вынесена отдельно.
|
||
|
||
4) Утилиты вокруг имени и файлов
|
||
|
||
BlockchainNameUtil — извлекает login из blockchainName (отрезает 3 символа суффикса).
|
||
FileStoreUtil — безопасное файловое хранилище:
|
||
|
||
|
||
5) Объяснение структуры работы
|
||
|
||
Типичный сценарий: пришёл блок → проверить → принять
|
||
Шаг 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
|
||
); |