You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用Hardhat与Ethers.js开发时调用合约写函数触发MetaMask链ID不匹配错误求助

解决MetaMask RPC错误:Invalid chainId问题

从你的错误信息能直接定位核心问题:MetaMask连接的网络chainId和Hardhat本地节点的预期chainId(31337)不匹配。读函数能正常工作是因为它不需要用户签名,直接从节点拉取数据;但写交易需要MetaMask对交易签名,这时候会严格校验chainId是否一致,不匹配就会抛出这个错误。

下面是分步解决方法:

1. 明确配置Hardhat本地节点的chainId

虽然Hardhat默认本地节点的chainId是31337,但显式配置能避免潜在的不一致问题。修改你的hardhat.config.js

require("@nomicfoundation/hardhat-toolbox");
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
  solidity: "0.8.8",
  networks: {
    hardhat: {
      chainId: 31337 // 明确指定chainId,避免自动识别偏差
    }
  }
};

2. 确保MetaMask连接到正确的本地网络

打开MetaMask,检查当前连接的网络:

  • 如果还没添加Hardhat本地网络,手动添加:
    • RPC URL: http://localhost:8545
    • Chain ID: 31337
    • 货币符号: ETH
  • 如果已经添加,确认chainId确实是31337(有些时候MetaMask会自动识别错误,需要手动修正)。

3. 前端代码添加网络检测与切换逻辑

为了避免用户连接错网络,在你的Connect函数里添加chainId校验,自动请求切换到正确网络:
修改App.js里的Connect函数:

async function Connect() {
  if (window.ethereum) {
    try {
      // 检查当前chainId(十六进制格式)
      const currentChainId = await window.ethereum.request({ method: 'eth_chainId' });
      const targetChainId = '0x7A69'; // 31337的十六进制表示
      
      if (currentChainId !== targetChainId) {
        // 请求切换到目标网络
        await window.ethereum.request({
          method: 'wallet_switchEthereumChain',
          params: [{ chainId: targetChainId }],
        });
      }

      await window.ethereum.request({ method: 'eth_requestAccounts' })
      console.log('connected')
    } catch (error) {
      // 如果网络未添加,提示用户添加
      if (error.code === 4902) {
        try {
          await window.ethereum.request({
            method: 'wallet_addEthereumChain',
            params: [
              {
                chainId: '0x7A69',
                chainName: 'Hardhat Local',
                rpcUrls: ['http://localhost:8545'],
                nativeCurrency: {
                  name: 'Ether',
                  symbol: 'ETH',
                  decimals: 18
                }
              }
            ]
          });
        } catch (addError) {
          console.error('Failed to add network:', addError);
        }
      } else {
        console.log(error)
      }
    }
  }
}

额外注意事项

  • 确保你的Hardhat节点处于运行状态(执行npx hardhat node启动本地节点),并且部署合约时连接的是这个节点(执行npx hardhat run scripts/deploy.js --network localhost)。
  • 每次重启Hardhat节点后,之前部署的合约地址会失效,需要重新部署并更新App.js里的contractAddressabi(你当前代码里这两个是空的,记得补上实际值)。

内容的提问来源于stack exchange,提问作者Maaz Ahmed

火山引擎 最新活动