Make verification succeed on the first attempt — every time.
Almost every failed verification comes down to a handful of avoidable mistakes. These practices eliminate them.
Capture settings at deploy time
The single most important habit: record the exact compilation settings when you deploy, not when you later decide to verify. Store alongside your deployment artifacts:
- Compiler version (full string, including commit hash:
v0.8.24+commit.e11b9ed9) - Optimizer enabled flag and runs
- EVM version (
default,paris,shanghai,cancun, …) - Constructor arguments (ABI-encoded)
- Linked library addresses
Hardhat’s artifacts/build-info/ and Foundry’s out/ already contain all of this — commit or archive them.
Prefer standard JSON input
When verifying by hand or via API, use standard JSON input whenever possible. It embeds every compiler setting, so there’s nothing to misremember. Flattened-source verification forces you to restate settings manually — every restated field is a chance to be wrong.
Get constructor arguments right
Constructor arguments are ABI-encoded and appended to the init bytecode in the deployment transaction. To extract them:
- Open the deployment transaction on the explorer.
- Compare the input data against your compiled bytecode.
- The trailing bytes after the bytecode are the encoded constructor arguments.
Or encode them directly: cast abi-encode "constructor(string,uint256)" "MyToken" 1000000.
Declare libraries explicitly
If your contract links external libraries, the deployed bytecode contains their addresses in place of placeholders. Verification needs each library name mapped to its deployed address — collect these at deploy time.
Don’t hand-edit flattened source
Flattening tools sometimes reorder or alter pragmas. If you must flatten:
- Use the toolchain’s own flattener (
hardhat flatten,forge flatten) — not copy-paste. - Keep a single
pragma soliditystatement at the top. - Don’t “clean up” the flattened output; even whitespace-adjacent changes can shift the metadata hash (partial match) or worse.
Verify immediately after deployment
Fold verification into the deploy pipeline (forge script --verify, or a Hardhat task). Immediate verification:
- Uses settings that are still in context — nothing to reconstruct later.
- Catches toolchain misconfigurations while the deployer is still watching.
- Means users never see an unverified contract.
Aim for exact (full) match
Partial matches work fine in the explorer, but exact matches are the strongest signal. Keep the metadata hash intact by verifying with the original build info rather than reconstructed settings.
Verify on testnets first
If your project deploys to a testnet, rehearse the full deploy-and-verify flow there. Every lesson is cheaper on a testnet.
Common failure messages and fixes
| Symptom | Likely cause |
|---|---|
| Bytecode mismatch | Wrong compiler version or optimizer runs |
| Mismatch only in metadata section | Settings close but not exact — use standard JSON |
| ”Contract not found in provided sources” | contract_name ≠ declared name (or wrong file set) |
| Placeholder left in libraries | Missing library address mapping |
| Constructor argument decoding error | Arguments not ABI-encoded, or 0x prefix issues |
Next steps
- Verification Examples
- Advanced Features — proxies, Vyper, similar-match