This guide assumes you have already deployed your app to an existing Ethereum network.

Setting up a Hardhat project

Abstract has a great guide on how to migrate your existing Hardhat project to ZKsync here.

For a specific example of deploying a contract to Topaz checkout the example guide below.

Setting up a Foundry project

For Foundry projects, we recommend using the foundryup-zksync package. Building for ZKsync and running tests is as simple, however you may run into issues with the zksolc compiler. We currently recommend to use Hardhat instead of Foundry for deploying contracts to Treasure Chain.

1

Install ZKsync Foundry

If you are on macOS you will need to install libusb first:

brew install libusb

If you are on Windows, you will need to install and use Git BASH or WSL, as your terminal, since foundryup-zksync currently does not support Powershell or Cmd. Windows support is currently provided as best-effort.

Then install the foundryup-zksync package:

curl -L https://raw.githubusercontent.com/matter-labs/foundry-zksync/main/install-foundry-zksync | bash
2

Set forge to use zksync compiler

Add --zksync to your forge commands:

forge build --zksync
3

Add zkout to your .gitignore

When building with zksync, output files are now generated in the zkout directory instead of out.

4

Adjust your contracts

You may need to adjust your contracts based off the limitations of ZKsync’s Foundry fork.

5

Deploy your contracts

Deploy your contract with forge create and specify the blockchain information:

$ forge create --zksync \
--rpc-url https://rpc.topaz.treasure.lol \
--constructor-args "ARG1" "ARG2" \
--private-key <your_private_key> \
    --verifier zksync  \
    --verifier-url https://rpc-explorer-verify.topaz.treasure.lol/contract_verification \
    --verify \
    src/MyContract.sol:MyContract

Deploying to Topaz with Hardhat

Whether your project is setup with Foundry or Hardhat, you can use the following example to deploy your contract to Topaz using hardhat-deploy which supports ZKsync.

You can also use hardhat-zksync to deploy a Foundry project. Additionally, hardhat-deploy is not maintained by (nor receiving contributions from) Matter Labs, the creators of ZKsync.

In this example we are deploying a contract using a wallet stored in the AWS Key Management Service (KMS) using the @treasure-dev/hardhat-kms package. In the Abstract docs linked above they provide an example using a private key instead of a KMS key.

1

Install the required packages

This will install the following packages:

  • dotenv: To load environment variables from a .env file.
  • hardhat-deploy: To deploy contracts to a network.
  • @treasure-dev/hardhat-kms: To use a KMS key to sign your deployments.
  • hardhat: The main Hardhat package.
  • @matterlabs/hardhat-zksync: The zksolc compiler.
  • @matterlabs/hardhat-zksync-verify: To verify contracts on zkSync.
  • @nomicfoundation/hardhat-foundry: To use Foundry to compile your contracts. (Needed if you are using Foundry instead of Hardhat)
  • ethers: Used in the deploy process.
  • zksync-ethers: Used in the deploy process.
  • ts-node: To run TypeScript files.
  • typescript: To compile TypeScript files.
2

Setup your .env file

In your .env file you will need to define the following variables:

DEV_KMS_RESOURCE_ID="<ARN_FOR_KMS_KEY>"
AWS_PROFILE="<AWS_PROFILE_NAME>"
AWS_REGION="<AWS_REGION>"

This should be the profile, region, and ARN of the KMS key you want to use to sign your deployments. You can find the ARN in the AWS console under the KMS key you want to use.

3

Add a hardhat.config.ts file

This hardhat.config.ts file is using the network information for Topaz as seen in the network details.

import 'dotenv/config';
import "hardhat-deploy";
import "@treasure-dev/hardhat-kms";
import "@matterlabs/hardhat-zksync";
import "@matterlabs/hardhat-zksync-verify";
import "@nomicfoundation/hardhat-foundry";
import { HardhatUserConfig } from "hardhat/config";

const devKmsKey = process.env.DEV_KMS_RESOURCE_ID;

const config: HardhatUserConfig = {
    defaultNetwork: "treasureTopaz",
    networks: {
        treasureTopaz: {
            url: "https://rpc.topaz.treasure.lol",
            ethNetwork: "sepolia",
            zksync: true,
            verifyURL: "https://rpc-explorer-verify.topaz.treasure.lol/contract_verification",
            kmsKeyId: devKmsKey,
        },
    },
    zksolc: {
        version: "latest",
    },
    solidity: {
        version: "0.8.23",
    },
    namedAccounts: {
        deployer: 0,
    },
};

export default config;
4

Add a tsconfig.json file

This tsconfig.json file is used for running your deploy script.

{
    "compilerOptions": {
        "target": "ES2020",
        "module": "commonjs",
        "strict": true,
        "esModuleInterop": true,
        "moduleResolution": "node",
        "forceConsistentCasingInFileNames": true,
        "outDir": "dist",
        "resolveJsonModule": true
    },
    "include": [
        "./hardhat.config.ts",
        "./deploy"
    ]
}

Make sure to include any other typescript files you may have in your project.

5

Create your deploy script

Create a deploy directory and add a deploy.ts file to it. Replace <YOUR_CONTRACT_NAME> with the name of your contract.

import type { HardhatRuntimeEnvironment } from 'hardhat/types';
import type { DeployFunction } from 'hardhat-deploy/types';

const func: DeployFunction = async (hre: HardhatRuntimeEnvironment) => {
    const { getNamedAccounts, deployments } = hre;
    const { deploy } = deployments;
    const { deployer } = await getNamedAccounts();

    const contract = await deploy('<YOUR_CONTRACT_NAME>', {
        from: deployer,
        args: [],
    });

    console.log("Contract deployed to:", contract.address);
}

export default func;
6

Add Hardhat scripts to your package.json

Add the following scripts to your package.json file:

{
    "scripts": {
        "clean": "hardhat clean",
        "compile": "hardhat compile --network treasureTopaz",
        "deploy:treasure-topaz": "hardhat deploy-zksync --network treasureTopaz"
    }
}
  • clean: Removes the artifacts and cache directories.
  • compile: Compiles your contracts for Topaz.
  • deploy:treasure-topaz: Deploys your contracts to Topaz.
7

Run your deploy script

Run the following command to deploy your contract:

npm run deploy:treasure-topaz

This will deploy your contract to Topaz using the KMS key you specified in your .env file.