将 web3 从 1.x 升级到 4.x 后,由于“setProvider 不是函数”错误,无法连接到 MetaMask

问题描述 投票:0回答:1

以下代码工作正常,直到我决定将以下两个依赖项从 1.7.5 版本升级到最新版本:

"web3": "^4.1.1",
"web3-eth-contract": "^4.0.5"

更新后,当我使用我的应用程序连接到元掩码时,我收到 TypeError:

"web3_eth_contract__WEBPACK_IMPORTED_MODULE_0__.default.setProvider is not a function"

错误指向的行: Web3EthContract.setProvider(以太坊);

import Web3EthContract from "web3-eth-contract";
import Web3 from "web3";
import MyContractABI from "../../contracts/myContractABI.json";
import { fetchData } from "../data/dataActions";

const connectRequest = () => {
  return {
    type: "CONNECTION_REQUEST",
  };
};

const connectSuccess = (payload) => {
  return {
    type: "CONNECTION_SUCCESS",
    payload: payload,
  };
};

const connectFailed = (payload) => {
  return {
    type: "CONNECTION_FAILED",
    payload: payload,
  };
};

const updateAccountRequest = (payload) => {
  return {
    type: "UPDATE_ACCOUNT",
    payload: payload,
  };
};

export const connect = () => {
  return async (dispatch) => {
    dispatch(connectRequest());
    const { ethereum } = window;
    const metamaskIsInstalled = ethereum && ethereum.isMetaMask;
    await window.ethereum.request({
      method: "eth_requestAccounts",
    });
    if (metamaskIsInstalled) {
     // In the next line the code shows the following error:
     // TypeError: web3_eth_contract__WEBPACK_IMPORTED_MODULE_0__.default.setProvider is not a function
      Web3EthContract.setProvider(ethereum);
      let web3 = new Web3(ethereum);
      try {
        const accounts = await ethereum.request({
          method: "eth_requestAccounts",
        });
        const networkId = await ethereum.request({
          method: "net_version",
        });
        if (networkId == 679420) { // this is a local ganache testing net ID
          const myContract = new Web3EthContract( MyContractABI, "0x3d7Eec9C41c7A99489fD27e6B087f9C827b16d3F"); 
          dispatch(
            connectSuccess({
              account: accounts[0],
              _myContract: myContract,      
              web3: web3,
            })
          );
          ethereum.on("accountsChanged", (accounts) => {
              window.location.reload();
          });
          ethereum.on("chainChanged", () => {
            window.location.reload();
          });
        } else {
          dispatch(connectFailed("Change Metamask Network to Polygon and Connect again!"));
        }
      } catch (err) {
        dispatch(connectFailed("Could not connect to Polygon Network. Check MetaMask settings."));
        console.log(err);
      }
    } else {
      dispatch(connectFailed("Please install Metamask to your browser extensions, and try again!"));
    }
  };
};
export const updateAccount = (account) => {
  return async (dispatch) => {
    dispatch(updateAccountRequest({ account: account }));
    dispatch(fetchData(account));
  };
};

我尝试在这里查看最新的官方语法: 《如何使用 web3-eth-contract 中的 web3-eth-contract.setProvider 函数》 snyk.io/advisor/npm-package/web3-eth-contract

我还在这里查看了官方的重大更改列表: docs.web3js.org/guides/web3_upgrade_guide

我看不出我做错了什么,最新的例子似乎使用了完全相同的语法,但老实说我还不太理解 web3 代码。如果我恢复到上述依赖项的 1.75 版本,我的 dapp 将连接到元掩码并且工作正常。 我没有具体的理由想要从 1.75 版本升级,我只是想让我的 dapp 面向未来。

web3js metamask web3-react
1个回答
0
投票

“setProvider 不是函数”通常发生在您使用过时的库或库的 API 中存在重大更改时。

您可以按如下方式修改您的代码;我希望这有帮助。

    import Web3 from "web3"; 
    import Web3EthContract from "web3-eth-contract";
    import MyContractABI from "../../contracts/myContractABI.json";
    import { fetchData } from "../data/dataActions";

    export const connect = () => {
    return async (dispatch) => {
      dispatch(connectRequest());
      const { ethereum } = window;
      const metamaskIsInstalled = ethereum && ethereum.isMetaMask;
      await window.ethereum.request({
        method: "eth_requestAccounts",
      });
      if (metamaskIsInstalled) {
        let web3;
        try {
          const accounts = await ethereum.request({
            method: "eth_requestAccounts",
          });
          const networkId = await ethereum.request({
            method: "net_version",
          });
          if (networkId == 679420) {
            web3 = new Web3(ethereum); 
            const myContract = new web3.eth.Contract(
              MyContractABI,
              "0x3d7Eec9C41c7A99489fD27e6B087f9C827b16d3F"
            );
            dispatch(
              connectSuccess({
                account: accounts[0],
                _myContract: myContract,
                web3: web3,
              })
            );
            ethereum.on("accountsChanged", (accounts) => {
              window.location.reload();
            });
            ethereum.on("chainChanged", () => {
              window.location.reload();
            });
          } else {
            dispatch(
              connectFailed(
                "Change Metamask Network to Polygon and Connect again!"
              )
            );
          }
        } catch (err) {
          dispatch(
            connectFailed(
              "Could not connect to Polygon Network. Check MetaMask settings."
            )
          );
          console.log(err);
        }
      } else {
        dispatch(
          connectFailed(
            "Please install Metamask to your browser extensions, and try again!"
          )
        );
      }
    };
    };

    export const updateAccount = (account) => {
    return async (dispatch) => {
      dispatch(updateAccountRequest({ account: account }));
      dispatch(fetchData(account));
    };
    };
© www.soinside.com 2019 - 2024. All rights reserved.