Links

Deploy with HardHat

Introduction

This article shows how to deploy and interact with smart contracts using Hardhat on any of Quai Network's 13 chains.
Hardhat is an Ethereum 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.
Hardhat also supports combined Solidity and JavaScript stack traces, which allows for a streamlined deployment and debugging process.

Prerequisites

NodeJS

First, install the LTS version of nodejs. NodeJS bundles npm and npx.
Hardhat also supports yarn usage. To install yarn use:
npm install -g yarn

Quai Network and Solidity

It is useful to have basic knowledge of both Quai Network and Solidity.
Deployment of your smart contract on a Quai Network chain requires:
  • An active instance of a Quai Network full node or a remote node's RPC endpoint.
  • An instance of the Quai Manager (if you are deploying locally).
  • Sufficient balance in the address that you are deploying with.

Initialize Hardhat

Hardhat is utilized through a local installation within individual project directories. Start by creating an npm project.
cd path/to/directory
npm init
Install Hardhat by running:
npm install --save-dev hardhat
Install dependencies:
npm install dotenv
Initialize the Hardhat development process using:
npx hardhat
After running this command, Hardhat will output a number of options below:
$ npx hardhat
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.0.8
? 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.
Note that selecting this option allows you to automatically install @nomiclabs/hardhat-toolbox. This toolbox contains @nomiclabs/hardhat-ethers and @nomiclabs/hardhat-waffle which are useful for this tutorial.

Project Configuration

Smart Contracts

The Create a Javascript project setup option provides a sample contract named Greeter.sol which can be seen below.
Greeter.sol
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
import "hardhat/console.sol";
contract Greeter {
string private greeting;
constructor(string memory _greeting) {
console.log("Deploying a Greeter with greeting:", _greeting);
greeting = _greeting;
}
function greet() public view returns (string memory) {
return greeting;
}
function setGreeting(string memory _greeting) public {
console.log("Changing greeting from '%s' to '%s'", greeting, _greeting);
greeting = _greeting;
}
}
The Greeter.sol contract allows the deployer to set a greeting string, deploy the contract, and later either change or return the set greeting. You can also add your own contracts.

Environment Variable Setup

To prevent committing your private keys or RPC endpoints, create an environment file to securely store variables.
touch process.env
Set up your process.env like this:
process.env
#Localhost URL with chain specific port
ROPSTEN_URL="http://127.0.0.1:PORT"
#Remote node endpoint or Localhost url with port for a locally hosted node
MAINNET_RPC_URL="https://quai.node.endpoint.io"
#Ropsten address private key
ROPSTEN_PRIVATE_KEY="0x..."
#Mainnet address private key
MAINNET_PRIVATE_KEY="0x..."
A list of all Quai chains with their associated port can be found here for use in defining both the ROPSTEN_RPC_URL and MAINNET_RPC_URL. Private keys should be exported from MetaMask Flask.
Make sure to include process.env in the .gitignore file when committing to a remote repository. After providing your private keys and RPC URLs, we're now ready to securely consume them inside of hardhat.config.js.

Hardhat Config

Similar to Truffle, Hardhat uses hardhat.config.js as the configuration file. 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 quaitestnet or a local instance of Quai ropsten.
hardhat.config.js
/**
* @type import('hardhat/config').HardhatUserConfig
*/
require("@nomiclabs/hardhat-ethers");
require("@nomiclabs/hardhat-waffle");
const dotenv = require("dotenv");
dotenv.config({ path: "process.env" });
const {
ROPSTEN_RPC_URL,
MAINNET_RPC_URL,
ROPSTEN_PRIVATE_KEY,
MAINNET_PRIVATE_KEY,
} = process.env; // consume priv/pub keys and RPC URLs from process.env
module.exports = {
defaultNetwork: "ropsten",
networks: {
// quaitestnet is the default quai network during the entire development phase.
quaitestnet: {
url: MAINNET_RPC_URL,
accounts: [MAINNET_PRIVATE_KEY],
chainId: 994, // Mainnet (technically testnet right now) chainId
websocket: true,
gas: 2000000, // gas limit used for deploys. This is an arbitrary value, accurate gas estimates must be obtained for deployments.
},
// ropsten is a locally ran testnet of all 13 of the quai network blockchains.
ropsten: {
url: ROPSTEN_RPC_URL,
accounts: [ROPSTEN_PRIVATE_KEY],
chainId: 3, // Ropsten chainId
websocket: true,
gas: 2000000, // gas limit used for deploys. This is an arbitrary value, accurate gas estimates must be obtained for deployments.
},
},
// include compiler version defined in your smart contract
solidity: {
compilers: [
{
version: "0.8.0",
},
],
},
paths: {
sources: "./contracts",
cache: "./cache",
artifacts: "./artifacts",
},
mocha: {
timeout: 200000,
},
};
Note that you may have to alter the gas value depending on the chain and the solc compiler based on the version defined inside of your smart contract.

Deploying Your Contract

Compile with Hardhat

Smart contract compilation with Hardhat is simple and can be done using npx in the CLI. Support for older solc compilers can be found here.
$ npx hardhat compile
Compiling...
Compiled 1 contract successfully

Add Deployment Script

The Hardhat sample project has a pre-made deployment script named sample-script in the scripts directory. We've gone ahead and renamed it to deploy.js.
deploy.js
async function main() {
// We get the contract to deploy
const Greeter = await ethers.getContractFactory("Greeter");
const greeter = await Greeter.deploy("Hello, Hardhat!");
await greeter.deployed();
console.log("Greeter deployed to:", greeter.address);
}
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 network of your choice, run:
$ npx hardhat run scripts/deploy.js
Which should output:
Greeter deployed to: 0xFFbD605Ef5E637E056C0C2650D6FA05AAdB3652e

Interact with Smart Contract

Hardhat has a developer console to interact with contracts and the network. For more information about Hardhat's console see here. Hardhat console is a NodeJS-REPL, and you can use different tools in it. ethers is the library that we'll use to interact with our network.
You can access the console using:
$ npx hardhat console --network ropsten
Welcome to Node.js v16.2.0.
Type ".help" for more information.
>
Define the deployed contract:
> let Greeter = await hre.ethers.getContractFactory("Greeter")
undefined
Specify the contract address:
> const greeter = await Greeter.attach("0xFFbD605Ef5E637E056C0C2650D6FA05AAdB3652e")
undefined
Change the greeting. It will output the transaction details associated with your call to change the greeting.
> (await greeter.setGreeting("Hello, Quai!"))
Print the greeting that you set above:
> (await greeter.greet()).toString()
'Hello, Quai!'
Hardhat also provides javascript based testing functionality for your smart contracts. This is typically done using the Mocha and Chai npm packages. More information on Hardhat's testing capabilities can be found here.

Summary

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