# Verify a Smart Contract

## [OKLink](https://www.oklink.com/gravity-alpha)

There are four major ways to verify contracts on OKLink:

### 1. Explorer Interface

You can verify a deployed contract directly through the [OKLink interface](https://web3.okx.com/explorer/gravity-alpha/verify-contract-preliminary).

### 2. Contract Verification APIs

OKLink provides a set of [contract verification APIs](https://www.oklink.com/docs/en/#developer-tools-contract-verification).&#x20;

### 3. Verify Using Foundry

**Prerequisite: Get an OKLink API Key**

Apply for an API key:\
<https://www.oklink.com/account/my-api>

**Run `forge verify-contract`**

To verify a contract, you need to provide:

* The deployed contract address
* The contract path and name (e.g., `src/MyToken.sol:MyToken`)
* The OKLink `verify-url` for your target chain
* Your OKLink API key

Command format:

```bash
bashCopyEditforge verify-contract <contract_address> \
  src/MyToken.sol:MyToken \
  --verifier oklink \
  --verifier-url https://www.oklink.com/api/v5/explorer/contract/verify-source-code-plugin/gravity \
  --api-key <Your_OKLink_API_Key> \
  --watch
```

**Check Verification Status**

It is recommended to use the `--watch` flag to continuously poll for verification status.

If you didn’t use `--watch`, you can manually check the result using:

```bash
bashCopyEditforge verify-check <contract_address> --verifier oklink
```

### 4. Verify Using Hardhat

#### Method 1 (Recommended): Using `@okxweb3/hardhat-explorer-verify` Plugin

This method uses an official Hardhat plugin provided by OKX. It provides a CLI command (`npx hardhat okverify`) to automate contract verification.

**1. Install the Plugin**

```bash
bashCopyEditnpm install @okxweb3/hardhat-explorer-verify
```

**2. Configure `hardhat.config.ts`**

Here is a sample configuration for Gravity Chain:

```ts
tsCopyEditimport { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";
import "@okxweb3/hardhat-explorer-verify";

const config: HardhatUserConfig = {
  solidity: "0.8.24",
  sourcify: {
    enabled: true,
  },
  networks: {
    gravity: {
      url: "https://rpc.gravity.xyz",
      accounts: ["<Your Private Key>"],
    },
  },
  okxweb3explorer: {
    apiKey: "<Your OKLink API Key>",
    customChains: [
      {
        network: "gravity",
        chainId: 1625,
        urls: {
          apiURL:
            "https://www.oklink.com/api/v5/explorer/contract/verify-source-code-plugin/gravity",
          browserURL: "https://www.oklink.com",
        },
      },
    ],
  },
};

export default config;
```

**3. Verify the Contract**

After deployment, verify with:

```bash
bashCopyEditnpx hardhat okverify --network gravity <ContractAddress>
```

**4. Verifying Proxy Contracts**

For contracts deployed via `TransparentUpgradeableProxy`, use:

```bash
bashCopyEditnpx hardhat okverify --network gravity --contract contracts/MyContract.sol:MyContract --proxy <ProxyAddress>
```

If you're using the 897 proxy standard, omit `--proxy` and just run the command as normal

#### Method 2: Manually Configuring `etherscan.customChains` for OKLink

You can also verify contracts using Hardhat's native Etherscan integration by overriding the default verification endpoint.

**Configuration Example:**

```js
jsCopyEditmodule.exports = {
  etherscan: {
    apiKey: "<Your OKLink API Key>",
    customChains: [
      {
        network: "gravity",
        chainId: 1625,
        urls: {
          apiURL:
            "https://www.oklink.com/api/v5/explorer/contract/verify-source-code-plugin/gravity",
          browserURL: "https://www.oklink.com",
        },
      },
    ],
  },
};
```

This enables Hardhat’s built-in `verify` task to interact with OKLink:

```bash
bashCopyEditnpx hardhat verify --network gravity <ContractAddress> <ConstructorArguments...>
```

> ⚠️ You’ll still need to ensure your contract metadata matches what OKLink expects (e.g., compiler version, optimization settings, source flattening if needed).

***

## [Blockscout](https://explorer.gravity.xyz)

{% hint style="info" %}
Blockscout uses the global blockscout verifier (so that similar contracts get automatically verified), it can sometimes be flaky. Please try again a bit later.

For contracts deployed by `create2,` you may ran into *Fail - Unable to verify.* You will have to visit the contract address page after deployment first. Then blockscout will fetch it from the RPC and see that it is a contract, then verification should work.\
Contract address page: `https://explorer.gravity.xyz/address/***`
{% endhint %}

For [hardhat](https://hardhat.org/) users, you will need to change your `hardhat.config.ts` to something like the following example:

```
  etherscan: {
    apiKey: {
      // ...
      // Not required. Can be any non-empty string
      gravity: "abc",
    },
    customChains: [
      // ...
      {
        network: "gravity",
        chainId: 1625,
        urls: {
          apiURL: "https://gscan.xyz/api",
          browserURL: "https://gscan.xyz",
          // For Blockscout
          // apiURL: "https://explorer.gravity.xyz/api",
          // browserURL: "https://explorer.gravity.xyz",
        },
      }
    ],
  },
  networks: {
    // ...
    gravity: {
      url: "https://rpc.gravity.xyz",
      chainId: 1625,
      accounts,
    },
  },
```

For [foundry](https://book.getfoundry.sh/) users, we recommend you to use [scripts](https://book.getfoundry.sh/tutorials/solidity-scripting) to deploy your contracts. You will need to configure the `foundry.toml` file as the following:

```
[etherscan]
# Gravity explorer does not require an API key, any non-empty string will do.
# gscan
gravity = { key = "abc", url="https://gscan.xyz/api", chain = 1625 }
# Blockscout
# gravity = { key = "abc", url="https://explorer.gravity.xyz/api", chain = 1625 }
```

Then you when you run your scripts, you can verify contracts deployed with `--verify` option.

```
forge script --chain 1625 script/YOUR_SCRIPT.s.sol:YOUR_SCRIPT --rpc-url $GRAVITY_RPC_URL --broadcast --verify -vvvv
```

NOTE: If contracts were deployed successfully but verification failed, DO NOT delete the `broadcast/` directory. You can resume the verification process by removing the `--broadcast` option and providing the deployment transaction sender's key like below: (or you can configure it in cast):

```
forge script --chain 1625 script/YOUR_SCRIPT.s.sol:YOUR_SCRIPT --private-key $PRIVATE_KEY --rpc-url  $GRAVITY_RPC_URL --verify -vvvv
```
