Деплой смарт-контракта в сети ZkSync Era на Windows

Disclaimer: для разворачивания смарт-контракта в сети ZkSync Era, вам нужно будет указывать свой приватный ключ от кошелька метамаск. Хоть он и не указывается в данном гайде на прямую, рекомендую вам не указывать приватный ключ основного кошелька, а использовать тестовые кошельки, во избежании утраты средств.

В этом гайде мы будем с вами делать деплой смарт контракта как в тестовой сети ZkSync Era, так и в мейннет

  • Добавляем сети ZkSync Era в метамаск:

Через сайт Chainlink:

Также можно в ручную:

Тестовая:

Network Name: zkSync Era Testnet
RPC URL: https://testnet.era.zksync.dev
Chain ID: 280
Currency Symbol: ETH
Block Explorer URL: https://goerli.explorer.zksync.io/
WebSocket URL: wss://testnet.era.zksync.dev/ws

Мейннет:

Network Name: zkSync Era Mainnet
RPC URL: https://mainnet.era.zksync.io
Chain ID: 324
Currency Symbol: ETH
Block Explorer URL: https://explorer.zksync.io/
WebSocket URL: wss://mainnet.era.zksync.io/ws

  • Обмениваем тестовые токены из Goerli в сеть ZkSync Era Goerli для работы в тестнете: https://portal.zksync.io/bridge.

  • Обмениваем токены из основной сети Ethereum в сеть ZkSync Era для работы в мейннете: https://portal.zksync.io/bridge.

  • Скачиваем и устанавливаем на ПК:
    а) Node.js - nodejs.com/en/ (я ставил версию, которая слева, рекомендованная для всех. После установки нужно перезагрузить ПК)
    б) Visual Studio Code - code.visualstudio.com/download

  • Создаем папку на рабочем столе HELLO-ZKSYNC

  • Открываем Visual Studio и открываем созданную вами папку HELLO-ZKSYNC, нажав в левом верхнем углу File - Open folder

  • Нажимаем на значок справа сверху, как показано на скрине, у вас откроется панель с консолью (по умолчанию будет выбран путь к вашей папке HELLO-ZKSYNC)
  • В консоле пишем команды по одной (или копируем и вставляем нажатие правой клавиши мыши):
npm init -y 
npm add -D typescript ts-node @types/node ethers@^5.7.2 zksync-web3@^0.14.3 @ethersproject/hash @ethersproject/web hardhat @matterlabs/hardhat-zksync-solc @matterlabs/hardhat-zksync-deploy
  • Далее создайте в папке HELLO-ZKSYNC (папка выбрана, когда галочка опущена вниз) файл, нажав на кнопку как на скрине и назовите его hardhat.config.ts
  • Нажав на него откроется окно, куда мы вставляем следующий код (копируйте и просто вставляйте целиком нажатием правой клавиши мыши и Paste). В зависимости от того в какой сети делаете деплой смарт контракта, тот скрипт и копируете. Если в тестовой, то скрипт для тестовой сети, если в мейннете, то скрипт для мейннет. Скрин ниже.

    Для тестовой сети:

import "@matterlabs/hardhat-zksync-deploy";
import "@matterlabs/hardhat-zksync-solc";

module.exports = {
  zksolc: {
    version: "1.3.5",
    compilerSource: "binary",
    settings: {},
  },
  defaultNetwork: "zkTestnet",
  networks: {
    zkTestnet: {
      url: "https://zksync2-testnet.zksync.dev", // URL of the zkSync network RPC
      ethNetwork: "goerli", // Can also be the RPC URL of the Ethereum network (e.g. `https://goerli.infura.io/v3/<API_KEY>`)
      zksync: true,
    },
  },
  solidity: {
    version: "0.8.17",
  },
};

Для мейннета:

import "@matterlabs/hardhat-zksync-deploy";
import "@matterlabs/hardhat-zksync-solc";

module.exports = {
  zksolc: {
    version: "1.3.5",
    compilerSource: "binary",
    settings: {},
  },
  defaultNetwork: "zkSyncMainnet",

  networks: {
    zkSyncMainnet: {
      url: "https://zksync2-mainnet.zksync.io",
      ethNetwork: "mainnet", // Can also be the RPC URL of the network (e.g. `https://goerli.infura.io/v3/<API_KEY>`)
      zksync: true,
    },
  },
  solidity: {
    version: "0.8.17",
  },
};

Скрин:

Закройте файл, нажав на крестик и сохраните изменения!

  • В левом меню в папке HELLO-ZKSYNC создаем папку contracts и папку deploy, нажав на кнопку, как на скриншоте
  • В папке contracts создаём файл Greeter.sol

и в него вставляем следующий код

//SPDX-License-Identifier: Unlicensed
pragma solidity ^0.8.0;

contract Greeter {
    string private greeting;

    constructor(string memory _greeting) {
        greeting = _greeting;
    }

    function greet() public view returns (string memory) {
        return greeting;
    }

    function setGreeting(string memory _greeting) public {
        greeting = _greeting;
    }
}

Закрываем файл нажав на крестик и сохраняем!

  • Далее в консоле вводим следующую команду и жмём Enter
npx hardhat compile

Если сделали всё правильно увидите следующее сообщение:

  • Выбираем в левом окне созданную нами папку deploy, в ней создаём файл deploy.ts

и вставляем в него следующий код (код я слегка изменил, чтобы приватник указывать не на прямую в контракте, а просто путь к файлу, где указываем приватный ключ. По мне, так безопасней, но гарантий также никаких нет. Можете сравнить с оригинальным кодом из пункта 6 (https://era.zksync.io/docs/api/hardhat/getting-started.html#write-and-deploy-a-contract), добавил строчки 1 и 7, они и указывают путь к созданному файлу с приватником).

import fs from "fs"
import { utils, Wallet } from "zksync-web3";
import * as ethers from "ethers";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { Deployer } from "@matterlabs/hardhat-zksync-deploy";

const PRIV_KEY = fs.readFileSync(".secret").toString()

// An example of a deploy script that will deploy and call a simple contract.
export default async function (hre: HardhatRuntimeEnvironment) {
  console.log(`Running deploy script for the Greeter contract`);

  // Initialize the wallet.
  const wallet = new Wallet(PRIV_KEY);

  // Create deployer object and load the artifact of the contract we want to deploy.
  const deployer = new Deployer(hre, wallet);
  const artifact = await deployer.loadArtifact("Greeter");

  // Deposit some funds to L2 in order to be able to perform L2 transactions.
  // const depositAmount = ethers.utils.parseEther("0.001");
 // const depositHandle = await deployer.zkWallet.deposit({
  //  to: deployer.zkWallet.address,
 //   token: utils.ETH_ADDRESS,
 //   amount: depositAmount,
//  });
  // Wait until the deposit is processed on zkSync
 // await depositHandle.wait();

  // Deploy this contract. The returned object will be of a `Contract` type, similarly to ones in `ethers`.
  // `greeting` is an argument for contract constructor.
  const greeting = "Hi there!";
  const greeterContract = await deployer.deploy(artifact, [greeting]);
  console.log("constructor args:" + greeterContract.interface.encodeDeploy([greeting]));


  // Show the contract info.
  const contractAddress = greeterContract.address;
  console.log(`${artifact.contractName} was deployed to ${contractAddress}`);

  // Call the deployed contract.
  const greetingFromContract = await greeterContract.greet();
  if (greetingFromContract == greeting) {
    console.log(`Contract greets us with ${greeting}!`);
  } else {
    console.error(`Contract said something unexpected: ${greetingFromContract}`);
  }

  // Edit the greeting of the contract
  const newGreeting = "Hey guys";
  const setNewGreetingHandle = await greeterContract.setGreeting(newGreeting);
  await setNewGreetingHandle.wait();

  const newGreetingFromContract = await greeterContract.greet();
  if (newGreetingFromContract == newGreeting) {
    console.log(`Contract greets us with ${newGreeting}!`);
  } else {
    console.error(`Contract said something unexpected: ${newGreetingFromContract}`);
  }
}

Закрываем файл и сохраняем!

  • Создаём файл в папке HELLO-ZKSYNC, назовём его .secret

Как раз таки в этот файл и вставляем свой приватный ключ. Приватный ключ брать тут:

Закрываем файл и сохраняем!

  • И наконец у нас последняя команда для деплоя контракта
npx hardhat deploy-zksync

Ждём появления следующих строчек:

  • После этого переходим в эксплорер для тестовой сети или эксплорер для мейннета, вводим номер своего контракта и видим, что он создан. Также можете ввести в эксплорере адрес своего метамаска и увидеть две транзакции, т.к. после команды деплоя сразу происходит еще и взаимодействие с контрактом.

Поздравляю, вы развернули смарт-контракт в тестовой сети ZKSync Era!!!

Также вы можете верифицировать свой контракт. Но после этого он будет доступен для каждого (поэтому сразу не стал выкладывать эту часть), что повышает риск взлома и кражи вашего приватного ключа. Как писал в начале, делайте все операции только на тестовом кошельке

Для этого:

  • Перейдите в эксплорер для тестовой сети или эксплорер для мейннета, введите адрес своего контракта (в какой сети делали смарт контракт, в тот эксплорер и заходите)

  • Далее нажмите на вкладку Contract

  • Нажимаем на кнопку Verify Smart Contract
  • Заполняем все поля, как указано на картинке:

В поле Enter the Solidy Contract Code вставляем:

//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;

contract Greeter {
    string private greeting;

    constructor(string memory _greeting) {
        greeting = _greeting;
    }

    function greet() public view returns (string memory) {
        return greeting;
    }

    function setGreeting(string memory _greeting) public {
        greeting = _greeting;
    }
}

В поле Constructor Arguments вставляем данные, что появились после деплоя контракта

Если у кого то он не появлялся, он одинаковый для всех, можете вводить

0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000094869207468657265210000000000000000000000000000000000000000000000
  • После того, как заполнили все поля, нажимаете кнопку Verify Smart Contract

Поздравляю, Вы верифицировали свой смарт контракт!

Subscribe to Garry In Crypto (GIC)
Receive the latest updates directly to your inbox.
Mint this entry as an NFT to add it to your collection.
Verification
This entry has been permanently stored onchain and signed by its creator.