Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Including some additional features in Lottery and Voting smart contract #306

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 173 additions & 23 deletions Level2/Lottery System/lottery.sol
Original file line number Diff line number Diff line change
@@ -1,31 +1,181 @@
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract Lottery{
address public manager;
address payable[] public participants;
// added VRF(verifiable random function contract and interface to generate truly random number)

constructor(){
manager = msg.sender;
}
receive() external payable{
require(msg.value>=100 wei);
participants.push(payable(msg.sender));
//for more information about VRF: https://docs.chain.link/vrf visit this website

import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
import "@chainlink/contracts/src/v0.8/interfaces/AutomationCompatibleInterface.sol";

error Lottery__SendMoreToEnterLottery();
error Lottery__LotteryNotOpen();
error Lottery__TransferFailed();
error Lottery__UpkeepNotNeeded(
uint256 currentBalance,
uint256 numPlayers,
uint256 LotteryState
);

contract Lottery is VRFConsumerBaseV2,AutomationCompatibleInterface{

// address payable[] public participants;

enum LotteryState {
OPEN,
CALCULATING
}



//Making Chainlink VRF Variables immutable to reduce gas consumption
VRFCoordinatorV2Interface private immutable i_vrfCoordinator;
uint64 private immutable i_subscriptionId;
bytes32 private immutable i_gasLane;
uint32 private immutable i_callbackGasLimit;
uint16 private constant REQUEST_CONFIRMATIONS = 3;
uint32 private constant NUM_WORDS = 1;
address public manager;

//making variable private as well as immuatable
uint256 private immutable i_interval;
uint256 private immutable i_entranceFee;
uint256 private s_lastTimeStamp;
address private s_recentWinner;
address payable[] private s_players;
LotteryState private s_LotteryState;

// Events
event RequestedLotteryWinner(uint256 indexed requestId);
event LotteryEnter(address indexed player);
event WinnerPicked(address indexed player);

constructor(
address vrfCoordinatorV2,
uint64 subscriptionId,
bytes32 gasLane,
uint256 interval,
uint256 entranceFee,
uint32 callbackGasLimit
)
VRFConsumerBaseV2(vrfCoordinatorV2) {
i_vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinatorV2);
i_gasLane = gasLane;
i_interval = interval;
i_subscriptionId = subscriptionId;
i_entranceFee = entranceFee;
s_LotteryState = LotteryState.OPEN;
s_lastTimeStamp = block.timestamp;
i_callbackGasLimit = callbackGasLimit;
manager=msg.sender;
}
// Defining functions

//Enter Lottery function with revert rathar than require which uses relativelt more gas

function enterLottery() public payable {
// require(msg.value >= i_entranceFee, "Not enough value sent");
// require(s_LotteryState == LotteryState.OPEN, "Lottery is not open");
if (msg.value < i_entranceFee) {
revert Lottery__SendMoreToEnterLottery();
}
function getBalance() public view returns(uint){
require(msg.sender==manager);
return address(this).balance;
if (s_LotteryState != LotteryState.OPEN) {
revert Lottery__LotteryNotOpen();
}
function random() public view returns(uint){
return uint(keccak256(abi.encodePacked(block.difficulty,block.timestamp,participants.length)));
s_players.push(payable(msg.sender));
emit LotteryEnter(msg.sender);
}

// In this function we check that we need to conduct lottery game or not
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 = (timePassed && isOpen && hasBalance && hasPlayers);
return (upkeepNeeded, "0x0"); // can we comment this out?
}


function performUpkeep(bytes calldata /* performData */) external override {
(bool upkeepNeeded, ) = checkUpkeep("");
if (!upkeepNeeded) {
revert Lottery__UpkeepNotNeeded(
address(this).balance,
s_players.length,
uint256(s_LotteryState)
);
}
function selectWinner() public{
require(msg.sender==manager);
require(participants.length>=3);
uint r = random();
address payable winner;
uint index = r % participants.length;
winner = participants[index];
winner.transfer(getBalance());
participants = new address payable[](0);
s_LotteryState = LotteryState.CALCULATING;
uint256 requestId = i_vrfCoordinator.requestRandomWords(
i_gasLane,
i_subscriptionId,
REQUEST_CONFIRMATIONS,
i_callbackGasLimit,
NUM_WORDS
);
emit RequestedLotteryWinner(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);
s_LotteryState = LotteryState.OPEN;
s_lastTimeStamp = block.timestamp;
(bool success, ) = recentWinner.call{ value: address(this).balance }("");
if (!success) {
revert Lottery__TransferFailed();
}
emit WinnerPicked(recentWinner);
}
//adding getter functions
function getLotteryState() public view returns (LotteryState) {
return s_LotteryState;
}

function getNumWords() public pure returns (uint256) {
return NUM_WORDS;
}

function getRequestConfirmations() public pure returns (uint256) {
return REQUEST_CONFIRMATIONS;
}

function getRecentWinner() public view returns (address) {
return s_recentWinner;
}

function getPlayer(uint256 index) public view returns (address) {
return s_players[index];
}

function getLastTimeStamp() public view returns (uint256) {
return s_lastTimeStamp;
}

function getInterval() public view returns (uint256) {
return i_interval;
}

function getEntranceFee() public view returns (uint256) {
return i_entranceFee;
}

function getNumberOfPlayers() public view returns (uint256) {
return s_players.length;
}
}
26 changes: 20 additions & 6 deletions Level2/Voting/Voting.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.0;
error Voting__NotOwner();
error Voting__AlreadyRegistered();

contract Voting {

address public owner;
address public winnerAddress;
string public eventName;
uint public totalVote;
bool votingStarted;
bool votingStarted;

struct Candidate{
string name;
Expand All @@ -34,11 +36,23 @@ contract Voting {
totalVote = 0;
votingStarted=false;
}

function registerCandidates(string memory _name, uint _age, address _candidateAddress) public {
require(msg.sender == owner, "Only owner can register Candidate!!");
require(_candidateAddress != owner, "Owner can not participate!!");
require(candidates[_candidateAddress] == 0, "Candidate already registered");
//added modifier function
modifier onlyOwner() {
require(msg.sender == owner, "Only the owner can call this function");
_;
}
// added revert instead of reequire to optimze gas ;

function registerCandidates(string memory _name, uint _age, address _candidateAddress) onlyOwner public {
// require(msg.sender == owner, "Only owner can register Candidate!!");
// require(_candidateAddress != owner, "Owner can not participate!!");
// require(candidates[_candidateAddress] == 0, "Candidate already registered");
if(_candidateAddress == owner){
revert Voting__NotOwner();
}
if(candidates[_candidateAddress] != 0){
revert Voting__AlreadyRegistered();
}
Candidate memory candidate = Candidate({
name: _name,
age: _age,
Expand Down
Loading