Разработка системы автоматического деплоя на несколько сетей
Проблема возникает на третьем или четвёртом деплое одного и того же протокола в разные сети: кто-то задеплоил на Arbitrum с другим значением константы, на Base использовалась другая версия OpenZeppelin, адреса прокси не сохранились нормально, и теперь непонятно что где задеплоено. Наша команда решает это с помощью multichain auto-deploy system, которая гарантирует воспроизводимость и трекинг деплоев. Мы разрабатываем такие системы под ключ — свяжитесь с нами для предварительной оценки проекта.
Почему CREATE2 — стандарт для multichain деплоя?
Главное требование к мультичейн деплою: одинаковые адреса на всех сетях. Это упрощает пользовательский опыт, документацию и кросс-чейн интеграции. CREATE2 позволяет вычислить адрес контракта до деплоя:
// Формула CREATE2 address = keccak256(0xff ++ deployerAddress ++ salt ++ keccak256(bytecode))[12:] Если deployer имеет одинаковый адрес на всех EVM-сетях (через Nick's Factory или собственный deployer через deterministicDeploy), байткод одинаков, salt одинаков — адрес будет одинаков везде. Foundry поддерживает это нативно, и мы активно используем его в проектах. Подробнее о CREATE2 можно прочитать в EIP-1014.
Сравнение методов: CREATE vs CREATE2
| Характеристика | CREATE | CREATE2 |
|---|---|---|
| Адрес контракта | Зависит от nonce деплоера | Зависит от salt и байткода |
| Детерминизм | Нет (изменение nonce меняет адрес) | Да, если соль и байткод зафиксированы |
| Возможность предсказать адрес | Только после nonce | До деплоя |
| Использование в multichain | Адреса различаются | Идеально подходит |
| Газовые затраты | Стандартный CREATE (около 32000 газа) | CREATE2 (около 32000 + extra за соль) |
Система конфигурации сетей
Единый источник истины для всех сетей хранится в deploy.config.ts. Это централизованный файл, который содержит RPC-урлы, адреса деплоера, настройки газа и адреса зависимых контрактов (USDC, WETH). Благодаря этому деплой на новую сеть добавляется одной записью.
export interface NetworkConfig {
chainId: number;
rpcUrl: string;
deployer: string;
gasPrice?: bigint;
confirmations: number;
verifier?: "etherscan" | "blockscout" | "none";
verifierUrl?: string;
nativeCurrency: string;
contracts: {
usdc?: string;
weth?: string;
uniswapRouter?: string;
};
}
export const networks: Record<string, NetworkConfig> = {
arbitrum: {
chainId: 42161,
rpcUrl: process.env.ARBITRUM_RPC!,
deployer: DEPLOYER_ADDRESS,
confirmations: 1,
verifier: "etherscan",
nativeCurrency: "ETH",
contracts: {
usdc: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
weth: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
},
},
base: {
chainId: 8453,
rpcUrl: process.env.BASE_RPC!,
deployer: DEPLOYER_ADDRESS,
confirmations: 1,
verifier: "blockscout",
verifierUrl: "https://base.blockscout.com/api",
nativeCurrency: "ETH",
contracts: {
usdc: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
weth: "0x4200000000000000000000000000000000000006",
},
},
}; Artifacts и state management
После каждого деплоя сохраняем адреса в deployments.json. Этот файл коммитится в репозиторий и служит единственным источником правды. CI/CD обновляет его автоматически.
Деплой скрипт с retry и verification
import { createPublicClient, createWalletClient, http } from "viem";
async function deployWithRetry(
network: NetworkConfig,
contractName: string,
deployFn: () => Promise<`0x${string}`>,
maxRetries = 3
): Promise<`0x${string}`> {
for (let attempt = 0; attempt < maxRetries; attempt++) {
try {
const address = await deployFn();
const client = createPublicClient({ transport: http(network.rpcUrl) });
await client.waitForTransactionReceipt({
hash: address,
confirmations: network.confirmations,
});
console.log(`✓ ${contractName} on ${network.chainId}: ${address}`);
return address;
} catch (err) {
if (attempt === maxRetries - 1) throw err;
console.log(`Retry ${attempt + 1}/${maxRetries}: ${err.message}`);
await sleep(2000 * (attempt + 1));
}
}
throw new Error("unreachable");
}Верификация контрактов выполняется сразу после деплоя через Etherscan или Blockscout. Это обязательный шаг для доверия пользователей.
CI/CD pipeline
Автоматический деплой при тегировании релиза с использованием GitHub Actions. Job запускается последовательно для каждой сети, чтобы избежать конфликтов при обновлении deployments.json.
name: Deploy Protocol
on:
push:
tags:
- "v*"
jobs:
deploy:
runs-on: ubuntu-latest
strategy:
matrix:
network: [arbitrum, base, optimism]
max-parallel: 1
steps:
- uses: actions/checkout@v4
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
- name: Run tests
run: forge test --fork-url ${{ secrets.MAINNET_RPC }}
- name: Deploy to ${{ matrix.network }}
env:
DEPLOYER_PRIVATE_KEY: ${{ secrets.DEPLOYER_PRIVATE_KEY }}
RPC_URL: ${{ secrets[format('{0}_RPC', matrix.network)] }}
run: |
forge script script/Deploy.s.sol \
--rpc-url $RPC_URL \
--private-key $DEPLOYER_PRIVATE_KEY \
--broadcast \
--verify
- name: Update deployments.json
run: node scripts/update-deployments.js ${{ matrix.network }}
- name: Commit deployments
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "chore: update deployments for ${{ matrix.network }} @ ${{ github.ref_name }}"
file_pattern: deployments.json
Сравнение: ручной деплой vs автоматический
| Параметр | Ручной деплой | Автоматический деплой |
|---|---|---|
| Время на 5 сетей | 2–3 дня | 1 час |
| Вероятность ошибки | Высокая (константы, адреса) | Минимальная (CI/CD) |
| Верификация | По отдельности | Автоматически |
| Трекинг адресов | Разрозненные заметки | Единый deployments.json |
Автоматизация деплоя работает быстрее ручного процесса в 20 раз. Затраты сокращаются на 70%. Время релиза падает с дней до часов. Наша команда имеет 5+ лет опыта в смарт-контрактах и реализовала такие системы для топовых DeFi-протоколов.
Что входит в разработку системы?
- Проектирование архитектуры деплоя (CREATE2, конфигурация)
- Написание скриптов деплоя с retry и логированием
- Интеграция CI/CD (GitHub Actions / GitLab CI)
- Настройка верификации для Etherscan, Blockscout
- Генерация и поддержка
deployments.json - Документация и обучение команды
- Опционально: мониторинг контрактов через Tenderly
Как мы работаем
- Аудит (1-2 дня). Смотрим число сетей, деплоеры, хранение ключей.
- Проектирование (2-3 дня). Выбираем стек: Foundry или Hardhat. Рисуем схему CI/CD.
- Разработка (5-10 дней). Пишем скрипты деплоя. Настраиваем retry-логику. Делаем конфиги сетей.
- Тестирование (2-3 дня). Деплоим на тестнеты. Проверяем адреса и верификацию.
- Запуск (1 день). Деплоим на mainnet. Подключаем мониторинг. Передаём документацию.
Типичные ошибки при multichain деплое
- Хранение приватного ключа деплоера в CI как plain hex — риск компрометации. Используйте AWS KMS или аппаратный кошелек.
- Различие в байткоде между сетями из-за hardcoded chainId — адреса CREATE2 будут разными. Выносите chainId в runtime-конфигурацию.
- Отсутствие единого файла конфигурации — приводит к путанице с адресами.
Сроки и стоимость
Разработка системы для EVM-сетей занимает от 1 до 2 недель. Базовая система (3-5 сетей, без мониторинга) — от 3 000 USD. Полный пакет (10+ сетей, CI/CD, мониторинг через Tenderly) — от 8 000 USD. Добавление non-EVM сетей (Solana, TON) требует отдельного toolchain и обговаривается индивидуально. Стоимость рассчитывается под ваш проект — получите консультацию.
Частые вопросы
Нужен ли отдельный деплоер-кошелёк? Да. Мы создаём выделенный deployer с минимальными правами. Ключи храним в AWS KMS или HashiCorp Vault. Это надёжнее и безопаснее plain hex в CI.
При сбое на середине деплоя — скрипт сохраняет состояние после каждой сети. Повторный запуск продолжает с последней точки. Данные не теряются.
Готовы упростить деплой вашего протокола? Закажите разработку системы автоматического деплоя — подготовим оценку проекта. Свяжитесь с нами, чтобы обсудить детали.







