Keepers for Lottery - Lesson 7 #893
-
Hi, I'm trying to run keepers for the lottery in Lesson 7. I pass the startLottery function the time interval to end the lottery and in the checkUpKeep function I check if enough time has passed to performUpKeep which calls the endLottery function. The problem that I encounter is the LOTTERY_STATE never gets updates and it gets stuck at state = 2 (Calculating Winner) // SPDX-License-Identifier: MIT
pragma solidity ^0.6.6;
import "@chainlink/contracts/src/v0.7/interfaces/AggregatorV3Interface.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@chainlink/contracts/src/v0.7/VRFConsumerBase.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@chainlink/contracts/src/v0.7/KeeperCompatible.sol";
contract Lottery is VRFConsumerBase, Ownable {
address payable[] public players;
address payable public recentWinner;
uint256 public randomness;
uint256 public usdEntryFee;
uint256 internal interval;
AggregatorV3Interface internal ethUsdPriceFeed;
enum LOTTERY_STATE {
OPEN,
CLOSED,
CALCULATING_WINNER
}
LOTTERY_STATE public lottery_state;
uint256 public fee;
bytes32 public keyhash;
event RequestedRandomness(bytes32 requestId);
// 0
// 1
// 2
constructor(
address _priceFeedAddress,
address _vrfCoordinator,
address _link,
uint256 _fee,
bytes32 _keyhash
) public VRFConsumerBase(_vrfCoordinator, _link) {
usdEntryFee = 50 * (10**18);
ethUsdPriceFeed = AggregatorV3Interface(_priceFeedAddress);
lottery_state = LOTTERY_STATE.CLOSED;
fee = _fee;
keyhash = _keyhash;
}
function enter() public payable {
// $50 minimum
require(lottery_state == LOTTERY_STATE.OPEN);
require(msg.value >= getEntranceFee(), "Not enough ETH!");
players.push(msg.sender);
}
function getEntranceFee() public view returns (uint256) {
(, int256 price, , , ) = ethUsdPriceFeed.latestRoundData();
uint256 adjustedPrice = uint256(price) * 10**10; // 18 decimals
// $50, $2,000 / ETH
// 50/2,000
// 50 * 100000 / 2000
uint256 costToEnter = (usdEntryFee * 10**18) / adjustedPrice;
return costToEnter;
}
function startLottery(uint256 _interval) public onlyOwner {
require(
lottery_state == LOTTERY_STATE.CLOSED,
"Can't start a new lottery yet!"
);
lottery_state = LOTTERY_STATE.OPEN;
interval = _interval;
lastTimeStamp = block.timestamp;
}
function endLottery() public {
lottery_state = LOTTERY_STATE.CALCULATING_WINNER;
bytes32 requestId = requestRandomness(keyhash, fee);
emit RequestedRandomness(requestId);
}
function fulfillRandomness(bytes32 _requestId, uint256 _randomness)
internal
override
{
require(
lottery_state == LOTTERY_STATE.CALCULATING_WINNER,
"You aren't there yet!"
);
require(_randomness > 0, "random-not-found");
uint256 indexOfWinner = _randomness % players.length;
recentWinner = players[indexOfWinner];
recentWinner.transfer(address(this).balance);
// Reset
players = new address payable[](0);
lottery_state = LOTTERY_STATE.CLOSED;
randomness = _randomness;
}
function checkUpkeep(
bytes calldata /* checkData */
)
external
override
returns (
bool upkeepNeeded,
bytes memory /* performData */
)
{
upkeepNeeded = (block.timestamp - lastTimeStamp) > interval;
}
function performUpkeep(
bytes calldata /* performData */
) external override {
lastTimeStamp = block.timestamp;
interval = 0;
endLottery();
}
}
I appreciate any help with this issue. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
Hello @as you are using keepers to manage the timestamp, I suggest to increase the time it waits, as fulfill randomness is an asynchronous functions it make be taking more time to get completed. Also could you please share your deploy script here? |
Beta Was this translation helpful? Give feedback.
Hello @as you are using keepers to manage the timestamp, I suggest to increase the time it waits, as fulfill randomness is an asynchronous functions it make be taking more time to get completed.
Also could you please share your deploy script here?