美文网首页
以太坊智能合约-猜数字

以太坊智能合约-猜数字

作者: embedsky | 来源:发表于2018-08-30 17:37 被阅读0次

准备

以太坊智能合约初探,完成猜数字游戏记录。
开发工具:智能合约在线编辑remix,可能需要翻墙使用。
浏览器钱包:matemask,需要翻墙安装在Chrome或者Firefox浏览器上面。使用brave(基于Chrome)浏览器也可以。
测试网络:matemask-RopstenTestNet获取测试ETH

思路

猜数字游戏规则:限定两个人玩,每个人从1-10中选中一个数字,然后下注一定金额的ETH。当两个人都下注完成之后开奖。开奖结果是随机生成一个随机数,谁猜的数字与随机数相同则赢得游戏,并获取两个人下注的所有ETH,如果都没猜中或者都猜中则平分所有下注的ETH。

参考古千峰老师猜数字游戏教程

碰到的坑:
1、remix的run标签里面设置Environment为injected web3,即使用matemask的测试网络。一直设置不成功,提示matemask未启动。多刷新几次
2、之前执行合约的bet方法,一直提示gas 计算不出来,导致交易无法完成,因为把checkPlayerExists这个方法声明成了private类型,改成public即就ok了。

pragma solidity ^0.4.20;

contract Casino{
    
    address public owner;
    uint8 private decimals = 18;//小数
    uint256 public mininumBet = 1*10**(uint256(decimals)-3);//
    uint256 public totalBet;
    uint256 public numberOfBets;
    uint256 constant public maxAmountOfBets=2;
    uint256 public numberGenerated;
    uint256 public winnerEtherAmount;
    address[] public players;
    
    struct Player{
        uint256 amontBets;
        uint256 numberSelected;
    }
    
    mapping(address=>Player) public playerInfo;
    
    // gouzao 
    constructor()public{
        owner=msg.sender;
    }
    
    function bet(uint256 numberSelected)public payable{
        require(!checkPlayerExists(msg.sender));
        require(numberSelected >= 1 && numberSelected <=10);
        require(msg.value >= mininumBet);
        require(numberOfBets<=maxAmountOfBets);
        
        playerInfo[msg.sender].amontBets = msg.value;
        playerInfo[msg.sender].numberSelected = numberSelected;
        numberOfBets++;
        players.push(msg.sender);
        totalBet += msg.value;
        
        if(numberOfBets>=maxAmountOfBets) generateNumberWinner();
    }
    
    function kill() public{
        if(msg.sender==owner) selfdestruct(owner);
    }
    
    function checkPlayerExists(address player) public constant returns(bool){
        for(uint8 i = 0 ; i < players.length ; i++ ){
            if( players[i]==player ) return true;
        }
        return false;
    }
    
    function generateNumberWinner() private{
        numberGenerated = (block.number % 10 +1);// bu an quan 
        distributePrizze(numberGenerated);
    }
    
    function distributePrizze(uint256 numberWinner) private{
        address[maxAmountOfBets] memory winners;
        bool hasWiner=false;
        uint256 count = 0;
        for(uint16 i = 0 ; i<players.length;++i){
            address playerAddress = players[i];
            if(playerInfo[i].numberSelected==numberWinner){
                winners[count]=playerAddress;
                count++;
            }
            delete playerInfo[playerAddress];
        }
        
        if(count==0){
            count = maxAmountOfBets;
            hasWiner = false;
        }else{
            hasWiner= true;
        }
        
        winnerEtherAmount = totalBet*95/100/count;
        
        for(uint16 j = 0; j < count ; j ++){
            if(hasWiner){
                if(winners[j]!=address(0)) winners[j].transfer(winnerEtherAmount);
            }else{
                if(players[j]!=address(0)) players[j].transfer(winnerEtherAmount);
            }
        }
        players.length = 0;
        totalBet=0;
        numberOfBets=0;
        
    }
}

相关文章

网友评论

      本文标题:以太坊智能合约-猜数字

      本文链接:https://www.haomeiwen.com/subject/poyrwftx.html