Deploy contract with CREATE2 opcode


Deploy contract with CREATE2 opcode

With zkSync Era contract can be deployed using the CREATE2 by simply building the contract into a binary format and deploying it to the zkSync Era network.

There is a user guideopen in new window on how to compile Solidity smart contracts using zksolc compiler. zksolc compiler generates a *.zbin and a combined.json file that contains the bytecode and ABI of a smart contract.

Deploy contract

import { Provider, types, Wallet, ContractFactory } from "zksync2-js";
import { ethers, Contract, Typed } from "ethers";

const provider = Provider.getDefaultProvider(types.Network.Goerli);
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const wallet = new Wallet(PRIVATE_KEY, provider);

async function main() {
  const conf = require("../../solidity/storage/build/combined.json");
  const abi = conf.contracts["Storage.sol:Storage"].abi;
  const bytecode: string = conf.contracts["Storage.sol:Storage"].bin;

  const factory = new ContractFactory(abi, bytecode, wallet, "create2");
  const storage = (await factory.deploy({
    customData: { salt: ethers.hexlify(ethers.randomBytes(32)) },
  })) as Contract;
  console.log(`Contract address: ${await storage.getAddress()}`);

  console.log(`Value: ${await storage.get()}`);

  const tx = await storage.set(Typed.uint256(200));
  await tx.wait();

  console.log(`Value: ${await storage.get()}`);
}

main()
  .then()
  .catch((error) => {
    console.log(`Error: ${error}`);
  });

Deploy contract with constructor

import { Provider, types, Wallet, ContractFactory } from "zksync2-js";
import { Contract, ethers } from "ethers";

const provider = Provider.getDefaultProvider(types.Network.Goerli);
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const wallet = new Wallet(PRIVATE_KEY, provider);

async function main() {
  const conf = require("../../solidity/incrementer/build/combined.json");
  const abi = conf.contracts["Incrementer.sol:Incrementer"].abi;
  const bytecode: string = conf.contracts["Incrementer.sol:Incrementer"].bin;

  const factory = new ContractFactory(abi, bytecode, wallet, "create2");
  const incrementer = (await factory.deploy(2, {
    customData: { salt: ethers.hexlify(ethers.randomBytes(32)) },
  })) as Contract;
  console.log(`Contract address: ${await incrementer.getAddress()}`);

  console.log(`Value before Increment method execution: ${await incrementer.get()}`);

  const tx = await incrementer.increment();
  await tx.wait();

  console.log(`Value after Increment method execution: ${await incrementer.get()}`);
}

main()
  .then()
  .catch((error) => {
    console.log(`Error: ${error}`);
  });

Deploy contract with dependencies

import { Provider, types, Wallet, ContractFactory } from "zksync2-js";
import { Contract, ethers } from "ethers";

const provider = Provider.getDefaultProvider(types.Network.Goerli);
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const wallet = new Wallet(PRIVATE_KEY, provider);

async function main() {
  const conf = require("../../solidity/demo/build/combined.json");
  const abi = conf.contracts["Demo.sol:Demo"].abi;
  const bytecode: string = conf.contracts["Demo.sol:Demo"].bin;

  const factory = new ContractFactory(abi, bytecode, wallet, "create2");
  const demo = (await factory.deploy({
    customData: {
      salt: ethers.hexlify(ethers.randomBytes(32)),
      factoryDeps: [conf.contracts["Foo.sol:Foo"].bin],
    },
  })) as Contract;
  console.log(`Contract address: ${await demo.getAddress()}`);

  console.log(`Value: ${await demo.getFooName()}`);
}

main()
  .then()
  .catch((error) => {
    console.log(`Error: ${error}`);
  });