Skip to content
LogoLogo

Contract Verification

Verify your smart contracts on Tempo using contracts.tempo.xyz, a Sourcify-compatible contract verification service. Verified contracts display source code and ABI in the Tempo Explorer, making it easier for users to interact with your contracts.

Verify with Foundry

The easiest way to verify contracts is to include the --verify flag when deploying. You can specify Tempo's verifier by either setting the VERIFIER_URL environment variable:

export VERIFIER_URL=https://contracts.tempo.xyz

Or by passing --verifier-url https://contracts.tempo.xyz directly to the command.

The chain ID is auto-detected from the RPC URL, but you can specify it explicitly with --chain <CHAIN_ID> if needed.

Verify during deployment

Deploy and verify in a single command:

# Deploy and verify with forge create
forge create src/Token.sol:Token \
  --rpc-url $TEMPO_RPC_URL \
  --interactive \
  --broadcast \
  --verify
 
# Deploy and verify with forge script
forge script script/Deploy.s.sol \
  --rpc-url $TEMPO_RPC_URL \
  --interactive \
  --sender <YOUR_WALLET_ADDRESS> \
  --broadcast \
  --verify

Verify an existing contract

To verify a contract that's already deployed, use forge verify-contract:

forge verify-contract \
  --rpc-url $TEMPO_RPC_URL \
  --verifier-url https://contracts.tempo.xyz \
  <CONTRACT_ADDRESS> \
  src/MyContract.sol:MyContract

Replace <CONTRACT_ADDRESS> with your deployed contract address and src/MyContract.sol:MyContract with the path and name of your contract.

Retry options

If verification fails intermittently, use --retries and --delay to automatically retry:

forge create src/Token.sol:Token \
  --rpc-url $TEMPO_RPC_URL \
  --interactive \
  --broadcast \
  --verify \
  --retries 10 \
  --delay 10

This retries verification up to 10 times with a 10-second delay between attempts.

For more details on deployment and verification options, see the Foundry documentation.

Verify with Hardhat

If you deployed with Hardhat, add Sourcify verification to your hardhat.config.ts using @nomicfoundation/hardhat-verify:

import "@nomicfoundation/hardhat-verify";
 
const config: HardhatUserConfig = {
  // ... your existing config
  sourcify: {
    enabled: true,
    apiUrl: "https://contracts.tempo.xyz",
    browserUrl: "https://explore.tempo.xyz",
  },
};

Then verify:

npx hardhat verify --network tempo <CONTRACT_ADDRESS> [constructor args...]

Verify from deployment artifacts

If you have Hardhat deployment JSON files (from hardhat-deploy or hardhat-ignition) but no longer have the project set up, you can still verify. These files contain embedded compiler metadata with full source code (when compiled with useLiteralContent: true, the default for hardhat-deploy).

Extract the metadata field, parse it as JSON, then construct a verification API request using:

  • metadata.sourcesstdJsonInput.sources
  • metadata.settings (optimizer, evmVersion, remappings) → stdJsonInput.settings
  • metadata.compiler.versioncompilerVersion
  • metadata.settings.compilationTargetcontractIdentifier (format: path/to/File.sol:ContractName)

Proxy Contracts

OpenZeppelin proxy deployments (e.g., TransparentUpgradeableProxy) create multiple contracts — typically an implementation, a proxy, and a ProxyAdmin. Each must be verified separately and may use different compiler versions (e.g., your contract uses solc 0.8.22 while the OZ proxy uses solc 0.8.10).

If you have the deployment artifact for each contract, the correct compiler version and settings are already embedded in each file's metadata.

Verify with the API

You can also verify contracts directly using the REST API. Verification is asynchronous—you submit a request, then poll for the result.

Submit for Verification

curl -X POST https://contracts.tempo.xyz/v2/verify/42431/<CONTRACT_ADDRESS> \
  -H 'Content-Type: application/json' \
  -d '{
    "stdJsonInput": {
      "language": "Solidity",
      "sources": {
        "src/MyContract.sol": {
          "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.20;\n\ncontract MyContract { }"
        }
      },
      "settings": {
        "optimizer": { "enabled": false, "runs": 200 },
        "evmVersion": "cancun"
      }
    },
    "compilerVersion": "0.8.20+commit.a1b79de6",
    "contractIdentifier": "src/MyContract.sol:MyContract"
  }'

The API returns 202 Accepted with a verification ID:

{
  "verificationId": "550e8400-e29b-41d4-a716-446655440000"
}

Check Verification Status

Poll the status endpoint until verification completes:

curl https://contracts.tempo.xyz/v2/verify/<VERIFICATION_ID>

The endpoint returns 200 for completed jobs, but you must check the response body to determine success or failure:

{
  "isJobCompleted": true,
  "contract": {
    "match": "exact_match",
    "chainId": "42431",
    "address": "0x1234567890abcdef1234567890abcdef12345678",
    "name": "MyContract"
  }
}

The match field can be exact_match (bytecode and metadata match), match (bytecode matches but metadata differs), or null (verification failed).

Retrieve Verified Contract

Once verified, retrieve the contract details:

curl https://contracts.tempo.xyz/v2/contract/42431/<CONTRACT_ADDRESS>

Add ?fields=all to get full compilation artifacts including ABI, source files, and bytecode.

Vyper Support

The verification service supports Vyper contracts. Use "language": "Vyper" in the stdJsonInput:

curl -X POST https://contracts.tempo.xyz/v2/verify/42431/<CONTRACT_ADDRESS> \
  -H 'Content-Type: application/json' \
  -d '{
    "stdJsonInput": {
      "language": "Vyper",
      "sources": {
        "contracts/Token.vy": {
          "content": "# @version ^0.3.10\n..."
        }
      },
      "settings": {}
    },
    "compilerVersion": "0.3.10+commit.91361694",
    "contractIdentifier": "contracts/Token.vy:Token"
  }'

API Reference

EndpointDescription
POST /v2/verify/{chainId}/{address}Submit contract for verification
GET /v2/verify/{verificationId}Check verification status
GET /v2/contract/{chainId}/{address}Get verified contract details
GET /v2/contracts/{chainId}List all verified contracts
GET /chainsGet supported chains

View the full API documentation at contracts.tempo.xyz/docs.

Supported Chains

NetworkChain ID
Tempo Mainnet4217
Tempo Testnet (Moderato)42431
Tempo Devnet31318

Troubleshooting

Verification Failed

If verification fails, check the following:

  • Compiler version: Use the full version string with commit hash (e.g., 0.8.20+commit.a1b79de6)
  • Optimizer settings: Optimizer enabled/disabled and runs must match deployment settings
  • EVM version: Must match the EVM version used during deployment
  • Source files: All imported files must be included in the sources object
  • Contract identifier: Must match the format path/to/Contract.sol:ContractName

Common Errors

ErrorCause
contract_not_foundNo bytecode exists at the address
compilation_errorSource code has syntax errors
compilation_failedCompilation service returned an error
contract_not_found_in_outputContract identifier not found in compiled output
no_matchCompiled bytecode doesn't match on-chain code