合約地址: 0xbee0e72afae3727b66b07ae894e961618be1c028d3c5a808a737df8ae84895e2
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Lottery {
address[] public players;
address public recentWinner;
address private _owner;
uint256 private _totalMoney;
uint256 public entranceFee;
// 建立onlyOwner的modifier
modifier onlyOwner(){
require (msg.sender==_owner, "This action can only be activated by the owner");
_;
}
// 定義enum
enum LOTTERY_STATE{
CLOSED,
OPEN,
DRAWING
}
// 宣告enum
LOTTERY_STATE state;
constructor() {
_owner=msg.sender;
state=LOTTERY_STATE.CLOSED;
_totalMoney=0;
}
function enter() public payable{
require(state==LOTTERY_STATE.OPEN, "Lottery isn't open!");
require(msg.value>=entranceFee, "You don't have enough money!");
_totalMoney+=msg.value;
players.push(msg.sender);
}
function startLottery(uint256 setEntranceFee) public onlyOwner(){
require(state!=LOTTERY_STATE.OPEN, "Lottery is already open!");
state=LOTTERY_STATE.OPEN;
entranceFee=setEntranceFee;
}
function endLottery() public onlyOwner(){
require(state!=LOTTERY_STATE.CLOSED, "Action not applicable");
state=LOTTERY_STATE.DRAWING;
uint256 indexOfWinner = uint256(
keccak256(
abi.encodePacked(msg.sender, block.difficulty, block.timestamp)
)
)%players.length;
(bool success, )=payable(players[indexOfWinner]).call{value: _totalMoney}("");
require(success, "Transaction failed");
_totalMoney=0;
recentWinner=players[indexOfWinner];
delete players;
state=LOTTERY_STATE.CLOSED;
}
}
將變數初始化、設定莊家為部署合約的人。
首先檢查樂透狀態、交易發起人的金額是否可支付入場費,兩條件皆符合才將其加入參加者名冊。
先透過onlyOwner() modifier確認交易發起人為莊家後才准許執行後續動作。一開始確認樂透不是開放狀態以避免重複開場,接著才將樂透狀態設為開放,並透過此函式設定入場費。
一開始將state設定為正在抽獎中,接著隨機選出中獎者號碼,將彩金轉帳給得獎者,轉帳成功後將彩金金額歸零,並將其設為最近得獎者,最後才將players陣列清空、把樂透狀態設為關閉。
莊家設定入場費後開始樂透
檢視入場費
玩家1(0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2
)加入
顯示玩家1錢包地址 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2
玩家2(0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db
)加入
顯示玩家2錢包地址 0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db
此時檢視最近得獎者資訊,由於尚未開獎,數值為初始值0
此時以玩家2身分要求結束樂透,會遭到拒絕並顯示錯誤訊息 "This action can only be activated by the owner"
切換回莊家身分結束樂透後,顯示得獎者資訊,得獎者為 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2
(玩家1)