准备
以太坊智能合约初探,完成猜数字游戏记录。
开发工具:智能合约在线编辑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;
}
}
网友评论