> For the complete documentation index, see [llms.txt](https://bluwhale.gitbook.io/bluwhaleai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bluwhale.gitbook.io/bluwhaleai/oceanum-oxn/smart-contract-development/verifying-contracts-on-the-explorer.md).

# 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 Oceanum (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 <a href="#verification-is-optional-but-recommended" id="verification-is-optional-but-recommended"></a>

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 <a href="#verification-methods" id="verification-methods"></a>

OXN's block explorer supports two paths:

1. **Direct upload** — paste source code into the explorer's verify form.
2. **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 <a href="#what-the-explorer-needs" id="what-the-explorer-needs"></a>

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 be `paris` for OXN.
* **Constructor arguments** — ABI-encoded, if your constructor took arguments.

### Flattening source <a href="#flattening-source" id="flattening-source"></a>

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 <a href="#abi-encoding-constructor-arguments" id="abi-encoding-constructor-arguments"></a>

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 <a href="#verifying-proxy-contracts" id="verifying-proxy-contracts"></a>

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 <a href="#troubleshooting" id="troubleshooting"></a>

**"Bytecode mismatch."** The most common failure. Causes:

* Compiler version off by a patch (`0.8.24` vs `0.8.25`).
* Optimizer runs differ (`200` vs `1000`).
* `evmVersion` differs (`paris` vs `shanghai`).
* 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.

### Next steps <a href="#next-steps" id="next-steps"></a>

* [**Deploying Contracts**](https://docs.bout.network/build/deploying)
* [**Debugging & Troubleshooting**](https://docs.bout.network/build/debugging)

[Edit this page](https://github.com/oxn-network/oxn-docs/edit/main/docs/06-build/verifying.md)[PreviousDeploying Contracts](https://docs.bout.network/build/deploying)[NextDebugging and Troubleshooting](https://docs.bout.network/build/debugging)
