Disclaimer: для разворачивания смарт-контракта в сети 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;
}
}
Закрываем файл нажав на крестик и сохраняем!
npx hardhat compile
Если сделали всё правильно увидите следующее сообщение:
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
Поздравляю, Вы верифицировали свой смарт контракт!