Contract verification publishes your Solidity source code on Etherscan so anyone can read it and confirm it matches the deployed bytecode. To verify: go to etherscan.io/verifyContract, paste your contract address, select the compiler version and optimization settings that match your deployment, upload your source code (or paste it), and submit. Etherscan compiles your source and checks if the output matches what is on-chain.

How to Verify a Smart Contract on Etherscan

4 min read

The short version

When a contract is unverified on Etherscan, you see raw bytecode (meaningless hex). When it is verified, you see the actual Solidity source code that anyone can read and audit. Verification proves that the readable code you published is genuinely what is running on-chain. For users: verified means you can check what a contract does before interacting. For developers: verification builds trust because anyone can inspect your logic.

How It Works

The verification process. Prerequisites: you need the exact Solidity source code, the exact compiler version (e.g., v0.8.20), the exact optimization settings (runs count, enabled/disabled), and constructor arguments (if your contract took parameters at deployment). Step 1: Deploy your contract (if not already deployed). You should have the deployment transaction hash and the deployed contract address. Step 2: Go to etherscan.io/verifyContract (or the equivalent for your chain: arbiscan.io, basescan.org). Step 3: Enter the contract address. Step 4: Select compiler type. For single files: Solidity (Single File). For projects with imports: Solidity (Standard-Json-Input) or Solidity (Multi-Part Files). Hardhat and Foundry export Standard-Json-Input automatically. Step 5: Select the exact compiler version from the dropdown (must match what you compiled with, down to the patch version). Step 6: Select optimization settings (Yes/No and the runs count, must match your hardhat.config.js or foundry.toml). Step 7: Paste your source code or upload the Standard-Json-Input file. Step 8: Enter constructor arguments in ABI-encoded hex (if applicable). Tools like abi.hashex.org help encode these. Step 9: Click Verify and Publish. Etherscan compiles your code and compares the resulting bytecode to what is deployed. If they match: verified (green checkmark). If not: error message indicating what does not match. Automated verification: Hardhat plugin (hardhat-etherscan) and Foundry (forge verify-contract) can verify automatically after deployment with one command. This is the standard developer workflow. For verifying contracts you did not deploy (as a user checking legitimacy): look for the green checkmark on the Contract tab. Click Read Contract to see public state. Click Write Contract to interact directly.

Verifying a contract deployed with Hardhat

You deployed a token contract to Ethereum mainnet using Hardhat. Contract address: 0xYourContract. Automated method (recommended): In hardhat.config.js, add your Etherscan API key. Run: npx hardhat verify --network mainnet 0xYourContract Constructor Arg 1 Constructor Arg 2. Hardhat uploads source, compiler settings, and constructor args automatically. Output: Successfully verified contract on Etherscan. Takes 30 seconds. Manual method: go to etherscan.io/verifyContract. Paste address. Compiler: v0.8.20+commit.a1b79de6. Optimization: Yes, 200 runs. Upload the Standard-Json-Input from artifacts/build-info/. Constructor args: ABI-encode your constructor parameters. Submit. Wait 10-30 seconds for compilation. Result: green checkmark, source visible on the Contract tab. Anyone can now read your transfer(), approve(), and any admin functions. Transparency established.

What People Get Wrong

  • Verified means safe

    Verified means readable, not audited. A verified contract could contain malicious code (hidden mint functions, blacklist logic, proxy upgradeability) that is clearly visible in the source to anyone who reads it. Verification lets you check for yourself, it does not certify safety. Always read the verified code (or rely on auditors who did) before trusting significant funds.

  • Unverified contracts are always scams

    Many legitimate contracts launch unverified (verification takes a separate step developers sometimes delay). However, for any contract asking you to deposit money: unverified is a red flag. Legitimate projects verify within hours of deployment. If a contract holding user funds remains unverified for days, treat it with high suspicion.

  • Verification is permanent and cannot be undone

    Verification is permanent for that specific contract address. However, if the contract uses a proxy pattern (upgradeable), the implementation behind the proxy can change. A verified proxy today could point to a different (potentially unverified) implementation tomorrow. Check whether the contract has an upgrade function.

Sources & Further Reading

Questions People Also Ask

Why does verification fail with bytecode does not match?
The most common causes: (1) Wrong compiler version (even one patch version off fails). (2) Different optimization settings (if you compiled with optimization on but selected off during verification, bytecode differs). (3) Missing or wrong constructor arguments. (4) Different source code (even adding a comment changes compilation). Make sure every setting matches your deployment exactly.
Do I need an Etherscan API key?
For manual verification: no. For automated verification via Hardhat/Foundry: yes (free, sign up at etherscan.io/apis). Each block explorer (Arbiscan, Basescan, Polygonscan) requires its own API key. All are free with rate limits.
How do I verify on L2s (Arbitrum, Base, Optimism)?
Same process, different explorers. Arbiscan.io, basescan.org, optimistic.etherscan.io all support the same verification flow. In Hardhat/Foundry, just change the network flag: --network arbitrum, --network base. The tooling handles the correct explorer automatically if configured in your config file.

More in Practical Guides

See all →
Was this page helpful?

Page last checked