Verifying Contracts on the Explorer
Contract verification publishes your Solidity source alongside the deployed bytecode, letting users and developers read the code, call functions from the explorer UI, and audit the contract's behavior against the source.
On OXN, deployed bytecode is public exactly as on Ethereum — so verification does not reveal anything additional. What it does reveal is the source code, which you may or may not want public.
Verification is optional but recommended
You should verify a contract when:
- You want users to trust it. A verified contract lets anyone read the code before interacting.
- You want other developers to compose with it. Verified interfaces are easier to integrate.
- You want to enable the explorer's "Read Contract" / "Write Contract" UI. These features require verified ABIs.
You might skip verification for:
- Contracts whose logic is a competitive advantage.
- Contracts still under active development (verify the final version, not every iteration).
Even for unverified contracts, the compiled bytecode remains public on-chain. Verification just adds the human-readable form.
Verification methods
OXN's block explorer supports two paths:
- Direct upload — paste source code into the explorer's verify form.
- Hardhat / Foundry plugin — automated via CLI.
The specific plugin / API is TBD as the explorer's verify endpoint stabilizes. This page will be updated with the exact commands once the workflow is finalized. In the interim, direct upload works for all contracts.
What the explorer needs
For any verification method, you'll need to provide:
- Solidity source code — every file, including imports. For imports outside your own repo (OpenZeppelin, libraries), the explorer typically supports "flattened" upload.
- Compiler version — exact match required (e.g.
0.8.24). - Optimizer settings — must match what you deployed with (
enabled,runs). evmVersion— must beparisfor OXN.- Constructor arguments — ABI-encoded, if your constructor took arguments.
Flattening source
Some verification flows want a single flat file:
# Hardhat
npx hardhat flatten contracts/MyToken.sol > flat.sol
# Foundry
forge flatten src/MyToken.sol > flat.sol
Both tools inline all imports into one file. Watch for SPDX-License-Identifier duplication after flattening — the tools usually collapse them but sometimes leave conflicts you must resolve manually.
ABI-encoding constructor arguments
If your contract had constructor arguments, the explorer needs them as an ABI-encoded hex string:
# Foundry
cast abi-encode "constructor(uint256,string)" 1000000000000000000 "Hello"
// ethers.js
const iface = new ethers.Interface(["constructor(uint256,string)"]);
const encoded = iface.encodeDeploy([1_000_000_000_000_000_000n, "Hello"]);
console.log(encoded.slice(2)); // strip 0x prefix if the explorer expects that
Verifying proxy contracts
For OpenZeppelin proxies, verify both the proxy and the implementation contract. The explorer may then detect the proxy pattern and let users interact with the proxy as if it were the implementation.
Detailed proxy verification steps depend on the explorer's UI — refer to the on-explorer help for exact clicks.
Troubleshooting
"Bytecode mismatch." The most common failure. Causes:
- Compiler version off by a patch (
0.8.24vs0.8.25). - Optimizer runs differ (
200vs1000). evmVersiondiffers (parisvsshanghai).- Metadata hash (
bytecodeHash) differs — set to"none"in your compiler if you want reproducible builds.
Verify the exact bytecode from your artifacts matches what's on-chain before troubleshooting the verify form:
const artifact = require("./artifacts/contracts/MyToken.sol/MyToken.json");
const onchain = await provider.getCode("0xYourContractAddress");
console.log("Match:", artifact.deployedBytecode === onchain);
"Metadata not found." Some verifiers require the Solidity metadata JSON alongside the source. Hardhat produces this under artifacts/build-info/; Foundry stores it in each artifact under the metadata key.