我有一个部署到mainnet的合约。我有一个javascript文件,它导出函数,以便其他文件可以调用它们。我有一个按钮,从我的react调用getOwnerOfToken
。当我点击按钮时,没有任何事情发生,也没有任何记录。我知道,由于这是一个视图只读方法,我只需要提供程序(元任务(。在访问应用程序之前,我验证用户,以便使用window.ethereum
检测元任务。
// Gallery.js (a react component)
import React from "react";
import { getOwnerOfToken } from "../services/nftcontract";
class Gallery extends React.Component {
constructor(props){
//constructor stuff here
}
// called by onClick of a button in react
handleProfileChange = selected(selectedIndex) => {
getOwnerOfToken(selectedIndex).then((address) => {
this.setState({ currentSelectionnOwner: address });
console.log(this.state.currentSelectionnOwner);
});
}
render() {
// a button with the callback attached to onclick
<button onClick=onClick={() => this.handleProfileChange ()}>Change Profile</button>
}
}
这是在之上导入的service/nftcontract.js文件
import { ethers } from "ethers";
// Note: the full abi was copied from the ABI section found in etherscan.
// This is a simplified version for this example
const abi = [
{
inputs: [{ internalType: "uint256", name: "tokenId", type: "uint256" }],
name: "ownerOf",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
type: "function",
},
];
const provider = new ethers.providers.Web3Provider(window.ethereum);
const address = global.config.addresses.collections.genesis;
const contract = new ethers.Contract(address, abi, provider);
const getOwnerOfToken = async (tokenid) => {
return await contract.ownerOf(tokenid);
};
export { getOwnerOfToken };
使用解决方案编辑:我发现了问题!这是一个元任务注入问题。在启动时,在元任务注入窗口之前会发生异步调用。在我的情况下,这种情况并不总是发生,但在第一次访问该应用程序时会发生。因此,为了解决这个问题,我像这样移动了异步函数中的所有变量。因此,每当进行异步调用时,都会创建一个新的合约实例。
const getOwnerOfToken = async (tokenid) => {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const address = global.config.addresses.collections.genesis;
const contract = new ethers.Contract(address, abi, provider);
const ownerAddress = await contract.ownerOf(tokenid);
// console.log(`EFService: ${ownerAddress}`);
return ownerAddress;
};
您应该像这样调用provider
上的getSigner()
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
const address = global.config.addresses.collections.genesis;
const contract = new ethers.Contract(address, abi, signer);
getSigner()
来自官方文件
返回由该以太坊节点管理的JsonRpcSigner,位于addressOrIndex。如果没有提供addressOrIndex,则使用第一个帐户(帐户#0(。
您可以在此处阅读https://docs.ethers.io/v5/api/providers/jsonrpc-provider/
此外,请确保您在ethers.contract
中传递了正确的地址
ps:您应该在react 中从类切换到功能组件