Lesson 9: Function has override but does not override anything. #1690
-
Hello Friends, Please I am working on lesson 9, Raffle project. When I run hh compile, I get the error "Function has override but does not override anything". I have searched online but can't find solution, looked through the discussion section here too but the similar issue didn't solve my problem. Your help would be very much appreciated. Please here is my code below // SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/KeeperCompatible.sol";
error Raffle__NotEnoughETH();
error Raffle__TransferFailed();
error Raffle__NotOpen();
error Raffle__UpkeepNotNeeded(
uint256 currentBalance,
uint256 numPlayers,
uint256 raffleState
);
/**
* @title A sample Raffle Contract
* @author Erasmus Antwi
* @notice This contract is for creating an untamperable decentralized smart contract
* @dev This implements Chainlink VRF v2 and Chainlink Keepers
*/
abstract contract Raffle is VRFConsumerBaseV2, KeeperCompatible {
/* Type declarations */
enum RaffleState {
OPEN,
CALCULATING
}
/* State Variables */
uint256 private immutable i_entranceFee;
address payable[] private s_players;
VRFCoordinatorV2Interface private immutable i_vrfCoordinator;
bytes32 private immutable i_keyHash;
uint64 private immutable i_subscriptionId;
uint32 private immutable i_callbackGasLimit;
uint16 private constant REQUEST_CONFIRMATIONS = 3;
uint16 private constant NUM_WORDS = 1;
/* Lotery Variables */
address private s_recentWinner;
RaffleState private s_raffleState;
uint256 private s_lastTimeStamp;
uint256 private immutable i_interval;
/* Events */
event RaffleEntered(address indexed player);
event RequestedRaffleWinner(uint256 indexed requestId);
event WinnerPicked(address indexed winner);
constructor(
address vrfCoordinatorV2,
uint256 entranceFee,
bytes32 keyHash,
uint64 subscriptionId,
uint32 callbackGasLimit,
uint256 interval
) VRFConsumerBaseV2(vrfCoordinatorV2) {
i_entranceFee = entranceFee;
i_vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinatorV2);
i_keyHash = keyHash;
i_subscriptionId = subscriptionId;
i_callbackGasLimit = callbackGasLimit;
s_raffleState = RaffleState.OPEN;
s_lastTimeStamp = block.timestamp;
i_interval = interval;
}
function enterRaffle() public payable {
if (msg.value < i_entranceFee) {
revert Raffle__NotEnoughETH();
}
if (s_raffleState != RaffleState.OPEN) {
revert Raffle__NotOpen();
}
s_players.push(payable(msg.sender));
emit RaffleEntered(msg.sender);
}
/**
* @dev This is the functions that the Chainlink Keeper nodes call
*They look for the `upkeepNeeded` to return true.
*The following should be true in order to return true.
* 1. Our time interval should have passed.
* 2. The lotery should have at least 1 player, and have some ETH.
* 3. Our subscription is funded with LINK.
* 4. The lottery should be in an `open state`.
*/
function checkUpKeep(
bytes memory /*checkData*/
)
public
override
returns (
bool upKeepNeeded,
bytes memory /* performData */
)
{
bool isOpen = (s_raffleState == RaffleState.OPEN);
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);
}
function requestRandomWinner() external {
s_raffleState = RaffleState.CALCULATING;
uint256 requestId = i_vrfCoordinator.requestRandomWords(
i_keyHash,
i_subscriptionId,
REQUEST_CONFIRMATIONS,
i_callbackGasLimit,
NUM_WORDS
);
emit RequestedRaffleWinner(requestId);
}
function performUpKeep(
uint256, /*requestId*/
uint256[] memory randomWords
) external override {
(bool upKeepNeeded, ) = checkUpKeep("");
if (!upKeepNeeded) {
revert Raffle__UpkeepNotNeeded(
uint256(address(this).balance),
uint256(s_players.length),
uint256(s_raffleState)
);
}
uint256 indexOfWinner = randomWords[0] % s_players.length;
address payable recentWinner = s_players[indexOfWinner];
s_recentWinner = recentWinner;
s_raffleState = RaffleState.OPEN;
s_players = new address payable[](0);
s_lastTimeStamp = block.timestamp;
(bool success, ) = recentWinner.call{ value: address(this).balance }("");
if (!success) {
revert Raffle__TransferFailed();
}
emit WinnerPicked(recentWinner);
}
function getEntranceFee() public view returns (uint256) {
return i_entranceFee;
}
function getPlayer(uint256 index) public view returns (address) {
return s_players[index];
}
function getRecentWinner() public view returns (address) {
return s_recentWinner;
}
function getRaffleState() public view returns (RaffleState) {
return s_raffleState;
}
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;
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 4 comments 6 replies
-
you have mismatched the stuff // SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
import "@chainlink/contracts/src/v0.8/interfaces/KeeperCompatibleInterface.sol";
error Raffle__NotEnoughETH();
error Raffle__TransferFailed();
error Raffle__NotOpen();
error Raffle__UpkeepNotNeeded(
uint256 currentBalance,
uint256 numPlayers,
uint256 raffleState
);
/**
* @title A sample Raffle Contract
* @author Erasmus Antwi
* @notice This contract is for creating an untamperable decentralized smart contract
* @dev This implements Chainlink VRF v2 and Chainlink Keepers
*/
abstract contract Raffle is VRFConsumerBaseV2, KeeperCompatibleInterface {
/* Type declarations */
enum RaffleState {
OPEN,
CALCULATING
}
/* State Variables */
uint256 private immutable i_entranceFee;
address payable[] private s_players;
VRFCoordinatorV2Interface private immutable i_vrfCoordinator;
bytes32 private immutable i_keyHash;
uint64 private immutable i_subscriptionId;
uint32 private immutable i_callbackGasLimit;
uint16 private constant REQUEST_CONFIRMATIONS = 3;
uint16 private constant NUM_WORDS = 1;
/* Lotery Variables */
address private s_recentWinner;
RaffleState private s_raffleState;
uint256 private s_lastTimeStamp;
uint256 private immutable i_interval;
/* Events */
event RaffleEntered(address indexed player);
event RequestedRaffleWinner(uint256 indexed requestId);
event WinnerPicked(address indexed winner);
constructor(
address vrfCoordinatorV2,
uint256 entranceFee,
bytes32 keyHash,
uint64 subscriptionId,
uint32 callbackGasLimit,
uint256 interval
) VRFConsumerBaseV2(vrfCoordinatorV2) {
i_entranceFee = entranceFee;
i_vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinatorV2);
i_keyHash = keyHash;
i_subscriptionId = subscriptionId;
i_callbackGasLimit = callbackGasLimit;
s_raffleState = RaffleState.OPEN;
s_lastTimeStamp = block.timestamp;
i_interval = interval;
}
function enterRaffle() public payable {
if (msg.value < i_entranceFee) {
revert Raffle__NotEnoughETH();
}
if (s_raffleState != RaffleState.OPEN) {
revert Raffle__NotOpen();
}
s_players.push(payable(msg.sender));
emit RaffleEntered(msg.sender);
}
/**
* @dev This is the functions that the Chainlink Keeper nodes call
*They look for the `upkeepNeeded` to return true.
*The following should be true in order to return true.
* 1. Our time interval should have passed.
* 2. The lotery should have at least 1 player, and have some ETH.
* 3. Our subscription is funded with LINK.
* 4. The lottery should be in an `open state`.
*/
function checkUpkeep(
bytes memory /*checkData*/
)
public
override
returns (
bool upKeepNeeded,
bytes memory /* performData */
)
{
bool isOpen = (s_raffleState == RaffleState.OPEN);
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);
}
function performUpkeep(
bytes calldata /* performData */
) external override {
(bool upkeepNeeded, ) = checkUpkeep("");
// require(upkeepNeeded, "Upkeep not needed");
if (!upkeepNeeded) {
revert Raffle__UpkeepNotNeeded(
address(this).balance,
s_players.length,
uint256(s_raffleState)
);
}
s_raffleState = RaffleState.CALCULATING;
uint256 requestId = i_vrfCoordinator.requestRandomWords(
i_keyHash,
i_subscriptionId,
REQUEST_CONFIRMATIONS,
i_callbackGasLimit,
NUM_WORDS
);
emit RequestedRaffleWinner(requestId);
}
function fulfillRandomWords(
uint256, /* requestId */
uint256[] memory randomWords
) internal override {
uint256 indexOfWinner = randomWords[0] % s_players.length;
address payable recentWinner = s_players[indexOfWinner];
s_recentWinner = recentWinner;
s_players = new address payable[](0); // reseting player array
s_raffleState = RaffleState.OPEN;
s_lastTimeStamp = block.timestamp;
(bool success, ) = recentWinner.call{value: address(this).balance}("");
// require(success, "Transfer failed");
if (!success) {
revert Raffle__TransferFailed();
}
emit WinnerPicked(recentWinner);
}
function getEntranceFee() public view returns (uint256) {
return i_entranceFee;
}
function getPlayer(uint256 index) public view returns (address) {
return s_players[index];
}
function getRecentWinner() public view returns (address) {
return s_recentWinner;
}
function getRaffleState() public view returns (RaffleState) {
return s_raffleState;
}
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;
}
} |
Beta Was this translation helpful? Give feedback.
-
@refugedesigns Check your imports and first contract line, and match with this: import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
import "@chainlink/contracts/src/v0.8/KeeperCompatible.sol";
contract Raffle is VRFConsumerBaseV2, KeeperCompatibleInterface { |
Beta Was this translation helpful? Give feedback.
-
Hello @refugedesigns make sure your imports section is this way.
|
Beta Was this translation helpful? Give feedback.
-
Hello @refugedesigns There's several errors in your code, since we are overriding functions from another contracts, you need to be keen on the variables. YOu shouldn't change them. 2: The variable names for
function performUpkeep(
bytes calldata /*performData*/
) external override {
(bool upkeepNeeded, ) = checkUpkeep("");
if (!upkeepNeeded) {
revert Raffle__UpkeepNotNeeded(
uint256(address(this).balance),
uint256(s_players.length),
uint256(s_raffleState)
);
}
s_raffleState = RaffleState.CALCULATING;
uint256 requestId = i_vrfCoordinator.requestRandomWords(
i_keyHash,
i_subscriptionId,
REQUEST_CONFIRMATIONS,
i_callbackGasLimit,
NUM_WORDS
);
emit RequestedRaffleWinner(requestId);
}
function fulfillRandomWords(
uint256, /*requestId*/
uint256[] memory randomWords
) internal override {
uint256 indexOfWinner = randomWords[0] % s_players.length;
address payable recentWinner = s_players[indexOfWinner];
s_recentWinner = recentWinner;
s_raffleState = RaffleState.OPEN;
s_players = new address payable[](0);
s_lastTimeStamp = block.timestamp;
(bool success, ) = recentWinner.call{value: address(this).balance}("");
if (!success) {
revert Raffle__TransferFailed();
}
emit WinnerPicked(recentWinner);
} |
Beta Was this translation helpful? Give feedback.
Hello @refugedesigns There's several errors in your code, since we are overriding functions from another contracts, you need to be keen on the variables. YOu shouldn't change them.
A couple suggestions:
1: Your third import should be
interfaces/KeeperCompatibleInterface.sol
notv0.8/KeeperCompatible.sol
also change it in the contract declaration line:contract Raffle is VRFConsumerBaseV2, KeeperCompatibleInterface {
Be sure to add
interface
2: The variable names for
checkUpkeep
andperformUpkeep
should be identical to the same variables in the VRF contracts that we are inheriting. Do a search and replace and changecheckUpKeep
andperformUpKeep
tocheckUpkeep
andperformUpkeep
DON'T capit…