chore: initial commit for v0.0.1

DChain single-node blockchain + React Native messenger client.

Core:
- PBFT consensus with multi-sig validator admission + equivocation slashing
- BadgerDB + schema migration scaffold (CurrentSchemaVersion=0)
- libp2p gossipsub (tx/v1, blocks/v1, relay/v1, version/v1)
- Native Go contracts (username_registry) alongside WASM (wazero)
- WebSocket gateway with topic-based fanout + Ed25519-nonce auth
- Relay mailbox with NaCl envelope encryption (X25519 + Ed25519)
- Prometheus /metrics, per-IP rate limit, body-size cap

Deployment:
- Single-node compose (deploy/single/) with Caddy TLS + optional Prometheus
- 3-node dev compose (docker-compose.yml) with mocked internet topology
- 3-validator prod compose (deploy/prod/) for federation
- Auto-update from Gitea via /api/update-check + systemd timer
- Build-time version injection (ldflags → node --version)
- UI / Swagger toggle flags (DCHAIN_DISABLE_UI, DCHAIN_DISABLE_SWAGGER)

Client (client-app/):
- Expo / React Native / NativeWind
- E2E NaCl encryption, typing indicator, contact requests
- Auto-discovery of canonical contracts, chain_id aware, WS reconnect on node switch

Documentation:
- README.md, CHANGELOG.md, CONTEXT.md
- deploy/single/README.md with 6 operator scenarios
- deploy/UPDATE_STRATEGY.md with 4-layer forward-compat design
- docs/contracts/*.md per contract
This commit is contained in:
vsecoder
2026-04-17 14:16:44 +03:00
commit 7e7393e4f8
196 changed files with 55947 additions and 0 deletions

213
docs/contracts/auction.md Normal file
View File

@@ -0,0 +1,213 @@
# auction
English auction с on-chain token escrow. Ставки хранятся в contract treasury. При перебивании ставки предыдущий топ-биддер получает автоматический refund.
## Жизненный цикл
```
seller buyer-1 buyer-2 anyone
│ │ │ │
│─ create ──────▶│ │ │
│ (min_bid, │ │ │
│ duration) │ │ │
│ │ │ │
│ │─ bid(500) ───▶│ │
│ │ treasury ←500│ │
│ │ │ │
│ │ │─ bid(800) ───▶│
│ │ refund→500 │ treasury ←800│
│ │ │ │
│ │ │ │ [end_block reached]
│ │ │ │
│◀─────────────────────────────────── settle ────│
│ treasury→800 │ │ │
│ (seller gets │ │ │
│ winning bid) │ │ │
```
**Статусы:** `open``settled` / `cancelled`
## Auction ID
Формат: `<block_height>:<seq>`, например `42:0`, `42:1`.
Генерируется автоматически при `create`, логируется как `created: <id>`.
## Методы
### `create`
Создать новый аукцион.
**Аргументы:**
| # | Имя | Тип | Описание |
|---|-----|-----|---------|
| 0 | `title` | string | Описание лота (max 128 байт) |
| 1 | `min_bid` | uint64 | Минимальная ставка в µT |
| 2 | `duration` | uint64 | Длительность в блоках |
**Поведение:**
- Сохраняет seller = caller
- `end_block = current_block + duration`
- Лог: `created: <auction_id>`
```bash
# Аукцион: мин. ставка 1 T, длительность 100 блоков
client call-contract --method create \
--arg "Rare NFT #42" --arg64 1000000 --arg64 100 \
--contract $AUC_ID --key /keys/node1.json \
--gas 20000 --node http://node1:8080
```
---
### `bid`
Поставить ставку. Средства переводятся из кошелька caller в treasury контракта.
**Аргументы:**
| # | Имя | Тип | Описание |
|---|-----|-----|---------|
| 0 | `auction_id` | string | ID аукциона |
| 1 | `amount` | uint64 | Ставка в µT |
**Проверки:**
- Аукцион в статусе `open`
- `current_block ≤ end_block`
- `amount > current_top_bid` (или `amount ≥ min_bid` если ставок нет)
**Поведение:**
- Переводит `amount` с caller → treasury
- Если был предыдущий топ-биддер → refund ему его ставки из treasury
- Обновляет `top_bidder` и `top_bid`
- Лог: `bid: <auction_id>`
```bash
client call-contract --method bid \
--arg "42:0" --arg64 2000000 \
--contract $AUC_ID --key /keys/node1.json \
--gas 30000 --node http://node1:8080
```
---
### `settle`
Завершить аукцион после истечения `end_block`. Переводит топ-ставку продавцу.
**Аргументы:**
| # | Имя | Тип |
|---|-----|-----|
| 0 | `auction_id` | string |
**Проверки:** `current_block > end_block`, статус `open`
**Поведение:**
- Если есть ставки: переводит `top_bid` из treasury → seller, статус → `settled`
- Если ставок нет: статус → `cancelled`
- Лог: `settled: <id>` или `cancelled: <id> (no bids)`
- Может вызвать **любой** (не только seller)
```bash
client call-contract --method settle --arg "42:0" \
--contract $AUC_ID --key /keys/node1.json \
--gas 20000 --node http://node1:8080
```
---
### `cancel`
Отменить аукцион без ставок. Только seller.
**Аргументы:**
| # | Имя | Тип |
|---|-----|-----|
| 0 | `auction_id` | string |
**Проверки:** статус `open`, ставок нет, `caller == seller`
```bash
client call-contract --method cancel --arg "42:0" \
--contract $AUC_ID --key /keys/node1.json \
--gas 10000 --node http://node1:8080
```
---
### `info`
Запросить состояние аукциона.
**Аргументы:**
| # | Имя | Тип |
|---|-----|-----|
| 0 | `auction_id` | string |
**Логи:**
```
seller: <pubkey>
title: <title>
top_bid: <amount>
end_block: <block>
status: open|settled|cancelled
```
```bash
client call-contract --method info --arg "42:0" \
--contract $AUC_ID --key /keys/node1.json \
--gas 5000 --node http://node1:8080
```
---
## State Layout
```
cstate:<contractID>:seq → uint64 (глобальный счётчик аукционов)
cstate:<contractID>:a:<id>:s → seller pubkey
cstate:<contractID>:a:<id>:t → title
cstate:<contractID>:a:<id>:b → top_bid (uint64 big-endian)
cstate:<contractID>:a:<id>:e → end_block (uint64 big-endian)
cstate:<contractID>:a:<id>:w → top_bidder pubkey
cstate:<contractID>:a:<id>:x → status byte ('o', 's', 'c')
```
## Полный пример сценария
```bash
# 1. Alice создаёт аукцион
docker exec node1 client call-contract \
--key /keys/node1.json --contract $AUC_ID \
--method create \
--arg "Special Edition #1" --arg64 500000 --arg64 50 \
--gas 20000 --node http://node1:8080
# Лог: created: 5:0
AUC_ITEM="5:0"
# 2. Bob делает ставку 1 T
docker exec node1 client call-contract \
--key /tmp/bob.json --contract $AUC_ID \
--method bid --arg $AUC_ITEM --arg64 1000000 \
--gas 30000 --node http://node1:8080
# 3. Charlie перебивает ставку — Bob получает refund автоматически
docker exec node1 client call-contract \
--key /tmp/charlie.json --contract $AUC_ID \
--method bid --arg $AUC_ITEM --arg64 1500000 \
--gas 30000 --node http://node1:8080
# 4. Проверить статус
docker exec node1 client call-contract \
--key /keys/node1.json --contract $AUC_ID \
--method info --arg $AUC_ITEM \
--gas 5000 --node http://node1:8080
# 5. После end_block — завершить (любой может)
docker exec node1 client call-contract \
--key /keys/node1.json --contract $AUC_ID \
--method settle --arg $AUC_ITEM \
--gas 20000 --node http://node1:8080
# Лог: settled: 5:0
# Alice получает 1.5 T на кошелёк
```