Деплой смарт-контрактів у zkSync

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Деплой смарт-контрактів у zkSync
Середній
від 4 годин до 2 днів
Часті запитання

Напрямки блокчейн-розробки

Етапи блокчейн-розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1306
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1217
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    919
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1146
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    609
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    884

Деплойментт смарт-контрактів в zkSync

zkSync Era — це ZK Rollup з EVM-сумісністю, але не EVM-еквівалентністю. Більшість Solidity контрактів компілюються та деплоюються без змін, але є специфіка zksolc компілятора та ряд опкодів, які ведуть себе по-іншому. Знати це потрібно до деплойменту, інакше контракт задеплоїться, але працюватиме неправильно.

Специфіка zkSync Era

Компілятор zksolc

zkSync використовує власний компілятор zksolc, який компілює Solidity в EraVM bytecode (не EVM bytecode). Це важлива відмінність:

  • Контракт, задеплоєний на zkSync, має інший bytecode ніж той же контракт на Ethereum
  • CREATE та CREATE2 працюють по-іншому: перед деплойментом байткод контракту повинен бути оголошений у транзакції (feature "factory dependencies")
  • SELFDESTRUCT — задеплоїти можна, але опкод не видаляє контракт (змінено в EIP-6049, zkSync слідує цій семантиці)
  • PUSH0 — підтримується починаючи з певних версій zksolc; для старих контрактів з pragma solidity ^0.8.19 може бути проблема

Відмінності в gas моделі

zkSync Era має двовимірну gas модель: gasLimit (computation) + gasPerPubdata (вартість публікації даних на L1). При деплойменті контрактів з великим bytecode gasPerPubdata може домінувати над обчислювальним gas.

Деплойментт через Hardhat

npm install -D @matterlabs/hardhat-zksync @matterlabs/zksync-contracts
// hardhat.config.ts
import { HardhatUserConfig } from 'hardhat/config'
import '@matterlabs/hardhat-zksync'

const config: HardhatUserConfig = {
  zksolc: {
    version: 'latest',
    settings: {
      optimizer: {
        enabled: true,
        mode: '3', // z (size), s (speed), 3 (balanced)
      },
    },
  },
  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

Деплойментт скрипт:

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)
  
  // Загружаємо артефакт (zksolc компілює в zk-специфічний формат)
  const artifact = await deployer.loadArtifact('MyContract')
  
  // Оцінюємо вартість деплойменту
  const deploymentFee = await deployer.estimateDeployFee(artifact, [/* constructor args */])
  console.log(`Estimated deploy fee: ${ethers.formatEther(deploymentFee)} ETH`)
  
  const contract = await deployer.deploy(artifact, [/* constructor args */])
  await contract.waitForDeployment()
  
  console.log(`Deployed to: ${await contract.getAddress()}`)
}
npx hardhat deploy-zksync --script deploy.ts --network zkSyncMainnet

Деплойментт через Foundry (zkSync fork)

Foundry офіційно підтримує zkSync через foundry-zksync — форк, який додає --zksync флаг:

# Встановлення 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

# Або через скрипт
forge script script/Deploy.s.sol \
  --rpc-url https://mainnet.era.zksync.io \
  --private-key $PRIVATE_KEY \
  --zksync \
  --broadcast

Верифікація контракту

# Через Hardhat
npx hardhat verify --network zkSyncMainnet CONTRACT_ADDRESS "constructor_arg1"

# Через zkSync Explorer API напрямку
curl -X POST https://zksync2-mainnet-explorer.zksync.io/contract_verification \
  -H "Content-Type: application/json" \
  -d '{
    "contractAddress": "0x...",
    "sourceCode": "...",
    "contractName": "MyContract",
    "compilerZksolcVersion": "v1.4.1",
    "compilerSolcVersion": "0.8.24",
    "optimizationUsed": true
  }'

Native Account Abstraction

Ключева перевага zkSync Era — нативна AA на рівні протоколу (на відміну від ERC-4337, який працює через entrypoint контракт). Кожен аккаунт може бути смарт-контрактом. Для деплойменту 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) {
        // Кастомна логіка валідації (multisig, session keys, etc.)
    }
    
    function executeTransaction(
        bytes32 _txHash,
        bytes32 _suggestedSignedHash,
        Transaction calldata _transaction
    ) external payable override {
        // Виконання
    }
    // ...
}

Мости та депозит ETH

Для деплойменту потрібен ETH на zkSync. Бридж через офіційний zkSync bridge (~15–30 хвилин фіналізація на L1). Програмний бридж через L1 контракт:

import { Provider, Wallet, utils } from 'zksync-ethers'
import { ethers } from 'ethers'

const l1Provider = new ethers.JsonRpcProvider(L1_RPC_URL)
const l2Provider = new Provider('https://mainnet.era.zksync.io')
const wallet = new Wallet(PRIVATE_KEY, l2Provider, l1Provider)

// Депозит 0.1 ETH з L1 на L2
const depositHandle = await wallet.deposit({
  token: utils.ETH_ADDRESS,
  amount: ethers.parseEther('0.1'),
})
await depositHandle.waitFinalize()

Деплойментт простого контракту займає кілька годин (підготовка окружуння + верифікація). Міграція існуючого Ethereum проекту на zkSync з урахуванням специфіки компілятора та тестуванням — 1–2 дні.