Skip to main content

Single-Chain Deployment Tutorial

Introduction

This article shows how to deploy a simple smart contract using Hardhat on any of Quai Network's 9 chains. This tutorial covers deploying a simple, non SolidityX based smart contract to a single chain within Quai Network. For more complex deployments involving SolidityX or multi-chain deployments, visit the Multi-Chain Deploy Tutorial page.

warning

If you want to skip basic environment setup for contract deployment, the hardhat-example repository provides a pre-configured environment for deploying smart contracts on Quai Network. Clone the repository on your local machine to get started.

Prerequisites

NodeJS

To use Hardhat, you'll need the LTS version of nodejs. NodeJS bundles npm and npx.

Hardhat also supports yarn usage.

Hardhat

Hardhat is an EVM development environment for professionals written in TypeScript. It is useful for performing frequent tasks such as running tests, automatically checking code for mistakes, or interacting with a smart contract.

Quai Network and Solidity

It is useful to have basic knowledge of both Quai Network and Solidity. Quai Network utilizes a modified version of Solidity named SolidityX that provides support for additional opcodes.

Deployment of a smart contract on a Quai Network chain requires:

  • An active instance of a Quai Network node or a remote node's RPC endpoint.
  • Sufficient balance in the address that you are deploying with.

Environment Setup

Initialize Hardhat

Hardhat is utilized through a local installation within individual project directories. Start by creating an npm project.

warning

For the purposed of this simplified tutorial, we'll be installing the generic version of Solidity that does not support cross-chain capabilities. If you're interested in deploying a contract that utilizes SolidityX's cross-chain capabilities, visit the Multi-Chain Smart Contract Tutorial.

mkdir deploy-simple-quai-contract
cd deploy-simple-quai-contract
npm init -y

Running npm init will prompt you to name your project and configure a few other variables.

Install Hardhat by running:

npm install --save-dev hardhat

Install dependencies:

npm install dotenv quais quais-polling quai-hardhat-plugin

Initialize the Hardhat development process using:

npx hardhat

After running this command, Hardhat will output a number of options below:

888    888                      888 888               888
888 888 888 888 888
888 888 888 888 888
8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888
888 888 "88b 888P" d88" 888 888 "88b "88b 888
888 888 .d888888 888 888 888 888 888 .d888888 888
888 888 888 888 888 Y88b 888 888 888 888 888 Y88b.
888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888

Welcome to Hardhat v2.17.2

? What do you want to do? …
❯ Create a Javascript project
Create a TypeScript project
Create an empty hardhat.config.js
Quit

For this article, we will select the Create a Javascript project option. This will provide you with a preset basic Hardhat project structure with simple smart contracts, tests, and example scripts written in Javascript.

info

Selecting this option allows you to automatically install @nomicfoundation/hardhat-toolbox.

Smart Contracts

The Create a Javascript project setup option provides a sample contract named Lock.sol. In this tutorial, we're going to deploy a simpler contract example named Greeter.sol.

In the contracts folder, create a file named Greeter.sol and paste the following code into it.

Greeter.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.9;

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;
}
}

The Greeter.sol contract allows the deployer to initialize a contract with a greeting stored on-chain, retrieve the greeting string, and change the greeting as needed.

Environment Variables

To prevent committing your private keys or RPC endpoints, create an environment file to securely store variables. Ensure that .env is in your .gitignore.

Use the following command to create an environment file:

touch .env

After creating the .env file, paste the following code into it.

.env
## Sample environment file - change all values as needed

# Privkey
PRIVKEY="0x0000000000000000000000000000000000000000000000000000000000000000"

# RPC
RPCURL="http://localhost:8610" # local node cyprus1 URL

Information on endpoints can be found in the local network specifications section for local nodes and the testnet specifications section for remote nodes.

After providing a private key and a desired RPC URL, we're now ready to securely consume them inside of hardhat.config.js.

Hardhat Configuration

Hardhat uses hardhat.config.js to configure smart contract deployments. The config file allows you to define deployment networks, tasks, compilers, etc.

Paste the following code into your hardhat.config.js file to configure deployments to either the colosseum, garden, or local networks.

hardhat.config.js
/**
* @type import('hardhat/config').HardhatUserConfig
*/

require('@nomicfoundation/hardhat-toolbox');

const dotenv = require('dotenv');
dotenv.config({ path: '.env' });

module.exports = {
defaultNetwork: 'colosseum',
networks: {
// testnet
colosseum: {
url: `${process.env.RPCURL}`,
accounts: [process.env.PRIVKEY],
chainId: 9000, // colosseum chainId
},
// devnet
garden: {
url: `${process.env.RPCURL}`,
accounts: [process.env.PRIVKEY],
chainId: 12000, // garden chainId
},

// local
local: {
url: `${process.env.RPCURL}`,
accounts: [process.env.PRIVKEY],
chainId: 1337, // local chainId
},
},

// include compiler version defined in your smart contract
solidity: {
compilers: [
{
version: '0.8.9',
},
],
},

paths: {
sources: './contracts',
cache: './cache',
artifacts: './artifacts',
},
mocha: {
timeout: 20000,
},
};

Deploy

Compile with Hardhat

Smart contract compilation with Hardhat is simple and can be done using npx in the CLI.

Compile the Greeter.sol contract using:

npx hardhat compile

Which should output:

Downloading compiler 0.8.9

Compiled 1 Solidity file successfully

Add Deployment Script

The Hardhat sample project has a pre-made deployment script named deploy.js in the scripts directory. Copy the following into the deploy.js file.

deploy.js
const hre = require('hardhat');
const quais = require('quais');
const { pollFor } = require('quais-polling');
const GreeterJson = require('../artifacts/contracts/Greeter.sol/Greeter.json');

async function main() {
const quaisProvider = new quais.providers.JsonRpcProvider(hre.network.config.url);
const walletWithProvider = new quais.Wallet(hre.network.config.accounts[0], quaisProvider);
await quaisProvider.ready;

const QuaisContract = new quais.ContractFactory(GreeterJson.abi, GreeterJson.bytecode, walletWithProvider);
const quaisContract = await QuaisContract.deploy('Hello Quai', {
gasLimit: 1000000,
});

// Use quais-polling to wait for contract to be deployed
const deployReceipt = await pollFor(
quaisProvider, // provider passed to poller
'getTransactionReceipt', // method to call on provider
[quaisContract.deployTransaction.hash], // params to pass to method
1.5, // initial polling interval in seconds
1 // request timeout in seconds
);
console.log('Contract deployed to address: ', deployReceipt.contractAddress);
}

main()
.then(() => process.exit(0))
.catch(error => {
console.error(error);
process.exit(1);
});

Using deploy.js, we can set the initial greeting and log out the contract address upon deployment. Scripts can be used to automate many different functions other than deployment.

Deploy Your Contract

To deploy Greeter.sol to the local network set in your hardhat.config.js, run:

npx hardhat run scripts/deploy.js --network local

Which should output:

Found address 0x0f12d55D09D5E53DB2941a6119d27aa83cFD11f7 on shard zone-0-0 for shard zone-0-0
Contract deployed to address: 0x13d8c5fc0AB5A87870353f3C0409c102f2a772A9

Congratulations, you've now deployed a simple smart contract to Quai Network!

Interact with a Smart Contract

Hardhat console does not currently offer support for interaction with smart contracts on Quai Network. In order to interact with your smart contract, you'll need to utilize the the client JSON RPC or quais.js library, which functions similar to ethers.js.

Summary

Now you have all the tools you need to launch a local instance of Quai Network, create a simple Hardhat project, deploy, and interact with your own smart contracts.