前端调用Solidity合约getEnteranceFee函数返回空数据(0x)求助
问题:调用Solidity合约view函数返回空数据(0x)
我基于Solidity和Next.js开发一款彩票DApp,将合约部署到本地Hardhat网络后,使用wagmi的useReadContract调用合约中的getEnteranceFee函数时,持续遇到错误:
ContractFunctionExecutionError: The contract function "getEnteranceFee" returned no data ("0x")
已确认合约地址正确、合约包含该函数,且仅传入了该函数的ABI,但问题仍未解决。以下是相关代码、部署输出及已执行的排查步骤:
Solidity合约代码
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; import "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol"; import "@chainlink/contracts/src/v0.8/vrf/dev/interfaces/IVRFCoordinatorV2Plus.sol"; import "@chainlink/contracts/src/v0.8/automation/interfaces/AutomationCompatibleInterface.sol"; import "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol"; error Lottery__NotEnoughETHEntered(); error Lottery_TransferFailed(); error Lottery_NotOpen(); error Lottery_UpKeepNotNeeded(uint256 currentBalance, uint256 numPlayers, uint256 lotteryState); contract Lottery is VRFConsumerBaseV2Plus, AutomationCompatibleInterface { /* Type declaration*/ enum LotteryState { OPEN, CALCULATING } //uint256 0=OPEN, 1=CALCULATING /* State Variables */ uint256 private immutable i_enteranceFee; address payable[] private s_players; // IVRFCoordinatorV2Plus private immutable i_vrfCoordinator; bytes32 private immutable i_gasLane; uint256 private immutable i_subscriptionId; uint32 private immutable i_callbackGasLimit; uint16 private constant REQUEST_CONFIRMATIONS = 3; uint32 private constant NUM_WORDS = 1; //Lottery Variables address private s_recentWinner; LotteryState private s_lotteryState; uint256 private s_lastTimeStamp; uint256 private immutable i_interval; /* Evnets*/ event LotteryEnter(address indexed player); event RequestedLotteryWinner(uint256 indexed requestId); event WinnerPicked(address indexed winner); /* Functions */ constructor( address vrfCoordinatorV2, //contract address uint256 enteranceFee, bytes32 gasLane, uint256 subscriptionId, uint32 callbackGasLimit, uint256 interval ) VRFConsumerBaseV2Plus(vrfCoordinatorV2) { i_enteranceFee = enteranceFee; // i_vrfCoordinator = IVRFCoordinatorV2Plus(vrfCoordinatorV2); i_gasLane = gasLane; i_subscriptionId = subscriptionId; i_callbackGasLimit = callbackGasLimit; s_lotteryState = LotteryState.OPEN; s_lastTimeStamp = block.timestamp; //block.timestamp is a globally known variable i_interval = interval; } function enterLottery() public payable { if (msg.value < i_enteranceFee) { revert Lottery__NotEnoughETHEntered(); } if (s_lotteryState != LotteryState.OPEN) { revert Lottery_NotOpen(); } s_players.push(payable(msg.sender)); emit LotteryEnter(msg.sender); } function checkUpkeep(bytes memory /*checkData*/ ) public view override returns (bool upKeepNeeded, bytes memory /* performData*/ ) { bool isOpen = (LotteryState.OPEN == s_lotteryState); bool timePassed = (block.timestamp - s_lastTimeStamp) > i_interval; bool hasPlayers = (s_players.length > 0); bool hasBalance = address(this).balance > 0; upKeepNeeded = (isOpen && timePassed && hasPlayers && hasBalance); return (upKeepNeeded, ""); } function performUpkeep(bytes calldata /*performData*/ ) external override { (bool upKeepNeeded,) = checkUpkeep(""); if (!upKeepNeeded) { revert Lottery_UpKeepNotNeeded(address(this).balance, s_players.length, uint256(s_lotteryState)); } s_lotteryState = LotteryState.CALCULATING; uint256 requestId = s_vrfCoordinator.requestRandomWords( VRFV2PlusClient.RandomWordsRequest({ keyHash: i_gasLane, //gasLane subId: i_subscriptionId, //Subscription ID that we need for funding requests (here it is to request a random number) requestConfirmations: REQUEST_CONFIRMATIONS, //It says how many confirmations the chainlink node should wait before responding callbackGasLimit: i_callbackGasLimit, //The limit for how much gas to use for the callback request to our contract's fulfillRandomWords() function. numWords: NUM_WORDS, // number of random words we need extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: false})) }) ); //THis is redudant!! emit RequestedLotteryWinner(requestId); } function fulfillRandomWords(uint256, /*requestId*/ uint256[] calldata randomWords) internal override { uint256 indexOfWinner = randomWords[0] % s_players.length; address payable recentWinner = s_players[indexOfWinner]; s_recentWinner = recentWinner; s_lotteryState = LotteryState.OPEN; s_players = new address payable[](0); s_lastTimeStamp = block.timestamp; (bool success,) = recentWinner.call{value: address(this).balance}(""); if (!success) { revert Lottery_TransferFailed(); } emit WinnerPicked(recentWinner); } /* view / pure functions*/ function getEnteranceFee() public view returns (uint256) { return i_enteranceFee; } function getPalyers(uint256 index) public view returns (address) { return s_players[index]; } function getRecentWinner() public view returns (address) { return s_recentWinner; } function getLotteryState() public view returns (LotteryState) { return s_lotteryState; } function getNumWords() public pure returns (uint256) { return NUM_WORDS; } function getNumberOfPlayers() public view returns (uint256) { return s_players.length; } function getLatestTimeStamp() public view returns (uint256) { return s_lastTimeStamp; } function getRequestConfirmations() public pure returns (uint256) { return REQUEST_CONFIRMATIONS; } function getInterval() public view returns (uint256) { return i_interval; } }
React组件代码
import React from "react" import { abi, contractAddresses } from "../constants" import { useAccount, useReadContract } from "wagmi" import { config } from "../config" import { useState, useEffect } from "react" const LotteryEntrance = () => { const [enteranceFee, setEnteranceFee] = useState(null) const [contractAddress, setContractAddress] = useState(null) const { isConnected, address } = useAccount() const account = useAccount() const chainId = account.chainId console.log("chainId:", chainId) // console.log(contractAddress[chainId][0]) useEffect(() => { const fetchContractAddress = async () => { if (chainId && contractAddresses[chainId]) { const address = contractAddresses[chainId][0] setContractAddress(address) console.log("Contract Address:", address) } else { console.error("Invalid chain ID or contract address not found for this chain") } } if (chainId) { fetchContractAddress() } }, [chainId]) const { data: fee, isLoading, error, } = useReadContract({ abi: [ { "inputs": [], "name": "getEnteranceFee", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, ], address: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9", functionName: "getEnteranceFee", args: [], enabled: !!contractAddress, }) console.log("fee:", fee) useEffect(() => { async function updateUI() { console.log("1") if (isConnected && fee) { console.log("2") const enteranceFee = await fee.toString() setEnteranceFee(enteranceFee) console.log("enteranceFee:", enteranceFee) } } updateUI() }, [isConnected, fee]) if (isLoading) return <div>Loading entrance fee...</div> if (error) { console.log(error) return <div>Error fetching entrance fee: {error.message}</div> } return <div>Lottery entrance fee: {enteranceFee ? `${enteranceFee}` : "N/A"}</div> } export default LotteryEntrance
Hardhat部署输出
Nothing to compile Local network detected! Deploying mocks... deploying "VRFCoordinatorV2_5Mock" (tx: 0x5610f99e25943d1e61152d198e3bc82947059e723c727708f35121f44c6722f6)...: deployed at 0x5FbDB2315678afecb367f032d93F642f64180aa3 with 3057197 gas Mocks Deployed! ---------------------------------------------------- local network detected ..... subscriptionId :105366054316822285762677720084519815636149581806396942115848005774721615015833 enterance fee: BigNumber { value: "5000000000000000" } deploying "Lottery" (tx: 0x3d42183eb5cbf3c183e843614df291642e287639272f171430967a49137c1696)...: deployed at 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9 with 1005908 gas Consumer is added -------------------------------------------
错误信息
The contract function "getEnteranceFee" returned no data ("0x").
已执行的排查步骤
- 将合约部署到本地Hardhat网络
- 确认部署输出中的合约地址正确
- 使用wagmi的useReadContract调用函数
- 确认合约中存在getEnteranceFee函数(为view类型)
寻求可能的问题原因及解决方案。
内容的提问来源于stack exchange,提问作者ALISHA REDDY
相关产品推荐
相关产品推荐

