买了那么多彩票还是没中奖?那用智能合约写一个彩票网吧!天天冲!期期中!
Posted 小生凡一
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了买了那么多彩票还是没中奖?那用智能合约写一个彩票网吧!天天冲!期期中!相关的知识,希望对你有一定的参考价值。
目录
前言
这个项目是以前在网上学区块链的时候写的,现在才写出来做点笔记。
区块链小白一枚,也欢迎大家一起学习进步~
不过提醒一下,以太坊智能合约实际企业应用不多,这个了解一下即可,重点还是放在超级账本
上面吧!
业务逻辑分析
remix
编写智能合约
- 函数:智能合约接收投注的以太币(
payable
) - 状态变量:账户的保存(数组:[{0x00:1231242}, {0x01:1231242}, {0x00:1231243}])
- 函数:查询账户信息(需要接收
账户地址
,余额
,投注信息
) - 函数:开奖 (点击开奖按钮,随机生成中奖号码)
- 中奖号码状态变量: 存储中奖号码
- 中奖用户状态变量:存储中奖用户
go-web
对接智能合约,渲染数据到前端
-
操作智能合约
- 把投注人和对应的投注信息传到智能合约
- 查询投注人的投注信息(投注的号码)
- 查询指定账户的信息(余额)
- 开奖:(查询开奖结果)
-
渲染数据到前端
- 投注账户实现渲染到前端(长连接)
- 渲染投注信息
- 渲染余额信息
- 前端渲染
- 接收账户地址、账户交易密码,进行转账到智能合约
- 渲染信息
- 固定的智能合约代码
已经开源GitHub
:LotteryWeb
欢迎来star
目前已经把获取期数,投注,查询等功能做完了,后续会继续完善其他部分!(不摸的话)
演示一下~
1. 智能合约部分
1.1 编写智能合约
function RunLottery() public CheckOwner { // 开奖函数
for(int i=1;i<=4;i++){ // 红球从1-4里面随机选一个,选4次
uint256 random1 = uint256(keccak256(abi.encodePacked(block.difficulty, int(now)+i)));
uint256 num1 = random1 % 4 + 1; // 去掉0的就+1
retNums.push(num1);
}
// 蓝球从1-3里面随机选一个,选一次
uint256 random2 = uint256(keccak256(abi.encodePacked(block.difficulty, int(now)+5)));
uint256 num2 = random2 % 3 + 1; // 去掉0的+1
retNums.push(num2);
historyAccounts[total] = accounts; // 存储投注人和投注号码历史记录
historyRetNums[total] = retNums; // 存储彩票期数,开奖结果历史记录
delete accounts; // 清空投注记录
delete retNums; // 清空开奖结果数组
total = total + 1; //期数加一
}
1.2 生成abi文件
点击这里进行复制
然后复制这个ABI,生成一个abi文件
生成智能合约
所对应得go
文件
abigen --abi lottery.abi --pkg eth --type Lottery --out lottery.go
然后就会生成以通同名的lottery.go
文件目录
1.3 部署合约
启动私链
geth --datadir "lottery_data" --identidy "fanone_lottery" --rpc --rpcport 8545 --rpcapi "eth,personal,web3,net,db" --rpccorsdomain "*" console
连接,这个一定要选择Web3
但是由于账户是没有钱的,所以我们要进行挖矿
miner.start(2) 开始挖矿
miner.stop() 停止挖矿
挖矿完成之后,这两个账户就有钱了~
然后我们Deploy
部署就行。但是如下黄色框框这样的是还没成功部署的~
我们要通过挖矿来确认,是否部署成功
出现下面黄色框框这些就可以了,这样就部署成功了~
2. Go语言部分
2.1 连接以太坊智能合约
连接以太坊智能合约
var LotteryObj *Lottery
var err error
func init() {
client,err := ethclient.Dial("http://127.0.0.1:8545") //连接以太坊智能合约
if err != nil {
fmt.Println("连接以太坊智能合约出错")
}
contractAddr:="0xFAE1ed84956411e651C8B3abFcD21B131b3767f4" //合约地址
commonContractAddr := common.HexToAddress(contractAddr)
LotteryObj ,err = NewLottery(commonContractAddr,client) //实例化合约
if err != nil {
fmt.Println("实例化合约失败")
}
}
2.2 编写接口函数
- 获取投注信息
func GetBetAccounts() []map[string]interface{} {
var addrsMap []map[string]interface{}
var i int64 = 0
for {
addrStruct,err := LotteryObj.Accounts(nil,big.NewInt(i))
if err != nil {
break
}
addr := addrStruct.Addr
nums := addrStruct.Nums
newNums := strings.Split(nums," ")
addrMap := map[string]interface{}{}
addrMap["addr"] = addr
addrMap["nums"] = newNums
addrsMap = append(addrsMap,addrMap)
i++
}
return addrsMap
}
- 获取指定账户的函数
func GetAccountBalance(addr string) (*big.Int, error) {
balance,err:=LotteryObj.GetAccountBalance(nil,common.HexToAddress(addr))
return balance,err
}
2.3 成果演示
这里的1
就是我们智能合约里面的1
我们就可以成功连接到以太坊智能合约了~
其他功能也是类似的!就不过多说明了!
3. 前端部分
3.1 websocket 部分
使用ws进行长连接获取投注数据。
var ws = new WebSocket("ws://127.0.0.1:8080/get-accounts");
ws.onmessage = function (ev) {
var data = ev["data"];
// console.log(data);
data = jQuery.parseJSON(data);
// console.log(typeof data);
var accounts = data["account"];
var accounts_tag = document.getElementById("accounts");
// 所有的已有的子标签删除
var child = accounts_tag.lastElementChild;
while (child) {
accounts_tag.removeChild(child);
child = accounts_tag.lastElementChild;
}
for(var i=0;i<accounts.length; i++){
const addr = accounts[i]["addr"];
const tr = document.createElement("tr");
const td1 = document.createElement("td");
td1.innerText = addr;
const td2 = document.createElement("td");
const ul = document.createElement("ul");
ul.className = "kjh";
const nums = accounts[i]["nums"];
for(var j=0;j<nums.length;j++){
var li = document.createElement("li");
li.innerText = nums[j];
ul.appendChild(li);
}
td2.appendChild(ul);
tr.appendChild(td1);
tr.appendChild(td2);
accounts_tag.appendChild(tr);
}
};
3.1 例子说明
我们可以查询到账户的余额信息。
然后到remix中查看账户余额是一样的~
投注的数据也是一样的~
最后
小生凡一,期待你的关注。
以上是关于买了那么多彩票还是没中奖?那用智能合约写一个彩票网吧!天天冲!期期中!的主要内容,如果未能解决你的问题,请参考以下文章