Excluded from release bundle:
- CONTEXT.md, CHANGELOG.md (agent/project working notes)
- client-app/ (React Native messenger — tracked separately)
- contracts/hello_go/ (unused standalone example)
Kept contracts/counter/ and contracts/name_registry/ as vm-test fixtures
(referenced by vm/vm_test.go; NOT production contracts).
Docs refactor:
- docs/README.md — new top-level index with cross-references
- docs/quickstart.md — rewrite around single-node as primary path
- docs/node/README.md — full rewrite, all CLI flags, schema table
- docs/api/README.md — add /api/well-known-version, /api/update-check
- docs/contracts/README.md — split native (Go) vs WASM (user-deployable)
- docs/update-system.md — new, full 5-layer update system design
- README.md — link into docs/, drop CHANGELOG/client-app references
Build-time version system (inherited from earlier commits this branch):
- node --version / client --version with ldflags-injected metadata
- /api/well-known-version with {build, protocol_version, features[]}
- Peer-version gossip on dchain/version/v1
- /api/update-check against Gitea release API
- deploy/single/update.sh with semver guard + 15-min systemd jitter
Запуск ноды
Три основных сценария — по возрастанию сложности.
| Сценарий | Где подробно |
|---|---|
| Одна нода локально (dev, genesis) | ../quickstart.md → Путь 1 |
| Одна нода с TLS и доменом (production personal) | ../../deploy/single/README.md |
| Multi-validator federation (3+ нод, PBFT quorum) | ../../deploy/prod/README.md + multi-server.md |
Этот документ — про native запуск (не через docker) и обзор всех флагов.
Native build
Требования:
- Go 1.24+
- BadgerDB + libp2p встроены в бинарь (no-cgo,
CGO_ENABLED=0)
go build -ldflags "-s -w \
-X go-blockchain/node/version.Tag=$(git describe --tags --always --dirty) \
-X go-blockchain/node/version.Commit=$(git rev-parse HEAD) \
-X go-blockchain/node/version.Date=$(date -u +%Y-%m-%dT%H:%M:%SZ) \
-X go-blockchain/node/version.Dirty=$(git diff --quiet HEAD -- && echo false || echo true)" \
-o node ./cmd/node
./node --version
# dchain-node v0.0.1 (commit=abc1234 date=… dirty=false)
Ldflags не обязательны — без них версия будет "dev". Makefile в корне
инкапсулирует это: make build.
Single node (genesis)
Сгенерировать ключ и поднять блок 0 с собой как единственным валидатором:
./node --version # проверка
./client keygen --out node.json
./node \
--key node.json \
--db ./data \
--genesis \
--listen /ip4/0.0.0.0/tcp/4001 \
--stats-addr :8080
После первого успешного запуска удалите --genesis (no-op, но шумит в логах).
Join existing network
Зная URL хотя бы одной живой ноды:
./node \
--key node.json \
--db ./data \
--join http://seed1.example.com:8080,http://seed2.example.com:8080 \
--listen /ip4/0.0.0.0/tcp/4001 \
--stats-addr :8080
Нода скачает /api/network-info, подхватит chain_id, genesis_hash, список
валидаторов и peer multiaddrs. По умолчанию запускается как observer
(применяет блоки, принимает tx, но не голосует). Чтобы стать валидатором,
существующий валидатор должен подать ADD_VALIDATOR tx с multi-sig.
Все флаги
Каждый флаг имеет env fallback (DCHAIN_<FLAG_NAME> в UPPERCASE с
заменой - на _).
Идентичность
| Флаг | env | По умолчанию | Описание |
|---|---|---|---|
--key |
DCHAIN_KEY |
node.json |
Ed25519 + X25519 identity file |
--db |
DCHAIN_DB |
chaindata |
BadgerDB directory |
Сеть
| Флаг | env | По умолчанию | Описание |
|---|---|---|---|
--listen |
DCHAIN_LISTEN |
/ip4/0.0.0.0/tcp/4001 |
libp2p listen multiaddr |
--announce |
DCHAIN_ANNOUNCE |
auto | Что анонсировать пирам (публичный IP!) |
--peers |
DCHAIN_PEERS |
— | Bootstrap peers (comma-sep multiaddrs) |
--join |
DCHAIN_JOIN |
— | Seed HTTP URLs для onboarding |
Консенсус
| Флаг | env | По умолчанию | Описание |
|---|---|---|---|
--genesis |
DCHAIN_GENESIS |
false | Создать block 0 при первом старте |
--validators |
DCHAIN_VALIDATORS |
— | Initial validator set (для --genesis) |
--observer |
DCHAIN_OBSERVER |
false | Observer mode (не голосовать) |
--allow-genesis-mismatch |
— | false | Пропустить safety check (опасно) |
Relay
| Флаг | env | По умолчанию | Описание |
|---|---|---|---|
--register-relay |
DCHAIN_REGISTER_RELAY |
false | Подать REGISTER_RELAY tx при старте |
--relay-fee |
— | 1000 | Fee за relay envelope, µT |
--relay-key |
— | relay.json |
X25519 key для E2E шифрования envelope |
--mailbox-db |
— | — | Badger dir для offline-получателей |
Governance / misc
| Флаг | env | По умолчанию | Описание |
|---|---|---|---|
--governance-contract |
DCHAIN_GOVERNANCE_CONTRACT |
— | ID governance контракта |
--heartbeat |
— | false | Слать heartbeat tx каждые 60 мин |
--log-format |
DCHAIN_LOG_FORMAT |
text |
text или json |
HTTP / WebSocket / UI
| Флаг | env | По умолчанию | Описание |
|---|---|---|---|
--stats-addr |
— | :8080 |
HTTP + WS listen address |
--disable-ui |
DCHAIN_DISABLE_UI |
false | Выключить блок-эксплорер HTML-страницы |
--disable-swagger |
DCHAIN_DISABLE_SWAGGER |
false | Выключить /swagger + /swagger/openapi.json |
--api-token |
DCHAIN_API_TOKEN |
— | Bearer token для submit (пусто = public) |
--api-private |
DCHAIN_API_PRIVATE |
false | Требовать token и для чтения |
Update system
| Флаг | env | По умолчанию | Описание |
|---|---|---|---|
--update-source-url |
DCHAIN_UPDATE_SOURCE_URL |
— | Gitea /api/v1/.../releases/latest URL |
--update-source-token |
DCHAIN_UPDATE_SOURCE_TOKEN |
— | PAT для приватных repo |
Файл ключа
{
"pub_key": "26018d40...", // Ed25519 public (64 hex chars)
"priv_key": "16aba1d2...", // Ed25519 private (128 hex chars, priv||pub)
"x25519_pub": "baada10a...", // X25519 public для relay E2E
"x25519_priv":"a814c191..." // X25519 private
}
client keygen --out node.json — создаёт валидный файл.
Схема ключей BadgerDB
height → uint64 (tip)
block:<index> → JSON Block
tx:<txid> → JSON TxRecord
txchron:<block20d>:<seq04d> → tx_id (recent-tx index)
balance:<pubkey> → uint64 (µT)
stake:<pubkey> → uint64 (µT)
id:<pubkey> → JSON RegisterKeyPayload
chan:<channelID> → JSON CreateChannelPayload
chan-member:<ch>:<pub> → ""
contract:<contractID> → JSON ContractRecord
cstate:<contractID>:<key> → bytes
clog:<ct>:<block>:<seq> → JSON ContractLogEntry
relay:<pubkey> → JSON RegisterRelayPayload
validator:<pubkey> → "" (presence = active)
schema:ver → uint32 (migration version)
Метрики + healthcheck
- Healthcheck:
curl http://localhost:8080/api/netstatsвозвращает 200 с JSON, если нода живая. - Prometheus:
GET /metrics— см. ../api/README.md. - Время блока: норма ~5 сек (константа в
consensus/pbft.go).
Сброс данных
# Native
rm -rf ./data ./mailbox
# Docker
docker compose down -v
# Single-node container
docker stop dchain && docker rm dchain
docker volume rm dchain_data
После сброса нода начнёт с пустого стейта; c --genesis — создаст новый
chain_id, с --join — синкается с сетью.