# Архитектура DChain ## Обзор DChain — это L1-блокчейн для децентрализованного мессенджера. Архитектура разделена на четыре слоя: ``` ┌─────────────────────────────────────────────────────────────┐ │ L3 Application — messaging, usernames, auctions, escrow │ │ (Smart contracts: username_registry, governance, auction, │ │ escrow; deployed on-chain via DEPLOY_CONTRACT) │ ├─────────────────────────────────────────────────────────────┤ │ L2 Transport — relay mailbox, E2E NaCl encryption │ │ (relay/, mailbox, GossipSub envelopes, RELAY_PROOF tx) │ ├─────────────────────────────────────────────────────────────┤ │ L1 Chain — PBFT consensus, WASM VM, BadgerDB │ │ (blockchain/, consensus/, vm/, identity/) │ ├─────────────────────────────────────────────────────────────┤ │ L0 Network — libp2p, GossipSub, DHT, mDNS │ │ (p2p/) │ └─────────────────────────────────────────────────────────────┘ ``` --- ## Консенсус (PBFT) **Алгоритм:** Practical Byzantine Fault Tolerance, кворум 2/3. **Фазы:** ``` Leader Validator-2 Validator-3 │── PRE-PREPARE ──▶│ │ │── PRE-PREPARE ────────────────────────▶ │ │◀─ PREPARE ───────│ │ │◀─ PREPARE ────────────────────────────── │ │── COMMIT ────────▶│ │ │── COMMIT ──────────────────────────────▶ │ │◀─ COMMIT ────────│ │ │◀─ COMMIT ────────────────────────────── │ AddBlock() ``` **Свойства:** - Safety при ≤ f Byzantine нодах где N ≥ 3f+1 - Текущий testnet: N=2 валидатора, f=0 (узел node3 — relay-only observer) - View-change при недоступном лидере: таймаут 10 секунд **Блок-производство:** - Fast ticker (500 ms) — при наличии транзакций в mempool - Idle ticker (5 s) — пустые блоки для heartbeat и синхронизации **Ключевые файлы:** ``` consensus/engine.go — PBFT engine consensus/msg.go — ConsensusMsg типы (PRE-PREPARE, PREPARE, COMMIT, VIEW-CHANGE) ``` --- ## Хранилище (BadgerDB) Весь state хранится в BadgerDB (LSM-дерево, pure Go). **Пространства ключей:** | Префикс | Тип | Описание | |---------|-----|---------| | `block:` | JSON | Блоки по индексу | | `height` | uint64 JSON | Текущая высота | | `balance:` | uint64 JSON | Балансы токенов | | `id:` | JSON | Identity (RegisterKey payload) | | `validator:` | presence | Активный сет валидаторов | | `relay:` | JSON | Зарегистрированные relay-ноды | | `contract:` | JSON | ContractRecord (метаданные + WASM) | | `cstate::` | raw bytes | Состояние контракта | | `clog:::` | JSON | Логи контракта | | `rep:` | JSON | Репутация (blocks, relays, slashes) | | `contact_in::` | JSON | Входящие contact requests | | `mail:::` | JSON | Relay mailbox (TTL 7 дней) | **Две отдельные БД:** - `--db ./chaindata` — chain state (consensus state machine) - `--mailbox-db ./mailboxdata` — relay mailbox (отдельная изоляция) --- ## P2P сеть (libp2p) **Компоненты:** - **Transport:** TCP `/ip4/0.0.0.0/tcp/4001` - **Identity:** Ed25519 peer key (вывод из node identity) - **Discovery:** mDNS (локалка) + Kademlia DHT (WAN) - **Pub/Sub:** GossipSub с тремя топиками: | Топик | Содержимое | |-------|-----------| | `dchain/tx/v1` | Транзакции (gossip) | | `dchain/blocks/v1` | Готовые блоки (gossip от лидера) | | `dchain/relay/v1` | Relay envelopes (зашифрованные сообщения) | - **Direct streams:** PBFT consensus messages (pre-prepare/prepare/commit/view-change) идут напрямую между валидаторами через `/dchain/consensus/1.0.0` протокол - **Sync:** block range sync по `/dchain/sync/1.0.0` при подключении нового пира --- ## WASM Virtual Machine **Runtime:** wazero v1.7.3, interpreter mode (детерминированный на всех платформах). **Жизненный цикл контракта:** ``` DEPLOY_CONTRACT tx ├── validate: wazero.CompileModule() — если ошибка, tx отклоняется ├── contractID = hex(sha256(deployerPubKey || wasmBytes))[:16] ├── BadgerDB: contract: → ContractRecord{WASMBytes, ABI, ...} └── state: cstate::* — изначально пусто CALL_CONTRACT tx ├── ABI validation: метод существует, число аргументов совпадает ├── pre-charge: tx.Fee + gasLimit × gasPrice ├── vm.Call(contractID, wasmBytes, method, argsJSON, gasLimit, hostEnv) │ ├── compile (cached) + instrument (gas_tick в loop headers) │ ├── register "env" host module (14 функций) │ ├── [optional] wasi_snapshot_preview1 (для TinyGo контрактов) │ └── fn.Call(ctx) → gasUsed, error ├── refund: (gasLimit - gasUsed) × gasPrice → обратно sender └── logs: clog::: → BadgerDB ``` **Gas модель:** каждый вызов функции (WASM или host) = 100 gas units. `gasCost (µT) = gasUsed × gasPrice` (gasPrice управляется governance или константа 1 µT). **Типы контрактов:** - **Binary WASM** — написаны на Go через кодогенераторы (`contracts/*/gen/main.go`) - **TinyGo WASM** — написаны на Go, компилируются с `tinygo -target wasip1` --- ## Экономика **Supply:** Фиксированный. Genesis-блок минтит **21 000 000 T** на ключ node1. Последующей эмиссии нет. **Unit:** µT (микро-токен). 1 T = 1 000 000 µT. **Доходы валидаторов:** только комиссии из транзакций блока (`TotalFees`). Без блок-реварда. **Комиссии:** | Операция | Минимальная fee | |---------|----------------| | Все транзакции | 1 000 µT (MinFee) | | CONTACT_REQUEST | tx.Amount → recipient (anti-spam) | | DEPLOY_CONTRACT | 10 000 µT | | CALL_CONTRACT | MinFee + gasUsed × gasPrice | | RELAY_PROOF | sender → relay node (произвольно) | **Governance:** gas_price, relay_fee и другие параметры можно менять on-chain через governance-контракт без хардфорка. --- ## Relay (E2E мессенджер) **Шифрование:** NaCl box (X25519 Diffie-Hellman + XSalsa20 + Poly1305). **Ключи:** каждый Identity имеет два ключа: - Ed25519 (подпись транзакций, chain identity) - X25519 (вывод из Ed25519 seed, шифрование сообщений) **Поток сообщения:** ``` Alice node1 (relay) Bob │ │ │ │── seal(msg, bob.X25519) ──▶ │ │ │ POST /relay/broadcast │ │ │ │── gossip envelope ──▶ │ │ │ store mailbox │ │ │ (TTL 7 days) │ │ │ │ │ │◀── GET /relay/inbox ──│ │ │ │── open(envelope) │ │ │ → plaintext ``` **Anti-spam:** - Первый контакт — платный (CONTACT_REQUEST tx, fee идёт получателю) - Envelope: max 64 KB, max 500 envelopes на получателя (FIFO) - RELAY_PROOF: подписанное доказательство доставки, fee снимается со sender и кредитуется relay --- ## Динамические валидаторы Сет валидаторов хранится on-chain в `validator:`. Любой текущий валидатор может добавить или убрать другого (ADD_VALIDATOR / REMOVE_VALIDATOR tx). После commit такого блока PBFT-движок перезагружает сет без рестарта ноды. **Ключевые файлы:** ``` blockchain/chain.go — state machine, applyTx, VMHostEnv consensus/engine.go — PBFT, UpdateValidators() vm/vm.go — wazero runtime, NewVM() vm/host.go — host module "env" (14 функций) vm/gas.go — gas counter, Remaining() relay/mailbox.go — BadgerDB TTL mailbox relay/crypto.go — NaCl seal/open p2p/host.go — libp2p host, GossipSub node/api_routes.go — HTTP API routing ```