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
6.9 KiB
6.9 KiB
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>
# Аукцион: мин. ставка 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_blockamount > current_top_bid(илиamount ≥ min_bidесли ставок нет)
Поведение:
- Переводит
amountс caller → treasury - Если был предыдущий топ-биддер → refund ему его ставки из treasury
- Обновляет
top_bidderиtop_bid - Лог:
bid: <auction_id>
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)
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
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
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')
Полный пример сценария
# 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 на кошелёк