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
8.0 KiB
Host Functions
Полный справочник 14 host-функций, которые DChain экспортирует в WASM-контракты через модуль env.
Все функции регистрируются в vm/host.go. Контракт импортирует их через //go:wasmimport env <name> (TinyGo) или напрямую в секции imports WASM-модуля.
Аргументы
get_args
get_args(dstPtr i32, dstLen i32) → written i32
Читает весь JSON-массив аргументов транзакции в буфер [dstPtr, dstPtr+dstLen).
Возвращает количество записанных байт (0 если аргументов нет).
get_arg_str
get_arg_str(idx i32, dstPtr i32, dstLen i32) → written i32
Читает аргумент с индексом idx как строку (без кавычек JSON).
dstLen — максимальная длина буфера.
Возвращает 0 если аргумент не существует или тип не строка.
SDK: dc.ArgStr(idx, maxLen)
get_arg_u64
get_arg_u64(idx i32) → val i64
Читает аргумент с индексом idx как беззнаковое 64-битное число.
Возвращает 0 если индекс вне диапазона или тип не число.
SDK: dc.ArgU64(idx)
State
get_state_len
get_state_len(keyPtr i32, keyLen i32) → valLen i32
Возвращает размер значения по ключу (0 если ключ не найден).
Используется перед get_state для выделения буфера нужного размера.
get_state
get_state(keyPtr i32, keyLen i32, dstPtr i32, dstLen i32) → written i32
Читает min(len(value), dstLen) байт по ключу в буфер.
Возвращает фактически записанное количество байт.
SDK: dc.GetState(key) (выделяет буфер автоматически через get_state_len)
set_state
set_state(keyPtr i32, keyLen i32, valPtr i32, valLen i32)
Записывает значение по ключу. Если valLen == 0 — удаляет ключ.
SDK: dc.SetState(key, value), dc.SetStateStr(key, s), dc.PutU64(key, v)
put_u64
put_u64(keyPtr i32, keyLen i32, val i64)
Записывает val как 8 байт big-endian. Эквивалентно set_state с 8-байтным big-endian значением, но компактнее в вызове.
SDK: dc.PutU64(key, v)
get_u64
get_u64(keyPtr i32, keyLen i32) → val i64
Читает 8 байт big-endian по ключу. Возвращает 0 если ключ не найден.
SDK: dc.GetU64(key)
Идентификация
get_caller
get_caller(bufPtr i32, bufLen i32) → written i32
Записывает hex-pubkey вызывающего аккаунта (64 символа ASCII).
Если bufLen < 64, записывает частично.
SDK: dc.Caller()
get_block_height
get_block_height() → height i64
Возвращает высоту текущего блока (в котором исполняется транзакция).
SDK: dc.BlockHeight()
get_contract_treasury
get_contract_treasury(bufPtr i32, bufLen i32) → written i32
Записывает hex-pubkey treasury контракта (64 символа).
Treasury — специальный счёт, привязанный к контракту. Контракт может переводить с treasury как from без ограничений.
SDK: dc.Treasury()
Токены
get_balance
get_balance(pubPtr i32, pubLen i32) → balance i64
Возвращает баланс адреса в µT (микро-токены).
SDK: dc.Balance(pubKeyHex)
transfer
transfer(fromPtr i32, fromLen i32, toPtr i32, toLen i32, amount i64) → errCode i32
Переводит amount µT с from на to.
Возвращает 0 при успехе, 1 при ошибке (недостаточно средств, неверный адрес).
Ограничения:
fromдолжен быть либоdc.Caller(), либоdc.Treasury().- Контракт не может тратить чужие деньги (только caller'а или свой treasury).
SDK: dc.Transfer(from, to, amount) bool
Межконтрактные вызовы
call_contract
call_contract(cidPtr i32, cidLen i32, mthPtr i32, mthLen i32, argPtr i32, argLen i32) → errCode i32
Вызывает метод другого контракта.
| Параметр | Тип | Описание |
|---|---|---|
cidPtr/cidLen |
i32 | hex-ID целевого контракта (16 символов) |
mthPtr/mthLen |
i32 | имя метода |
argPtr/argLen |
i32 | JSON-массив аргументов |
Возврат: 0 = успех, 1 = ошибка (превышена глубина, контракт не найден, и т.д.)
Gas: подвызов получает gc.Remaining() от родительского счётчика. Потраченный gas вычитается из родителя.
State: все вызовы в цепочке разделяют одну badger.Txn. Если подвызов не падает, его изменения видны родителю.
Подробнее: Межконтрактные вызовы
SDK: dc.CallContract(contractID, method, argsJSON) bool
Логирование
log
log(msgPtr i32, msgLen i32)
Записывает строку в лог контракта. Логи привязаны к транзакции и видны в Explorer → вкладка Logs.
fmt.Println и log.Printf через WASI stdout не попадают в блокчейн-логи. Используйте только log.
SDK: dc.Log(msg)
Gas
gas_tick
gas_tick()
Вызывается автоматически при каждой итерации цикла в бинарных WASM-контрактах (инструментация вручную). Списывает 1 unit gas.
Для TinyGo-контрактов TinyGo генерирует собственную инструментацию.
Таблица функций
| # | Имя | Сигнатура | SDK |
|---|---|---|---|
| 1 | get_args |
(i32,i32)→i32 |
— |
| 2 | get_arg_str |
(i32,i32,i32)→i32 |
ArgStr |
| 3 | get_arg_u64 |
(i32)→i64 |
ArgU64 |
| 4 | get_state_len |
(i32,i32)→i32 |
внутри GetState |
| 5 | get_state |
(i32,i32,i32,i32)→i32 |
GetState |
| 6 | set_state |
(i32,i32,i32,i32) |
SetState |
| 7 | put_u64 |
(i32,i32,i64) |
PutU64 |
| 8 | get_u64 |
(i32,i32)→i64 |
GetU64 |
| 9 | get_caller |
(i32,i32)→i32 |
Caller |
| 10 | get_block_height |
()→i64 |
BlockHeight |
| 11 | get_contract_treasury |
(i32,i32)→i32 |
Treasury |
| 12 | get_balance |
(i32,i32)→i64 |
Balance |
| 13 | transfer |
(i32,i32,i32,i32,i64)→i32 |
Transfer |
| 14 | call_contract |
(i32,i32,i32,i32,i32,i32)→i32 |
CallContract |
| 15 | log |
(i32,i32) |
Log |
| 16 | gas_tick |
() |
— |
Паттерн прямого импорта (без SDK)
Если вы пишете бинарный WASM вручную (без TinyGo), функции импортируются в секции imports:
(import "env" "get_state_len" (func (param i32 i32) (result i32)))
(import "env" "get_state" (func (param i32 i32 i32 i32) (result i32)))
(import "env" "set_state" (func (param i32 i32 i32 i32)))
...
Подробнее: Бинарный WASM