Skip to main content

Introduction

This article shows how to deploy a Solidity smart contract using Hardhat on any of Quai Network’s chains.

Prerequisites

To deploy single chain smart contracts on Quai, we’ll need a few tool-kits and dependencies. Here’s an overview of all of the dependencies we’ll be using:

Environment Setup

Install Example Repository

Start by cloning the hardhat-example repository, navigating to the Solidity directory we’ll be using for this tutorial, and installing the dependencies via npm.

Smart Contracts

The Solidity/ directory comes with 2 sample contracts: ERC20.sol and ERC721.sol inside of the contracts/ directory. Both contracts are implementations derived from the Open Zeppelin library. We’ll be using the ERC20.sol sample contract for this tutorial, but you can also add your own contracts or use contracts from other libraries.
The Quai Network EVM supports Solidity versions up to 0.8.20. Using a newer version of Solidity may result in errors when deploying smart contracts.

Environment Variables

We’ve included a sample environment file, .env.dist, file at the root of the hardhat-example repo to manage token details, private keys, and your RPC URL in a secure fashion.
The .env.dist file is a template file and should not be used as is. You should copy the .env.dist file to a new .env file.This file lives at the root of the hardhat-example repository and serves as the config file for the Solidity/ directory.
Copy the .env.dist file in the root to a new .env file in the repository root using the following command:
Open the .env file and add your private key, RPC URL, and token args for the contract you’d like to deploy. The .env file should look like this:
.env
The sample .env.dist targets Orchard testnet so you can deploy without spending real QUAI. To deploy to mainnet, change CHAIN_ID to 9 and RPC_URL to https://rpc.quai.network.
Further information on RPC endpoints can be found on the Networks page. The hardhat-example repository uses the Quais SDK to configure network connections using only a single RPC URL. To learn more about how the SDK configures network providers, visit the SDK provider examples section. After filling in your private key and RPC URL, we’re now ready to securely consume them inside of hardhat.config.js.

Hardhat Configuration

Hardhat uses a hardhat.config.js file to configure smart contract deployments. The config file allows you to define deployment networks, tasks, compilers, etc. hardhat-example contains a prebuilt hardhat.config.js file with configuration for deploying and verifying smart contracts on Cyprus-1.
This sample configuration file is provided as part of the hardhat-example repository.
hardhat.config.js
Cyprus-1 is currently the only active zone on Quai Network, so the sample config defines a single cyprus1 network. See Networks for the full list of zone endpoints.
The metadata.bytecodeHash: 'ipfs' and useLiteralContent: true compiler settings are required for @quai/hardhat-deploy-metadata to produce verifiable output. Removing them will break Quaiscan verification.
When deploying a contract, hardhat.config.js pulls your private key and RPC URL from the .env file. You can also specify the Solidity version and compiler settings in the solidity object.

Deploy and Interact

1

Compile with Hardhat

Smart contract compilation with Hardhat is simple and can be done using npx in the CLI.Compile all of the contracts inside the contracts/ directory with:
Which should output:
2

Configure deployment scripts

Inside the scripts/ directory, you’ll find a deploy script for both the ERC20 and ERC721 contracts: deployERC20.js and deployERC721.js. For this tutorial, we’ll be deploying an ERC20 contract.The deployERC20.js script pulls your network configuration from hardhat.config.js and your token arguments from the .env file at the root of the repository and uses them to deploy your contract.Token arguments are consumed via the tokenArgs array:
Before the contract is deployed, the script uses the @quai/hardhat-deploy-metadata plugin to push the compiled contract’s metadata to IPFS and returns the resulting CID:
The CID is then passed as the fourth argument to ContractFactory, which embeds it in the deployed bytecode. Quaiscan reads that CID later to fetch your source for verification — without it, the contract can be deployed but not verified.
We’ll use these ideas to properly modify the token args and network specification to deploy our contract in the next step.
The deployERC721.js script follows the same structure with different contract arguments and a different ABI/bytecode. You can replicate this configuration for any contract you’d like to deploy.
3

Deploy your contract

The deploy script takes in a --network flag to specify the network you’d like to deploy to. The sample config only defines cyprus1, which we’ll use here.
Which should output:
The CID printed in the first line is the IPFS hash you’ll need to verify the contract on Quaiscan — save it.Congratulations, you’ve now deployed an ERC20 token to Quai Network!
The ERC20.sol and ERC721.sol sample contracts are basic implementations of each token for example purposes. It is highly recommended to modify these contracts to fit your specific use case before deploying them for any production use.
4

Interact with the contract

Hardhat console does not currently offer support for interaction with smart contracts on Quai Network.To interact with the contract, you can configure a simple script using the Quais SDK. The script below configures a Contract instance for the ERC20 token we deployed to 0x00735E9B2c731Fd3eCC8129a3653ACb99dF969cC to get the name, symbol, and total supply of the token.
getContractDetails.js

Summary

Now you have all the tools you need to create a simple Hardhat project, deploy, and interact with your own smart contracts. Because the deploy script pushed your contract’s metadata to IPFS, you can now verify it on Quaiscan — see Verifying Contract on Quaiscan for the next step.