# Getting started

***

{% hint style="info" %}
If you are using Windows, we strongly recommend you use Windows Subsystem for Linux (also known as WSL 2). You can use <mark style="color:blue;">`Hardhat`</mark> and <mark style="color:blue;">`Hardhat ZKsync plugins`</mark> without it, but it will work better if you use it.To install Node.js using WSL 2, please read this [guide](https://learn.microsoft.com/en-us/windows/dev-environment/javascript/nodejs-on-wsl).
{% endhint %}

[Hardhat](https://hardhat.org/) is an Ethereum development environment, designed for easy smart contract development. One of its most prominent features is extendability: you can easily add new plugins to your hardhat project.

Along with the official plugins, there are [other plugins from the community](/docs/tooling/hardhat-validium/plugins/hardhat-community-plugins.md) that you can use with Validium.

To learn more about Hardhat itself, check out [the official documentation](https://hardhat.org/getting-started/).

This tutorial shows you how to setup a Validium Solidity project with Hardhat using the [ZKsync CLI](/docs/cli/getting-started.md).

If you are using Vyper, check out the [Vyper plugin documentation](/docs/tooling/hardhat-validium/plugins/hardhat-zksync-vyper.md) or the [vyper-example](https://github.com/matter-labs/hardhat-zksync/tree/main/examples/vyper-example) in GitHub!

### Project setup <a href="#project-setup" id="project-setup"></a>

To create a new project run the `zksync-cli create` command, passing a project name:

**Solidity project**

```bash
npx zksync-cli create demo --template hardhat_solidity
```

**Vyper project**

```bash
npx zksync-cli create demo --template hardhat_vyper
```

This command creates a `demo` folder and clones a Hardhat template project inside it. The downloaded project is already configured and contains all the required plugins.

If you want to migrate an existing project, please check the [project migration guide](/docs/tooling/hardhat-validium/guides/migrating-hardhat-project-to-validium.md).

### Hardhat configuration <a href="#hardhat-configuration" id="hardhat-configuration"></a>

The `hardhat.config.ts` file contains some Validium specific configurations:

The Validium deployment and compiler plugin imports:

**Solidity project**

```javascript
import "@matterlabs/hardhat-zksync";
```

The `zksolc` block contains the minimal configuration for the compiler.

```javascript
zksolc: {
  version: "latest", // Uses latest available in https://github.com/matter-labs/zksolc-bin
  settings: {},
},
```

**Vyper project**

```javascript
import "@nomiclabs/hardhat-vyper";
import "@matterlabs/hardhat-zksync-deploy";
import "@matterlabs/hardhat-zksync-vyper";
```

The `zkvyper` block contains the minimal configuration for the compiler.

```javascript
zkvyper: {
  version: "latest", // Uses latest available in https://github.com/matter-labs/zkvyper-bin
  settings: {},
},
```

**Network**

The network endpoints of the `zkSyncTestnet` network change dynamically for local tests.

```javascript
// dynamically changes endpoints for local tests
const zkSyncTestnet =
  process.env.NODE_ENV == "test"
    ? {
        url: "http://localhost:3050",
        ethNetwork: "http://localhost:8545",
        zksync: true,
      }
    : {
        url: "https://sepolia.era.zksync.dev",
        ethNetwork: "sepolia",
        zksync: true,
      };
```

For local Validium testing, modify `url` and `ethNetwork` in `hardhat.config.ts` to align with your local Validium and Ethereum node's L2 and L1 RPC URLs, respectively.This template project includes a basic unit test in the `/test` folder that runs with the local-setup and can be executed with `yarn test`.

### Set your Private Key <a href="#set-your-private-key" id="set-your-private-key"></a>

Rename `.env.example` to `.env` and set your private key:

```bash
WALLET_PRIVATE_KEY=YourPrivateKeyHere
```

Your private key will be used for paying the costs of deploying the smart contract.

### Compile and deploy a contract <a href="#compile-and-deploy-a-contract" id="compile-and-deploy-a-contract"></a>

Smart contracts belong in the `contracts` folder.

**1. To compile the contract, run**

```bash
yarn hardhat compile
```

You'll see the following output:

```bash
Compiling 1 Solidity file
Successfully compiled 1 Solidity file
// Successfully compiled 1 Vyper file - Vyper project
✨  Done in 1.09s.
```

The `artifacts-zk` and `cache-zk` folders appear in the root directory (instead of the regular Hardhat's `artifacts` and `cache`). These folders contain the compilation artifacts (including contract's ABIs) and compiler cache files.

The `artifacts-zk` and `cache-zk` folders are included in the `.gitignore` file.

The `deploy-greeter.ts` script is in the `deploy` folder. This script uses the `Deployer` class from the `hardhat-zksync-deploy` package to deploy the `Greeter.sol`/`Greeter.vy` contract.

```javascript
import { Wallet, utils } from "zksync-ethers";
import * as ethers from "ethers";
import { HardhatRuntimeEnvironment } from "hardhat/types";
import { Deployer } from "@matterlabs/hardhat-zksync-deploy";

// load env file
import dotenv from "dotenv";
dotenv.config();

// load wallet private key from env file
const PRIVATE_KEY = process.env.WALLET_PRIVATE_KEY || "";

if (!PRIVATE_KEY) throw "⛔️ Private key not detected! Add it to the .env file!";

// 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(PRIVATE_KEY);

  // Create deployer object and load the artifact of the contract you want to deploy.
  const deployer = new Deployer(hre, wallet);
  const artifact = await deployer.loadArtifact("Greeter");

  // Estimate contract deployment fee
  const greeting = "Hi there!";
  const deploymentFee = await deployer.estimateDeployFee(artifact, [greeting]);

  // ⚠️ OPTIONAL: You can skip this block if your account already has funds in L2
  // const depositHandle = await deployer.zkWallet.deposit({
  //   to: deployer.zkWallet.address,
  //   token: utils.ETH_ADDRESS,
  //   amount: deploymentFee.mul(2),
  // });
  // // Wait until the deposit is processed on ZKsync
  // await depositHandle.wait();

  // Deploy this contract. The returned object will be of a `Contract` type, similar to ones in `ethers`.
  // `greeting` is an argument for contract constructor.
  const parsedFee = ethers.formatEther(deploymentFee);
  console.log(`The deployment is estimated to cost ${parsedFee} ETH`);

  const greeterContract = await deployer.deploy(artifact, [greeting]);

  // obtain the Constructor Arguments
  console.log("constructor args:" + greeterContract.interface.encodeDeploy([greeting]));

  // Show the contract info.
  const contractAddress = await greeterContract.getAddress();
  console.log(`${artifact.contractName} was deployed to ${contractAddress}`);
}
```

**2. To execute the deployment script run**

```bash
yarn hardhat deploy-zksync --script deploy-greeter.ts
```

This script deploys the `Greeting` contract with the message "Hi there!" to Validium Sepolia Testnet.

You should see something like this:

```bash
Running deploy script for the Greeter contract
The deployment is estimated to cost 0.00579276320831943 ETH
constructor args:0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000094869207468657265210000000000000000000000000000000000000000000000
Greeter was deployed to 0x46f1d2d8A16DBD8b47e9D61175a826ac667288Be4D1293a22E8

✨  Done in 12.69s.
```

Congratulations! You have deployed a smart contract project to Validium Sepolia Testnet with Hardhat 🎉

**Request-Rate Exceeded message**:

* This message is caused by using the default RPC endpoints provided by ethers.
* To avoid this, use your own Sepolia RPC endpoint in the `hardhat.config.ts` file.
* Find multiple [node providers here](https://github.com/arddluma/awesome-list-rpc-nodes-providers).

### Interact with the contract <a href="#interact-with-the-contract" id="interact-with-the-contract"></a>

The template project contains another script to interact with the contract.

1. Enter the address of the deployed Greeter contract in the `CONTRACT_ADDRESS` variable of the `use-greeter.ts` script:use-greeter.ts

   ```javascript
   import { Provider } from "zksync-ethers";
   import * as ethers from "ethers";
   import { HardhatRuntimeEnvironment } from "hardhat/types";

   // load env file
   import dotenv from "dotenv";
   dotenv.config();

   // load contract artifact. Make sure to compile first! - Solidity Project
   import * as ContractArtifact from "../artifacts-zk/contracts/Greeter.sol/Greeter.json";
   // load contract artifact. Make sure to compile first! - Vyper Project
   //import * as ContractArtifact from "../artifacts-zk/contracts/Greeter.vy/Greeter.json";

   const PRIVATE_KEY = process.env.WALLET_PRIVATE_KEY || "";

   if (!PRIVATE_KEY) throw "⛔️ Private key not detected! Add it to the .env file!";

   // Address of the contract on Validium testnet
   const CONTRACT_ADDRESS = "";

   if (!CONTRACT_ADDRESS) throw "⛔️ Contract address not provided";

   // An example of a deploy script that will deploy and call a simple contract.
   export default async function (hre: HardhatRuntimeEnvironment) {
     console.log(`Running script to interact with contract ${CONTRACT_ADDRESS}`);

     // Initialize the provider.
     // @ts-ignore
     const provider = new Provider(hre.userConfig.networks?.zkSyncTestnet?.url);
     const signer = new ethers.Wallet(PRIVATE_KEY, provider);

     // Initialise contract instance
     const contract = new ethers.Contract(CONTRACT_ADDRESS, ContractArtifact.abi, signer);

     // Read message from contract
     console.log(`The message is ${await contract.greet()}`);

     // send transaction to update the message
     const newMessage = "Hello people!";
     const tx = await contract.setGreeting(newMessage);

     console.log(`Transaction to change the message is ${tx.hash}`);
     await tx.wait();

     // Read message after transaction
     console.log(`The message now is ${await contract.greet()}`);
   }
   ```
2. To execute the script, run:

   ```bash
   yarn hardhat deploy-zksync --script use-greeter.ts
   ```

   \
   The script will:

   * Retrieve the message from the contract by calling the `greet()` method.
   * Update the greeting message in the contract with the `setGreeting()` method.
   * Retrieve the message from the contract again.

   \
   You should see something like this:

   ```bash
   Running script to interact with contract Greeter
   The message is Hello there!
   Transaction to change the message is 0x12f16578A16DB0f47e9D61175a823ac214288Af
   The message now is Hello people!

   ✨  Done in 14.32s.
   ```

### Learn more <a href="#learn-more" id="learn-more"></a>

* To learn more about the ZKsync Hardhat plugins check out the [plugins documentation](/docs/tooling/hardhat-validium/guides/getting-started.md).
* If you want to know more about how to interact with ZKsync using Javascript, check out the [zksync-ethers Javascript SDK documentation](https://sdk.zksync.io/js/ethers).

Check the [installation guide](/docs/tooling/hardhat-validium/installation.md) for instructions!


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://validium.gitbook.io/docs/tooling/hardhat-validium/guides/getting-started.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
