Solution to the ConnectTimeoutError Encountered When Verifying Smart Contracts with Hardhat
Tags: solidity, hardhat, ethereum, smartcontract
Published: 2023-08-05 10:54:23

In the process of learning blockchain programming, whether it's the most popular [video tutorial](https://youtube.com/watch?v=gyMwXuJrbJQ) on YouTube or the Alchemy's [solidity bootcamp](https://university.alchemy.com), 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](https://github.com/smartcontractkit/full-blockchain-solidity-course-js/discussions/2247) 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.

## Firstly, I want to analyze the causes of this problem：
1. I'm using the WSL2 system. The proxy is set in the Windows environment, and the WSL2 system shares the proxy from the Windows environment. Therefore, the solution idea in the aforementioned post did not initially catch my attention. I originally thought that my WSL2 system had set up to share the proxy from the Windows environment, and that I could connect normally using the `curl http://google.com` command, so the inability to use Hardhat's verify function should not be a problem with the proxy settings.

2. Moreover, my error message and the content in the aforementioned post were quite different, aside from the ConnectTimeoutError. Given that Hardhat itself frequently updates, I thought it was an issue with the Hardhat version or a problem with one of its dependencies. What's more, GPT-4 analyzed the situation in the same way at the time, which somewhat misled my thinking.

3. I tried to upgrade and downgrade and adjust the versions of libraries and dependencies like Hardhat, @nomicfoundation/hardhat-verify, @nomicfoundation/hardhat-toolbox several times, and even tried to apply for multiple API keys on Etherscan, only to find it didn't help. In the end, I realized that although I globally shared the proxy from the Windows environment in WSL2, the verify plugin might not use the global proxy under the WSL2 environment when Hardhat is running due to some reason.

## Problem Solution and Contract Verification Process

1. Environment configuration: I have a simple [example project](https://github.com/codingJourneyFromUnemployment/my-upgradeable-contract) 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.

2. 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.

3. Apply for an API key on the [Etherscan](https://etherscan.io) 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.

4. 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);
    ```

5. 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.

6. 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.

#solidity #hardhat #ETH #etherscan #SmartContracts