> ## Documentation Index
> Fetch the complete documentation index at: https://metalayerlabs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Contract Verification

## Where To Verify

Blast has a several [block explorers](/tools/block-explorers) to choose from. Which explorer you choose to spend the most time with is a matter of personal preference, but one common question from new builders is **where do I verify my contracts?**. Out of the available options, **[blastscan.io](https://blastscan.io)** and **[blastexplorer.io](https://blastexplorer.io)** are where most people verify their contracts, so that's what we'd recommend.

The following guide will help you steer clear common issues while verifying your contracts with Foundry and  Hardhat.

## Do I Need An API Key?

Whether or not you need valid API key depends on (a) which network you're using and (b) which API you're targeting. Blastexplorer's API will let you verify on testnet and mainnet without requiring a valid API key, but blastscan does require one when verifying on mainnet. You can get a blastscan API key by creating a free account [here](https://blastscan.io/login), and navigating to the "API-KEYs" section of your profile.

| Explorer         |            Testnet           |            Mainnet           |
| :--------------- | :--------------------------: | :--------------------------: |
| blastscan.io     | <span class="good">no</span> | <span class="bad">yes</span> |
| blastexplorer.io | <span class="good">no</span> | <span class="good">no</span> |

<Warning>
  `forge` requires a value for the `--etherscan-api-key` option even in cases where a *valid* API key is not required. Just use a placeholder here.
</Warning>

## Verification Endpoints

Once you've decided where to verify, ensure that you are making your verification request to the correct API endpoint. In Hardhat, this "verification endpoint" is the `apiUrl` specified in config; in Foundry, this is the `--verifier-url` you'll need to provide in your forge command:

| blastscan       |                                        |
| :-------------- | :------------------------------------- |
| Testnet         | `https://api-sepolia.blastscan.io/api` |
| Mainnet         | `https://api.blastscan.io/api`         |

| blastexplorer |                                                                       |
| :------------ | :-------------------------------------------------------------------- |
| Testnet       | `https://api.routescan.io/v2/network/testnet/evm/168587773/etherscan` |
| Mainnet       | `https://api.routescan.io/v2/network/mainnet/evm/81457/etherscan`     |

## Verification Examples

### Foundry

Use these examples, filling in appropriate values as discussed above, to verify your contracts during deployment using `forge script` or to verify an existing deployment with `forge verify-contract`.

<Tabs>
  <Tab title="Verify During Deployment">
    ```yaml theme={null}
    forge script <deploy-script> 
        --verify --verifier-url <verification-endpoint> \
        --etherscan-api-key <api-key> --rpc-url <rpc-url> \
        --verify --broadcast -vvvv
    ```
  </Tab>

  <Tab title="Verify Deployed Contract">
    ```
    forge verify-contract <address> <contract> \
        --verifier-url <verification-endpoint> \
        --etherscan-api-key <api-key> --watch    
    ```
  </Tab>
</Tabs>

***

### Hardhat

Whether using `hardhat-ignition-ethers` or `hardhat-verify`, successful verification in Hardhat is primarily a matter of setting up your `hardhat.config.ts` or `hardhat.config.js` file correctly.

You'll need to configure the `networks` and `etherscan` properties as demonstrated below. In order to specify the correct verification endpoint from the [table above](#verification-endpoints), you will also need to configure the `etherscan.customChains` property.

<Tabs>
  <Tab title="Config">
    <CodeGroup>
      ```javascript hardhat.config.ts theme={null}

      import { HardhatUserConfig } from "hardhat/config";
      import "@nomicfoundation/hardhat-toolbox";
      import "@nomicfoundation/hardhat-ignition-ethers";
      import { vars } from "hardhat/config";

      const PRIVATE_KEY = vars.get("PRIVATE_KEY");

      const config: HardhatUserConfig = {
        solidity: "0.8.24",
        networks: {
          "blast-sepolia": {
          url: "https://sepolia.blast.io",
          accounts: [PRIVATE_KEY]
          },
          "blast-mainnet": {
              url: "https://rpc.blast.io",
              accounts: [PRIVATE_KEY]
          },    
        },
        etherscan: {
          apiKey: API_KEY,
          customChains: [
            {
              network: "blast-sepolia",
              chainId: 168587773,
              urls: {
                apiURL: <verification-endpoint>,
                browserURL: <explorer-url>
              }        
            },
            {
              network: "blast-mainnet",
              chainId: 81457,                        
              urls: {
                apiURL: <verification-endpoint>,
                browserURL: <explorer-url>
              }
            }
          ],
          enabled: true
        }
      };

      export default config;
      ```

      ```javascript hardhat.config.js theme={null}

      require("@nomicfoundation/hardhat-toolbox");
      require("@nomicfoundation/hardhat-toolbox");
      require("@nomicfoundation/hardhat-ignition-ethers");
      const { vars } =  require("hardhat/config");

      const PRIVATE_KEY = vars.get("PRIVATE_KEY");

      module.exports = {
        solidity: "0.8.24",
        networks: {
          "blast-sepolia": {
          url: "https://sepolia.blast.io",
          accounts: [PRIVATE_KEY]
          },
          "blast-mainnet": {
              url: "https://rpc.blast.io",
              accounts: [PRIVATE_KEY]
          },    
        },
        etherscan: {
          apiKey: API_KEY,
          customChains: [
            {
              network: "blast-sepolia",
              chainId: 168587773,
              urls: {
                apiURL: <verification-endpoint>,
                browserURL: <explorer-url>
              }        
            },
            {
              network: "blast-mainnet",
              chainId: 81457,                        
              urls: {
                apiURL: <verification-endpoint>,
                browserURL: <explorer-url>
              }
            }
          ],
          enabled: true
        }
      };
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Verify During Deployment">
    ```
    npx hardhat ignition deploy ignition/modules/Example.ts \
      --network <network> --verify
    ```
  </Tab>

  <Tab title="Verify Deployed Contract">
    <b>Using `ignition deploy` and `ignition veriry`</b>

    ```yaml theme={null}
    # 1. Deploy contract making sure to specify a deployment-id    
    npx hardhat ignition deploy ignition/modules/Example.ts \
      --network <network> --deployment-id <deployment-id>

    # 2. Use deployment-id to verify the corresponding deployment
    npx hardhat ignition verify <deployment-id>
    ```

    <b>Using `hardhat verify`</b>

    ```
    npx hardhat verify <address> --network <network>
    ```
  </Tab>
</Tabs>
