账户
0x33...a667
0x33...a667

0x33...a667

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.5.16+commit.9c3226ce
语言
Solidity
合同源代码
文件 1 的 1:CryptoGames.sol
// ╔══╗╔═══╗╔╗╔╗╔═══╗╔════╗╔══╗╔═══╗╔══╗╔╗──╔╗╔═══╗──╔══╗─╔═══╗╔════╗
// ║╔═╝║╔═╗║║║║║║╔═╗║╚═╗╔═╝║╔╗║║╔══╝║╔╗║║║──║║║╔══╝──║╔╗║─║╔══╝╚═╗╔═╝
// ║║──║╚═╝║║╚╝║║╚═╝║──║║──║║║║║║╔═╗║╚╝║║╚╗╔╝║║╚══╗──║╚╝╚╗║╚══╗──║║
// ║║──║╔╗╔╝╚═╗║║╔══╝──║║──║║║║║║╚╗║║╔╗║║╔╗╔╗║║╔══╝──║╔═╗║║╔══╝──║║
// ║╚═╗║║║║──╔╝║║║─────║║──║╚╝║║╚═╝║║║║║║║╚╝║║║╚══╗╔╗║╚═╝║║╚══╗──║║
// ╚══╝╚╝╚╝──╚═╝╚╝─────╚╝──╚══╝╚═══╝╚╝╚╝╚╝──╚╝╚═══╝╚╝╚═══╝╚═══╝──╚╝


//By playing platform games you agree that your age is over 21 and you clearly understand that you can lose your coins
//The platform is not responsible for all Ethereum cryptocurrency losses during the game.
//The contract uses the entropy algorithm Signidice
//https://github.com/gluk256/misc/blob/master/rng4ethereum/signidice.md

pragma solidity 0.5.16;

library SafeMath {
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a * b;
    assert(a == 0 || c / a == b);
    return c;
  }

  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a / b;
    return c;
  }

  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    assert(b <= a); 
    return a - b; 
  } 
  
  function add(uint256 a, uint256 b) internal pure returns (uint256) { 
    uint256 c = a + b; assert(c >= a);
    return c;
  }
}

contract CryptoGames {
    using SafeMath for uint;
    address payable public  owner = 0x333333e25F2176e2e165Aeb1b933cE10Cf315b47;
    address public  CROUPIER_BOB = 0xB0B3336c83A4c86FBd4f804BB8D410B23F181b05;
    uint public minStake = 0.01 ether;
    uint public maxStake = 15 ether;
    uint public constant WIN_COEFFICIENT = 198;
    uint public constant DICE_COEFFICIENT = 600;
    mapping(address => uint) public deposit;
    mapping(address => uint) public withdrawal;
    bool status = true;

    enum GameState {
        Pending,
        Win,
        Lose,
        Draw
    }
    
    enum Games {
        CoinFlip,
        KNB,
        Dice
    }

    struct Game {
        Games game_title;
        address payable player;
        uint bet;
        bytes32 seed;
        GameState state;
        uint result;
        bytes choice;
        uint profit;
    }

    event NewGame(address indexed player, bytes32 seed, uint bet, bytes choice, string  game);
    event DemoGame(address indexed player, bytes32 seed, uint bet, bytes choice, string  game);
    event ConfirmGame(address indexed player, string  game, uint profit, bytes choice, uint game_choice, bytes32 seed, bool status, bool draw,  uint timestamp);
    event Deposit(address indexed from, uint indexed block, uint value, uint time);
    event Withdrawal(address indexed from, uint indexed block, uint value, uint ident,uint time);
    mapping(bytes32 => Game) public listGames;
    
    // Only our croupier and no one else can open the bet
    modifier onlyCroupier() {
        require(msg.sender == CROUPIER_BOB);
        _;
    }
    
    // Check that the rate is between 0.01 - 15 ether
    modifier betInRange() {
        require(minStake <= msg.value && msg.value <= maxStake);
        _;
    }
    
    modifier onlyOwner {
        require(msg.sender == owner); _;
    }
    
    modifier isNotContract() {
        uint size;
        address addr = msg.sender;
        assembly { size := extcodesize(addr) }
        require(size == 0 && tx.origin == msg.sender);
        _;
    }
    
    modifier contractIsOn() {
        require(status);
        _;
    }

    // Game CoinFlip
    // The game of tossing a coin, the coin has 2 sides,
    // an eagle and a tails, which one is up to you to choose
    function game_coin(bytes memory _choice, bytes32 seed) public betInRange payable returns(uint8) {
        string memory game_title = 'CoinFlip';
        uint8 user_choice;
        assembly {user_choice := mload(add(0x1, _choice))}
        require(listGames[seed].bet == 0x0);
        require(_choice.length == 1);
        require(user_choice == 0 || user_choice == 1);
        
        listGames[seed] = Game({
            game_title: Games.CoinFlip,
            player: msg.sender,
            bet: msg.value,
            seed: seed,
            state: GameState.Pending,
            choice: _choice,
            result: 0,
            profit: 0
        });
        emit NewGame(msg.sender, seed, msg.value, _choice, game_title);
        return user_choice;
    }
    
    // Game KNB
    // Game of stone, scissors, paper
    // The stone breaks the scissors, the scissors cut the paper, the paper wraps the stone.
    // Everything is just kk in childhood, it remains only to try to play
    function game_knb(bytes memory _choice, bytes32 seed) public betInRange payable {
        string memory game_title = 'KNB';
        uint8 user_choice;
        assembly {user_choice := mload(add(0x1, _choice))}
        require(listGames[seed].bet == 0x0);
        require(_choice.length == 1);
        //Checking that bids are in the right range
        //1 - stone, 2 - scissors, 3 - paper
        require(user_choice >=1 && user_choice <=3);
        
        listGames[seed] = Game({
            game_title: Games.KNB,
            player: msg.sender,
            bet: msg.value,
            seed: seed,
            state: GameState.Pending,
            choice: _choice,
            result: 0,
            profit: 0
        });
       emit NewGame(msg.sender, seed, msg.value, _choice, game_title);
    }
    
    // Game Dice
    // Playing dice, the player can select up to 5 dice values at a time. The more dice a player chooses, the less his final reward.
    // The reward is calculated according to the formula:  (6 / number of selected cubes) * bet
    function game_dice(bytes memory _choice, bytes32 seed) public betInRange payable {
        string memory game_title = 'Dice';
        require(listGames[seed].bet == 0x0);
        //Checking that bids are in the right range, and no more than 5 cubes are selected
        require(_choice.length >= 1 && _choice.length <= 5);
        
        // for(uint i=0; i< _choice.length; i++){
        //     require(_choice[i] > 0 && _choice[i] < 7);
        // }
        
        listGames[seed] = Game({
            game_title: Games.Dice,
            player: msg.sender,
            bet: msg.value,
            seed: seed,
            state: GameState.Pending,
            choice: _choice,
            result: 0,
            profit: 0
        });
        emit NewGame(msg.sender, seed, msg.value, _choice, game_title);
    }

    //Casino must sign the resulting value V with its PrivKey, thus producing the digital signature S = sign(PrivKey, V), and send the corresponding TX, containing S.
    //The contract recovers the actual public key (K) from the digital signature S, and verifies that it is equal to the previously published PubKey (K == PubKey).
    //If APK does not match PubKey, it is tantamount to cheating. In this case, the contract simply rejects the transaction.
    //The contract uses S as a seed for the predefined PRNG algorithm (e.g. SHA-3 based), which produces the lucky number (L), e.g. between 1 and 6.
    function confirm(bytes32 seed, uint8 _v, bytes32 _r, bytes32 _s) public onlyCroupier {
        // Checking that it was Uncle Bob who signed the transaction, otherwise we reject the impostor transaction
        require (ecrecover(seed, _v, _r, _s) == CROUPIER_BOB);
        Game storage game = listGames[seed];
        bytes memory choice = game.choice;
        game.result = uint256(_s) % 12;
        uint profit = 0;
        uint8 user_choice;
        //Our algorithms are very simple and understandable even to the average Internet user and do not need additional explanation
        //Coin game algorithm
        if (game.game_title == Games.CoinFlip){
            assembly {user_choice := mload(add(0x1, choice))}
            if(game.result == user_choice){
                profit = game.bet.mul(WIN_COEFFICIENT).div(100);
                game.state = GameState.Win;
                game.profit = profit;
                game.player.transfer(profit);
                emit ConfirmGame(game.player, 'CoinFlip', profit, game.choice, game.result, game.seed, true, false, now);
            }else{
                game.state = GameState.Lose;
                emit ConfirmGame(game.player, 'CoinFlip', 0, game.choice, game.result, game.seed, false, false, now);
            }
        //KNB game algorithm
        }else if(game.game_title == Games.KNB){
            assembly {user_choice := mload(add(0x1, choice))}
            if(game.result != user_choice){
                if (user_choice == 1 && game.result == 2 || user_choice == 2 && game.result == 3 || user_choice == 3 && game.result == 1) {
                    profit = game.bet.mul(WIN_COEFFICIENT).div(100);
                    game.state = GameState.Win;
                    game.profit = profit;
                    game.player.transfer(profit);
                    emit ConfirmGame(game.player, 'KNB', profit, game.choice, game.result, game.seed, true, false, now);
                }else{
                    game.state = GameState.Lose;
                    emit ConfirmGame(game.player, 'KNB', 0, game.choice, game.result, game.seed, false, false, now);
                }
            }else{
                profit = game.bet.sub(0.001 ether);
                game.player.transfer(profit);
                game.state = GameState.Draw;
                emit ConfirmGame(game.player, 'KNB', profit, game.choice, game.result, game.seed, false, true, now);
            }
        //Dice game algorithm
        }else if(game.game_title == Games.Dice){
            uint length = game.choice.length + 1;
            for(uint8 i=1; i< length; i++){
                assembly {user_choice  := mload(add(i, choice))}
                if (user_choice == game.result){
                    profit = game.bet.mul(DICE_COEFFICIENT.div(game.choice.length)).div(100);
                }
            }
            if(profit > 0){
                game.state = GameState.Win;
                game.profit = profit;
                game.player.transfer(profit);
                emit ConfirmGame(game.player, 'Dice', profit, game.choice, game.result, game.seed, true, false, now);
            }else{
                game.state = GameState.Lose;
                emit ConfirmGame(game.player, 'Dice', 0, game.choice, game.result, game.seed, false, false, now);
            }
        }
    }
    // Demo game, 0 ether value. To reduce the cost of the game, we calculate a random result on the server
    function demo_game(string memory game, bytes memory _choice, bytes32 seed, uint bet) public {
        emit DemoGame(msg.sender, seed, bet, _choice, game);
    }
    
    function get_player_choice(bytes32 seed) public view returns(bytes memory) {
        Game storage game = listGames[seed];
        return game.choice;
    }
    
    //The casino has its own expenses for maintaining the servers, paying for them, each signature by our bot Bob costs 0.00135 ether
    //and we honestly believe that the money that players own is ours, everyone can try their luck and play with us
    function pay_royalty (uint _value) onlyOwner public {
        owner.transfer(_value * 1 ether);
    }
    
    //automatic withdrawal using server bot
    function multisend(address payable[] memory dests, uint256[] memory values, uint256[] memory ident) onlyOwner contractIsOn public returns(uint) {
        uint256 i = 0;
        
        while (i < dests.length) {
            uint transfer_value = values[i].sub(values[i].mul(3).div(100));
            dests[i].transfer(transfer_value);
            withdrawal[dests[i]]+=values[i];
            emit Withdrawal(dests[i], block.number, values[i], ident[i], now);
            i += 1;
        }
        return(i);
    }
    
    function startProphylaxy()onlyOwner public {
        status = false;
    }
    
    function stopProphylaxy()onlyOwner public {
        status = true;
    }
    // recharge function for games
    function() external isNotContract contractIsOn betInRange payable {
        deposit[msg.sender]+= msg.value;
        emit Deposit(msg.sender, block.number, msg.value, now);
    }
}

//P̴̩͖͈̳o̷̡̳̭̞͔̺̩̩w̸̡̡̡̤̹͙͔̜̮̟̺̬̰͔͉͉͎͉̠̝͜ͅe̵̜̤̹ŗ̶̹̞̰̭̹̭̻̤͔͈͓͉ę̵̡͉͚̲̞̘͙̥̳͇͓̭ḑ̷̞̰̯̭͚͎̣͔̜̝̬͜ͅͅ ̵̣̲b̷̢͙͈̣̝̩͔͉͖y̷̢̱̠̙̘̹̟̠̙͖͍̹̦͍ͅ ̵̡̢̠̗͎͍͕̯̹͈͈̬̹c̷̢̪̪͎̺̠̤̮̙̜̞͈̞̝̭̭r̸̥̯̩̩̝̟͉̲̪̣̬̟̮̤̲̜y̵̗̬͓͎̻̱̝̗͕̟͙̯͇̜̤̲͔̭̫͓p̸̢͇͇̠̪t̵̹̳̮͇͜ǫ̸̙̬ͅͅģ̵̹̬͉̫̣͔̝̳̘̰̘̤̮a̸̡͖̮͙̯̬̰̫̫̘͎͎̰͇̹̜̼̥͚͇͉͔͚͓m̸̢̫̙̫̮̪͕̭̟̬̣̟̫̦͙̖ȩ̸̡̧̟̰̯͖̲͍̳͚̘̦͎̙̥̫͎̺̤̮͜ͅ.̴̨̱̲͚b̸͍͔e̶̡̡̡̜̬͓̤̣͍̝͚͖̘͈̱̘̲̠͓͍͙͉̯͍t̵̻̮
//
//
设置
{
  "compilationTarget": {
    "CryptoGames.sol": "CryptoGames"
  },
  "evmVersion": "istanbul",
  "libraries": {},
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"string","name":"game","type":"string"},{"indexed":false,"internalType":"uint256","name":"profit","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"choice","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"game_choice","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"seed","type":"bytes32"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"},{"indexed":false,"internalType":"bool","name":"draw","type":"bool"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"ConfirmGame","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"bytes32","name":"seed","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"bet","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"choice","type":"bytes"},{"indexed":false,"internalType":"string","name":"game","type":"string"}],"name":"DemoGame","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"uint256","name":"block","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"bytes32","name":"seed","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"bet","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"choice","type":"bytes"},{"indexed":false,"internalType":"string","name":"game","type":"string"}],"name":"NewGame","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"uint256","name":"block","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ident","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"Withdrawal","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[],"name":"CROUPIER_BOB","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DICE_COEFFICIENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"WIN_COEFFICIENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"seed","type":"bytes32"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"confirm","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"string","name":"game","type":"string"},{"internalType":"bytes","name":"_choice","type":"bytes"},{"internalType":"bytes32","name":"seed","type":"bytes32"},{"internalType":"uint256","name":"bet","type":"uint256"}],"name":"demo_game","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"deposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"_choice","type":"bytes"},{"internalType":"bytes32","name":"seed","type":"bytes32"}],"name":"game_coin","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"_choice","type":"bytes"},{"internalType":"bytes32","name":"seed","type":"bytes32"}],"name":"game_dice","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes","name":"_choice","type":"bytes"},{"internalType":"bytes32","name":"seed","type":"bytes32"}],"name":"game_knb","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"seed","type":"bytes32"}],"name":"get_player_choice","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"listGames","outputs":[{"internalType":"enum CryptoGames.Games","name":"game_title","type":"uint8"},{"internalType":"address payable","name":"player","type":"address"},{"internalType":"uint256","name":"bet","type":"uint256"},{"internalType":"bytes32","name":"seed","type":"bytes32"},{"internalType":"enum CryptoGames.GameState","name":"state","type":"uint8"},{"internalType":"uint256","name":"result","type":"uint256"},{"internalType":"bytes","name":"choice","type":"bytes"},{"internalType":"uint256","name":"profit","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minStake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address payable[]","name":"dests","type":"address[]"},{"internalType":"uint256[]","name":"values","type":"uint256[]"},{"internalType":"uint256[]","name":"ident","type":"uint256[]"}],"name":"multisend","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address payable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"pay_royalty","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"startProphylaxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"stopProphylaxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"withdrawal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]