Try   HackMD

Programming Language Constructs Final Project

合約地址: 0xbee0e72afae3727b66b07ae894e961618be1c028d3c5a808a737df8ae84895e2

Code

// 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; } }

功能實作說明

constructor

將變數初始化、設定莊家為部署合約的人。

enter

首先檢查樂透狀態、交易發起人的金額是否可支付入場費,兩條件皆符合才將其加入參加者名冊。

startLottery

先透過onlyOwner() modifier確認交易發起人為莊家後才准許執行後續動作。一開始確認樂透不是開放狀態以避免重複開場,接著才將樂透狀態設為開放,並透過此函式設定入場費。

endLottery

一開始將state設定為正在抽獎中,接著隨機選出中獎者號碼,將彩金轉帳給得獎者,轉帳成功後將彩金金額歸零,並將其設為最近得獎者,最後才將players陣列清空、把樂透狀態設為關閉。

操作畫面截圖

莊家設定入場費後開始樂透

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

檢視入場費

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

玩家1(0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2)加入

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

顯示玩家1錢包地址 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

玩家2(0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db)加入

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

顯示玩家2錢包地址 0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

此時檢視最近得獎者資訊,由於尚未開獎,數值為初始值0

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

此時以玩家2身分要求結束樂透,會遭到拒絕並顯示錯誤訊息 "This action can only be activated by the owner"

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

切換回莊家身分結束樂透後,顯示得獎者資訊,得獎者為 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2(玩家1)

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →