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:
vsecoder
2026-04-17 14:16:44 +03:00
commit 7e7393e4f8
196 changed files with 55947 additions and 0 deletions

View File

@@ -0,0 +1,102 @@
(module
;; Counter smart contract — methods: increment, get, reset
;; State key "counter" stores uint64 as 8-byte big-endian.
;; State key "owner" stores the deployer pub key set on first reset() call.
;; ── imports ──────────────────────────────────────────────────────────────
(import "env" "put_u64"
(func $put_u64 (param i32 i32 i64)))
(import "env" "get_u64"
(func $get_u64 (param i32 i32) (result i64)))
(import "env" "get_caller"
(func $get_caller (param i32 i32) (result i32)))
(import "env" "get_state"
(func $get_state (param i32 i32 i32 i32) (result i32)))
(import "env" "set_state"
(func $set_state (param i32 i32 i32 i32)))
(import "env" "log"
(func $log (param i32 i32)))
;; ── memory ───────────────────────────────────────────────────────────────
;; Memory layout:
;; offset 0 : "counter" (7 bytes) — state key for the counter value
;; offset 16 : "owner" (5 bytes) — state key for the owner pub key
;; offset 32 : caller buffer (128 bytes)
;; offset 160 : owner buffer (128 bytes)
;; offset 288 : log messages
(memory (export "memory") 1)
(data (i32.const 0) "counter")
(data (i32.const 16) "owner")
(data (i32.const 288) "incremented")
(data (i32.const 300) "get called")
(data (i32.const 310) "reset")
(data (i32.const 316) "unauthorized")
(data (i32.const 329) "reset ok")
;; ── increment() ──────────────────────────────────────────────────────────
(func (export "increment")
(local $val i64)
(local.set $val (call $get_u64 (i32.const 0) (i32.const 7)))
(local.set $val (i64.add (local.get $val) (i64.const 1)))
(call $put_u64 (i32.const 0) (i32.const 7) (local.get $val))
(call $log (i32.const 288) (i32.const 11))
)
;; ── get() ─────────────────────────────────────────────────────────────────
(func (export "get")
(call $log (i32.const 300) (i32.const 10))
)
;; ── reset() ───────────────────────────────────────────────────────────────
;; Resets counter to 0. Only callable by the deployer (first caller sets ownership).
(func (export "reset")
(local $callerLen i32)
(local $ownerLen i32)
(local $i i32)
(local $same i32)
(local.set $callerLen (call $get_caller (i32.const 32) (i32.const 128)))
(local.set $ownerLen
(call $get_state (i32.const 16) (i32.const 5) (i32.const 160) (i32.const 128)))
;; No owner yet — first caller becomes owner and resets to 0
(if (i32.eqz (local.get $ownerLen))
(then
(call $set_state (i32.const 16) (i32.const 5) (i32.const 32) (local.get $callerLen))
(call $put_u64 (i32.const 0) (i32.const 7) (i64.const 0))
(call $log (i32.const 329) (i32.const 8))
return
)
)
;; Length mismatch → unauthorized
(if (i32.ne (local.get $callerLen) (local.get $ownerLen))
(then (call $log (i32.const 316) (i32.const 12)) return)
)
;; Byte-by-byte comparison
(local.set $same (i32.const 1))
(local.set $i (i32.const 0))
(block $break
(loop $loop
(br_if $break (i32.ge_u (local.get $i) (local.get $callerLen)))
(if (i32.ne
(i32.load8_u (i32.add (i32.const 32) (local.get $i)))
(i32.load8_u (i32.add (i32.const 160) (local.get $i))))
(then (local.set $same (i32.const 0)) (br $break))
)
(local.set $i (i32.add (local.get $i) (i32.const 1)))
(br $loop)
)
)
(if (i32.eqz (local.get $same))
(then (call $log (i32.const 316) (i32.const 12)) return)
)
;; Authorized — reset
(call $put_u64 (i32.const 0) (i32.const 7) (i64.const 0))
(call $log (i32.const 329) (i32.const 8))
)
)