5月28日 05:33

如何在 Hardhat 中将智能合约部署到多个网络?

在以太坊开发中,一份智能合约往往需要先部署到本地网络调试,再发布到测试网验证,最后才上主网。Hardhat 提供了灵活的多网络部署机制,让你用同一套代码在不同链上完成发布和验证。

网络配置:hardhat.config 文件

部署的第一步是在配置文件中声明目标网络。在 hardhat.config.js(或 .ts)中添加 networks 字段:

javascript
require("@nomicfoundation/hardhat-toolbox"); require("dotenv").config(); module.exports = { solidity: "0.8.24", networks: { hardhat: { // 内置本地网络,无需额外配置 }, sepolia: { url: process.env.SEPOLIA_RPC_URL, accounts: [process.env.PRIVATE_KEY], chainId: 11155111, }, baseSepolia: { url: process.env.BASE_SEPOLIA_RPC_URL, accounts: [process.env.PRIVATE_KEY], chainId: 84532, }, mainnet: { url: process.env.MAINNET_RPC_URL, accounts: [process.env.PRIVATE_KEY], chainId: 1, }, }, };

RPC URL 和私钥通过 .env 文件管理,不要硬编码到代码中:

bash
# .env SEPOLIA_RPC_URL=https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY MAINNET_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY PRIVATE_KEY=your_private_key_here ETHERSCAN_API_KEY=your_etherscan_key

.env 文件务必加入 .gitignore,避免私钥泄露。

编写部署脚本

scripts/ 目录下创建部署脚本,使用 ethers.js 完成合约的部署和可选的验证:

javascript
const hre = require("hardhat"); async function main() { const Contract = await hre.ethers.getContractFactory("MyContract"); const contract = await Contract.deploy(); await contract.deployed(); console.log("Deployed to:", contract.address); // 仅在真实网络上验证合约 if (hre.network.name !== "hardhat" && hre.network.name !== "localhost") { console.log("Waiting for confirmations..."); await contract.deployTransaction.wait(6); try { await hre.run("verify:verify", { address: contract.address, constructorArguments: [], }); console.log("Contract verified on Etherscan"); } catch (e) { console.log("Verification failed:", e.message); } } } main() .then(() => process.exit(0)) .catch((error) => { console.error(error); process.exit(1); });

脚本逻辑很直观:先部署,再判断是否在真实网络上,如果是就等待 6 个区块确认后提交验证请求。验证失败不会中断流程,只会打印警告。

执行部署命令

部署时通过 --network 参数指定目标网络:

bash
# 本地测试 npx hardhat run scripts/deploy.js # Sepolia 测试网 npx hardhat run scripts/deploy.js --network sepolia # Base Sepolia 测试网 npx hardhat run scripts/deploy.js --network baseSepolia # 以太坊主网 npx hardhat run scripts/deploy.js --network mainnet

每次部署后,记录合约地址和构造函数参数。你可以在项目里维护一个 deployments.json 文件跟踪各网络的部署记录:

json
{ "sepolia": { "MyContract": "0x1234...abcd", "deployedAt": "2026-05-28" }, "mainnet": { "MyContract": "0x5678...efgh", "deployedAt": "2026-06-01" } }

使用 Hardhat Ignition(推荐方式)

Hardhat Ignition 是官方推荐的声明式部署方案,比脚本方式更可靠。它支持断点续部署、自动重试和并行执行。

ignition/modules/ 下创建部署模块:

javascript
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); module.exports = buildModule("MyContractModule", (m) => { const contract = m.contract("MyContract"); return { contract }; });

如果合约构造函数需要参数,直接传入:

javascript
module.exports = buildModule("TokenModule", (m) => { const initialSupply = m.getParameter("initialSupply", 1000000); const token = m.contract("MyToken", [initialSupply]); return { token }; });

部署时加上 --verify 可以一步完成部署和验证:

bash
# 部署到 Sepolia 并自动验证 npx hardhat ignition deploy ignition/modules/MyContractModule.js --network sepolia --verify # 部署到主网 npx hardhat ignition deploy ignition/modules/MyContractModule.js --network mainnet

Ignition 会将部署状态保存在 ignition/deployments/chain-{chainId}/ 目录下,即使中途中断也能从上次的位置继续,不会重复执行已完成的步骤。

配置 Etherscan 验证插件

合约验证需要安装并配置 @nomicfoundation/hardhat-verify 插件:

javascript
// hardhat.config.js require("@nomicfoundation/hardhat-verify"); module.exports = { // ... networks 配置 etherscan: { apiKey: { sepolia: process.env.ETHERSCAN_API_KEY, mainnet: process.env.ETHERSCAN_API_KEY, }, }, };

如果部署时忘记加 --verify,也可以事后手动验证:

bash
npx hardhat verify --network sepolia <CONTRACT_ADDRESS> <CONSTRUCTOR_ARGS>

验证成功后,任何人都能在 Etherscan 上直接读取和交互你的合约源码。

多网络部署的常见问题

部署时 nonce 冲突怎么办?

这通常是因为本地节点与远程网络状态不同步。检查 RPC 节点是否正常,或者在 MetaMask 中重置账户交易历史。

测试网 ETH 从哪里获取?

使用 Chainlink Faucet 或 Alchemy Faucet,每个钱包每天可以领取一定量的 Sepolia ETH。

主网部署有哪些注意事项?

务必使用多签钱包(如 Gnosis Safe)管理私钥,设置合理的 gas 上限避免过高手续费,部署前在测试网上完整走一遍流程。建议在主网部署时使用 maxFeePerGas 限制最高 gas 价格:

javascript
mainnet: { url: process.env.MAINNET_RPC_URL, accounts: [process.env.PRIVATE_KEY], chainId: 1, gasPrice: 20000000000, // 20 Gwei }

Ignition 部署中断了怎么恢复?

直接重新运行同一命令即可。Ignition 的 journal 机制会记录每一步执行状态,已完成的步骤不会重复执行。

掌握 Hardhat 的多网络部署流程后,你可以高效地在本地、测试网和主网之间切换发布合约,结合 Ignition 的声明式部署和自动验证功能,让整个发布流程更加可靠和可重复。

标签:Hardhat