Files
SHiNE-server/docs/Blockchain/01_Common_Block_Format.md
T

117 lines
4.4 KiB
Markdown

# Общий формат пользовательского блока SHiNE — Frame v1 / ANS-104
Актуальный формат не поддерживает старый Frame v0. Новый пользовательский блок сразу создаётся как готовый подписанный ANS-104 DataItem.
## 1. Два уровня формата
Полный объект, который клиент отправляет в `AddBlock`, хранится в PostgreSQL и затем архивируется в Arweave:
```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
```
Цепочка SHiNE **не зависит от Arweave**. Arweave DataItem ID хранится отдельно и используется для дедупликации/поиска, но не является `prevHash`.
## 2. SHiNE Frame v1
Все целые поля Frame v1 — BigEndian.
| Поле | Размер | Описание |
|---|---:|---|
| `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 | данные конкретного типа |
`FRAME_HEADER_SIZE = 56` bytes.
```text
blockHash32 = SHA256(FrameV1Bytes)
next.prevHash32 = blockHash32
```
Подписи внутри Frame v1 нет. Единственная подпись пользователя — подпись окружающего ANS-104 DataItem.
## 3. ANS-104 DataItem
Для тестового контура используется generic Ed25519 signature type `2`: подпись 64 bytes, owner 32 bytes. Это отдельный generic Ed25519 signer type; Solana-specific signer в текущем Turbo/arbundles имеет другой type.
Подписывается стандартный 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.