100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Deploying to Testnets and Mainnet

A practical guide to deploying Solidity contracts with Hardhat: configuring networks and keys, understanding gas and nonces, waiting for confirmations, and verifying source on Etherscan.

Practical SolidityIntermediate10 min readJul 10, 2026
Analogies

From Local Network to Public Chains

During development your contracts run on Hardhat's local in-memory network, but eventually they must live on a real blockchain. Public testnets such as Sepolia mimic Ethereum mainnet's rules and clients but use valueless test ETH obtained from faucets, letting you rehearse deployment, integration with wallets like MetaMask, and interaction with real oracle or token infrastructure at zero financial cost. Mainnet is the production network where transactions cost real ETH and state is permanent, so you deploy there only after your contract is tested, audited, and verified to behave correctly on a testnet first.

🏏

Cricket analogy: It's like a warm-up tour match against a local side before the actual Test series, same format and rules, but the result does not count, letting the team rehearse conditions risk-free.

Configuring Networks and Deployment Scripts

You register each target chain in the networks section of hardhat.config.js, giving it an RPC endpoint URL (from a node provider such as Alchemy or Infura) and the account(s) that will pay for and sign the deployment. Critically, the deployer's private key must never be hard-coded; it is loaded from an environment variable via a package like dotenv, and the .env file is git-ignored. A deployment script uses ethers.getContractFactory(...) and .deploy(...) exactly as in tests, then awaits contract.waitForDeployment() before printing the resulting on-chain address.

🏏

Cricket analogy: It's like a captain sealing the team sheet in a locker rather than reading it aloud, because the private key is your signing authority and must stay hidden from opponents.

javascript
// hardhat.config.js
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();

module.exports = {
  solidity: "0.8.24",
  networks: {
    sepolia: {
      url: process.env.SEPOLIA_RPC_URL,        // e.g. Alchemy / Infura endpoint
      accounts: [process.env.DEPLOYER_PRIVATE_KEY],
    },
  },
  etherscan: {
    apiKey: process.env.ETHERSCAN_API_KEY,
  },
};

// scripts/deploy.js
const { ethers } = require("hardhat");

async function main() {
  const Token = await ethers.getContractFactory("MyToken");
  const token = await Token.deploy(1_000_000n);   // constructor arg: initial supply
  await token.waitForDeployment();
  console.log("Deployed to:", await token.getAddress());
}

main().catch((e) => { console.error(e); process.exitCode = 1; });

// Run: npx hardhat run scripts/deploy.js --network sepolia

Gas, Nonces, and Confirmations

Every account has a nonce, a counter of how many transactions it has sent, and each deployment consumes the next sequential nonce; if a transaction with a lower nonce is stuck, later ones queue behind it. Since EIP-1559, a transaction's fee is a base fee (burned, set by network congestion) plus a priority tip to the validator, and you can cap total spend with a max fee. After sending, you await tx.wait(confirmations) to wait until the transaction is mined and buried under enough blocks that a chain reorganization is extremely unlikely before treating the deployment as final.

🏏

Cricket analogy: It's like deliveries in an over bowled in strict sequence, where ball four cannot precede ball three, and you await the third-umpire confirmation before the wicket is truly final.

Never commit a real private key or seed phrase to a repository, even a private one. A leaked deployer key lets anyone drain that account and, if it owns your contracts, seize privileged functions. Load keys from git-ignored environment variables, and for mainnet use a hardware wallet or a dedicated deployer account holding only the ETH needed for gas.

Verifying Source Code on Etherscan

Verifying your contract on a block explorer like Etherscan uploads your Solidity source and compiler settings so the explorer can recompile it and confirm the bytecode matches what is deployed. Verification does not change the contract; it makes it transparent, letting anyone read the exact code, use Etherscan's Read/Write Contract tabs, and trust that the deployed bytecode corresponds to auditable source. With hardhat-verify you run npx hardhat verify --network sepolia <address> <constructorArgs>, and matching constructor arguments and the exact compiler version are essential for the match to succeed.

🏏

Cricket analogy: It's like publishing the full ball-by-ball scorecard so any fan can independently confirm the final total, making the contract's inner workings auditable to everyone.

Testnet ETH has no monetary value and is dispensed free by rate-limited faucets (for example a Sepolia faucet), so deploy and test efficiently. A contract's address on a testnet is independent of mainnet, and redeploying the same code to mainnet produces a brand-new address.

  • Deploy to a public testnet like Sepolia first, using free faucet ETH, before spending real value on mainnet.
  • Networks are configured in hardhat.config.js with an RPC URL (Alchemy/Infura) and signing accounts.
  • Private keys must be loaded from git-ignored environment variables, never hard-coded in source.
  • EIP-1559 fees are a burned base fee plus a priority tip; nonces order an account's transactions sequentially.
  • Wait for enough confirmations with tx.wait so a reorg cannot undo the deployment before treating it as final.
  • Verifying source on Etherscan recompiles and matches bytecode, making the contract transparent and auditable.
  • Verification requires matching constructor arguments and the exact compiler version used at deployment.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#SolidityStudyNotes#DeployingToTestnetsAndMainnet#Deploying#Testnets#Mainnet#Local#StudyNotes#SkillVeris#ExamPrep