L2 counter contract

Deploy a contract in ZKsync Era that has a counter.

L2 Counter

Now that we have an address for the L1 governance contract, we can build, deploy, and test the counter contract on L2.

  1. cd out of L1-governance and initialize the L2-counter project:
    npx zksync-cli create L2-counter --template hardhat_solidity
    
  2. For the purposes of this tutorial, we don't need the example smart contracts and deployment script files generated by zksync-cli. Run the following commands to remove them:
    cd L2-counter
    rm -rf ./contracts/*
    rm -rf ./scripts/*
    

Create L2 Counter Contract

  1. In the L2-counter/contracts/ directory, create a new file Counter.sol.
    touch contracts/Counter.sol
    

    This contract contains the address of the governance contract deployed previously on layer 1, and an incrementable counter which can only be invoked by the governance contract.
  2. Copy/paste the following code into the file:
    Counter.sol
    // SPDX-License-Identifier: Unlicense
    
    pragma solidity ^0.8.17;
    
    contract Counter {
      uint256 public value = 0;
      address public governance;
    
      constructor(address newGovernance) {
        governance = newGovernance;
      }
    
      function increment() public {
        require(msg.sender == governance, 'Only governance is allowed');
    
        value += 1;
      }
    }
    
  3. Compile the contract from the L2-counter root:
    Compilations happens only after the installation of a compiler.
    npm run compile
    

Deploy L2 Counter Contract

  1. Create a new file inside the scripts folder named deploy.ts.
    touch scripts/deploy.ts
    
  2. Copy/paste the following code into L2-counter/scripts/deploy.ts, replacing <GOVERNANCE-ADDRESS> with the address of the Governance contract we just deployed:
    L2-counter/scripts/deploy.ts
    import { ethers, network } from 'hardhat';
    import { utils } from 'zksync-ethers';
    
    const GOVERNANCE_ADDRESS = process.env.GOVERNANCE_ADDRESS ?? '<GOVERNANCE-ADDRESS>';
    
    async function main() {
      const CONTRACT_NAME = 'Counter';
      const ARGS = [utils.applyL1ToL2Alias(GOVERNANCE_ADDRESS)];
      console.log(`Deploying ${CONTRACT_NAME} contract to ${network.name}`);
      const contract = await ethers.deployContract(CONTRACT_NAME, ARGS, {});
      await contract.waitForDeployment();
      const contractAddress = await contract.getAddress();
      console.log(`${CONTRACT_NAME} deployed to ${contractAddress}`);
    }
    
    main()
      .then(() => process.exit(0))
      .catch((error) => {
        console.error(error);
        process.exit(1);
      });
    
  3. Now deploy the contract from the L2-counter/ folder root to ZKsync Era Sepolia:
    npm run deploy
    

    You should see output like this:
    Deploying Counter contract to ZKsyncEraSepolia
    Counter deployed to 0x111C3E89Ce80e62EE88318C2804920D4c96f92bb
    

Read the Counter Value

Now both contracts are deployed, we can create a script to retrieve the value of the counter.

  1. Create a new file in the scripts folder named display-value.ts.
    touch scripts/display-value.ts
    
  2. Copy and paste in the following code, adding the deployed counter contract address:
    L2-counter/scripts/display-value.ts
    import { ethers } from 'hardhat';
    
    async function main() {
      const COUNTER_ADDRESS = process.env.COUNTER_ADDRESS ?? '<COUNTER_ADDRESS>';
    
      const [signer] = await ethers.getSigners();
      const counterFactory = await ethers.getContractFactory('Counter');
      const counterContract = counterFactory.connect(signer).attach(COUNTER_ADDRESS);
    
      const value = (await counterContract.value()).toString();
      console.log(`The counter value is ${value}`);
    }
    
    main()
      .then(() => process.exit(0))
      .catch((error) => {
        console.error(error);
        process.exit(1);
      });
    
  3. Run the script:
    npx hardhat run ./scripts/display-value.ts
    

    The output should be:
    The counter value is 0
    

Made with ❤️ by the ZKsync Community