Розробка appchain на базі Cosmos SDK
Питання "чому не Ethereum L2" виникає першим, і на нього потрібна чесна ответ. Ethereum L2 (Arbitrum, Optimism, zkSync) дає вам чужу віртуальну машину, чужий gas токен, чужий sequencer, чужі правила. Cosmos SDK appchain — це ваш блокчейн: власний консенсус, власний gas токен, власна governance, власні правила валідації. Ціна — повна відповідальність за безпеку й децентралізацію validator set. Для більшості додатків L2 — правильний вибір. Для випадків, де потрібен повний контроль над екопомікою протоколу, суверенітет над даними або спеціалізовані механізми консенсусу — Cosmos SDK.
Архітектура Cosmos SDK
Модульна структура
Cosmos SDK будується на модулях. Кожен модуль — ізольований компонент з власним state (у IAVL дереві), типами повідомлень (Msgs), запитами (Queries) й хуками життєвого циклу:
Application
├── x/auth — акаунти й підписи
├── x/bank — перевід токенів
├── x/staking — validator set, делегування
├── x/distribution — розподіл staking rewards
├── x/gov — on-chain governance
├── x/slashing — штрафи за мисбехейвіор валідаторів
├── x/ibc — IBC протокол
└── x/yourapp — ваша бізнес-логіка
Ваш кастомний модуль живе в x/yourapp. Це де вся ваша логіка.
Consensus: CometBFT (раніше Tendermint)
CometBFT — BFT консенсус з instant finality. Це ключова відмінність від PoW: якщо блок закоммічен — він фінальний, без fork risk. Latency фіналізації: ~1–6 секунд залежно від конфігурації й розміру validator set.
Обмеження: BFT консенсус потребує >2/3 голосуючого stake в мережі для живості. При < 33% онлайн — мережа зупиняється (safety over liveness). Це свідомий trade-off.
Максимально практичний validator set: 150–300 валідаторів. Більше — мережа сповільнюється через комунікаційні overhead в BFT раунді.
Розробка кастомного модуля
Структура модуля
x/
└── mymodule/
├── keeper/
│ ├── keeper.go — бізнес-логіка, доступ до state
│ ├── msg_server.go — обробники транзакцій
│ └── query_server.go — обробники запитів
├── types/
│ ├── msgs.go — типи повідомлень
│ ├── genesis.go — початковий стан
│ └── params.go — параметри модуля (governance-управлювані)
├── module.go — реєстрація модуля
└── proto/
└── mymodule/ — Protobuf визначення
Keeper та управління state
State зберігається в IAVL-дереві через KVStore. Keeper — єдина точка доступу до state:
type Keeper struct {
cdc codec.BinaryCodec
storeKey storetypes.StoreKey
bankKeeper types.BankKeeper // залежність від bank модуля
authKeeper types.AccountKeeper
}
func (k Keeper) SetOrder(ctx sdk.Context, order types.Order) {
store := ctx.KVStore(k.storeKey)
bz := k.cdc.MustMarshal(&order)
store.Set(types.OrderKey(order.Id), bz)
}
func (k Keeper) GetOrder(ctx sdk.Context, id uint64) (types.Order, bool) {
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.OrderKey(id))
if bz == nil {
return types.Order{}, false
}
var order types.Order
k.cdc.MustUnmarshal(bz, &order)
return order, true
}
Важливо: у Cosmos SDK нема "транзакція не вдалася, state відкатився" у розумінні EVM. Якщо msg_server повернув помилку, газ спалюється, але state не змінився. Якщо повернув nil — state змінився й це фінально. Тому всі перевірки мають йти до зміни state.
Msg Server: обробка транзакцій
func (k msgServer) CreateOrder(
goCtx context.Context,
msg *types.MsgCreateOrder,
) (*types.MsgCreateOrderResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
// 1. Валідація
if msg.Amount.IsZero() {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, "amount cannot be zero")
}
// 2. Перевірка балансу й блокування коштів
err := k.bankKeeper.SendCoinsFromAccountToModule(ctx, msg.Creator, types.ModuleName, sdk.NewCoins(msg.Amount))
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInsufficientFunds, err.Error())
}
// 3. Зміна state
order := types.Order{
Id: k.GetNextOrderID(ctx),
Creator: msg.Creator,
Amount: msg.Amount,
CreatedAt: ctx.BlockTime().Unix(),
}
k.SetOrder(ctx, order)
k.IncrementOrderID(ctx)
// 4. События для клієнтів
ctx.EventManager().EmitEvent(sdk.NewEvent(
types.EventTypeCreateOrder,
sdk.NewAttribute(types.AttributeOrderID, fmt.Sprintf("%d", order.Id)),
sdk.NewAttribute(types.AttributeCreator, msg.Creator),
))
return &types.MsgCreateOrderResponse{OrderId: order.Id}, nil
}
BeginBlock / EndBlock хуки
Потужний механізм: виконувати логіку кожний блок без зовнішнього тригеру. Приклади використання:
- Order matching — матчинг ордерів в кінці кожного блоку (DEX без газу на matching)
- Liquidations — перевірка здоров'я позицій і ліквідація при необхідності
- Epoch transitions — перехід між епохами стейкингу, розподіл наград
- Oracle price updates — агрегація даних від validators
func (am AppModule) EndBlock(ctx sdk.Context, _ abci.RequestEndBlock) []abci.ValidatorUpdate {
keeper.ProcessExpiredOrders(ctx)
keeper.MatchPendingOrders(ctx)
return []abci.ValidatorUpdate{}
}
Це принципово неможливо у EVM без зовнішніх keeper-ботів — тут нема native cron.
IBC: міжсітьова взаємодія
IBC (Inter-Blockchain Communication Protocol) — killer feature Cosmos. Дозволяє передавати токени й довільні дані між chains без мосту (trustless, через light client верифікацію).
ICS-20: трансфер токенів
Найпростіший IBC use case — трансфер токенів між chains:
// Відправка токенів із вашої chain у Osmosis
transfer := channeltypes.NewMsgTransfer(
"transfer", // port
"channel-0", // channel до Osmosis
sdk.NewCoin("uatom", amount),
sender,
receiver,
timeoutHeight,
timeoutTimestamp,
"memo",
)
Отримувач у Osmosis бачить токен як ibc/HASH — це "wrapped" версія вашого токена. Для "native" представлення потрібен ICS-20 + кастомний denom alias.
Custom IBC packets
Для передачі довільної логіки між chains — кастомні IBC пакети:
// Відправка довільних даних
packet := channeltypes.NewPacket(
modulePacketData, // ваші дані, серіалізовані в protobuf
sequence,
sourcePort, sourceChannel,
destPort, destChannel,
timeoutHeight, timeoutTimestamp,
)
Отримуюча chain верифікує Merkle proof що пакет був committed на відправляючій chain — це trustless, жодний оракул не потрібен.
Latency IBC: залежить від часів блоків обох chains й швидкості relayer. Зазвичай 10–30 секунд для Cosmos-to-Cosmos трансферу.
Relayer інфраструктура
IBC пакети не доставляються самі — потрібні relayers. Це off-chain процеси які читають пакети з однієї chain й submit їх в іншу.
Дві основні реалізації: Hermes (Rust, висока производительність) та Go relayer. Для production — Hermes.
Конфігурація Hermes для вашої chain → Osmosis:
[[chains]]
id = "yourchain-1"
rpc_addr = "http://localhost:26657"
grpc_addr = "http://localhost:9090"
key_name = "relayer"
[[chains]]
id = "osmosis-1"
rpc_addr = "https://osmosis-rpc.polkachu.com"
grpc_addr = "https://osmosis-grpc.polkachu.com:12590"
key_name = "relayer-osmosis"
Relayer повинен мати токени на обох chains для оплати газу. Для mainnet — моніторинг балансу й auto-refill критичні.
Governance та параметри
On-chain governance — одна з причин вибрати Cosmos. Зміна параметрів протоколу через голосування тримачів токена:
// Параметри модуля, змінювані через governance
type Params struct {
MinOrderSize sdk.Coin `json:"min_order_size"`
TradingFeeRate sdk.Dec `json:"trading_fee_rate"`
MaxOrdersPerBlock uint64 `json:"max_orders_per_block"`
}
Proposal → Deposit period → Voting period (зазвичай 14 днів) → Execution. Якщо >50% stake проголосувало за — параметри змінюються автоматично.
Testnet та запуск
Localnet для розробки:
ignite chain serve # Ignite CLI — швидкий старт
# або
./scripts/run_node.sh # кастомний скрипт ініціалізації
Public testnet:
- Genesis файл з початковими валідаторами
- Faucet для отримання тестових токенів
- Explorer (Mintscan, Ping.pub) для visibility
Mainnet запуск:
- Параметри genesis — обговорюються публічно
- Gentx від початкових валідаторів (кожен створює create-validator транзакцію)
- Збирання gentx, формування genesis.json
- Синхронний запуск нод валідаторами в момент genesis time
Validator onboarding: потрібно привабити достатньо децентралізованих й надійних валідаторів. Для серйозної mainnet — мінімум 20–30 незалежних валідаторів з географічною й юрисдикційною діверсифікацією.
Стек та інструменти
| Компонент | Технологія |
|---|---|
| Framework | Cosmos SDK v0.50.x |
| Consensus | CometBFT v0.38.x |
| Мова | Go 1.21+ |
| Scaffolding | Ignite CLI |
| Protobuf | buf + cosmos-proto |
| Testing | Go testing + simapp |
| Explorer | Mintscan (Cosmostation) або кастомний |
| Relayer | Hermes (Informal Systems) |
| Monitoring | Prometheus + Grafana + Cosmos-specific дашборди |
Срок разработки кастомного appchain з одним-двома бізнес-модулями, IBC, governance: 4–7 місяців до testnet, +2–3 місяці до mainnet.







