买了那么多彩票还是没中奖?那用智能合约写一个彩票网吧!天天冲!期期中!

Posted 小生凡一

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了买了那么多彩票还是没中奖?那用智能合约写一个彩票网吧!天天冲!期期中!相关的知识,希望对你有一定的参考价值。

前言

这个项目是以前在网上学区块链的时候写的,现在才写出来做点笔记。
区块链小白一枚,也欢迎大家一起学习进步~
不过提醒一下,以太坊智能合约实际企业应用不多,这个了解一下即可,重点还是放在超级账本上面吧!

业务逻辑分析

  • remix编写智能合约
  1. 函数:智能合约接收投注的以太币(payable
  2. 状态变量:账户的保存(数组:[{0x00:1231242}, {0x01:1231242}, {0x00:1231243}])
  3. 函数:查询账户信息(需要接收账户地址余额投注信息
  4. 函数:开奖 (点击开奖按钮,随机生成中奖号码)
    1. 中奖号码状态变量: 存储中奖号码
    2. 中奖用户状态变量:存储中奖用户
  • go-web对接智能合约,渲染数据到前端
  1. 操作智能合约

    1. 把投注人和对应的投注信息传到智能合约
    2. 查询投注人的投注信息(投注的号码)
    3. 查询指定账户的信息(余额)
    4. 开奖:(查询开奖结果)
  2. 渲染数据到前端

    1. 投注账户实现渲染到前端(长连接)
    2. 渲染投注信息
    3. 渲染余额信息
  • 前端渲染
  1. 接收账户地址、账户交易密码,进行转账到智能合约
  2. 渲染信息
  3. 固定的智能合约代码

已经开源GitHubLotteryWeb

欢迎来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中查看账户余额是一样的~

投注的数据也是一样的~

最后

小生凡一,期待你的关注。

以上是关于买了那么多彩票还是没中奖?那用智能合约写一个彩票网吧!天天冲!期期中!的主要内容,如果未能解决你的问题,请参考以下文章

java一个彩票算法的问题

彩票算概率问题

彩票的预测

用循环与数组模拟双色球彩票中奖

彩票中奖机会练习

彩票网双色球历史开奖有些啥?