Deploying a smart contract on the ZkSync Era on Windows

Disclaimer: To deploy a smart contract on the ZkSync Era network, you will need to provide your private key to the metamask wallet. I recommend you do not specify the private key of the main wallet, but use test wallets in order to avoid losing funds.

In this guide, we will be deploying a smart contract both on the ZkSync Era testnet and on the mainnet

  • Add the ZkSync Era networks to metamask:

With Chainlink site:

Also you can add manually:

Testnet:

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

Mainnet:

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

  • Exchange test tokens from Goerli in the ZkSync Era Goerli network: https://portal.zksync.io/bridge.

  • Exchange tokens from Ethereum in the ZkSync Era network: https://portal.zksync.io/bridge.

  • Download and install on PC:
    a) Node.js - nodejs.com/en/ (I installed the version on the left, “recommended for everyone”. After installation, you need to restart your PC)
    b) Visual Studio Code - code.visualstudio.com/download

  • Create a folder on the desktop HELLO-ZKSYNC

  • Open Visual Studio and open the HELLO-ZKSYNC folder you created by clicking File - Open folder in the upper left corner

  • Click on the icon on the top right, as shown in the screenshot, you will open a panel with the Terminal (by default, the path to your HELLO-ZKSYNC folder will be selected)
  • In the Terminal, write commands one at a time (or copy and paste by pressing the right mouse button):
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
  • Next, create a file in folder HELLO-ZKSYNC by clicking on the button as in the screenshot and name it hardhat.config.ts
  • By clicking on it, a field will open where we paste the following text (copy and just paste by pressing the right mouse button and Paste). Depending on which network you are deploying the smart contract to, you copy that script. If in the test, then the script for the test network, if in the mainnet, then the script for the mainnet. Screen below.

    For Testnet:

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",
  },
};

For mainnet:

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",
  },
};

Screenshot:

Close the file by clicking on the cross and save your changes!

  • In the left menu in the folder HELLO-ZKSYNC, create folders contracts and deploy by clicking on the button, as in the screenshot
  • In the folder contracts, create the file Greeter.sol

and paste the following code into it

//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;
    }
}

Close the file by clicking on the cross and save!

  • Next, in the Terminal type next command and press Enter
npx hardhat compile

If you did everything correctly, you will see the following message:

  • Select folder deploy we created before, create the deploy.ts file into it

and paste the code into it:

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}`);
  }
}

Close the file and save!

  • Create a file in folder HELLO-ZKSYNC, let's call it .secret
    Paste private key here

Close the file and save!

  • Type the last command to deploy the contract
npx hardhat deploy-zksync
  • If you did everything right, the next notifications will appear

After that, go to the explorer for the test network or the explorer for the mainnet, enter the number of our contract and see that it has been created. You can also enter the address of your metamask in the explorer and see three transactions, because after the deployment command, there is also an interaction with the contract.

Congratulations, you have deployed a smart contract on the ZKSync Era testnet!!!

You can also verify your contract. But after that, it will be available to everyone, which increases the risk of hacking and theft of your private key. As I wrote at the beginning, do all operations only on a test wallet

For this:

  • Go to the explorer for the test network or the explorer for the mainnet, enter the address of your smart contract (in which network the smart contract was deploy, go to that explorer)

  • Next, click on the Contract tab

  • Click on the Verify Smart Contract button
  • Fill in all the fields as shown in the picture:

In the Enter the Solidy Contract Code field, paste:

//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;
    }
}

In the Constructor Arguments field, insert the data that appeared after the deployment of the contract

If someone did not have it, it is the same for everyone, you can enter

0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000094869207468657265210000000000000000000000000000000000000000000000

After you have filled in all the fields, click the Verify Smart Contract button

Congratulations, you have verified your 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.