在React中使用ABI和Ether.js查询智能合约



我有一个部署到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 中从类切换到功能组件

相关内容

  • 没有找到相关文章

最新更新