Разработка appchain на базе Cosmos SDK

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1Все 1306 услуг
Разработка appchain на базе Cosmos SDK
Сложный
от 2 недель до 3 месяцев
Часто задаваемые вопросы

Направления блокчейн-разработки

Этапы блокчейн-разработки

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1309
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1222
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    922
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1151
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    614
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    887

Разработка appchain на базе Cosmos SDK

Вопрос "почему не Ethereum L2" возникает первым, и на него нужен честный ответ. Ethereum L2 (Arbitrum, Optimism, zkSync) даёт вам чужую виртуальную машину, чужой gas token, чужой sequencer, чужие правила. Cosmos SDK appchain — это ваш блокчейн: собственный консенсус, собственный gas token, собственная 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 consensus с instant finality. Это ключевое отличие от PoW: если блок закоммичен — он финальный, без fork risk. Latency финализации: ~1–6 секунд в зависимости от конфигурации и размера validator set.

Ограничения: BFT consensus требует >2/3 голосующего stake для живости. При < 33% онлайн — сеть останавливается (safety over liveness). Это сознательный trade-off.

Максимально практичный validator set: 150–300 валидаторов. Больше — сеть замедляется из-за коммуникационных overhead в BFT round.

Разработка кастомного модуля

Структура модуля

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 management

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 вернул ошибку, gas сжигается, но 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. Events для клиентов
    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 verification).

ICS-20: transfer токенов

Самый простой 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 + custom 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% держателей — параметры меняются автоматически.

Testnet и запуск

Localnet для разработки:

ignite chain serve  # Ignite CLI — быстрый старт
# или
./scripts/run_node.sh  # кастомный скрипт инициализации

Public testnet:

  • Genesis файл с начальными валидаторами
  • Faucet для получения тестовых токенов
  • Explorer (Mintscan, Ping.pub) для visibility

Mainnet запуск:

  1. Параметры genesis — обсуждаются публично
  2. Gentx от начальных валидаторов (каждый создаёт create-validator транзакцию)
  3. Сбор gentx, формирование genesis.json
  4. Синхронный запуск нод валидаторами в момент genesis time

Validator onboarding: нужно привлечь достаточно decentralized и надёжных валидаторов. Для серьёзной mainnet — минимум 20–30 независимых валидаторов с geografической и юрисдикционной диверсификацией.

Стек и инструменты

Компонент Технология
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.