以下代码工作正常,直到我决定将以下两个依赖项从 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 面向未来。
“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));
};
};