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:
213
docs/contracts/auction.md
Normal file
213
docs/contracts/auction.md
Normal 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 на кошелёк
|
||||
```
|
||||
Reference in New Issue
Block a user