Docker Desktop中本地Hardhat实例部署ERC20可升级合约超时问题
解决Docker Desktop本地Hardhat部署ERC20可升级合约超时问题
问题背景
在Docker Desktop运行的本地Hardhat环境中部署UUPS可升级ERC20合约时,触发部署超时错误。日志显示一个合约部署成功,另一个交易处于pending状态约1分钟后报错。
相关代码
智能合约代码
// SPDX-License-Identifier: MIT pragma solidity >=0.8.9; import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; contract ERC20Test is ERC20Upgradeable, OwnableUpgradeable, AccessControlUpgradeable, UUPSUpgradeable { function initialize() initializer public { __ERC20_init("Test1", "TST1"); __Ownable_init(); __AccessControl_init(); _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); } function _authorizeUpgrade(address newImplementation) internal onlyRole(DEFAULT_ADMIN_ROLE) override {} }
部署脚本
require("dotenv").config(); const hre = require("hardhat"); async function main() { try { const provider = new hre.ethers.providers.JsonRpcProvider( process.env.PROVIDER_URL ); const owner = new hre.ethers.Wallet(process.env.PRIVATE_KEY, provider); const Token = await hre.ethers.getContractFactory("Test1", owner); const token = await hre.upgrades.deployProxy(Token, ["Test1", "TST1"], { txOverrides: { maxFeePerGas: 10e9 }, initializer: "initialize", owner, }); console.log("Test Address:", token); } catch (err) { console.error(err); process.exit(1); } } main() .then(() => process.exit(0)) .catch((error) => { console.error(error); process.exit(1); });
错误信息
Timed out waiting for implementation contract deployment to address 0x... with transaction 0x...
解决方案
1. 调整Hardhat网络超时参数
在hardhat.config.js中延长交易超时时间,确保节点有足够时间处理部署:
module.exports = { networks: { localhost: { url: "http://localhost:8545", timeout: 120000, // 延长至120秒 gasPrice: 1000000000 } } };
2. 提升Docker资源分配
Docker默认资源不足可能导致本地节点处理缓慢:
- 打开Docker Desktop设置,进入Resources选项卡
- 增加CPU核心数(建议≥2核)和内存(建议≥4GB)
- 重启Docker容器使配置生效
3. 修正部署脚本参数错误
脚本存在两处关键问题,修正后如下:
require("dotenv").config(); const hre = require("hardhat"); async function main() { try { const provider = new hre.ethers.providers.JsonRpcProvider( process.env.PROVIDER_URL ); const owner = new hre.ethers.Wallet(process.env.PRIVATE_KEY, provider); // 合约名应为ERC20Test,而非Test1 const Token = await hre.ethers.getContractFactory("ERC20Test", owner); // 移除无效的owner参数,增加gasLimit确保部署资源足够 const token = await hre.upgrades.deployProxy(Token, [], { txOverrides: { maxFeePerGas: 10e9, gasLimit: 3000000 }, initializer: "initialize", }); // 等待合约完全部署完成 await token.deployed(); console.log("Test Address:", token.address); } catch (err) { console.error(err); process.exit(1); } } main() .then(() => process.exit(0)) .catch((error) => { console.error(error); process.exit(1); });
4. 清理本地节点缓存
旧缓存可能导致交易卡住:
- 停止Hardhat节点和Docker容器
- 删除项目下的
cache和artifacts目录 - 重启节点重新部署
5. 确认Gas参数合理性
通过hre.ethers.provider.getFeeData()获取节点建议的Gas价格,以此为基准设置maxFeePerGas;手动指定gasLimit为3000000或更高,避免因Gas不足导致交易pending。
内容的提问来源于stack exchange,提问作者Kasun Abaywardana
相关产品推荐
相关产品推荐

