You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Wagmi调用合约owner函数返回0x报错求助

问题排查:Wagmi useContractRead调用owner函数返回空数据

问题背景

使用Wagmi(v1.3.9)、viem(v1.3.0)搭配Next.js 13(v13.4.12) App Router开发,已在layout.tsx中用WagmiProvider包裹子组件。ABI直接从Hardhat artifacts复制且包含owner函数,合约部署在Sepolia链,Etherscan和Remix可正常读取owner地址,但在Navbar组件中用useContractRead调用时,控制台报错:

ContractFunctionExecutionError: The contract function "owner" returned no data ("0x")

替换其他合约地址可正常返回owner,仅当前合约出现此问题。

相关代码

合约构造函数

constructor(
  uint256 _entryCost,
  uint64 subscriptionId
) VRFConsumerBaseV2(0x...) {
  COORDINATOR = VRFCoordinatorV2Interface(
    0x...
  );
  owner = msg.sender;
  entryCost = _entryCost;
  s_subscriptionId = subscriptionId;
}
"use client";

import { Container, Flex, Text } from "@chakra-ui/react";
import Link from "next/link";
import { RAFFLE_CONTRACT_ADDRESS, TOKENRAFFLE_CONTRACT_ABI } from "../../../const/";
import { Web3Button } from "@web3modal/react";
import { useAccount, useContractRead } from "wagmi";
import { useEffect, useState } from "react";

const Navbar = () => {
  const [mounted, setMounted] = useState<boolean>(false);

  const { address, isConnecting, isDisconnected } = useAccount();

  const {
    data: ownerAddress,
    isError,
    isLoading,
  } = useContractRead({
    address: RAFFLE_CONTRACT_ADDRESS,
    abi: TOKENRAFFLE_CONTRACT_ABI,
    functionName: "owner",
  });

  useEffect(() => {
    setMounted(true);
  }, []);

  if (!mounted) return <>></>;

  return (
    <Container
      maxW="1440px"
      py={8}
    >
      <Flex
        flexDirection="row"
        justifyContent="space-between"
        alignItems="center"
      >
        <Link href="/">
          <Text>RAFFLE APP</Text>
        </Link>
        <Flex
          flexDirection="row"
          alignItems="center"
        >
          {!isLoading && ownerAddress == address && (
            <Link href="/admin">
              <Text mr={4}>Admin</Text>
            </Link>
          )}
          <Web3Button />
        </Flex>
      </Flex>
    </Container>
  );
};

export default Navbar;

排查与解决方案

1. 确认合约地址与链配置匹配

  • 检查WagmiProvider的链配置是否为Sepolia,确保和合约部署链一致。如果Wagmi默认链不是Sepolia,需显式指定:
    const config = createConfig({
      chains: [sepolia],
      transports: {
        [sepolia.id]: http(),
      },
      // ...其他配置
    });
    
  • 核对RAFFLE_CONTRACT_ADDRESS是否为Sepolia链上的正确合约地址,避免复制错误或混淆测试链/主网地址。

2. 验证ABI的准确性

  • 检查TOKENRAFFLE_CONTRACT_ABI中owner函数的定义是否正确。如果合约中owner是公共状态变量,ABI应包含:
    {
      "inputs": [],
      "name": "owner",
      "outputs": [{"internalType": "address", "name": "", "type": "address"}],
      "stateMutability": "view",
      "type": "function"
    }
    
  • 确认ABI是从已部署的合约对应的Hardhat artifacts中复制的,而非本地未编译的合约文件。如果合约部署后有修改但未重新部署,ABI会不匹配。

3. 检查合约是否存在函数选择器冲突

  • 确认合约中没有其他签名相同的owner函数(比如参数不同但函数名相同的重载),这会导致函数选择器匹配错误,返回空数据。
  • 可在Etherscan上查看合约的Read Contract标签,确认owner函数的输入输出是否和ABI一致。

4. 显式指定链ID(可选)

在useContractRead中显式指定链ID,强制请求发送到Sepolia链,避免Wagmi使用钱包当前切换的其他链:

const {
  data: ownerAddress,
  isError,
  isLoading,
} = useContractRead({
  address: RAFFLE_CONTRACT_ADDRESS,
  abi: TOKENRAFFLE_CONTRACT_ABI,
  functionName: "owner",
  chainId: 11155111, // Sepolia链ID
});

5. 确认合约owner变量初始化正确

虽然构造函数中赋值了owner = msg.sender,但需确认合约部署时的发送地址是否正确,且合约没有被恶意篡改(比如部署后通过某种方式重置了owner变量)。可在Etherscan上调用owner函数验证返回值。

总结

最可能的原因是链配置不匹配或ABI与实际合约不对应,优先检查这两点。如果其他合约能正常调用,说明Wagmi的基础配置没问题,问题集中在当前合约的地址、ABI或链匹配上。

内容的提问来源于stack exchange,提问作者wrong24

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 08:43:15