Розробка системи автоматичного деплою на кілька мереж
Проблема виникає на третьому або четвертому деплої одного й того ж протоколу в різні мережі: хтось задеплоїв на 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 разів. Витрати скорочуються значно. Час релізу падає з днів до годин. Наша команда має 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.
При збої на середині деплою — скрипт зберігає стан після кожної мережі. Повторний запуск продовжує з останньої точки. Дані не втрачаються.
Готові спростити деплой вашого протоколу? Замовте розробку системи автоматичного деплою — оцінимо проєкт безкоштовно. Зв'яжіться з нами, щоб обговорити деталі.







