Разработка L3/appchain на базе OP Stack
Запуск собственного appchain перестал быть прерогативой крупных протоколов с $10M+ бюджетом. OP Stack — модульный фреймворк, из которого собраны Optimism, Base, Zora, Mode — позволяет поднять EVM-совместимый L2 за дни, а не месяцы. L3 (appchain поверх L2) — это следующий шаг: суверенный блокчейн с кастомным gas token, приватными транзакциями, специфическими precompiles, работающий поверх Base или OP Mainnet вместо Ethereum L1.
Когда нужен собственный appchain
Запуск appchain оправдан если у вас хотя бы два из следующих требований:
Производительность. Shared L2 (Arbitrum, Base) имеет конкуренцию за блок-спейс — в пиковые моменты gas растёт. На собственной цепочке весь throughput принадлежит вашему приложению.
Кастомный gas token. На shared L2 комиссии платятся в ETH. На appchain можно сделать gas token — нативный токен вашего протокола. Экономика токена меняется радикально: каждая транзакция сжигает/захватывает value для держателей.
Приватность транзакций. На публичных L2 все транзакции видны. Для gaming (hidden moves), финансовых приложений с корпоративными данными — нужна изоляция.
Кастомная логика консенсуса. Permissioned sequencer с KYC, или наоборот — fully decentralized sequencer set для censorship resistance.
Нет если: у вас < 100K транзакций/день, нет команды для операционной поддержки ноды, нет ликвидности для обеспечения bridge.
Архитектура OP Stack
OP Stack построен на принципе modularity. Компоненты можно заменять независимо:
L1 (Ethereum / Base / OP Mainnet)
↑ settlements, DA
[OptimismPortal Contract] ← bridge L1↔L2
[L2OutputOracle Contract] ← state roots
↑
L2 / L3 Chain
├─ op-node (consensus client) ← derives chain from L1 data
├─ op-geth (execution client) ← EVM, state, mempool
└─ op-batcher ← submits transaction batches to L1
└─ op-proposer ← submits state roots to L1
op-node — "consensus client" L2. Читает данные из L1 (или родительского L2), применяет derivation rules, синхронизирует op-geth через Engine API. Форк Ethereum consensus client под OP Stack.
op-geth — форк go-ethereum с минимальными изменениями: убраны proof-of-work, добавлен deposit transaction type (L1→L2 bridge), кастомные precompiles.
op-batcher — берёт транзакции из L2 mempool, упаковывает в batches, публикует в L1 как calldata или EIP-4844 blobs. Это ключевой компонент для cost: EIP-4844 blobs в ~10x дешевле calldata.
Настройка кастомного L3
Шаг 1: Развёртывание контрактов на родительской цепочке
git clone https://github.com/ethereum-optimism/optimism
cd packages/contracts-bedrock
# Конфигурация цепочки
cat > deploy-config/my-l3.json << EOF
{
"l1ChainID": 8453, // Base (родительский L2)
"l2ChainID": 12345678, // наш L3
"l2BlockTime": 2,
"maxSequencerDrift": 600,
"sequencerWindowSize": 3600,
"channelTimeout": 300,
"p2pSequencerAddress": "0x...",
"batchInboxAddress": "0x...",
"batchSenderAddress": "0x...",
"l2OutputOracleSubmissionInterval": 120,
"l2OutputOracleStartingBlockNumber": 0,
"l2OutputOracleStartingTimestamp": 1700000000,
"l2OutputOracleProposer": "0x...",
"l2OutputOracleChallenger": "0x...",
"finalizationPeriodSeconds": 604800,
"proxyAdminOwner": "0x...", // multisig
"baseFeeVaultRecipient": "0x...",
"l1FeeVaultRecipient": "0x...",
"sequencerFeeVaultRecipient": "0x...",
"governanceTokenName": "MyApp Token",
"governanceTokenSymbol": "MYAPP",
"governanceTokenOwner": "0x..."
}
EOF
forge script scripts/Deploy.s.sol --rpc-url $BASE_RPC_URL --broadcast
Шаг 2: Кастомный gas token
OP Stack поддерживает Custom Gas Token начиная с OP Stack Fjord. Конфигурация в genesis:
{
"customGasToken": {
"enabled": true,
"l1Address": "0x...MyToken на Base",
"l2Address": "0x4200000000000000000000000000000000000023"
}
}
При этом нативный токен L3 = ваш ERC-20 из родительской сети. Gas fees в транзакциях оплачиваются им. Важный нюанс: токен должен быть стандартным ERC-20 без transfer fees (no-fee-on-transfer), иначе bridge ломается.
Шаг 3: Запуск нод
# docker-compose для L3 секвенсера
services:
op-geth:
image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-geth:latest
volumes:
- ./data/geth:/data
- ./genesis.json:/genesis.json
command: >
--datadir=/data
--networkid=12345678
--http --http.addr=0.0.0.0 --http.port=8545
--http.api=web3,debug,eth,txpool,net,engine
--ws --ws.addr=0.0.0.0 --ws.port=8546
--authrpc.addr=0.0.0.0 --authrpc.port=8551
--authrpc.jwtsecret=/data/jwt.txt
--syncmode=full
--gcmode=archive # нужен для indexer
--override.fjord=1700000000
op-node:
image: us-docker.pkg.dev/oplabs-tools-artifacts/images/op-node:latest
depends_on:
- op-geth
command: >
op-node
--l1=$BASE_WS_RPC
--l1.beacon=$BASE_BEACON_URL
--l2=http://op-geth:8551
--l2.jwt-secret=/data/jwt.txt
--rollup.config=/rollup.json
--p2p.sequencer.key=$SEQUENCER_PRIVATE_KEY
--sequencer.enabled
--sequencer.l1-confs=4
--rpc.addr=0.0.0.0 --rpc.port=9545
Data Availability: выбор DA слоя
По умолчанию OP Stack публикует данные на L1 (Ethereum или Base). Это дорого и создаёт зависимость. Альтернативы:
EIP-4844 Blobs (Dencun). Уже встроено в OP Stack. Blobs дешевле calldata в ~5-10x, но хранятся только ~18 дней (pruning). Достаточно для fraud proofs (7-дневное окно).
Celestia DA. OP Stack + Celestia через op-plasma или AltDA mode. Данные публикуются в Celestia (~$0.001 за KB vs ~$0.01+ на Ethereum), L1 хранит только commitment. Режим: op-batcher → Celestia, op-node читает из Celestia. Снижение DA costs в 50-100x.
# Запуск op-node с Celestia DA
op-node \
--altda.enabled=true \
--altda.da-server=http://celestia-da-server:3100 \
--altda.da-service=true \
...
EigenDA. Аналогично Celestia, но через restaking на Ethereum. Более молодое решение, но с более сильными экономическими гарантиями безопасности.
Avail DA. Ещё одна DA-специализированная сеть, популярна в Polygon экосистеме.
Кастомные precompiles
Precompiles — это встроенные функции на уровне EVM, выполняются без bytecode (C++ в geth). Стандартные: ecrecover (0x01), SHA256 (0x02), BN254 pairing (0x08) и т.д.
В op-geth можно добавить кастомные precompiles для специфичных операций: ZK верификация, кастомные крипто-примитивы, быстрый доступ к L1 state:
// В op-geth: регистрация кастомного precompile
var customPrecompiles = map[common.Address]vm.PrecompiledContract{
common.HexToAddress("0x0000...1234"): &MyCustomPrecompile{},
}
type MyCustomPrecompile struct{}
func (c *MyCustomPrecompile) RequiredGas(input []byte) uint64 {
return 1000 // фиксированный gas cost
}
func (c *MyCustomPrecompile) Run(input []byte) ([]byte, error) {
// кастомная логика: например верификация Groth16 proof
return verifyGroth16Proof(input)
}
Примеры практических применений: batch BLS signature verification для oracle networks, efficient Poseidon hashing для ZK applications, VRF verification.
Bridging и ликвидность
Стандартный OP Stack bridge — нативный, через OptimismPortal. Deposit (L2→L3): ~15 минут. Withdrawal (L3→L2): 7 дней (fraud proof window). 7-дневное ожидание неприемлемо для пользователей.
Решение: fast bridge через liquidity providers. Протоколы типа Across, Hop, Stargate предоставляют "быстрые" withdrawals: LP fronts средства мгновенно, получает средства с L3 после 7 дней + комиссию за риск. Интеграция через Across Protocol SDK:
import { AcrossClient } from '@across-protocol/sdk';
const client = AcrossClient.create({ chains: [myL3Chain, base] });
const quote = await client.getQuote({
route: { originChainId: myL3Chain.id, destinationChainId: base.id },
inputToken: USDC_ON_L3,
outputToken: USDC_ON_BASE,
inputAmount: parseUnits('1000', 6),
});
// Выполняем быстрый вывод (секунды, не 7 дней)
await client.executeQuote({ quote, walletClient });
Sequencer: centralized vs decentralized
Centralized sequencer (стандарт для большинства appchain): один оператор упорядочивает транзакции. Риски: downtime (если sequencer упал — цепочка не движется), censorship. Митигация: force inclusion через L1 Portal контракт (транзакция включается принудительно через 12+ часов если sequencer цензурирует).
Decentralized sequencer через OP Stack + MEVA или через Espresso Systems Shared Sequencer. Более сложно, нужен leader election протокол. Для production appchain с $1M+ TVL стоит рассматривать.
Операционная инфраструктура
Минимальный production setup:
| Нода | Назначение | Требования |
|---|---|---|
| Sequencer | Обрабатывает транзакции | 32GB RAM, 500GB NVMe SSD, надёжный uptime |
| op-batcher | Публикует батчи на L1 | 8GB RAM, стабильный L1 RPC |
| op-proposer | Публикует state roots | 8GB RAM |
| RPC нода | Публичный RPC для пользователей | 32GB RAM, 1TB+ SSD |
| Archive нода | Исторические данные для индексации | 64GB RAM, 2TB+ SSD |
Monitoring: блок-производство (алерт если нет нового блока > 30 сек), batcher lag (непосубмитированные батчи), proposer status (missed proposals), L1 gas price (batcher может застрять при экстремальном L1 gas).
Сроки и этапы
Фаза 1 — Testnet (3-4 недели). Deploy контрактов на тестовой сети, запуск нод, базовый bridge UI, тестирование кастомного gas token.
Фаза 2 — Mainnet prep (2-3 недели). Security review контрактов, настройка multisig для admin ключей, мониторинг, runbooks для операторов.
Фаза 3 — Mainnet launch (1 неделя). Deploy, миграция ликвидности, публичный анонс, мониторинг 24/7 первые две недели.
Ongoing: обновление OP Stack (регулярные hardfork'и Optimism Superchain), мониторинг, поддержка bridge ликвидности.
Общая стоимость инфраструктуры: ~$500-2000/месяц для нод + L1 DA costs ($500-5000/месяц в зависимости от активности).







