Наші інженери часто бачать, як розробники переносять EVM-контракти на zkSync без змін — і отримують сюрпризи: CREATE2 не працює, газ летить у 3 рази вище очікуваного, а верифікація падає через несумісність байткоду. У цій статті розберемо, як деплоїти смарт-контракти в zkSync Era правильно: з урахуванням zksolc, EraVM, Native Account Abstraction та двовимірної газової моделі.
Проблеми, які вирішуємо
Несумісність байткоду. zksolc генерує EraVM bytecode, а не EVM. Якщо не вказати factory dependencies, CREATE (і CREATE2) просто не спрацюють — потрібно заздалегідь оголосити всі контракти, що створюються з коду. Газова модель. У zkSync діє двовимірний газ: звичайний gas за виконання та gasPerPubdata за публікацію даних у L1. При деплої важкого контракту (наприклад, з великими конструкторами) підсумкова вартість може виявитися в 2–3 рази вищою, ніж на Ethereum Mainnet, якщо не оптимізувати payload. Відсутність документації. Багато хто не знає про Native Account Abstraction і втрачає можливість впровадити смарт-акаунти з кастомною валідацією прямо на рівні протоколу, без окремого entrypoint.
Якщо ви зіткнулися з цими проблемами, зв'яжіться з нами — ми допоможемо.
Як ми це робимо
Використовуємо перевірений стек: Hardhat з плагіном @matterlabs/hardhat-zksync (для складних проектів) або Foundry-zksync (для швидких прототипів). Конфігурацію налаштовуємо під специфіку проекту — режими оптимізації zksolc (size/speed/balanced) впливають на розмір контракту до 40% і на витрати газу до 50%. Нижче порівняння інструментів:
| Інструмент | Компіляція | Верифікація | Гнучкість | Ідеально для |
|---|---|---|---|---|
| Hardhat | zksolc, повна підтримка | Вбудована через плагін | Висока, багато модулів | Продукційні контракти з безліччю залежностей |
| Foundry-zksync | forge з --zksync | Через API | Середня, менше плагінів | Швидкі прототипи та тести |
Foundry-zksync, за нашими вимірами, деплоїть контракти в 2–3 рази швидше за рахунок прямої відправки транзакцій, але Hardhat дає більш детальний контроль над factory dependencies та верифікацією.
| Режим оптимізації zksolc | Розмір контракту | Газ на виконання | Де застосувати |
|---|---|---|---|
| size | -40% | +20% | Легкі контракти з малою кількістю викликів |
| speed | +10% | -30% | Контракти, що часто викликаються (токени, DEX) |
| balanced | базовий | базовий | Універсальний варіант |
Що таке zksolc і чому він важливий?
Компілятор zksolc перетворює Solidity у байткод для кастомної віртуальної машини EraVM. Це означає:
- Стандартні патерни (CREATE2 для детермінованого деплою) вимагають явного зазначення factory dependencies. Без них деплой впаде з помилкою ContractDeployedWithoutFactoryDep.
- Опкод SELFDESTRUCT не знищує контракт — zkSync слідує EIP-6049 і повертає помилку.
- PUSH0 може не підтримуватися в старих версіях zksolc, що ламає контракти з pragma ^0.8.19. У таких випадках використовуємо pragma ^0.8.13 або додаємо fallback.
Як деплоїти через Hardhat?
Встановіть плагін і налаштуйте конфігурацію:
// hardhat.config.ts import { HardhatUserConfig } from 'hardhat/config' import '@matterlabs/hardhat-zksync' const config: HardhatUserConfig = { zksolc: { version: 'latest', settings: { optimizer: { enabled: true, mode: '3', }, }, }, networks: { zkSyncMainnet: { url: 'https://mainnet.era.zksync.io', ethNetwork: 'mainnet', zksync: true, verifyURL: 'https://zksync2-mainnet-explorer.zksync.io/contract_verification', }, zkSyncTestnet: { url: 'https://sepolia.era.zksync.dev', ethNetwork: 'sepolia', zksync: true, verifyURL: 'https://explorer.sepolia.era.zksync.dev/contract_verification', }, }, solidity: '0.8.24', } export default config Скрипт деплою через Deployer:
import { Wallet, Provider } from 'zksync-ethers' import { Deployer } from '@matterlabs/hardhat-zksync' import { HardhatRuntimeEnvironment } from 'hardhat/types' export default async function (hre: HardhatRuntimeEnvironment) { const provider = new Provider(hre.network.config.url) const wallet = new Wallet(process.env.DEPLOYER_PRIVATE_KEY!, provider) const deployer = new Deployer(hre, wallet) const artifact = await deployer.loadArtifact('MyContract') const deploymentFee = await deployer.estimateDeployFee(artifact, []) console.log(`Estimated deploy fee: ${ethers.formatEther(deploymentFee)} ETH`) const contract = await deployer.deploy(artifact, []) await contract.waitForDeployment() console.log(`Deployed to: ${await contract.getAddress()}`) } Запуск: npx hardhat deploy-zksync --script deploy.ts --network zkSyncMainnet
Як деплоїти через Foundry?
Встановіть Foundry-zksync і виконайте команду:
curl -L https://raw.githubusercontent.com/matter-labs/foundry-zksync/main/install-foundry-zksync | bash forge create src/MyContract.sol:MyContract \ --rpc-url https://mainnet.era.zksync.io \ --private-key $PRIVATE_KEY \ --zksync \ --constructor-args "arg1" 123 Верифікація через API виконується запитом: POST https://zksync2-mainnet-explorer.zksync.io/contract_verification з тілом JSON.
Що таке Native Account Abstraction у zkSync?
Нативна AA працює на рівні протоколу — кожен акаунт може бути смарт-контрактом. Для реалізації потрібно реалізувати інтерфейс IAccount:
import "@matterlabs/zksync-contracts/l2/system-contracts/interfaces/IAccount.sol"; contract MyAccount is IAccount { function validateTransaction( bytes32 _txHash, bytes32 _suggestedSignedHash, Transaction calldata _transaction ) external payable override returns (bytes4 magic) { // кастомна валідація } function executeTransaction( bytes32 _txHash, bytes32 _suggestedSignedHash, Transaction calldata _transaction ) external payable override { // виконання } } Це економить до 30% газу порівняно з ERC-4337 за рахунок відсутності окремого entrypoint-контракту.
Чому zkSync вимагає спеціальної оптимізації газу?
Двовимірний газ — ключова особливість. gasPerPubdata може становити до 40% вартості транзакції. Оптимізуйте calldata: уникайте довгих рядкових аргументів і масивів у конструкторі. Використовуйте режим оптимізації 'size' для економії місця, якщо контракт деплоїться один раз і викликається рідко.
Типові помилки при деплої в zkSync
- Пропущені factory dependencies — найчастіша причина провалу деплою. Для кожного контракту, що створюється через CREATE/CREATE2, необхідно додавати адресу в масив dependancies при деплої.
- Ігнорування двовимірного газу — газ за публікацію даних (gasPerPubdata) може становити до 40% вартості транзакції.
- Використання непідтримуваних опкодів — SELFDESTRUCT, PUSH0, деякі версії DELEGATECALL можуть не працювати або працювати інакше. Завжди тестуйте на тестовій мережі.
Чек-лист перевірки сумісності з zkSync:
- Перевірити наявність factory dependencies для всіх dynamic контрактів
- Переконатися, що не використовуються непідтримувані опкоди (SELFDESTRUCT, PUSH0)
- Налаштувати оптимізатор zksolc (режим size/speed/balanced)
- Протестувати на тестовій мережі zkSync Sepolia
- Верифікувати контракт після деплою
Що входить в роботу з деплою?
- Етап 1. Аналітика та аудит існуючих контрактів на сумісність з zkSync. Перевіряємо on-chain та off-chain безпеку, виявляємо проблемні опкоди.
- Етап 2. Налаштування компілятора zksolc та оптимізація газової моделі. Підбираємо режим оптимізації, налаштовуємо factory dependencies.
- Етап 3. Підготовка скриптів деплою (Hardhat/Foundry). Включаємо оцінку газу, factory dependencies, конфігурацію мережі.
- Етап 4. Верифікація контракту на блокчейн-експлорері. Використовуємо плагін hardhat-zksync-verify або прямий виклик API.
- Етап 5. Написання документації розгортання та рекомендацій з експлуатації. Фіксуємо всі параметри та залежності.
- Етап 6. Техпідтримка на етапі запуску (2 тижні). Допомагаємо інтегрувати контракт в інтерфейси.
Багаторічний досвід у блокчейн-розробці та понад 50 успішних деплоїв на L2 дозволяють гарантувати коректну роботу контракту в мережі zkSync. Для комплексних проектів підключаємо формальну верифікацію за допомогою solc-verify або Certora.
Вартість деплою визначається після аналізу складності контракту. Наші клієнти економлять до 30% на газі завдяки оптимізації.
Терміни: від 1 до 5 днів залежно від складності.
Отримайте консультацію — зв'яжіться з нами для безкоштовного аудиту вашого контракту на сумісність з zkSync. Деплой контракту під ключ з гарантією сумісності.







