Developers

Verify your contract

Publish your source so the explorer can prove it matches the bytecode, and open up the read and write tabs.

Verify your contract

Deploying a contract puts machine code on the chain. Verifying it publishes the source that produced that code, and proves the two match. Until you do, the explorer shows your contract as unverified: nobody can read what it does, and nobody can call it from the explorer.

Verification is free, permissionless and takes about a minute. There is no reason not to do it.

What verification proves

The explorer compiles the source you submit with the compiler version you name, and compares the result against the bytecode already on the chain.

Exact match means the two are byte for byte identical.

Partial match means everything matches except the metadata fingerprint the compiler appends at the end. That happens when the source is the same but a path or a comment differed at build time. It is normal and it is not a problem.

If neither matches, nothing is published and the contract stays unverified.

Verification says nothing about whether your contract is safe or well written. It says only that the published source is the code that runs.

What you need

The compiler version you built with, down to the exact patch, such as 0.8.24. Guessing does not work, because a different compiler produces different bytecode.

The Standard JSON Input your compiler used. This is a single JSON document holding your sources, your optimizer settings and everything else the compiler was told. It is what makes the build reproducible, which is why the explorer asks for it rather than for a pasted .sol file.

Where to find it:

Tool Where it is
Hardhat artifacts/build-info/*.json, in the input field
Foundry Build with forge build --build-info, then look in out/build-info/*.json, again under input
solc directly The --standard-json document you already fed it

In the Hardhat and Foundry files, the input field is the whole document you need, and the same file names the compiler version under solcVersion or solcLongVersion.

Doing it

  1. Open your contract's address on l2pscan.com.
  2. Go to the Contract tab. Since it is not verified yet, it offers Verify contract.
  3. Pick your compiler version from the list.
  4. Paste the Standard JSON Input into the box.
  5. Submit, and wait a moment.

On success the page reloads into the verified view, with your source, the compiler details and the match type.

After verifying

Code shows your source to anyone who opens it, along with the ABI.

Read contract lets anyone call your view functions from the browser, with no wallet and no cost.

Write contract lets anyone call your state-changing functions with a wallet. This does not grant anything that was not already possible: a contract on a public chain is callable by anyone who knows its address, verified or not. Verification only makes the interface visible.

The ABI also becomes available through the API, so tooling can decode your contract's transactions and events from then on. See The explorer API.

When it fails

The compiler version is wrong. The most common cause by far. Take it from the build info file rather than from memory.

The settings differ. Optimizer on or off, the number of runs, the EVM version: all of them change the output. Submitting the Standard JSON Input from the actual build avoids this, which is exactly why it is the required format.

The wrong address. If your contract sits behind a proxy, verify the implementation at its own address, not the proxy. The explorer marks proxies and points its read and write tabs at the implementation.

It was deployed from different source. A local edit after the deploy, however small, is a different contract. Verify the source as it was when you deployed.

Proxies

Verify both halves at their own addresses. Once the implementation is verified, the proxy's page shows the notice that it forwards to it, and the read and write tabs use the implementation's interface.