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

285
docs/api/contracts.md Normal file
View File

@@ -0,0 +1,285 @@
# Contracts API
REST API для работы с WASM-контрактами: деплой, вызов, чтение state и логов.
> Деплой и вызов контрактов выполняются через CLI-команды `client deploy-contract` и `client call-contract`, которые формируют и отправляют подписанные транзакции через `POST /api/tx`. Прямой HTTP-деплой не поддерживается.
## Список контрактов
### `GET /api/contracts`
Все задеплоенные контракты.
```bash
curl http://localhost:8081/api/contracts
```
```json
{
"count": 4,
"contracts": [
{
"contract_id": "a1b2c3d4e5f60001",
"deployer_pub": "03abcd...",
"deployed_at": 100,
"wasm_size": 1842,
"abi": {
"contract": "governance",
"version": "1.0.0",
"methods": [...]
}
},
...
]
}
```
---
## Детали контракта
### `GET /api/contracts/{contractID}`
```bash
curl http://localhost:8081/api/contracts/a1b2c3d4e5f60001
```
```json
{
"contract_id": "a1b2c3d4e5f60001",
"deployer_pub": "03abcd...",
"deployed_at": 100,
"wasm_size": 1842,
"abi_json": "{...}"
}
```
| Поле | Тип | Описание |
|------|-----|---------|
| `contract_id` | string | 16-символьный hex ID |
| `deployer_pub` | string | Pubkey деплоера |
| `deployed_at` | uint64 | Высота блока деплоя |
| `wasm_size` | int | Размер WASM в байтах |
| `abi_json` | string | JSON ABI контракта |
---
## State контракта
### `GET /api/contracts/{contractID}/state/{key}`
Читает значение из state контракта по ключу.
```bash
# Строковое значение
curl http://localhost:8081/api/contracts/a1b2c3d4e5f60001/state/admin
# Вложенный ключ
curl "http://localhost:8081/api/contracts/a1b2c3d4e5f60001/state/param:gas_price"
# Ключ эскроу
curl "http://localhost:8081/api/contracts/.../state/e:deal-001:b"
```
```json
{
"key": "admin",
"value_b64": "MDNhYmNk...",
"value_hex": "30336162636...",
"value_u64": null
}
```
| Поле | Тип | Описание |
|------|-----|---------|
| `value_b64` | string | Base64-encoded raw bytes |
| `value_hex` | string | Hex-encoded raw bytes |
| `value_u64` | uint64\|null | Если значение ровно 8 байт big-endian |
**Примеры чтения state контрактов:**
```bash
# Governance: live параметр
curl "http://localhost:8081/api/contracts/$GOV_ID/state/param:gas_price"
# Governance: pending предложение
curl "http://localhost:8081/api/contracts/$GOV_ID/state/prop:gas_price"
# Username registry: pubkey по имени
curl "http://localhost:8081/api/contracts/$REG_ID/state/name:alice"
# value_hex = hex(pubkey_bytes) → hex.DecodeString(value_hex) = pubkey
# Escrow: статус сделки
curl "http://localhost:8081/api/contracts/$ESC_ID/state/e:deal-001:x"
# value_hex: 61='a' (active), 64='d' (disputed), 72='r' (released), 66='f' (refunded)
```
---
## Логи контракта
### `GET /api/contracts/{contractID}/logs?limit=N`
Последние `N` лог-записей (по умолчанию 50, максимум 100).
```bash
curl "http://localhost:8081/api/contracts/a1b2c3d4e5f60001/logs?limit=20"
```
```json
{
"contract_id": "a1b2c3d4e5f60001",
"count": 5,
"logs": [
{
"tx_id": "tx-abc123",
"block_index": 1024,
"timestamp": 1710000000,
"message": "registered: alice"
},
{
"tx_id": "tx-def456",
"block_index": 1020,
"timestamp": 1709999800,
"message": "initialized"
}
]
}
```
Логи отсортированы от новейших к старейшим.
---
## Деплой контракта (через CLI)
```bash
client deploy-contract \
--key key.json \
--wasm mycontract.wasm \
--abi mycontract_abi.json \
--node http://localhost:8081
```
Успешный деплой печатает:
```
contract_id: a1b2c3d4e5f60001
```
В Docker:
```bash
docker exec node1 client deploy-contract \
--key /keys/node1.json \
--wasm /contracts/mycontract.wasm \
--abi /contracts/mycontract_abi.json \
--node http://node1:8080
```
---
## Вызов контракта (через CLI)
```bash
# Без аргументов
client call-contract \
--contract a1b2c3d4e5f60001 \
--method increment \
--gas 5000 \
--key key.json --node http://localhost:8081
# Строковый аргумент
client call-contract \
--contract $REG_ID \
--method register \
--arg alice \
--gas 30000 \
--key key.json --node http://localhost:8081
# Числовой аргумент (uint64)
client call-contract \
--contract $ESC_ID \
--method create \
--arg "deal-001" \
--arg "$SELLER_PUB" \
--arg64 5000000 \
--gas 30000 \
--key key.json --node http://localhost:8081
# Несколько аргументов в JSON
client call-contract \
--contract $AUCTION_ID \
--method create \
--args '["Rare item #1", 1000000, 100]' \
--gas 20000 \
--key key.json --node http://localhost:8081
```
### Флаги call-contract
| Флаг | Тип | Описание |
|------|-----|---------|
| `--contract` | string | ID контракта (16 hex) |
| `--method` | string | Имя метода |
| `--arg` | string | Добавить строковый аргумент (повторяемый) |
| `--arg64` | uint64 | Добавить числовой аргумент (повторяемый) |
| `--args` | JSON | Массив всех аргументов `["str", 42, ...]` |
| `--gas` | uint64 | Gas лимит |
| `--key` | path | Файл ключа |
| `--node` | URL | Node URL |
---
## Токены и NFT
### `GET /api/tokens`
```bash
curl http://localhost:8081/api/tokens
```
```json
{"count": 2, "tokens": [{...}]}
```
### `GET /api/tokens/{id}`
```bash
curl http://localhost:8081/api/tokens/abc123
```
### `GET /api/tokens/{id}/balance/{pubkey}`
```bash
curl http://localhost:8081/api/tokens/abc123/balance/03abcd...
```
```json
{
"token_id": "abc123",
"pub_key": "03abcd...",
"address": "DCabc...",
"balance": 1000
}
```
### `GET /api/nfts`
```bash
curl http://localhost:8081/api/nfts
```
### `GET /api/nfts/{id}`
```bash
curl http://localhost:8081/api/nfts/nft-abc123
```
### `GET /api/nfts/owner/{pubkey}`
```bash
curl http://localhost:8081/api/nfts/owner/03abcd...
```
```json
{"count": 3, "nfts": [{...}]}
```