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:
203
docs/contracts/governance.md
Normal file
203
docs/contracts/governance.md
Normal file
@@ -0,0 +1,203 @@
|
||||
# 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 если уже установлен
|
||||
|
||||
```bash
|
||||
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-предложение уже есть → перезаписывает
|
||||
|
||||
```bash
|
||||
# Предложить новую цену газа 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>`
|
||||
|
||||
```bash
|
||||
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.
|
||||
|
||||
```bash
|
||||
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>` — параметр не установлен
|
||||
|
||||
```bash
|
||||
client call-contract --method get --arg gas_price \
|
||||
--contract $GOV_ID --key /keys/node1.json \
|
||||
--gas 3000 --node http://node1:8080
|
||||
```
|
||||
|
||||
Через REST (без транзакции):
|
||||
```bash
|
||||
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.
|
||||
|
||||
```bash
|
||||
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 необходимо его **привязать** к ноде:
|
||||
|
||||
```bash
|
||||
# Автоматически через deploy-скрипт
|
||||
# Или вручную:
|
||||
curl -X POST http://localhost:8081/api/governance/link \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"governance\": \"$GOV_ID\"}"
|
||||
```
|
||||
|
||||
Подробнее: [Governance интеграция](../node/governance.md)
|
||||
Reference in New Issue
Block a user