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
5.8 KiB
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 интеграция