Hardhat
Install Hardhat, configure for Mandala, deploy a contract, verify on Blockscout.
Hardhat works against Mandala with two additions: a networks entry for the RPC, and an etherscan.customChains block for verification via Blockscout's Etherscan-compatible API.
Install
mkdir my-project && cd my-project
npm init -y
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox dotenv
npx hardhat initPick "Create a TypeScript project". Hardhat scaffolds contracts/, scripts/, test/, and hardhat.config.ts.
Configure
Replace hardhat.config.ts:
import "dotenv/config";
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
const config: HardhatUserConfig = {
solidity: "0.8.24",
networks: {
mandala: {
url: "https://rpc1-mainnet.mandalachain.io",
chainId: 20010,
accounts: [process.env.PRIVATE_KEY!],
},
mandalaTestnet: {
url: "https://rpc1-testnet.mandalachain.io",
chainId: 20011,
accounts: [process.env.PRIVATE_KEY!],
},
},
etherscan: {
apiKey: {
mandala: "empty",
mandalaTestnet: "empty",
},
customChains: [
{
network: "mandala",
chainId: 20010,
urls: {
apiURL: "https://explorer.mandalachain.io:443/api/",
browserURL: "https://explorer.mandalachain.io",
},
},
{
network: "mandalaTestnet",
chainId: 20011,
urls: {
apiURL: "https://explorer.testnet.mandalachain.io:443/api/",
browserURL: "https://explorer.testnet.mandalachain.io",
},
},
],
},
};
export default config;Blockscout exposes an Etherscan-compatible API; the "empty" string is required by hardhat-verify but Blockscout does not validate it.
Set PRIVATE_KEY in .env:
echo "PRIVATE_KEY=0xyour..." > .env
echo ".env" >> .gitignoreDeploy
A minimal deploy script at scripts/deploy.ts:
import { ethers } from "hardhat";
async function main() {
const counter = await ethers.deployContract("Counter");
await counter.waitForDeployment();
console.log("Counter deployed at:", await counter.getAddress());
}
main().catch((err) => {
console.error(err);
process.exit(1);
});Run it:
npx hardhat run scripts/deploy.ts --network mandalaTestnetThe script prints the contract address. Open it in explorer.testnet.mandalachain.io.
For larger deploys, Hardhat Ignition modules (in ignition/modules/) give you idempotent deployments with state tracking.
Verify
hardhat-toolbox already includes hardhat-verify. Run:
npx hardhat verify --network mandalaTestnet 0xYourAddressFor contracts with constructor arguments:
npx hardhat verify --network mandalaTestnet 0xYourAddress "0xConstructorArg" 42For contract collisions (multiple contracts with the same name), pass the fully-qualified contract path:
npx hardhat verify --network mandalaTestnet --contract contracts/Counter.sol:Counter 0xYourAddressAfter verification succeeds, the Code tab on the explorer shows your source.
Common errors
Error HH101: Hardhat was set to use chain id 20010, but connected to a chain with id .... Your RPC and config disagree. Verify Chain ID is 20010 (mainnet) or 20011 (testnet).
Error: insufficient funds for gas. Bridge KPG via the Arbitrum Portal or get KPGT for testnet.
Bytecode does not match during verification. Compiler version, optimizer runs, or EVM target mismatch. Make sure your local solidity settings match what was used at deploy time.
Already verified. Not an error. Blockscout sometimes reports this when the source matches an already-verified deployment of the same bytecode.

