# 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/>


---

# 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://docs.zulunetwork.io/zulu-evm-layer/deploy-your-dapp/quick-start.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.
