In the process of learning blockchain programming, whether it's the most popular video tutorial on YouTube or the Alchemy's solidity bootcamp, content related to Hardhat is inevitable. This is not surprising as in the field of Web3 development, Hardhat is undoubtedly one of the most mainstream frameworks. However, I encountered the same pitfall in the process of learning these two courses, that is, after using Hardhat to deploy smart contracts, I could never succeed in the verification. The same error always occurred:
An unexpected error occurred:
ConnectTimeoutError: Connect Timeout Error
......
I searched on Google for a long time but didn't find a complete solution. Then I tried to ask GPT-4 but still failed to solve it. Eventually, I found some insights in this post on GitHub. Now, in combination with the actual process of solving this problem myself, I will record the process of analysis and verification, hoping to help those who also encounter this problem.
curl http://google.com
command, so the inability to use Hardhat's verify function should not be a problem with the proxy settings.Environment configuration: I have a simple example project here, which deploys an upgradeable contract. You can refer to my package.json file. Many answers online are quite outdated, but my libraries are all up to date. Of particular note is the need to install the Undici library, which will be used to set the proxy for verification.
Writing the contract and deployment script: This is a standard step and not the focus of this article. But if you are a beginner like me, you can also refer to the simple contract and deployment script in my aforementioned repository. After the writing is done, we can deploy the contract under the Hardhat localhost environment or on the testnet. However, only when deployed on the testnet or mainnet can we use Hardhat's verify plugin.
Apply for an API key on the Etherscan website, which is free. After application, create a new .env file in the root directory of the Hardhat project and paste ETHERSCAN_KEY=yourApiKey
into it. Then set it in the hardhat.config.js configuration file. You can also refer to the configuration method in this file in my repository.
Use the ip route | grep default | awk '{print $3}'
command to view your IP address, assuming it's http://xxx.xx.xxx.x, then check the "LAN" corresponding HTTP port through the VPN client in your Windows environment, assuming it's yyyyy. Add the following content to your hardhat.config.js file:
const { ProxyAgent, setGlobalDispatcher } = require("undici");
const proxyAgent = new ProxyAgent("http://xxx.xx.xxx.x:yyyyy");
setGlobalDispatcher(proxyAgent);
Please note that you should not use the IP address and port in the aforementioned GitHub post, because everyone's VPN client and IP are different. The post also mentioned looking at the DNS server IP using cat /etc/resolv.conf
and adding it to the configuration. But if you, like me, share the Windows proxy in the WSL2 environment, then your DNS is likely set by yourself, such as 8.8.8.8. So using the method I mentioned in the fourth point above is the safest. Also, don't forget to turn on options like "Allow LAN connections" in your VPN client. If your client doesn't have this option, you may need to switch to another one.
Use the npx hardhat verify --network yourNetWork CONTRACT_ADDRESS
command to verify the contract, or you can write an additional verification function in the deployment script, which will complete the verification immediately after deployment.