Cover photo

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:

https://chainlist.org/?search=zksync+Era&testnets=true

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

post image
  • 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)

post image
  • 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

post image
  • 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:

post image

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

post image
  • In the left menu in the folder HELLO-ZKSYNC, create folders contracts and deploy by clicking on the button, as in the screenshot

post image
  • In the folder contracts, create the file Greeter.sol

post image

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:

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

post image

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

post image

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

post image

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

post image

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

post image
  • Click on the Verify Smart Contract button

post image
  • Fill in all the fields as shown in the picture:

post image

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

post image

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

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

post image

Congratulations, you have verified your smart contract!

post image