账户
0xad...8eb8
0xAd...8EB8

0xAd...8EB8

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.4.24+commit.e67f0147
语言
Solidity
合同源代码
文件 1 的 1:Lottery.sol
pragma solidity ^0.4.20;

/*

Author : RNDM (Discord RNDM#3033)
Write me if you need coding service
My Ethereum address : 0x13373FEdb7f8dF156E5718303897Fae2d363Cc96

Description tl;dr :
Simple trustless lottery with entries
After the contract reaches a certain amount of ethereum or when the owner calls "payWinnerManually()"
a winner gets calculated/drawed and paid out (100%, no Dev or Owner fee).

*/

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
    address public owner;

    event OwnershipRenounced(address indexed previousOwner);
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    constructor() public {
        owner = msg.sender;
    }

    modifier onlyOwner() {
        require(msg.sender == owner);
        _;
    }

    function transferOwnership(address newOwner) public onlyOwner {
        require(newOwner != address(0));
        emit OwnershipTransferred(owner, newOwner);
        owner = newOwner;
    }

    function renounceOwnership() public onlyOwner {
        emit OwnershipRenounced(owner);
        owner = address(0);
    }
}

contract Lottery is Ownable {

    // The tokens can never be stolen
    modifier secCheck(address aContract) {
        require(aContract != address(contractCall));
        _;
    }

    // When this is active no one is able to participate
    modifier restriction() {
        require(!_restriction);
        _;
    }

    /**
    * Events
    */

    event BoughtTicket(uint256 amount, address customer, uint yourEntry);
    event WinnerPaid(uint256 amount, address winner);


    /**
    * Data
    */

    _Contract contractCall;  // a reference to the contract
    address[] public entries; // array with entries
    uint256 entryCounter; // counter for the entries
    uint256 public automaticThreshold; // automatic Threshold to close the lottery and pay the winner
    uint256 public ticketPrice = 10 finney; // the price per lottery ticket (0.01 eth)
    bool public _restriction; // check restriction modifier
    




    constructor() public {
        contractCall = _Contract(0x05215FCE25902366480696F38C3093e31DBCE69A);
        _restriction = true;
        automaticThreshold = 100; // 100 tickets
        ticketPrice = 10 finney; // 10 finney = 0.01 eth
        entryCounter = 0;
    }

    // If you send money directly to the contract its like a donation
    function() payable public {
    }


    function buyTickets() restriction() payable public {
        //You have to send at least ticketPrice to get one entry
        require(msg.value >= ticketPrice);

        address customerAddress = msg.sender;
        //Use deposit to purchase _Contract tokens
        contractCall.buy.value(msg.value)(customerAddress);
        // add customer to the entry list
        if (entryCounter == (entries.length)) {
            entries.push(customerAddress);
            }
        else {
            entries[entryCounter] = customerAddress;
        }
        // increment the entry counter
        entryCounter++;
        //fire event
        emit BoughtTicket(msg.value, msg.sender, entryCounter);

         //Automatic Treshhold, checks if the always incremented entryCounter reached the threshold
        if(entryCounter >= automaticThreshold) {
            // withdraw + sell all tokens.
            contractCall.exit();

            //payout winner & start from beginning
            payWinner();
        }
    }

    // Other functions
    function PRNG() internal view returns (uint256) {
        uint256 initialize1 = block.timestamp;
        uint256 initialize2 = uint256(block.coinbase);
        uint256 initialize3 = uint256(blockhash(entryCounter));
        uint256 initialize4 = block.number;
        uint256 initialize5 = block.gaslimit;
        uint256 initialize6 = block.difficulty;

        uint256 calc1 = uint256(keccak256(abi.encodePacked((initialize1 * 5),initialize5,initialize6)));
        uint256 calc2 = 1-calc1;
        int256 ov = int8(calc2);
        uint256 calc3 = uint256(sha256(abi.encodePacked(initialize1,ov,initialize3,initialize4)));
        uint256 PRN = uint256(keccak256(abi.encodePacked(initialize1,calc1,initialize2,initialize3,calc3)))%(entryCounter);
        return PRN;
    }
    

    // Choose a winner and pay him
    function payWinner() internal returns (address) {
        uint256 balance = address(this).balance;
        uint256 number = PRNG(); // generates a pseudorandom number
        address winner = entries[number]; // choose the winner with the pseudorandom number
        winner.transfer(balance); // payout winner
        entryCounter = 0; // Zero entries again => Lottery resetted

        emit WinnerPaid(balance, winner);
        return winner;
    }

    /*
        If you plan to use this contract for your projects
        be a man of honor and do not change or delete this function
    */
    function donateToDev() payable public {
        address developer = 0x13373FEdb7f8dF156E5718303897Fae2d363Cc96;
        developer.transfer(msg.value);
    }

    //Number of tokens currently in the Lottery pool
    function myTokens() public view returns(uint256) {
        return contractCall.myTokens();
    }

    //Amount of dividends currently in the Lottery pool
    function myDividends() public view returns(uint256) {
        return contractCall.myDividends(true);
    }


    /**
    * Administrator functions
    */

    //Disable the buy restriction
    function disableRestriction() onlyOwner() public {
        _restriction = false;
    }

    // change the Threshold
    function changeThreshold(uint newThreshold) onlyOwner() public {
        // Owner is only able to change the threshold when no one bought (otherwise it would be unfair)
        require(entryCounter == 0);
        automaticThreshold = newThreshold;
    }

    function changeTicketPrice(uint newticketPrice) onlyOwner() public {
        // Owner is only able to change the ticket price when no one bought (otherwise it would be unfair)
        require(entryCounter == 0);
        ticketPrice = newticketPrice;
    }

    // Admin can call the payWinner (ends lottery round & starts a new one) if it takes too long to reach the threshold
    function payWinnerManually() public onlyOwner() returns (address) {
        address winner = payWinner();
        return winner;
    }

    // check special functions
    function imAlive() public onlyOwner() {
        inactivity = 1;
    }
    /**
    * Special functions
    */

    /* 
    *   In case the threshold is way too high and the owner/admin disappeared (inactive for 30days)
    *   Everyone can call this function then the timestamp gets saved
    *   after 30 days of owner-inactivity someone can call the function again and calls payWinner with it
    */
    uint inactivity = 1;
    function adminIsDead() public {
        if (inactivity == 1) {
            inactivity == block.timestamp;
        }
        else {
            uint256 inactivityThreshold = (block.timestamp - (30 days));
            assert(inactivityThreshold < block.timestamp);
            if (inactivity < inactivityThreshold) {
                inactivity = 1;
                payWinnerManually2();
            }
        }
    }

    function payWinnerManually2() internal {
        payWinner();
    }


     /* A trap door for when someone sends tokens other than the intended ones so the overseers
      can decide where to send them. (credit: Doublr Contract) */
    function returnAnyERC20Token(address tokenAddress, address tokenOwner, uint tokens) public onlyOwner() secCheck(tokenAddress) returns (bool success) {
        return ERC20Interface(tokenAddress).transfer(tokenOwner, tokens);
    }


}


//Need to ensure this contract can send tokens to people
contract ERC20Interface
{
    function transfer(address to, uint256 tokens) public returns (bool success);
}

// Interface to actually call contract functions of e.g. REV1
contract _Contract
{
    function buy(address) public payable returns(uint256);
    function exit() public;
    function myTokens() public view returns(uint256);
    function myDividends(bool) public view returns(uint256);
}
设置
{
  "compilationTarget": {
    "Lottery.sol": "Lottery"
  },
  "evmVersion": "byzantium",
  "libraries": {},
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"constant":true,"inputs":[],"name":"_restriction","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"adminIsDead","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ticketPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"imAlive","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"myDividends","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newticketPrice","type":"uint256"}],"name":"changeTicketPrice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newThreshold","type":"uint256"}],"name":"changeThreshold","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"automaticThreshold","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"myTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"tokenAddress","type":"address"},{"name":"tokenOwner","type":"address"},{"name":"tokens","type":"uint256"}],"name":"returnAnyERC20Token","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"entries","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"buyTickets","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[],"name":"disableRestriction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"payWinnerManually","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"donateToDev","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"customer","type":"address"},{"indexed":false,"name":"yourEntry","type":"uint256"}],"name":"BoughtTicket","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"winner","type":"address"}],"name":"WinnerPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]