SHA256
Аввив 2.0 - работает, заливка!!
This commit is contained in:
@@ -1,49 +1,116 @@
|
||||
# Общий формат добавляемого блока (Frame v0)
|
||||
# Общий формат пользовательского блока SHiNE — Frame v1 / ANS-104
|
||||
|
||||
Этот файл описывает **единый бинарный формат** блока, который клиент отправляет через `AddBlock` в поле `blockBytesB64`.
|
||||
Актуальный формат не поддерживает старый Frame v0. Новый пользовательский блок сразу создаётся как готовый подписанный ANS-104 DataItem.
|
||||
|
||||
## 1. Полная структура блока
|
||||
## 1. Два уровня формата
|
||||
|
||||
Блок состоит из двух частей:
|
||||
Полный объект, который клиент отправляет в `AddBlock`, хранится в PostgreSQL и затем архивируется в Arweave:
|
||||
|
||||
1. **PREIMAGE** (подписывается)
|
||||
2. **TAIL** (маркер подписи + подпись)
|
||||
```text
|
||||
ANS-104 DataItem
|
||||
signature_type = 2 (generic Ed25519)
|
||||
signature = 64 bytes
|
||||
owner = 32-byte blockchain public key
|
||||
target = absent
|
||||
anchor = absent
|
||||
tags
|
||||
data = SHiNE Frame v1
|
||||
```
|
||||
|
||||
### PREIMAGE
|
||||
Цепочка SHiNE **не зависит от Arweave**. Arweave DataItem ID хранится отдельно и используется для дедупликации/поиска, но не является `prevHash`.
|
||||
|
||||
- `frameCode (uint16)`
|
||||
- `prevHash32 (32 bytes)`
|
||||
- `blockSize (int32)` — размер PREIMAGE
|
||||
- `blockNumber (int32)`
|
||||
- `timestamp (int64)`
|
||||
- `type (uint16)`
|
||||
- `subType (uint16)`
|
||||
- `version (uint16)`
|
||||
- `bodyBytes (N)`
|
||||
## 2. SHiNE Frame v1
|
||||
|
||||
### TAIL
|
||||
Все целые поля Frame v1 — BigEndian.
|
||||
|
||||
- `sigMarker (uint16)`
|
||||
- `signature64 (64 bytes, Ed25519)`
|
||||
| Поле | Размер | Описание |
|
||||
|---|---:|---|
|
||||
| `frameCode` | 2 | `0x0001` |
|
||||
| `prevHash32` | 32 | SHA-256 полного Frame v1 предыдущего SHiNE-блока; для блока 0 — нули |
|
||||
| `blockSize` | 4 | точный размер Frame v1, включая header и body |
|
||||
| `blockNumber` | 4 | номер блока, начиная с 0 |
|
||||
| `timestamp` | 8 | Unix time seconds |
|
||||
| `type` | 2 | тип сообщения |
|
||||
| `subType` | 2 | подтип |
|
||||
| `version` | 2 | версия body |
|
||||
| `body` | N | данные конкретного типа |
|
||||
|
||||
## 2. Что проверяет сервер при AddBlock
|
||||
`FRAME_HEADER_SIZE = 56` bytes.
|
||||
|
||||
- `frameCode` должен быть `0x0000`.
|
||||
- `sigMarker` должен быть `0x0100`.
|
||||
- `blockNumber` должен идти строго по порядку (`last + 1`).
|
||||
- `prevHash32` должен совпасть с вершиной цепочки на сервере.
|
||||
- `body` должен пройти `check()` для конкретного типа.
|
||||
- подпись должна валидироваться публичным ключом блокчейна.
|
||||
```text
|
||||
blockHash32 = SHA256(FrameV1Bytes)
|
||||
next.prevHash32 = blockHash32
|
||||
```
|
||||
|
||||
## 3. Ограничения
|
||||
Подписи внутри Frame v1 нет. Единственная подпись пользователя — подпись окружающего ANS-104 DataItem.
|
||||
|
||||
- максимальный полный размер блока: до 4 MiB;
|
||||
- timestamp не должен сильно уходить в будущее;
|
||||
- `bodyBytes` парсится по `type/subType/version` из заголовка блока.
|
||||
## 3. ANS-104 DataItem
|
||||
|
||||
## 4. Почему это важно
|
||||
Для тестового контура используется generic Ed25519 signature type `2`: подпись 64 bytes, owner 32 bytes. Это отдельный generic Ed25519 signer type; Solana-specific signer в текущем Turbo/arbundles имеет другой type.
|
||||
|
||||
Одинаковый общий формат позволяет:
|
||||
- передавать разные виды записей через один RPC `AddBlock`;
|
||||
- валидировать блоки единообразно;
|
||||
- расширять типы `body`, не ломая каркас блока.
|
||||
Подписывается стандартный ANS-104 deep-hash:
|
||||
|
||||
```text
|
||||
[
|
||||
"dataitem",
|
||||
"1",
|
||||
"2",
|
||||
owner,
|
||||
target(empty),
|
||||
anchor(empty),
|
||||
rawAvroTags,
|
||||
FrameV1Bytes
|
||||
]
|
||||
```
|
||||
|
||||
`rawAvroTags` — ровно те Avro-serialized bytes тегов, которые лежат внутри DataItem.
|
||||
|
||||
`dataItemId32 = SHA256(signature64)`.
|
||||
|
||||
### Обязательный тестовый тег
|
||||
|
||||
Каждый блок:
|
||||
|
||||
```text
|
||||
App = test5590
|
||||
```
|
||||
|
||||
Это временное namespace-значение для разработки. Перед реальным запуском оно будет заменено отдельным изменением протокола/кода.
|
||||
|
||||
### Канальный тег
|
||||
|
||||
Если блок относится к конкретному каналу, он дополнительно содержит:
|
||||
|
||||
```text
|
||||
c = <canonical_channel_slug>
|
||||
```
|
||||
|
||||
Slug входит в подпись DataItem и не может быть изменён сервером после подписи.
|
||||
|
||||
## 4. Что хранится в PostgreSQL
|
||||
|
||||
`blocks.block_bytes` содержит **полный serialized ANS-104 DataItem**, а не только Frame.
|
||||
|
||||
Отдельно индексируются:
|
||||
|
||||
- `block_hash` — SHA-256(Frame v1);
|
||||
- `block_signature` — 64-byte Ed25519 signature из DataItem;
|
||||
- `data_item_id` — SHA-256(signature), UNIQUE;
|
||||
- `block_number`, `bch_name`, message fields;
|
||||
- состояние публикации в Arweave.
|
||||
|
||||
Локальные `.bch`, `.tmp_bch` и marker-файлы для пользовательских blockchain больше не используются.
|
||||
|
||||
## 5. Проверка AddBlock
|
||||
|
||||
Сервер обязан:
|
||||
|
||||
1. распарсить полный ANS-104 DataItem;
|
||||
2. проверить `App=test5590`;
|
||||
3. проверить `c`, если тип блока требует канал;
|
||||
4. проверить ANS-104 Ed25519 подпись;
|
||||
5. проверить, что `owner` равен текущему blockchain public key пользователя;
|
||||
6. распарсить Frame v1 и body;
|
||||
7. проверить `blockNumber == last + 1`;
|
||||
8. проверить `prevHash32 == lastBlockHash`;
|
||||
9. записать DataItem и новое состояние атомарно в PostgreSQL.
|
||||
|
||||
Reference in New Issue
Block a user