web3:无法读取新ethers之后的null的属性。

发布于 2025-01-24 17:02:36 字数 1825 浏览 3 评论 0原文

实例化之后,我正试图使用​​智能合约。但是,我有一个错误:

未被发现(在承诺中)TypeError:无法读取null的属性 (阅读“呼叫”)

我认为我在实例化之后就无法访问这些功能,但似乎并非如此。还可以是什么?有人已经有类似的问题吗?

当前代码:

import React, { useEffect, useState } from 'react';
import Head from 'next/head';

import { useWeb3React } from '@web3-react/core';
import NFTCollectionArtifact from 'artifacts/contracts/NFTCollection.sol/NFTCollection.json';
import { Contract, ethers, Signer } from 'ethers';
import { Provider } from '@openmint/utils/provider';

export const Index = () => {
  const context = useWeb3React<Provider>();
  const { library } = context;

  const [contractInstance, setContractInstance] = useState<Contract | undefined>();
  const [signer, setSigner] = useState<Signer>();
  const [name, setName] = useState<String>('');

  useEffect(() => {

    const address = '0x5FbDB2315678afecb367f032d93F642f64180aa3';
    const nftCollection = new ethers.Contract(
      address,
      NFTCollectionArtifact.abi,
      signer
    );

    setContractInstance(nftCollection);
  }, []);

  useEffect(() => {
    if(!contractInstance) return;

    const setContractName = async () => {
      try{
        console.log(await contractInstance?.name());
        setName(await contractInstance?.name());
      } catch(e){
        console.error('my error', e);
      }
    }
  
    setContractName();
  }, [contractInstance]);

  useEffect((): void => {
    if (!library) {
      setSigner(undefined);
      return;
    }

    setSigner(library.getSigner());
  }, [library]);

  return (
    <>
      <Head>
        <title>Preview NFTs</title>
      </Head>
    </>
  );
};

export default Index;

I am trying to use a smart contract just after I instantiate it. However, I get an error:

Uncaught (in promise) TypeError: Cannot read properties of null
(reading 'call')

I thought I did not have access to the functions just after instantiating it, but it does not seem to be it. What else could it be? Someone already had a similar problem?

Current code:

import React, { useEffect, useState } from 'react';
import Head from 'next/head';

import { useWeb3React } from '@web3-react/core';
import NFTCollectionArtifact from 'artifacts/contracts/NFTCollection.sol/NFTCollection.json';
import { Contract, ethers, Signer } from 'ethers';
import { Provider } from '@openmint/utils/provider';

export const Index = () => {
  const context = useWeb3React<Provider>();
  const { library } = context;

  const [contractInstance, setContractInstance] = useState<Contract | undefined>();
  const [signer, setSigner] = useState<Signer>();
  const [name, setName] = useState<String>('');

  useEffect(() => {

    const address = '0x5FbDB2315678afecb367f032d93F642f64180aa3';
    const nftCollection = new ethers.Contract(
      address,
      NFTCollectionArtifact.abi,
      signer
    );

    setContractInstance(nftCollection);
  }, []);

  useEffect(() => {
    if(!contractInstance) return;

    const setContractName = async () => {
      try{
        console.log(await contractInstance?.name());
        setName(await contractInstance?.name());
      } catch(e){
        console.error('my error', e);
      }
    }
  
    setContractName();
  }, [contractInstance]);

  useEffect((): void => {
    if (!library) {
      setSigner(undefined);
      return;
    }

    setSigner(library.getSigner());
  }, [library]);

  return (
    <>
      <Head>
        <title>Preview NFTs</title>
      </Head>
    </>
  );
};

export default Index;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

茶底世界 2025-01-31 17:02:36

好的,我仍然不明白以下解决方案有效的全部图片,但是如果外面有人有类似的问题,这对我有用:

useEffect((): void => {
    if (!contractInstance) {
      return;
    }

    async function getStatus(MyContract: Contract): Promise<void> {
      const name = await MyContract.name();

      const newStatus: StatusInterface = {
        ...status,
        name
      };

      console.log('newStatus', newStatus);
      if (!isEqual(status, newStatus)) {
        setStatus(newStatus);
      }
    }

    getStatus(contractInstance);
  }, [contractInstance, status, account]);
  • 只有在有差异的
  • 情况 下改变状态对于功能,

我的理解是这是一个范围问题。

Ok, I still do not understand the whole picture of why the following solution works, but if anyone out there is having a similar issue, this was what worked for me:

useEffect((): void => {
    if (!contractInstance) {
      return;
    }

    async function getStatus(MyContract: Contract): Promise<void> {
      const name = await MyContract.name();

      const newStatus: StatusInterface = {
        ...status,
        name
      };

      console.log('newStatus', newStatus);
      if (!isEqual(status, newStatus)) {
        setStatus(newStatus);
      }
    }

    getStatus(contractInstance);
  }, [contractInstance, status, account]);
  • Only change the state if there is a difference
  • Pass the contract as a prop for the function

My understanding is that this was a scope issue.

〃安静 2025-01-31 17:02:36

确保您的环境配置已正确设置帐户。就我而言,这是因为我有一个额外的wallet_private_key =使用Ethers + Harthat时在我的.env中设置的行。

Make sure your environment config has an account set up correctly. In my case this was happening because I had an extra WALLET_PRIVATE_KEY= line set in my .env when using ethers + hardhat.

稀香 2025-01-31 17:02:36

通常可以看到签名对象无效/未定义。任何具有无效签名对象的活动(例如合同创建,呼叫,发送事务等)都会有错误:TypeError:无法在合同中读取Null(读取'call')的属性。 (node_modules@ethersproject \ Contracts \ src.ts \ index.ts:397:47)...

This is usually seen if the signer object is invalid/undefined. Any activity with an invalid signer object like contract creation, call, send transaction, etc, will have the error: TypeError: Cannot read properties of null (reading 'call') at Contract. (node_modules@ethersproject\contracts\src.ts\index.ts:397:47)...

猥琐帝 2025-01-31 17:02:36

以防万一 - 如果您在创建合同对象时根本不提供第三个参数,则可能发生:

contract = new ethers.Contract(address, abi);

正确的方法是:

contract = new ethers.Contract(address, abi, providerOrSigner);

我希望有更清晰的错误消息,字面上说您没有提供签名者/提供者。与其在合同对象的创建上默默地接受此内容,然后以毫无意义的堆栈跟踪读取null的属性(读取'call')。

Just in case - this can happen if you simply don't provide a third parameter when creating a contract object:

contract = new ethers.Contract(address, abi);

The proper way would be:

contract = new ethers.Contract(address, abi, providerOrSigner);

I wish there was a clearer error message that literally said you did not supply a signer/provider. Instead of silently accepting this on contract object creation, and then later throwing the cryptic TypeError: Cannot read properties of null (reading 'call') with a meaningless stack trace.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文