Last active
July 19, 2023 21:13
-
-
Save grantjoy/0d0d5255625b37eaee35a0c7c36a5258 to your computer and use it in GitHub Desktop.
Coin Flip Contract
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: UNLICENSED | |
pragma solidity ^0.8.18; | |
contract CoinFlip { | |
enum CoinSide {HEADS, TAILS, UNKNOWN} | |
CoinSide public winSide = CoinSide.UNKNOWN; | |
struct Bet { | |
uint256 amount; | |
address payable bettor; | |
} | |
mapping(CoinSide => Bet) public bets; | |
mapping(CoinSide => uint256) public wins; | |
uint256 private constant BET_AMOUNT = 0.01 ether; | |
uint256 private constant SIDES = 2; | |
event BetPlaced(CoinSide winSide, address winAddress); | |
event WinSideDeclared(CoinSide winSide, address winAddress, address loseAddress); | |
function bet(CoinSide side) external payable { | |
require(msg.value == BET_AMOUNT, "Bet amount must be 0.01 Ether"); | |
require(bets[side].amount == 0, "A bet for this side has already been placed"); | |
bets[side] = Bet(msg.value, payable(msg.sender)); | |
emit BetPlaced(side, msg.sender); | |
if (bets[CoinSide.HEADS].amount == BET_AMOUNT && bets[CoinSide.TAILS].amount == BET_AMOUNT) { | |
flip(); | |
} | |
} | |
function flip() internal { | |
require(bets[CoinSide.HEADS].amount == BET_AMOUNT, "Heads bet not set"); | |
require(bets[CoinSide.TAILS].amount == BET_AMOUNT, "Tails bet required"); | |
require(address(this).balance >= BET_AMOUNT * SIDES, "Insufficient contract balance"); | |
winSide = getWinSide(); | |
CoinSide loseSide = (winSide == CoinSide.HEADS ? CoinSide.TAILS : CoinSide.HEADS); | |
address loseAddress = bets[loseSide].bettor; | |
address payable winAddress = bets[winSide].bettor; | |
wins[winSide]++; | |
winAddress.transfer(BET_AMOUNT * SIDES); | |
emit WinSideDeclared(winSide, winAddress, loseAddress); | |
reset(); | |
} | |
function getWinSide() internal view returns (CoinSide) { | |
uint256 random = uint256(keccak256(abi.encodePacked(block.timestamp))); | |
return CoinSide(random % SIDES); | |
} | |
function reset() internal { | |
delete bets[CoinSide.HEADS]; | |
delete bets[CoinSide.TAILS]; | |
winSide = CoinSide.UNKNOWN; | |
} | |
function getBet(CoinSide side) public view returns (uint256, address) { | |
return (bets[side].amount, bets[side].bettor); | |
} | |
function getWins(CoinSide side) public view returns (uint256) { | |
return wins[side]; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment