智能合约猜数字游戏代码分析
2020-03-08 本文已影响0人
playnumbers
拿playnumbers.xyz网站来举例如何实现公平赌博:
此网站链接:playNumbers
一、智能合约部分:
此网站每人提供一个随机数,然后将所有随机数相加,再加上开奖时间来取得随机数。
1.1 投注部分
function placeBetA(uint256 _s, uint256 _g) external payable {
uint256 s = _s;
//s是随机数
uint256 g = _g;
//g是所猜的结果
require(msg.value == BET_PRICE, "every bet need pay 0.1 ether");
//检查每注需要0.1 ETH
require(aTimes < 2, "already full, refund firstly");
//检查猜的次数不能大于2
require(g == 0 || g == 1, "only 0 or 1(guessnumber)");
//提供的随机数只能0或者1
require(s == 0 || s == 1, "only 0 or 1(seed)");
//提供的猜的数也只能是0或者1
aTimes++;
//竞猜次数增加1
if (aTimes == 2) {
//如果是第二次猜的话
require(aBets[1].gnum != g, "should not same!");
//不能跟第一次猜的数字一致
}
seedId += 1;
//存储的位置加一
sTable[seedId] = s;
//stable是private的,为了防止别人看到提供的种子数,将s转存到其他地方
aBets[aTimes].seed = seedId;
//将投注的seed只存储保存种子的位置
aBets[aTimes].gnum = g;
//保存猜的数字
aBets[aTimes].addr = msg.sender;
//保存竞猜人的地址
emit placeBetEvent(msg.sender, 2, aBets[aTimes].gnum, now);
//触发投注事件
}
1.2 开奖部分
function revealA() external {
require(aTimes == 2, "only refund with 2 bets");
//开奖先检查是否已经有2人来竞猜
aBets[1].seed = sTable[aBets[1].seed];
//将private竞猜的种子拉出来
aBets[2].seed = sTable[aBets[2].seed];
//将第二个private的种子拿出来
aBets[3].seed = now % 2;
//将开奖的事件作为第三个种子,除以2得到随机数
aBets[3].addr = msg.sender;
//将开奖地址存储起来
aBets[3].gnum = now;
//将开奖的竞猜数也设置成开奖时间
uint256 finalNumber = (aBets[1].seed + aBets[2].seed + aBets[3].seed) %2;
//最终随机数就是将三个随机数相加,除2取余
address payable winner;
if (aBets[1].gnum == finalNumber) {
//如果第一个猜中
winner = aBets[1].addr;
//将第一个地址设置成获奖者
} else {
winner = aBets[2].addr;
//如果不是第一个猜中,就是第二个猜中了
}
sendFunds(winner, 0.198 ether, 2);
//发送奖金
aTimes = 0;
//将竞猜次数归零
//将开奖的过程数据转存道4、5、6的位置
aBets[4] = aBets[1];
aBets[5] = aBets[2];
aBets[6] = aBets[3];
}
二、前端用react来写,代码待续