Разработка решений на модульном стеке (execution + DA + settlement)

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Разработка решений на модульном стеке (execution + DA + settlement)
Сложная
от 2 недель до 3 месяцев
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1221
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1163
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    855
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1056
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    828

Разработка системы на модульном стеке (execution + DA + settlement)

Монолитный блокчейн делает всё сам: исполняет транзакции, обеспечивает доступность данных, финализирует состояние. Модульный подход разбивает эти функции между специализированными слоями. Результат — экосистема, где можно выбирать компоненты как модули: Celestia для DA, Ethereum для settlement, OP Stack или Arbitrum Orbit для execution. Это не теория — так построены десятки mainnet L2 и L3 в 2024–2025 году.

Типичный запрос: «хотим свой appchain с низкими комиссиями и кастомной логикой, но с безопасностью Ethereum». Это правильно сформулированная задача, и модульный стек — правильный ответ на неё.

Слои и их роли

Execution Layer

Исполняет транзакции, поддерживает состояние. Это ваш chain — со своими правилами, gas token, precompiles.

OP Stack (Optimism, Base, Zora) — самый зрелый фреймворк для Optimistic Rollup-based L2/L3. EVM-эквивалентность. op-geth + op-node + op-batcher + op-proposer.

Arbitrum Orbit — Arbitrum-based L2/L3. Поддерживает Stylus (WASM смарт-контракты на Rust/C++). Более гибкая кастомизация gas, permission models.

Polygon CDK — ZK-based chain development kit. zkEVM под капотом. Более сложно в эксплуатации, но ZK finality вместо fraud window.

Sovereign rollup через Rollkit — execution layer с любым execution environment, settlement в любой цепи (или без settlement вообще). Максимальная гибкость, минимальная зрелость.

Data Availability Layer

Блоки должны быть доступны для скачивания — иначе fraud proofs и state reconstruction невозможны. DA layer хранит данные транзакций (calldata или blobs).

Ethereum L1 (EIP-4844 blobs) — максимальная security, наивысшая стоимость. После EIP-4844: ~3–6 blobs per block, каждый blob ~128KB, стоимость blob gas отдельна от execution gas. Blobs удаляются через ~18 дней, но commitment (KZG) остаётся навсегда.

Celestia — специализированный DA layer. Data availability sampling (DAS): light nodes проверяют доступность через random sampling, не скачивая весь блок. Стоимость на порядки ниже Ethereum blobs при сопоставимых security guarantees для большинства use cases.

EigenDA — DA layer поверх Ethereum через EigenLayer restaking. Экономическая безопасность от рестейкнутого ETH. Значительно выше throughput чем Ethereum L1 при более высоких security гарантиях чем Celestia (на сегодня).

Avail — DA layer с data availability sampling, forkless upgrades. Хорошая альтернатива Celestia.

Settlement Layer

Финализация: определяет, что является каноническим состоянием rollup. Обрабатывает withdrawals, resolves disputes.

Для большинства проектов — Ethereum mainnet через L1 bridge contract. Альтернатива для L3 — использовать L2 как settlement layer (например, Arbitrum One как settlement для Orbit chain).

Практическая сборка: OP Stack + Celestia + Ethereum

Покажу конкретную конфигурацию, которую используют в production.

Компоненты

[Users/Apps]
     ↓
[op-geth (execution)] ← кастомный EVM, ваши precompiles
     ↓
[op-node (rollup node)] ← derive chain state, communicate with L1
     ↓
[op-batcher] → [Celestia] ← публикует batch данных в Celestia
     ↓
[op-proposer] → [L1 Settlement Contract] ← публикует state roots на Ethereum

Настройка Celestia DA

// Celestia client для отправки blobs
import (
    "github.com/celestiaorg/celestia-node/api/rpc/client"
    "github.com/celestiaorg/celestia-openrpc/types/blob"
)

type CelestiaDA struct {
    client    *client.Client
    namespace blob.Namespace
}

func (c *CelestiaDA) Submit(ctx context.Context, data []byte) (uint64, error) {
    b, err := blob.NewBlob(0, c.namespace, data)
    if err != nil {
        return 0, fmt.Errorf("create blob: %w", err)
    }
    
    height, err := c.client.Blob.Submit(ctx, []*blob.Blob{b}, blob.DefaultGasPrice())
    if err != nil {
        return 0, fmt.Errorf("submit blob: %w", err)
    }
    
    return height, nil
}

func (c *CelestiaDA) Retrieve(ctx context.Context, height uint64) ([]byte, error) {
    blobs, err := c.client.Blob.GetAll(ctx, height, []blob.Namespace{c.namespace})
    if err != nil {
        return nil, err
    }
    if len(blobs) == 0 {
        return nil, ErrBlobNotFound
    }
    return blobs[0].Data, nil
}

Namespace — 29-байтовый идентификатор вашего rollup в Celestia. Нужно зарезервировать уникальный namespace до запуска.

Конфигурация op-batcher для Celestia

OP Stack batcher нативно не поддерживает Celestia — нужен кастомный DA provider через AltDA (Alternative DA) интерфейс:

// Реализация AltDA provider для Celestia
type CelestiaAltDA struct {
    da *CelestiaDA
}

func (c *CelestiaAltDA) GetInput(ctx context.Context, commitment []byte) ([]byte, error) {
    // Decode commitment → Celestia block height + namespace
    height, err := decodeCommitment(commitment)
    if err != nil {
        return nil, err
    }
    return c.da.Retrieve(ctx, height)
}

func (c *CelestiaAltDA) SetInput(ctx context.Context, data []byte) ([]byte, error) {
    height, err := c.da.Submit(ctx, data)
    if err != nil {
        return nil, err
    }
    return encodeCommitment(height), nil
}

В конфигурации op-batcher:

[da]
type = "celestia"
rpc = "http://celestia-light-node:26658"
auth_token = "${CELESTIA_AUTH_TOKEN}"
namespace = "0x0000000000000000000000000000000000yournamespace"

L1 Settlement контракты

На Ethereum деплоятся два контракта:

OptimismPortal — входная/выходная точка для cross-domain сообщений и withdrawals. Handles challenge window для Optimistic.

L2OutputOracle — хранит state roots предложенные proposer'ом. Это то, от чего зависит finality withdrawals.

// Упрощённая схема interaction
contract L2OutputOracle {
    struct OutputProposal {
        bytes32 outputRoot;    // keccak256(state_root, msg_passer_storage_root, latest_block_hash)
        uint128 timestamp;
        uint128 l2BlockNumber;
    }
    
    OutputProposal[] public l2Outputs;
    address public proposer;
    uint256 public constant FINALIZATION_PERIOD = 7 days;
    
    function proposeL2Output(
        bytes32 _outputRoot,
        uint256 _l2BlockNumber,
        bytes32 _l1BlockHash,
        uint256 _l1BlockNumber
    ) external payable {
        require(msg.sender == proposer, "Not proposer");
        // Верификация что l1BlockHash соответствует _l1BlockNumber
        require(blockhash(_l1BlockNumber) == _l1BlockHash, "Bad L1 block");
        
        l2Outputs.push(OutputProposal({
            outputRoot: _outputRoot,
            timestamp: uint128(block.timestamp),
            l2BlockNumber: uint128(_l2BlockNumber)
        }));
    }
}

Кастомизация execution layer

Custom precompiles

Precompiles — предкомпилированные контракты по фиксированным адресам с нативной реализацией. Например, добавить BLS12-381 операции или кастомный хэш-алгоритм:

// В op-geth: добавление custom precompile
var CustomPrecompiles = map[common.Address]vm.PrecompiledContract{
    common.HexToAddress("0x0000000000000000000000000000000000000100"): &blsG1Add{},
    common.HexToAddress("0x0000000000000000000000000000000000000101"): &customHashFunction{},
}

type blsG1Add struct{}

func (c *blsG1Add) RequiredGas(input []byte) uint64 {
    return 500  // фиксированная стоимость
}

func (c *blsG1Add) Run(input []byte) ([]byte, error) {
    if len(input) != 128 {
        return nil, errors.New("invalid input length")
    }
    // BLS G1 point addition
    p1 := new(bls12381.G1Affine)
    p2 := new(bls12381.G1Affine)
    p1.Unmarshal(input[:64])
    p2.Unmarshal(input[64:])
    
    result := new(bls12381.G1Affine).Add(p1, p2)
    return result.Marshal(), nil
}

Gas token кастомизация

OP Stack поддерживает Custom Gas Token — native gas token, отличный от ETH. Это позволяет использовать ваш ERC-20 токен как gas.

Ограничение: custom gas token должен быть задеплоен на L1, иметь стандартный ERC-20 интерфейс, и не иметь transfer fees (rebasing/fee-on-transfer токены не поддерживаются).

Fee структура и sequencer revenue

User Transaction Fee = (base_fee + priority_fee) × gas_used    [L2 execution cost]
                     + L1 data fee                              [cost of DA]

Sequencer Revenue = collected fees - DA costs - L1 costs

При использовании Celestia вместо Ethereum для DA, L1 data fee снижается на 90–95% для большинства транзакций. Это главный экономический аргумент.

Мониторинг модульного стека

Мониторить нужно все три слоя независимо:

# Ключевые метрики
execution_layer:
  - l2_block_time_seconds        # должен быть стабильным
  - sequencer_queue_depth        # нагрузка на sequencer
  - tx_pool_size                 # размер mempool

da_layer:
  - celestia_blob_submission_latency_ms
  - celestia_blob_submission_cost_utia  # стоимость в TIA
  - da_submission_failures_total

settlement_layer:
  - l1_output_proposal_delay_blocks  # proposer не отстаёт?
  - l1_finalization_pending_count    # withdrawals ожидающие финализации
  - l1_gas_price_gwei                # стоимость proposer transactions

Alerting: если DA submission начинает отставать от block production — это блокирующая проблема. Без DA блоки непроверяемы, а challengers не могут получить данные для fraud proof.

Декомпозиция по срокам

Фаза Содержание Срок
Design Выбор стека, namespace, токеномика, bridge design 2–3 нед
Core setup op-stack deployment, L1 contracts, genesis 3–4 нед
DA integration Celestia/EigenDA connector, batcher config 2–3 нед
Testnet Публичный тестнет, bridge testing, stress test 3–4 нед
Security Аудит bridge контрактов, fault proof testing 4–6 нед
Mainnet Деплой, sequencer ops, monitoring 2–3 нед

Критический путь — аудит bridge контрактов. Bridge — это где живут реальные деньги пользователей, и именно здесь большинство L2 находило критические уязвимости. Экономить на аудите bridge нельзя.

Итого: 16–23 недели от старта до mainnet. Команда: 2–3 backend инженера с опытом Go, 1 Solidity разработчик, DevOps/инфраструктурный инженер.