← Course home Module 14 / 19 Blockchain — Part 2

Deployment & Layer 2

You can write, test, and secure smart contracts — but they are worthless until they live on a real network. This final module of Part 2 takes your contracts from localhost to the world: testnet deployment, mainnet checklists, Etherscan verification, and Layer 2 rollups that slash gas costs by 10-100x. By the end, you will have deployed to a real chain.

~75 min read Module 14 ⟠ Part 2
📌 Section 1

Recap: From Code to Chain

In Part 2 you have built a complete smart contract development workflow: Solidity fundamentals (Module 7), advanced Solidity patterns (Module 8), ERC-20 tokens (Module 9), professional tooling with Hardhat (Module 10), testing with viem in TypeScript (Module 11), DApp frontends with MetaMask + viem (Module 12), and security best practices (Module 13). Your contracts are written, tested, and audited. Now it is time to deploy them to real networks.

The Deployment Journey

Deployment is not a single step — it is a pipeline. You start on a local node (Hardhat Network) for rapid iteration. Then you deploy to a testnet (Sepolia) to validate in a real blockchain environment with free test ETH. After thorough testing and an audit, you go to mainnet — where every transaction costs real money. Finally, you may deploy to a Layer 2 chain to reduce costs for your users.

Deployment Pipeline

Stage
Network
Cost
Purpose
Development
Hardhat Network
Free
Rapid iteration, unit tests, debugging with console.log.
Staging
Sepolia Testnet
Free (faucet ETH)
Integration testing, frontend testing, real block times.
Production
Ethereum Mainnet
$5 — $50+ per TX
Real value, real users, immutable deployment.
Scaling
L2 (Arbitrum, Base...)
$0.01 — $0.50 per TX
Lower gas, faster finality, same Solidity code.
🏁

Part 2 Finale

This is the final module of Part 2. After this module, you will have every skill needed to go from an idea to a live, verified, cost-efficient smart contract. Part 3 will shift focus to permissioned blockchains (Hyperledger Fabric) and enterprise use cases.

🧪 Section 2

Testnet Deployment

Testnets are public blockchains that mirror mainnet behavior but use valueless ETH. They are your staging environment — deploy, test, break, and iterate without spending a cent. Sepolia is the recommended Ethereum testnet in 2024-2025.

Why Sepolia?

Sepolia is a proof-of-stake testnet with a small validator set, making it fast and stable. Unlike Goerli (deprecated), Sepolia has a controlled ETH supply so faucets can remain generous. All major tooling supports Sepolia: Hardhat, Foundry, Etherscan, Alchemy, Infura.

Getting Testnet ETH

You need test ETH to pay for gas. Use one of these faucets:

  • Alchemy Sepolia Faucet — requires a free Alchemy account. Reliable and fast.
  • Infura Sepolia Faucet — requires an Infura account. Good alternative.
  • Google Cloud Web3 Faucet — no account needed. Limited to 0.05 ETH per day.
💧

Faucets dispense small amounts (0.05-0.5 ETH). That is enough for dozens of deployments and hundreds of transactions.

Hardhat Configuration

Add Sepolia to your hardhat.config.js. You need an RPC endpoint (from Alchemy or Infura) and a deployer private key stored in a .env file.

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

module.exports = {
  solidity: "0.8.24",
  networks: {
    sepolia: {
      url: process.env.SEPOLIA_RPC_URL,
      accounts: [process.env.DEPLOYER_PRIVATE_KEY],
    },
  },
};

Environment Variables (.env)

.env Bash
# .env — NEVER commit this file!
SEPOLIA_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY
DEPLOYER_PRIVATE_KEY=0xabc123...your_private_key
⚠️

Never commit your .env file. Add it to .gitignore immediately. A leaked private key means all funds in that wallet are gone.

Deploy with Hardhat Ignition

Hardhat Ignition is the modern deployment system for Hardhat. You define deployment modules in JavaScript, and Ignition handles the execution, gas estimation, and transaction tracking.

ignition/modules/MyToken.js JavaScript
// ignition/modules/MyToken.js
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules");

module.exports = buildModule("MyToken", (m) => {
  const token = m.contract("MyToken", ["MyToken", "MTK", 1000000]);
  return { token };
});

Deploy to Sepolia with a single command:

Deploy to Sepolia Bash
npx hardhat ignition deploy ignition/modules/MyToken.js \
  --network sepolia

After Deployment

Hardhat Ignition saves the deployed addresses in ignition/deployments/. You can view your contract on sepolia.etherscan.io by pasting the contract address. At this point, the code is live but not verified — users see raw bytecode, not Solidity source.

✅ Section 3

Etherscan Verification

Verification means publishing your Solidity source code on Etherscan so anyone can read and audit it. Without verification, users see only opaque bytecode and have no way to trust your contract. A green checkmark on Etherscan signals transparency.

Why Verify?

  • Trust: Users can read the source code and confirm what the contract does.
  • Interaction: Etherscan generates a Read/Write interface so users can call functions directly from the browser.
  • Composability: Other developers can integrate with your contract by reading verified source and ABI.
  • Professional standard: Every serious project verifies. Unverified contracts are a red flag.

Get an Etherscan API Key

Create a free account at etherscan.io and generate an API key in your profile settings. Add it to your .env and Hardhat config.

hardhat.config.js JavaScript
// hardhat.config.js — add etherscan section
module.exports = {
  // ... networks config ...
  etherscan: {
    apiKey: process.env.ETHERSCAN_API_KEY,
  },
};

Verify with Hardhat

After deployment, run the verify command with the contract address and constructor arguments:

Verify command Bash
npx hardhat verify --network sepolia \
  0xYourContractAddress \
  "MyToken" "MTK" 1000000
🔑

Constructor arguments must match exactly what was passed during deployment — same order, same types, same values. If they do not match, verification fails.

Complex Constructor Arguments

For contracts with complex arguments (arrays, structs, addresses), create an arguments file:

arguments.js JavaScript
// arguments.js
module.exports = [
  "MyToken",
  "MTK",
  1000000,
  "0xOwnerAddress...",
];

// Then verify with:
// npx hardhat verify --network sepolia \
//   --constructor-args arguments.js 0xContractAddress

The Green Checkmark

Once verified, your contract page on Etherscan shows a green checkmark on the Contract tab. The source code is displayed, and Read/Write panels let anyone interact with your contract. This is the standard for transparency in the Ethereum ecosystem.

🚀 Section 4

Mainnet Deployment

Mainnet deployment is irreversible. Once deployed, the bytecode lives on Ethereum forever. There is no undo, no rollback, no delete. Every bug, every missing access control, every gas inefficiency is permanent. Mainnet demands preparation.

Pre-Deployment Checklist

  • All tests pass: 100% of unit tests and integration tests. No skipped tests. Run npx hardhat test and forge test one final time.
  • Security audit completed: At least one professional audit for contracts holding significant value. All critical and high findings resolved.
  • Gas budget estimated: Calculate deployment gas cost using hardhat-gas-reporter. Multiply by current gas price (check etherscan.io/gastracker). Have 2x the estimated cost ready.
  • Multi-sig ownership: Deploy from a hot wallet, then transfer ownership to a multi-sig (Gnosis Safe). Never leave a single private key as the owner of a production contract.
  • Emergency mechanisms: Include a pause function (OpenZeppelin Pausable) for critical contracts. Test it on testnet.
  • Documentation: NatSpec comments on every external function. Deployment addresses documented. User-facing documentation ready.

Pre-Deployment Simulation

Before spending real ETH, simulate the full deployment on a local mainnet fork. This catches issues with constructor arguments, gas limits, and contract interactions that only appear with real mainnet state.

Mainnet fork simulation Bash
# Fork mainnet locally
npx hardhat node --fork https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY

# In another terminal — deploy against the fork
npx hardhat ignition deploy ignition/modules/MyToken.js \
  --network localhost
🧬

A mainnet fork replicates the full Ethereum state locally. Your deployment runs against real token balances, real Uniswap pools, and real oracle prices — but without spending real ETH.

Deploy to Mainnet

Once your checklist is complete and the simulation succeeds, deploy for real. Add mainnet to your Hardhat config:

hardhat.config.js JavaScript
// hardhat.config.js
networks: {
  mainnet: {
    url: process.env.MAINNET_RPC_URL,
    accounts: [process.env.DEPLOYER_PRIVATE_KEY],
    gasPrice: "auto",
  },
}

// Deploy
// npx hardhat ignition deploy ignition/modules/MyToken.js \
//   --network mainnet

Post-Deployment Steps

  1. Verify on Etherscan — same process as testnet, use --network mainnet.
  2. Transfer ownership — move admin/owner role to a multi-sig wallet (Gnosis Safe).
  3. Monitor — set up alerts with OpenZeppelin Defender or Forta for unusual activity.
  4. Announce — publish the verified contract address in your documentation, Discord, and GitHub.
⚡ Section 5

Layer 2 Solutions

Ethereum mainnet is secure but expensive. A simple ERC-20 transfer costs $5-50 depending on network congestion. Complex DeFi transactions can exceed $100. Layer 2 (L2) solutions process transactions off the main chain while inheriting Ethereum's security, reducing costs by 10x to 100x.

Why Layer 2?

Ethereum processes ~15 transactions per second (TPS). During peak demand, gas prices spike and price out ordinary users. L2 chains batch hundreds of transactions into a single L1 transaction, amortizing the cost across all users. Result: same security, 100x cheaper.

Optimistic Rollups

Optimistic Rollups assume transactions are valid by default and only check them if someone submits a fraud proof during a challenge period (typically 7 days). This makes them fast and cheap, with full EVM compatibility.

Chain
Backed By
Key Feature
Optimism
OP Labs / Coinbase
OP Stack — open-source rollup framework. Powers the Superchain ecosystem.
Arbitrum
Offchain Labs
Largest L2 by TVL. Full Nitro stack with WASM fraud proofs.
Base
Coinbase
Built on OP Stack. Coinbase on-ramp integration. Fastest-growing L2.

ZK Rollups

ZK Rollups generate a cryptographic validity proof (zero-knowledge proof) for every batch of transactions. The L1 contract verifies the proof mathematically — no challenge period needed. Finality is faster, but generating proofs is computationally expensive.

Chain
Proof System
Key Feature
zkSync Era
zkSNARK
Native account abstraction. Solidity + Vyper support via zkEVM.
StarkNet
zkSTARK
Cairo language. No trusted setup. Highest theoretical throughput.
Polygon zkEVM
zkSNARK
Type-2 zkEVM — high EVM equivalence. Direct Solidity deployment.

Optimistic vs ZK — Comparison

Feature
Optimistic Rollups
ZK Rollups
Security model
Fraud proofs (7-day challenge)
Validity proofs (math guarantee)
Finality
~7 days (challenge period)
~Minutes (once proof posted)
EVM compatibility
Full (identical bytecode)
Varies (Type-1 to Type-4)
Gas cost
10-20x cheaper than L1
10-50x cheaper than L1
Maturity
Battle-tested (2021+)
Emerging (2023+)
🎯

For most projects today, Optimistic Rollups (Arbitrum, Base, Optimism) offer the best balance of EVM compatibility, tooling support, and cost savings. ZK Rollups are the future but still maturing in terms of developer experience.

🛠 Section 6

Deploying to L2

The best part of L2 deployment: your Solidity code does not change. The same contracts, the same tests, the same tooling — you only change the RPC URL and chain ID. If it works on Sepolia, it works on Arbitrum.

Configure an L2 Network

Add Arbitrum One and Base to your Hardhat config. Each chain needs an RPC URL and chain ID:

hardhat.config.js JavaScript
// hardhat.config.js
networks: {
  arbitrum: {
    url: "https://arb1.arbitrum.io/rpc",
    chainId: 42161,
    accounts: [process.env.DEPLOYER_PRIVATE_KEY],
  },
  base: {
    url: "https://mainnet.base.org",
    chainId: 8453,
    accounts: [process.env.DEPLOYER_PRIVATE_KEY],
  },
}

Bridge ETH to L2

Before deploying on an L2, you need ETH on that chain to pay for gas. Use the official bridge for each network:

  • Arbitrum Bridge: bridge.arbitrum.io — deposit ETH from mainnet to Arbitrum. Takes ~10 minutes.
  • Base Bridge: bridge.base.org — deposit ETH from mainnet to Base. Takes ~10 minutes.
  • Third-party bridges: Stargate, Hop, Across — faster and sometimes cheaper, but add trust assumptions.

Deploy to Arbitrum

Deploy to Arbitrum Bash
# Same command, different network flag
npx hardhat ignition deploy ignition/modules/MyToken.js \
  --network arbitrum

# Verify on Arbiscan
npx hardhat verify --network arbitrum \
  0xYourContractAddress "MyToken" "MTK" 1000000

L2 Block Explorers

Each L2 has its own Etherscan-style explorer. Add their API keys to your Hardhat config for verification:

Gas Cost Comparison

The same ERC-20 transfer that costs $5-50 on mainnet costs pennies on L2:

Network
ERC-20 Transfer
Contract Deploy
Ethereum Mainnet
$5 — $50
$50 — $500+
Arbitrum One
$0.01 — $0.10
$0.50 — $5
Base
$0.001 — $0.01
$0.10 — $1

L2 gas costs depend on L1 gas prices (L2 batches are posted to L1). When mainnet is congested, L2 costs also rise — but remain 10-100x cheaper.

🌐 Section 7

Multi-Chain Strategy

Many projects deploy the same contract on multiple chains to reach different user bases. A token might live on Ethereum mainnet, Arbitrum, Base, and Polygon simultaneously. This requires careful planning around addresses, bridging, and state consistency.

When to Go Multi-Chain

  • User reach: Different users live on different chains. DeFi power users prefer Arbitrum; retail users prefer Base (Coinbase integration).
  • Cost optimization: Deploy governance on mainnet (high security), daily operations on L2 (low cost).
  • Ecosystem incentives: L2 chains offer grants, gas subsidies, and ecosystem funds to attract projects.

When to Stay Single-Chain

Multi-chain adds complexity. Stay on one chain if: your user base is concentrated on one network, your contract state must be unified (e.g., a single lending pool), or you lack the engineering resources to maintain multiple deployments.

CREATE2: Deterministic Addresses

By default, contract addresses depend on the deployer's nonce — deploy on two chains, get two different addresses. CREATE2 generates a deterministic address based on the deployer address, a salt, and the bytecode hash. Same inputs = same address on every chain.

CREATE2 formula Solidity
// CREATE2 address formula:
// address = keccak256(0xff ++ deployer ++ salt ++ keccak256(bytecode))

// Using a CREATE2 factory (e.g., Arachnid's deterministic deployer)
// Deploy the same bytecode with the same salt on every chain
// → identical contract address everywhere
🔗

CREATE2 is widely used by protocols like Uniswap (pair addresses), Safe (wallet addresses), and OpenZeppelin. It simplifies frontend configuration — one address works across all chains.

Cross-Chain Bridges

If your contract exists on multiple chains, users need to move tokens between them. Bridges lock tokens on one chain and mint equivalent tokens on the other. Key bridge protocols:

  • Native bridges: Each L2 has its own official bridge (Arbitrum Bridge, Base Bridge). Most secure, but slow (7-day withdrawal for Optimistic Rollups).
  • Liquidity bridges: Stargate, Hop, Across — use liquidity pools for instant transfers. Faster, but add trust assumptions.
  • Messaging protocols: LayerZero, Chainlink CCIP, Axelar — send arbitrary messages and data cross-chain. Required for cross-chain governance and state sync.
⚠️

Bridges are the most attacked infrastructure in crypto. Wormhole ($326M), Ronin ($625M), Nomad ($190M) — all bridge hacks. Use battle-tested bridges and minimize bridged value.

📝 Section 8

Exercise & Self-Check

Exercises

  1. Deploy to Sepolia: Take your ERC-20 token from Module 9 (or any contract from Part 2). Configure Hardhat for Sepolia, get test ETH from a faucet, and deploy using Hardhat Ignition. Share the contract address on Sepolia Etherscan.
  2. Verify on Etherscan: After deploying to Sepolia, get an Etherscan API key and verify your contract. Confirm the green checkmark appears and you can interact via the Read/Write tabs.
  3. Simulate a mainnet deploy: Fork Ethereum mainnet locally using npx hardhat node --fork. Deploy your contract against the fork. Compare gas costs between the fork and your Sepolia deployment.
  4. Deploy to an L2 testnet: Configure Hardhat for Arbitrum Sepolia (testnet) or Base Sepolia. Bridge test ETH to the L2 testnet and deploy the same contract. Compare gas costs with L1 Sepolia.
  5. Multi-chain analysis: Research a real protocol deployed on multiple chains (e.g., Uniswap, Aave, or Chainlink). List all chains they support. Do they use the same contract address on every chain? How do they handle cross-chain token transfers?

Self-Check Questions

  1. Why should you never commit a .env file containing a private key to a Git repository? What would happen if you did?
  2. Explain the difference between contract verification and contract deployment. Why is verification important even though the contract already works without it?
  3. What is the 7-day challenge period in Optimistic Rollups? Why does it exist, and what happens if someone submits a fraud proof?
  4. Why does CREATE2 produce the same address on every chain? What are the inputs to the address formula?
  5. You want to deploy a DeFi lending protocol. Would you choose Optimistic Rollups or ZK Rollups today, and why? What factors would change your decision in 2 years?
🏆

Part 2 Summary

Congratulations — you have completed Part 2: Smart Contract Development. You can now write Solidity contracts (Module 8), create tokens and standards (Module 9), implement advanced patterns (Module 10), test with Hardhat and Foundry (Module 11), build DApp frontends (Module 12), audit for security vulnerabilities (Module 13), and deploy to testnets, mainnet, and Layer 2 chains (Module 14). You have every tool needed to ship production smart contracts.

What Comes Next

Part 3 shifts focus from public blockchains to permissioned blockchains and enterprise use cases. You will explore Hyperledger Fabric, private channels, chaincode, and how enterprises use blockchain for supply chain, identity, and inter-company workflows.

Module 15: Why Permissioned? →
Course Project

Ready to apply everything you've learned? The end-of-course project combines smart contracts, AI, and Node.js into a real decentralised academic assistant.

View Project Brief →