Counter Smart Contract - Hardhat
Build & Deploy a Counter Contract on Kite AI using Hardhat
What is Hardhat?
Hardhat is a local development environment for Ethereum-style (EVM) blockchains. It lets you: • Compile, test, and deploy contracts from your machine. • Script deployments and verifications (great for CI/CD). • Fork networks locally, run a local node, and debug with stack traces and console logging. • Use a rich plugin ecosystem (ethers.js, Etherscan-style verification, gas reporters, coverage, etc.).
In this section, we will go over Hardhat workflow:
- Set up & Scaffold project
- Write contract
- Compile
- Configure network
- Deploy via script
- Interact via console/scripts
Prerequisites:
• Node.js 18+ and npm (or pnpm/yarn)
• A funded wallet (for Kite testnet/mainnet)
• MetaMask (optional - recommended for managing keys)
• Git (recommended)
1. Create a Hardhat Project:
Create and enter a new folder:
mkdir kite-counter-hardhat && cd kite-counter-hardhat
Initialize a Node project:
npm init -y
Install Hardhat and tooling:
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox dotenv
Scaffold a Hardhat project (choose “Create a TypeScript project” when prompted):
npx hardhat
This creates a hardhat.config.ts, sample tests, and a basic project structure.
2. Add Envrironment variable:
Create a .env file in the project root
touch.env
Put your secrets and Kite endpoints in it (replace placeholders):
Wallet private key (no 0x prefix or with 0x — Hardhat supports either):
PRIVATE_KEY=0xYOUR_PRIVATE_KEY_HERE
Kite AI network (testnet or mainnet) RPC:
KITE_RPC_URL=https://rpc-testnet.gokite.ai/
Chain ID (number):
KITE_CHAIN_ID=2368
KITE EXPLORER URL:
KITE_EXPLORER_BROWSER_URL=https://testnet.kitescan.ai/
.gitignore (ensure secrets aren’t committed):
node_modules
.env
cache
artifacts
typechain-types
3. Configure hardhat
Open hardhat.config.ts and replace with:
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import * as dotenv from "dotenv";
dotenv.config();
const PRIVATE_KEY = process.env.PRIVATE_KEY || "";
const KITE_RPC_URL = process.env.KITE_RPC_URL || "";
const KITE_CHAIN_ID = process.env.KITE_CHAIN_ID ? Number(process.env.KITE_CHAIN_ID) : undefined;
const config: HardhatUserConfig = {
solidity: {
version: "0.8.20",
settings: { optimizer: { enabled: true, runs: 200 } },
},
networks: {
// Rename to "kite" or "kiteMainnet" as you prefer
kiteTestnet: {
url: KITE_RPC_URL,
chainId: KITE_CHAIN_ID,
accounts: PRIVATE_KEY ? [PRIVATE_KEY] : [],
},
},
// Optional: If Kite explorer is Etherscan-compatible, enable this
etherscan: {
apiKey: {
kiteTestnet: process.env.EXPLORER_API_KEY || "",
},
customChains: [
{
network: "kiteTestnet",
chainId: KITE_CHAIN_ID || 0,
urls: {
apiURL: process.env.KITE_EXPLORER_API_URL || "",
browserURL: process.env.KITE_EXPLORER_BROWSER_URL || "",
},
},
],
},
};
export default config;
4. Write the Counter Contract
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract Counter {
uint256 public count;
function increment() public {
count += 1;
}
function decrement() public {
require(count > 0, "Counter cannot be negative");
count -= 1;
}
function getCount() public view returns (uint256) {
return count;
}
}
5. Compile
npx hardhat compile
6. Write a Deployment Script
Create scripts/deploy.ts:
import { ethers } from "hardhat";
async function main() {
const Counter = await ethers.getContractFactory("Counter");
const counter = await Counter.deploy();
await counter.waitForDeployment();
const address = await counter.getAddress();
console.log("Counter deployed to:", address);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
7. Fund Your Deployer & Add the Network (MetaMask)
- Add the Kite AI network to MetaMask using the same RPC URL and Chain ID you placed in .env.
- Fund the deployer address with KITE (or test KITE on testnet) to cover gas.
- Ensure the private key in .env matches the funded account.
8. Deploy to Kite AI
npx hardhat run scripts/deploy.ts --network kiteTestnet
Output example: Counter deployed to: 0xABCDEF1234567890abcdef1234567890ABCDEF12
Important - Copy and save this address on your notepad.
9. Verify if deployment went through successfully
- VIsit the explorer site - https://testnet.kitescan.ai/
- Copy and paste the deplotment contract from previous step on the search bar
- Look up the deployer details ( your public key) and contract details on the results page.
10. Troubleshooting
• Insufficient funds for gas * price + value - Fund your deployer wallet with KITE (or test KITE).
• Invalid sender / nonce too low - Reset your account nonce in MetaMask or wait for pending txs to clear; you can also specify a higher nonce manually.
• Unsupported chainId - Ensure KITE_CHAIN_ID in .env matches the network’s actual chain ID.
• No PRIVATE_KEY set - Add PRIVATE_KEY to .env and restart your command.
11. Security & Best Practices
• Never commit secrets (.env in .gitignore).
• Use a deployment-only wallet with limited funds.
• For teams, consider multi-sig for production keys and use a deployer bot with restricted permissions.
• Pin exact versions in package.json to ensure reproducibility.
• Keep compiler optimizations consistent across environments.
If you wish to integrate this deployed contract to a front-end with a user interface, visit the below link and follow the steps:
https://docs.gokite.ai/blockchain-development/sample-dapps-built-on-kite/counter-dapp
Last updated