本文最后更新于 2024-05-20,本文发布时间距今超过 90 天, 文章内容可能已经过时。最新内容请以官方内容为准

How to verify a contract with Foundry

Static Badge

Foundry 简介

Foundry 🛠️ 是一个强大的工具集,用于构建、测试和部署 Ethereum 智能合约。它包括 Forge(用于测试和部署)和 Cast(用于与合约交互的命令行工具)。

为什么需要验证合约

在 Web3 开发的世界中,智能合约的安全与透明性至关重要。Foundry,一个现代且高效的智能合约开发框架,提供了一套完整的工具来帮助开发者编写、测试、部署以及验证合约。本文将围绕如何使用 Foundry 在部署时验证合约,以及如何在不同的区块链上验证不同的合约。

部署与验证的重要性

智能合约一旦部署至区块链,其代码便是不可变的。因此,在部署前的验证尤为重要,它能确保合约代码的逻辑正确无误,防止潜在的安全风险。Foundry 的工具集,如 Forge 和 Anvil,支持从编写代码到部署的整个流程,并提供自动化的验证工具以确保部署的合约与开发者的原始代码一致。

如何使用 Foundry 验证合约

🥤 目前,foundry 支持在部署时验证合约和验证已经成功部署的合约。
因此,存在两种方法可以验证合约:

  1. 部署合约时验证合约
  2. 验证已部署的合约

部署合约时验证合约

要部署合约,可以使用 forge create 命令。这个命令需要 RPC URL (--rpc-url) 和部署者的私钥(--private-key)。例如:

  1. 准备环境:确保已安装最新版本的 Foundry 工具集,包括 Forge、Cast、Anvil 和 Chisel。

  2. 编写合约:创建你的智能合约,例如使用 Solidity 编写 ERC721 标准的 NFT 合约。

  3. 编译合约:使用 Foundry 编译合约,确保没有编译错误。

  4. 部署并验证:使用 forge create 命令部署合约,并结合 --verify 标志在 Etherscan 上自动验证合约。

    • --rpc-url: 指定 RPC URL,用于部署和验证合约。(rpc url 应该和 chain-id, etherscan-api-key 是相匹配的)
    • --private-key: 指定部署合约的 wallet 私钥。
    • --etherscan-api-key: 指定 Etherscan API 密钥,用于验证合约。
    • --verify: 启用自动验证合约,合约部署完成后会自动验证合约。
    forge create --rpc-url <your_rpc_url> \
        --private-key <your_private_key> \
        --etherscan-api-key <your_etherscan_api_key> \
        --verify \
        src/Contract.sol:Contract
    

验证已部署的合约

如果你需要验证一个已经部署在区块链上的合约,Foundry 提供了 forge verify-contract 命令来完成这个任务。
部署后,可以使用 forge verify-contract 命令在 Etherscan、Sourcify 或 Blockscout 上验证合约。这需要提供合约地址、合约名称或路径、以及 Etherscan API 密钥(如果使用 Etherscan 进行验证)。例如

  1. 获取合约信息:确定合约的地址、源文件路径、构造函数参数等信息。

  2. 构造验证命令:使用 forge verify-contract 命令并传入必要的参数,包括链 ID、编译器版本、优化次数等。

    请注意,如果在验证时没有设置 --num-of-optimizations 将默认为 0,而如果在部署时没有设置则默认为 200,所以如果你使用默认的编译设置,请确保输入 --num-of-optimizations 200

    • --chain-id: 指定链 ID,用于确定正确的 Etherscan API 端点。
    • --num-of-optimizations: 指定合约的优化次数。
    • --constructor-args: 如果合约有构造函数,则需要提供构造函数参数。
    • --verifier-url: 指定区块链浏览器的 API 端点。
    • --watch: 启用监视模式,用于在合约验证成功后自动退出。
    • <the_contract_address>: 指定合约的地址。
    • <the_contract_source_file>: 指定合约的源文件路径。
    forge verify-contract --chain-id 11155111 \
     --num-of-optimizations 200 \
     --constructor-args $(cast abi-encode "constructor(string,string,uint256,uint256)" "ForgeUSD" "FUSD" 18 1000000000000000000000) \
     --verifier-url <your_contract_deployed_chain_verifier_url> \
     --etherscan-api-key <your_etherscan_api_key> \
     --watch \
     <the_contract_address> \
     src/Contract.sol:Contract
    
  3. 提交验证:提交验证请求到相应的区块链浏览器,如 Etherscan,并获取验证结果。

验证不同区块链上的合约

不同的区块链可能需要不同的验证参数和过程。以下是一些通用步骤:

  1. 选择正确的网络:根据目标区块链设置正确的 RPC URL 和链 ID。(可参考 常用链及其对应 verifier_url)

  2. 适配验证工具:某些区块链可能需要特定的验证工具或参数,如 Arbitrum Sepolia Testnet 使用 Arbiscan。

  3. 使用正确的 API 密钥:针对不同的区块链浏览器,确保使用正确的 API 密钥。(可参考 API 密钥获取指南)

  4. 调整验证命令:根据目标区块链调整 forge verify-contract 命令的参数。

可能遇到的问题和解决方案

GitHub 问题 #6185 中,用户遇到了在 Arbitrum Sepolia 上验证合约的问题。问题描述了无论使用哪个编译器版本,合约都无法成功验证。解决这类问题通常需要检查以下几个方面:

  • 确保使用的编译器版本与部署合约时的版本一致。
  • 确保构造函数参数正确无误,并且已正确编码。
  • 检查 Etherscan API 密钥是否有效,并且有足够的配额。
  • 如果问题与 Solidity 编译器有关,尝试清理编译缓存并重新编译。
  • 确保合约源代码、ABI 和字节码与部署的合约匹配。

结论

Foundry 提供了一个强大而灵活的工具集,用于 Ethereum 智能合约的开发和验证。通过遵循正确的部署和验证流程,开发者可以在 Sepolia Arbitrum Testnet 或其他网络上成功部署和验证他们的合约。如果遇到问题,通常需要仔细检查配置和代码,以确保一切符合要求。记得,耐心和细致是解决技术问题的关键 🔍️。

延伸阅读

foundry 常用命令行参数

部署和验证智能合约时常用的命令行参数的详细说明:

参数 描述 示例
--rpc-url <url> 指定与部署合约的网络相对应的 RPC URL。 --rpc-url https://mainnet.infura.io/v3/YOUR-API-KEY
--private-key <key> 指定部署合约的钱包的私钥。 --private-key 0xabc123...
--etherscan-api-key <key> 指定用于在 Etherscan 上验证合约的 API 密钥。 --etherscan-api-key YOUR_ETHERSCAN_API_KEY
--chain-id <id> 指定部署合约的区块链网络的链 ID。用于确定网络(如主网、测试网)。 --chain-id 1 (以太坊主网)
--num-of-optimizations <num> 指定编译时 Solidity 编译器的优化次数。 --num-of-optimizations 1000
--constructor-args <args> ABI 编码的构造函数参数,用于初始化合约。 --constructor-args myArg1,myArg2
--constructor-args-path <file> 包含构造函数参数的文件路径,参数为空格分隔。 --constructor-args-path ./args.txt
--flatten 表示是否在验证前对源代码进行扁平化。 --flatten
--force 在验证之前不要编译扁平化的智能合约。 --force
--delay <delay> 可选的超时,在两次尝试之间,以秒为单位。 --delay 3
--retries <retries> 重试尝试验证的次数。 --retries 15
--show-standard-json-input 输出适合保存到文件并上传到区块浏览器进行验证的 JSON 格式数据。 --show-standard-json-input
--watch 提交后等待验证结果,并自动运行 forge verify-check 直到验证失败或成功。 --watch
--verifier <name> 验证提供者名称,如 etherscan, sourcify, blockscout --verifier etherscan
--verifier-url <url> 用于提交验证请求的验证网址。 --verifier-url https://api-sepolia.arbiscan.io/api
--build-info 生成构建信息文件。 --build-info
--root <path> 项目的根路径。 --root /path/to/your/project
--contracts <path> 合约源代码目录。 --contracts /path/to/contracts
--lib-paths <path> 库的文件夹路径。 --lib-paths /path/to/libraries
--remappings <remappings> 项目的重映射,格式为 <source>=<dest> --remappings "@openzeppelin/=lib/openzeppelin-contracts/"
--cache-path <path> 编译器缓存的路径。 --cache-path /path/to/cache

这些参数提供了灵活性和控制力,使开发者能够根据需要定制部署和验证过程。正确使用这些参数可以确保合约部署和验证过程的顺利进行。

在使用这些参数时,请确保你的 RPC URL、私钥、API 密钥以及链 ID 与你的部署目标网络匹配,以避免部署或验证失败。

此外,构造函数参数需要 ABI 编码,以确保正确地传递给智能合约。

常用链及其对应 verifier_url

以下是一些常见的以太坊测试网和主网的配置内容,用于 Foundry 的verify-contract命令来验证部署好的合约。

常见网络配置

Network Chain ID Verifier URL API Key Placeholder
Etherscan Sepolia Testnet 11155111 https://api-sepolia.etherscan.io/api <your_etherscan_api_key>
Ethereum Mainnet 1 https://api.etherscan.io/api <your_etherscan_api_key>
Arbitrum Sepolia Testnet 421614 https://api-sepolia.arbiscan.io/api <your_arbiscan_api_key>
Ropsten Testnet 3 https://api-ropsten.etherscan.io/api <your_etherscan_api_key>
Rinkeby Testnet 4 https://api-rinkeby.etherscan.io/api <your_etherscan_api_key>
Goerli Testnet 5 https://api-goerli.etherscan.io/api <your_etherscan_api_key>
Kovan Testnet 42 https://api-kovan.etherscan.io/api <your_etherscan_api_key>
Polygon Mainnet 137 https://api.polygonscan.com/api <your_polygonscan_api_key>
Polygon Mumbai Testnet 80001 https://api-testnet.polygonscan.com/api <your_polygonscan_api_key>
Binance Smart Chain 56 https://api.bscscan.com/api <your_bscscan_api_key>
BSC Testnet 97 https://api-testnet.bscscan.com/api <your_bscscan_api_key>
Fantom Opera 250 https://api.ftmscan.com/api <your_ftmscan_api_key>
Fantom Testnet 4002 https://api-testnet.ftmscan.com/api <your_ftmscan_api_key>
Avalanche Mainnet 43114 https://api.snowtrace.io/api <your_snowtrace_api_key>
Avalanche Fuji Testnet 43113 https://api-testnet.snowtrace.io/api <your_snowtrace_api_key>
Harmony Mainnet 1666600000 https://ctrver.t.hmny.io/verify <your_harmonyscan_api_key>
Harmony Testnet 1666700000 https://ctrver.t.hmny.io/verify?network=testnet <your_harmonyscan_api_key>

使用示例

使用 Foundry 的verify-contract命令时,可以按照以下格式进行配置。例如,验证 Arbitrum Sepolia Testnet 上的合约:

forge verify-contract --chain-id 421614 \
    --verifier-url https://api-sepolia.arbiscan.io/api \
    --etherscan-api-key <your_arbiscan_api_key> \
    <your_contract_address> \
    <your_contract_name>

其他网络的使用示例

Ethereum Mainnet

forge verify-contract --chain-id 1 \
    --verifier-url https://api.etherscan.io/api \
    --etherscan-api-key <your_etherscan_api_key> \
    <your_contract_address> \
    <your_contract_name>

Goerli Testnet

forge verify-contract --chain-id 5 \
    --verifier-url https://api-goerli.etherscan.io/api \
    --etherscan-api-key <your_etherscan_api_key> \
    <your_contract_address> \
    <your_contract_name>

Polygon Mumbai Testnet

forge verify-contract --chain-id 80001 \
    --verifier-url https://api-testnet.polygonscan.com/api \
    --etherscan-api-key <your_polygonscan_api_key> \
    <your_contract_address> \
    <your_contract_name>

通过这些配置和示例,你可以方便地使用 Foundry 工具来验证不同区块链网络上的智能合约部署。

请确保你已经替换了<your_etherscan_api_key>等占位符为实际的 API 密钥。

API 密钥获取指南

区块链浏览器 网站
Etherscan (以太坊) Etherscan
Arbiscan (Arbitrum) Arbiscan
Solana Explorer Solana
Polygonscan (Polygon) Polygonscan
BscScan (BSC) BscScan
TronScan Tron
NFTScan NFTScan
Ftmscan (Fantom) Ftmscan
SnowTrace (Avalanche) SnowTrace
Harmony Block Explorer Harmony
Terra Finder Terra
NEAR Explorer NEAR
Flow Explorer Flow
Tezos Beacon Tezos
Algorand Explorer Algorand

具体获取流程

  1. 注册或登录账号:访问 对应的区块链浏览器网站,例如 Etherscan,如果没有账号,请注册一个新账号。如果已有账号,请登录。
  2. 进入 API 密钥页面:在登录状态下,导航到 API-KEYs 页面
  3. 创建新密钥:点击“Add”按钮,输入描述信息,然后创建 API 密钥。

通过以上步骤,你可以轻松获取不同区块链浏览器的 API 密钥,并将其用于 Foundry 的合约验证。

确保在使用过程中妥善保管你的 API 密钥,避免泄露。

参考链接

  1. Foundry 官方文档 Forge Deploying
  2. Foundry 官方文档中文版 Forge Verify-Contract
  3. Arbitrum Sepolia Testnet 官方文档 Sepolia Arbiscan
  4. GitHub Issue Error verifying contract on arb sepolia