Hello ZKsync!

Learn to deploy smart contracts efficiently in the ZKsync environment.

Welcome to the ZKsync 101 guide for deploying smart contracts on ZKsync! In this series, we'll walk you through the process of creating and deploying a simple smart contract that creates a crowdfunding campaign for Zeek. In this section you will learn the following:

Initialize a new project with zksync-cli.

Craft a smart contract to fund Zeek's latest adventure.

Deploy the contract on the ZKsync Era using your choice of Hardhat or Foundry.

Let's dive in and start your developer journey on ZKsync!


Prerequisites

This series requires some initial setup of tools to elevate your development experience building for ZKsync. Make sure to go through the setup provided in the initial Getting started section.

Select the framework you want to get started using ZKsync Era with.

Run the following command in your terminal to initialize the project.

npx zksync-cli@latest create --template qs-hello-zksync hello-zksync-quickstart
cd hello-zksync-quickstart

Set up your wallet

Deploying contracts on the ZKsync Sepolia Testnet requires having testnet ETH. If you're working within the local development environment, you can utilize pre-configured rich wallets and skip this step. For testnet deployments, you should have your wallet funded from the previous step.

Compile the CrowdfundingCampaign.sol contract

This guide introduces a crowdfunding campaign contract aimed at supporting Zeek's inventive ventures. Let's start by reviewing the starter contract in the contracts/ directory.

The CrowdfundingCampaign contract is designed for project crowdfunding. This contract features:

  • A constructor to initialize the campaign's funding target.
  • The contribute method to log funds, triggering ContributionReceived and GoalReached events.
  • The withdrawFunds method, allowing the owner to collect accumulated funds post-goal achievement.

Smart contracts deployed to ZKsync must be compiled using our custom compiler. zksolc is the compiler used for Solidity.

To compile the contracts in a project, run the following command:

npm run compile

Upon successful compilation, you'll receive output detailing the zksolc and solc versions used during compiling and the number of Solidity files compiled.

Compiling contracts for ZKsync Era with zksolc v1.4.1 and solc v0.8.17
Compiling 15 Solidity files
Successfully compiled 15 Solidity files

The compiled artifacts will be located in the /artifacts-zk folder.

Deploy the contract

The deployment script is located at /deploy/deploy.ts.

deploy.ts
import { deployContract } from "./utils";

// An example of a basic deploy script
// It will deploy a CrowdfundingCampaign contract to selected network
// `parseEther` converts ether to wei, and `.toString()` ensures serialization compatibility.
export default async function () {
  const contractArtifactName = "CrowdfundingCampaign";
  const constructorArguments = [ethers.parseEther('.02').toString()];
  await deployContract(contractArtifactName, constructorArguments);
}

Key Components:

  • contractArtifactName: Identifies the CrowdfundingCampaign contract for deployment.
  • constructorArguments: Sets initialization parameters for the contract. In this case, the fundraising goal, converted from ether to wei to match Solidity's uint256 type.
  1. Execute the deployment command corresponding to your package manager. The default command deploys to the configured network in your Hardhat setup. For local deployment, append --network inMemoryNode to deploy to the local in-memory node running.
npx hardhat deploy-zksync --script deploy.ts
# The deploy keyword will trigger the `deploy` script command on `package.json`
# To deploy the contract on local in-memory node:
# npx hardhat deploy-zksync --script deploy.ts --network inMemoryNode

Upon successful deployment, you'll receive output detailing the deployment process, including the contract address, source, and encoded constructor arguments:

Starting deployment process of "CrowdfundingCampaign"...
Estimated deployment cost: 0.000501 ETH

"CrowdfundingCampaign" was successfully deployed:
 - Contract address: 0x4E3404F21b29d069539e15f8f9E712CeAE39d90C
 - Contract source: contracts/Crowdfund.sol:CrowdfundingCampaign
 - Encoded constructor arguments: 0x00000000000000000000000000000000000000000000000000470de4df820000

Requesting contract verification...
Your verification ID is: 10067
Contract successfully verified on ZKsync block explorer!

🥳 Congratulations! Your smart contract is now deployed. 🚀

foundry-zksync is still in an alpha stage, so some features might not be fully supported yet and may not work as fully intended. It is open-sourced and contributions are welcomed.

Run the following command in your terminal to initialize the Foundry project.

npx zksync-cli@latest create --template qs-fs-hello-zksync hello-zksync-foundry-quickstart
cd hello-zksync-foundry-quickstart

Set up your wallet

Deploying contracts on the ZKsync Sepolia Testnet requires having testnet ETH. If you're working within the local development environment, you can utilize pre-configured rich wallets and skip this step. For testnet deployments, you should have your wallet funded from the previous step.

Compile your first contract

This guide introduces a crowdfunding campaign contract aimed at supporting Zeek's inventive ventures.

Let's start by reviewing the starter contract in the src/ directory.

The CrowdfundingCampaign contract is designed for project crowdfunding. Owned and deployed with a set funding goal, it features:

  • A constructor to initialize the campaign's funding target.
  • The contribute method to log funds, triggering ContributionReceived and GoalReached events.
  • The withdrawFunds method, allowing the owner to collect accumulated funds post-goal achievement.

Smart contracts deployed to ZKsync must be compiled using our custom compiler. For this particular guide we are making use of zksolc.

To compile the contracts in the project, run the following command:

forge build --zksync --use=0.8.24

Upon successful compilation, you'll receive output detailing the zksolc and solc versions used during compiling and the number of Solidity files compiled.

[⠒] Compiling...
[⠃] Compiling 2 files with 0.8.20
[⠊] Solc 0.8.20 finished in 736.48ms
Compiler run successful!
Compiling contracts for ZKsync Era with zksolc v1.4.0

The compiled zkEVM artifacts will be located in the /zkout folder, and the solc artifacts will be located in the /out folder.

Deploy the CrowdfundingCampaign contract

The deployment script is located at /script/Deploy.s.sol.

Deploy.s.sol
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;

import "forge-std/Script.sol";
import "../src/Crowdfund.sol";

contract DeployCrowdfundContract is Script {
    function run() external {
        uint256 deployerPrivateKey = vm.envUint("WALLET_PRIVATE_KEY");
        vm.startBroadcast(deployerPrivateKey);

        uint256 fundingGoalInWei = 0.02 ether;
        new CrowdfundingCampaign(fundingGoalInWei);

        vm.stopBroadcast();
    }
}

Key Components:

  • Constructor Argument: The CrowdfundingCampaign contract is initialized with a single constructor argument, fundingGoalInWei.
  • Broadcast Method: The deployment uses vm.startBroadcast(deployerPrivateKey) to begin the transaction broadcast and vm.stopBroadcast() to end it, facilitating the actual deployment of the contract on the blockchain.

Execute the deployment command.

forge script script/Deploy.s.sol:DeployCrowdfundContract --account myKeystore --sender <KEYSTORE_ADDRESS> --rpc-url zkSyncSepoliaTestnet --broadcast --zksync
# To deploy the contract on local in-memory node:
# forge script script/Deploy.s.sol:DeployCrowdfundContract --account myKeystore --sender <KEYSTORE_ADDRESS> --rpc-url inMemoryNode --broadcast --zksync

Upon successful deployment, you'll receive output detailing the deployment process, including the contract address, transaction hash, and block number deployed to:

...
  [Success]Hash: 0x69f5f1f0f5b3fa12ed2fbab4d6bb6edc02bbfff2f8c414d8171cc8295250296c
Contract Address: 0xB0C0d3d02c270b6ABe4862EA90bBa1Af192314a8
Block: 1491370
Paid: 0.0001168854 ETH (1168854 gas * 0.1 gwei)

🥳 Congratulations! Your smart contract is now deployed. 🚀

Takeaways

  • EVM Compatibility: ZKsync is EVM compatible and you can write smart contracts in Solidity or Vyper.
  • Custom Compilation: Contracts deployed to ZKsync are compiled using zksolc or zkvyper as they generate a special bytecode for ZKsync's ZKEVM.
  • Development Tools: ZKsync supports your favorite development toolkit Hardhat and Foundry.

Next steps

Having successfully deployed your first contract on ZKsync, you're well on your way to becoming a proficient ZKsync developer. To expand your expertise:

  • Explore Contract Factories: Enhance your project by building a contract factory for the CrowdfundingCampaign contract in the next guide. This will allow you to efficiently manage multiple crowdfunding campaigns, each with its own unique parameters.
  • Dive Deeper into ZKsync Features: Investigate advanced ZKsync features such as account abstraction, and paymasters.
  • Join the Community: Engage with the ZKsync developer community through forums, Discord channels, Dev Discussions, or GitHub repositories. Share your experiences, ask questions, and collaborate on projects.

Made with ❤️ by the ZKsync Community