Getting started
Getting started
Hardhat is an Ethereum development environment, designed for easy smart contract development in Solidity. One of its most prominent features is extendability: you can easily add new plugins to your hardhat project.
zkSync has has the following plugins for Hardhat:
- @matterlabs/hardhat-zksync-solc - used to compile contracts written in Solidity.
- @matterlabs/hardhat-zksync-vyper - used to compile contracts written in Vyper.
- @matterlabs/hardhat-zksync-deploy - used to deploy smart contracts.
- @matterlabs/hardhat-zksync-chai-matchers - adds zkSync-specific capabilities to the Chai assertion library for testing smart contracts.
- @matterlabs/hardhat-zksync-verify - used to verify smart contracts.
To learn more about Hardhat itself, check out its official documentation.
This tutorial shows how to set up a zkSync Solidity project using Hardhat from scratch. If you are using Vyper, check out the Vyper plugin documentation or this example in GitHub!
Prerequisites
For this tutorial, the following programs must be installed:
yarn
package manager.npm
examples will be added soon.- A wallet with sufficient Göerli
ETH
on L1 to pay for bridging funds to zkSync as well as deploying smart contracts. We recommend using our faucet from the zkSync portal.
Project setup
- To initialize the project and install the dependencies, run the following commands in the terminal:
mkdir greeter-example
cd greeter-example
yarn init -y
yarn add -D typescript ts-node @types/node ethers@^5.7.2 zksync-web3 @ethersproject/hash @ethersproject/web hardhat @matterlabs/hardhat-zksync-solc @matterlabs/hardhat-zksync-deploy
The typescript
, ts-node
and @types/node
dependencies are optional - plugins will work fine in a vanilla JavaScript environment. Although, please note that this tutorial does use TypeScript.
Tips
If using Yarn 2 and over, you may need to do some extra steps for TypeScript
to work as expected in your editor. To learn more, check out Yarn's official documentation
Configuration
- Create the
hardhat.config.ts
file and paste the following code within it:
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",
},
};
Tips
To learn more about each specific property in the hardhat.config.ts
file, check out the plugins documentation
Write and deploy a contract
Create the
contracts
anddeploy
folders. In thecontracts
folder we will store all the smart contract files. In thedeploy
folder we'll place all the scripts related to deploying the contracts.Create the
contracts/Greeter.sol
contract and paste the following code:
//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;
}
}
- Run
yarn hardhat compile
which uses thehardhat-zksync-solc
plugin to compile the contract. Theartifacts-zk
andcache-zk
folders will be created in the root directory (instead of the regular Hardhat'sartifacts
andcache
).
Tips
Note that the artifacts-zk
and cache-zk
folders contain compilation artifacts and cache, and should not be added to version control, so it's a good practice to include them in the .gitignore
file of your project.
- Create the deployment script in
deploy/deploy.ts
with the following code:
import { utils, Wallet } from "zksync-web3";
import * as ethers from "ethers";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { Deployer } from "@matterlabs/hardhat-zksync-deploy";
// 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("<WALLET-PRIVATE-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]);
// 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}`);
}
}
- After replacing the
WALLET-PRIVATE-KEY
text with the private key of your Ethereum wallet, run the script using the following command:yarn hardhat deploy-zksync
. This script will:
- Transfer 0.001 ETH from Goerli to zkSync.
- Deploy the
Greeting
contract with the message "Hi there!" to zkSync Era Testnet. - Retrieve the message from the contract calling the
greet()
method. - Update the greet message in the contract with the
setGreeting()
method. - Retrieve the message from the contract again.
Congratulations! Your Hardhat project is now running on zkSync Era Testnet 🎉
Request-Rate Exceeded message
This message is caused by using the default RPC endpoints provided by ethers. To avoid this, use your own Goerli RPC endpoint.You can find multiple node providers here.
Learn more
- To learn more about the zkSync Hardhat plugins check out the plugins documentation.
- If you want to know more about how to interact with zkSync using Javascript, check out the zksync-web3 Javascript SDK documentation .
Future releases
There are two major points of improvement for the plugins which will be released in the future:
- Composability with the existing hardhat plugins. Compatibility with other hardhat plugins is planned for the future but has not been a focus yet.
- Improved cross-platform support.