Ethereum Lottery Example Part 3: Collecting an Entrance Fee

See Part 2 Here

Code Change: https://github.com/samuelfrench/solidity-lottery/commit/96c1763400c3b0f8603695ee4d4e4ef537f98df8

pragma solidity 0.6.12;
import "github.com/provable-things/ethereum-api/provableAPI_0.6.sol";

contract Lotto is usingProvable {
    address[] public entrants;
    mapping(address => uint) public balances;
    
    address public winner;
    bytes32 provableQueryId;
    
    function enter() external payable {
        if(balances[msg.sender] == 0 && msg.value==5000){
            balances[msg.sender] = msg.value;
            entrants.push(msg.sender);
        } //else you have not paid the entry fee or have already entered
    }
    
    function getLotteryBalance() external returns (uint256) {
       return address(this).balance;
    }
    
    function selectWinner() public {
        if(winnerHasNotBeenSet() && provableQueryHasNotRun()){
            provableQueryId = provable_query("WolframAlpha", constructProvableQuery());
        }
    }
    
    function winnerHasNotBeenSet() private view returns (bool){
        return winner == address(0);
    }
    
    function provableQueryHasNotRun() private view returns (bool){
        return provableQueryId == 0;
    }
    
    function constructProvableQuery() private view returns (string memory){
        return strConcat("random number between 0 and ", uint2str(entrants.length-1));
    }
    
    //provable callback for selectWinner function
    function __callback(bytes32 myid, string memory result) public override {
        if(myid != provableQueryId) revert();
        winner = entrants[parseInt(result)];
    }
}

Changelog:

  1. Add balances mapping to have a constant-time way to look up entrants
  2. Make enter a payable function to accept an entrance fee
    • Check entrance fee
    • Check balance to see if they’ve entered before
  3. Add getLotteryBalance for debugging
  4. Update solidity version (not shown in commit)
    1. Add override modifier to provable callback function (updating the language version requires it)

Notes:

  1. I need to start using separate PRs to make it easy to isolate changes between previous postings
  2. Initially it was unclear to me how to send a value with a function call, use the value field by the contract deploy button before invoking a payable function

Leave a Reply

Your email address will not be published. Required fields are marked *