SHA256
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
|
|
); |