尝试调用约定方法时发生Web3错误



我在尝试运行使用React、Truffle&Ganache。我也在使用web3版本1.7.1。问题是,代码在try/catch的catch(错误(序列中输入,然后显示它的正确意图。为什么会发生这种情况,为什么会出现以下错误?

index.js:1 TypeError: Cannot read properties of undefined (reading 'methods')
at HomePage.componentDidMount

代码应该做什么:显示类似于";地址为:0x0D05b3220E9cC7A90623fc506cEB64Ab885FD6C6";

代码的作用:它向我显示提示";未能加载web3、帐户或合同。检查控制台的细节";然后";地址为:0x0D05b3220E9cC7A90623fc506cEB64Ab885FD6C6";

代码如下:

import React, { Component } from "react";
import MySmartContract from "../contracts/MySmartContract.json";
import getWeb3 from "../getWeb3";
//Importing components

class HomePage extends Component {
constructor(props) {
super(props);
this.state = {
ContractInstance: undefined,
account: null,
web3: null,
isOwner: false
}
}
componentDidMount = async () => {
// For refreshing the page a single time
// so that web3 and instance is loaded every time
if (!window.location.hash) {
window.location = window.location + '#loaded';
window.location.reload();
}
try {
// Get network provider and web3 instance.
const web3 = await getWeb3();
// Use web3 to get the user's accounts.
const accounts = await web3.eth.getAccounts();
// Get the contract instance.
const networkId = await web3.eth.net.getId();
const deployedNetwork = MySmartContract.networks[networkId];
const instance = new web3.eth.Contract(
MySmartContract.abi,
deployedNetwork && deployedNetwork.address,
);
// Set web3, accounts, and contract to the state, and then proceed with an
// example of interacting with the contract's methods.
this.setState({ ContractInstance: instance, web3: web3, account: accounts[0] });

const owner = await this.state.ContractInstance.methods.getOwnerAddress().call();
if (this.state.account === owner) {
this.setState({ isOwner: true });
}

} catch (error) {
// Catch any errors for any of the above operations.
alert(
`Failed to load web3, accounts, or contract. Check console for details.`,
);
console.error(error);
}
};

render() {

if (!this.state.web3) {
return (

<h1>
Loading Web3, accounts and contract...
</h1>



)
}
return (
<div><h1>Address is: {this.state.account}</h1></div>
)
}
}
export default HomePage;

getWeb3.js的内容如下:

从"导入Web3";web3";;

const getWeb3 = () =>
new Promise((resolve, reject) => {
// Wait for loading completion to avoid race conditions with web3 injection timing.
window.addEventListener("load", async () => {
// Modern dapp browsers...
if (window.ethereum) {
const web3 = new Web3(window.ethereum);
try {
// Request account access if needed
await window.ethereum.enable();
// Accounts now exposed
resolve(web3);
} catch (error) {
reject(error);
}
}
// Legacy dapp browsers...
else if (window.web3) {
// Use Mist/MetaMask's provider.
const web3 = window.web3;
console.log("Injected web3 detected.");
resolve(web3);
}
// Fallback to localhost; use dev console port by default...
else {
const provider = new Web3.providers.HttpProvider(
"http://127.0.0.1:8545"
);
const web3 = new Web3(provider);
console.log("No web3 instance injected, using Local web3.");
resolve(web3);
}
});
});
export default getWeb3;

这段代码似乎是错误的!

this.setState({ ContractInstance: instance, web3: web3, account: accounts[0] });

const owner = await this.state.ContractInstance.methods.getOwnerAddress().call();

您不应该在设置后立即尝试使用状态值。

所以你需要在第二行调用你的函数,如下所示:

const owner = await instance.methods.getOwnerAddress().call();

注入的连接器代码示例

const ConnectToInjected = async () => {
let provider = null;
if (typeof window.ethereum !== 'undefined') {
provider = window.ethereum;
try {
await provider.request({ method: 'eth_requestAccounts' })
} catch (error) {
throw new Error("User Rejected");
}
} else if (window.web3) {
provider = window.web3.currentProvider;
} else if (window.celo) {
provider = window.celo;
} else {
throw new Error("No Web3 Provider found");
}
return provider;
};
export default ConnectToInjected;

用法:

const provider = await ConnectToInjected();
// Open metamask
await provider.request({ method: 'eth_requestAccounts' });
const web3 = new Web3(provider)

最新更新