# Quick Start

This guide shows you how to deploy and interact with a smart contract on ZuluPrime Testnet in less than 5 minutes.

&#x20;So&#x20;

> ZuluPrime is leveraging power of  [ZKStack](https://zkstack.io/) , which leverages the underlying technology of zkSync. **Building on ZuluPrime shares the same process of building on zkSync. You guys can easily migrate all all develop stack from zksync-era to ZuluPrime.** We recommend you to refer to the [documentation of zkSync](https://docs.zksync.io/build/) for more detailed information:

TL

This is what we're going to do:

* Fund your wallet with Testnet ZULU in [discord](https://discord.gg/ZVaQPjhxTG) .
* Use [zksync-cli](https://docs.zksync.io/build/tooling/zksync-cli/getting-started.html) to scaffold a new project.
* Build a smart contract that stores a greeting message and deploy it to ZuluPrime testnet.
* Run a script to retrieve and update the greeting message using [zksync-ethers](https://docs.zksync.io/build/sdks/js/getting-started.html).

### Prerequisites <a href="#prerequisites" id="prerequisites"></a>

* Make sure your machine satisfies the [system requirements](https://github.com/matter-labs/era-compiler-solidity/tree/main#system-requirements).
* Download and install [Node.js](https://nodejs.org/en/download).
* Use the `yarn` or `npm` package manager. We recommend using `yarn`. To install `yarn`, follow the [Yarn installation guide](https://yarnpkg.com/getting-started/install).
* Learn how to [get your private key from your Metamask wallet](https://support.metamask.io/hc/en-us/articles/360015289632-How-to-export-an-account-s-private-key) as we'll use it to deploy a contract.

### Create the project

Run the following command in your terminal to create a new project using zkSync CLI.

```
npx zksync-cli create hello-zksync
```

It will give you options for different types of projects but for this tutorial choose the the following:

```
? What type of project do you want to create? Contracts
? Template: Hardhat + Solidity
? Private key of the wallet responsible for deploying contracts (optional) ***************************************************
? Package manager: yarn
```

#### Project Structure

The project structure is pretty straight forward:

* `hardhat.config.ts` contains the general configuration for Hardhat and the zkSync plugins, which are already imported and setup.
* `/contracts` contains smart contracts. `zksync-cli` provides common examples like an ERC20, an NFT, and the Greeter contract that we'll use later on.
* `/deploy` contains the deployment scripts.

For this tutorial we'll focus on the `/contracts/Greeter.sol` contract:

```
//SPDX-License-Identifier: Unlicense
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;
    }
}
```

As you can see, it a simple Solidity contract with two methods to read a message, `greet()`, and modify it, `setGreeting()`.

On more thing needs to mention is  `hardhat.config.js`. As ZuluPrime is a Bitcoin Layer2, so the network in config will be little different. A demo as below:

```
import { HardhatUserConfig } from "hardhat/config";

import "@matterlabs/hardhat-zksync-node";
import "@matterlabs/hardhat-zksync-deploy";
import "@matterlabs/hardhat-zksync-solc";
import "@matterlabs/hardhat-zksync-verify";

const config: HardhatUserConfig = {
  // defaultNetwork: "dockerizedNode",
  defaultNetwork: "ZuluTestnet",
  networks: {
    ZuluTestnet: {
      url: "https://rpc-testnet.zulunetwork.io",
      ethNetwork: "", // NOTE: As ZULU is a bitcoin Layer2, so this param should be empty.
      zksync: true,
    },
    hardhat: {
      zksync: true,
    },
  },
  zksolc: {
    version: "latest",
    settings: {
      // find all available options in the official documentation
      // https://era.zksync.io/docs/tools/hardhat/hardhat-zksync-solc.html#configuration
    },
  },
  solidity: {
    version: "0.8.20",
  },
};

export default config;
```

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

Smart contracts deployed to ZuluPrime must be compiled using our custom compilers:

* `zksolc` for Solidity contracts.
* `zkvyper` for Vyper contracts.

As this is a Solidity project, it already has the `hardhat-zksync-solc` plugin installed and configured so there's nothing you need to setup. To compile the contracts in the project, run the following command:

```bash
yarn compile
# or
npm run compile
```

You'll get the following output:

```
Compiling contracts for zkSync Era with zksolc v1.3.21 and solc v0.8.17
Compiling 46 Solidity files
Successfully compiled 46 Solidity files
✨  Done in 21.55s.
```

The compiled artifacts will be located in the `/artifacts-zk` folder. These artifacts are similar to the ones generated by the Solidity compiler. For example, the ABI of the Greeter contract will be located in `/artifacts-zk/contracts/Greeter.sol/Greeter.json`.

The configuration for the `zksolc` compiler is located in the `zksolc` section of the `hardhat.config.ts` file. You can find more info about the compiler settings in the [hardhat-zksync-solc plugin](https://docs.zksync.io/build/tooling/hardhat/hardhat-zksync-solc.html) and the [compiler section](https://docs.zksync.io/zk-stack/components/compiler/specification/overview.html) of the ZK Stack documentation.

### Deploy and verify <a href="#deploy-and-verify" id="deploy-and-verify"></a>

The project also contains a script to deploy and verify the contract in `/deploy/deploy.ts`. Under the hood, this script uses `hardhat-zksync-deploy` and `hardhat-zksync-verify` for deployment and contract verification.

```
import { deployContract } from "./utils";

// An example of a basic deploy script
// It will deploy a Greeter contract to selected network
// as well as verify it on Block Explorer if possible for the network
export default async function () {
  const contractArtifactName = "Greeter";
  const constructorArguments = ["Hi there!"];
  await deployContract(contractArtifactName, constructorArguments);
}
```

To execute it, just run:

```
yarn deploy
# or
npm run deploy
```

You'll get the following output:

```
Starting deployment process of "Greeter"...
Estimated deployment cost: 0.0000648863 ETH

"Greeter" was successfully deployed:
 - Contract address: 0x0BaF96A7f137B05d0D35b76d59B16c86C1791D8D
 - Contract source: contracts/Greeter.sol:Greeter
 - Encoded constructor arguments: 0x000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000094869207468657265210000000000000000000000000000000000000000000000

Requesting contract verification...
Your verification ID is: 1781
```

Congratulations! You just deployed a smart contract to ZuluPrime testnet. You can find it in the [ZuluPrime Explorer ](https://testnet.zuluscan.io/)by searching the contract address.

In addition, the deployment script verified the contract automatically so you can see the source code in the contract tab of the block explorer.

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

The project also comes with a script to interact with the contract in `/deploy/interact.ts`. Add the address of the Greeter contract you just deployed in the `CONTRACT_ADDRESS` variable inside the `/deploy/interact.ts` file:

```
import * as hre from "hardhat";
import { getWallet } from "./utils";
import { ethers } from "ethers";

// Address of the contract to interact with
const CONTRACT_ADDRESS = "";
if (!CONTRACT_ADDRESS) throw "⛔️ Provide address of the contract to interact with!";

// An example of a script to interact with the contract
export default async function () {
  console.log(`Running script to interact with contract ${CONTRACT_ADDRESS}`);

  // Load compiled contract info
  const contractArtifact = await hre.artifacts.readArtifact("Greeter");

  // Initialize contract instance for interaction
  const contract = new ethers.Contract(
    CONTRACT_ADDRESS,
    contractArtifact.abi,
    getWallet() // Interact with the contract on behalf of this wallet
  );

  // Run contract read function
  const response = await contract.greet();
  console.log(`Current message is: ${response}`);

  // Run contract write function
  const transaction = await contract.setGreeting("Hello people!");
  console.log(`Transaction hash of setting new message: ${transaction.hash}`);

  // Wait until transaction is processed
  await transaction.wait();

  // Read message after transaction
  console.log(`The message now is: ${await contract.greet()}`);
}
```

As you can see, we're simply using `ethers` to interact with our contract. zkSync is EVM compatible so you can use existing tools and libraries like `Hardhat`, `ethers`, `web3.js`, and users can use their existing wallets like Metamask, Rabby or Zerion.

To execute the `/deploy/interact.ts` script, run:

```
yarn interact
# or
npm run interact
```

You'll get the following output:

```
Running script to interact with contract 0x0BaF96A7f137B05d0D35b76d59B16c86C1791D8D
Current message is: Hi there!
Transaction hash of setting new message: 0x7a534857cfcd6df7e3eaf40a79a2c88f2e36bb60ce6f2399345e5431362b04eb
The message now is: Hello people!
✨  Done in 4.13s.
```

Congratulations! You've retrieved and updated the message on the `Greeter` contract. You can see the transaction in the [block explorer](https://testnet.zuluscan.io/%E3%80%91) by searching the transaction hash.

### Reference

* <https://zkstack.io/>
* <https://docs.zksync.io/build/>
