Розробка системи автоматичного деплою на кілька мереж
Проблема виникає на третьому або четвертому деплої одного й того ж протоколу в різні мережі: хтось задеплоїв на 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
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 разів. Витрати скорочуються значно. Час релізу падає з днів до годин. Наша команда має 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 мереж, без моніторингу) — обговорюється індивідуально. Повний пакет (10+ мереж, CI/CD, моніторинг через Tenderly) — також розраховується після аудиту. Додавання non-EVM мереж (Solana, TON) потребує окремого toolchain і обговорюється окремо. Замовте консультацію для отримання точної оцінки.
Часті запитання
Чи потрібен окремий деплоєр-гаманець? Так. Ми створюємо виділений deployer з мінімальними правами. Ключі зберігаємо в AWS KMS або HashiCorp Vault. Це надійніше та безпечніше за plain hex в CI.
При збої на середині деплою — скрипт зберігає стан після кожної мережі. Повторний запуск продовжує з останньої точки. Дані не втрачаються.
Готові спростити деплой вашого протоколу? Замовте розробку системи автоматичного деплою — оцінимо проєкт. Зв'яжіться з нами, щоб обговорити деталі.







