Files
dchain/docs/contracts/governance.md
vsecoder 7e7393e4f8 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
2026-04-17 14:16:44 +03:00

5.8 KiB
Raw Permalink Blame History

governance

On-chain governance контракт для управления параметрами сети. Deployer становится admin. Любой может предложить изменение параметра; admin принимает или отклоняет.

Концепция

Участник        Admin
    │               │
    │── propose ──▶ │   state[prop:<key>] = value
    │               │
    │               │── approve ──▶  state[param:<key>] = value (live)
    │               │                 удаляет prop:<key>
    │               │
    │               │── reject  ──▶  удаляет prop:<key>

После approve параметр становится live и читается нодой при следующем вызове контракта.

Методы

init

Инициализировать контракт, установить caller как admin.

Аргументы: нет

Вызывается: один раз после деплоя (deploy-скрипт делает это автоматически).

Поведение:

  • Устанавливает state[admin] = caller_pubkey
  • Идемпотентен: повторный вызов не меняет admin если уже установлен
client call-contract --method init --contract $GOV_ID \
  --key /keys/node1.json --gas 5000 --node http://node1:8080

propose

Предложить новое значение параметра. Доступно всем.

Аргументы:

# Имя Тип Ограничение
0 key string max 64 байта
1 value string max 256 байт

Поведение:

  • Сохраняет state[prop:<key>] = value
  • Лог: proposed: <key>=<value>
  • Если pending-предложение уже есть → перезаписывает
# Предложить новую цену газа 5 µT/gas
client call-contract --method propose \
  --arg gas_price --arg 5 \
  --contract $GOV_ID --key /keys/node1.json \
  --gas 10000 --node http://node1:8080

approve

Admin принимает pending-предложение. Параметр становится live.

Аргументы:

# Имя Тип
0 key string

Права: только admin.

Поведение:

  • Копирует state[prop:<key>]state[param:<key>]
  • Удаляет state[prop:<key>]
  • Лог: approved: <key>
  • Если нет pending → лог no pending: <key>
client call-contract --method approve --arg gas_price \
  --contract $GOV_ID --key /keys/node1.json \
  --gas 10000 --node http://node1:8080

reject

Admin отклоняет pending-предложение.

Аргументы:

# Имя Тип
0 key string

Права: только admin.

client call-contract --method reject --arg gas_price \
  --contract $GOV_ID --key /keys/node1.json \
  --gas 5000 --node http://node1:8080

get

Прочитать текущее live-значение параметра.

Аргументы:

# Имя Тип
0 key string

Лог:

  • value: <value> — параметр установлен
  • not set: <key> — параметр не установлен
client call-contract --method get --arg gas_price \
  --contract $GOV_ID --key /keys/node1.json \
  --gas 3000 --node http://node1:8080

Через REST (без транзакции):

curl http://localhost:8081/api/contracts/$GOV_ID/state/param:gas_price

get_pending

Прочитать pending-предложение.

Аргументы:

# Имя Тип
0 key string

Лог:

  • pending: <value>
  • no pending: <key>

set_admin

Передать роль admin другому адресу.

Аргументы:

# Имя Тип
0 new_admin string (hex pubkey)

Права: только текущий admin.

client call-contract --method set_admin --arg <NEW_ADMIN_PUBKEY> \
  --contract $GOV_ID --key /keys/node1.json \
  --gas 10000 --node http://node1:8080

Управляемые параметры

Governance хранит произвольные string-параметры. Нода читает следующие:

Ключ Тип Описание По умолчанию
gas_price uint64 (строка) µT за 1 gas unit 1 µT

Нода читает gas_price при каждом CALL_CONTRACT через chain.GetEffectiveGasPrice().
Изменение вступает в силу немедленно после approve — без перезапуска.

Можно хранить любые параметры приложения (messenger_entry_fee, relay_fee, etc.) и читать их из других контрактов через межконтрактные вызовы.

State Layout

cstate:<contractID>:admin         →  admin pubkey (hex string bytes)
cstate:<contractID>:param:<key>   →  live value
cstate:<contractID>:prop:<key>    →  pending proposal

Интеграция с нодой

После деплоя governance необходимо его привязать к ноде:

# Автоматически через deploy-скрипт
# Или вручную:
curl -X POST http://localhost:8081/api/governance/link \
  -H "Content-Type: application/json" \
  -d "{\"governance\": \"$GOV_ID\"}"

Подробнее: Governance интеграция