Deploy with HardHat
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.
npm install -g yarn
Deployment of your smart contract on a Quai Network chain requires:
- Sufficient balance in the address that you are deploying with.
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.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.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
. 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.
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
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.To deploy
Greeter.sol
to the network of your choice, run:$ npx hardhat run scripts/deploy.js
Which should output:
Greeter deployed to: 0xFFbD605Ef5E637E056C0C2650D6FA05AAdB3652e
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.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.
Last modified 1mo ago