(四)基于区块链的自动抽奖系统从0到1实现

这篇文章主要介绍了(四)基于区块链的自动抽奖系统从0到1实现 ,文中通过代码以及文档配合进行讲解,很详细,它对在座的每个人的研究和工作具有很经典的参考价值。 如果需要,让我们与区块链资料网一起学习。

https://www.interchains.cc/21427.html

(四)基于区块链的自动抽奖系统从0到1实现是很好的区块链资料,他说明了区块链当中的经典原理,可以给我们提供资料,(四)基于区块链的自动抽奖系统从0到1实现学习起来其实是很简单的,

不多的几个较为抽象的概念也很容易理解,之所以很多人感觉(四)基于区块链的自动抽奖系统从0到1实现比较复杂,一方面是因为大多数的文档没有做到由浅入深地讲解,概念上没有注意先后顺序,给读者的理解带来困难

(四)基于区块链blockchain的自动抽奖系统从0到1实现

  • 预言机

上一章节我们已经编写了核心的预言机合约,并且部署测试成功,现在我们就来写基于区块链blockchain的自动抽奖系统DAPP,java语言开发,项目功能比较少,所以采用框架springboot+thymeleaf。

前言

上一章节我们已经编写了核心的预言机合约,并且部署测试成功,现在我们就来写基于区块链blockchain的自动抽奖系统DAPP,java语言开发,项目功能比较少,所以采用框架springboot+thymeleaf。

一、核心功能

1.页面展示

页面展示主要是显示实时的投票排名的列表信息,还有就是对抽奖中奖信息的展示,核心代码如下:

<div class="detail-title"></div>   <div class="time">基于区块链blockchain的自动抽奖系统</div>             <div class="time">1月11日——1月24日投票贡献排行榜,投票结束!当博主进入top100,会触发智能合约,系统自动抽奖一位用户中奖88现金红包</div>         <div class="time"><a href="https://bss.csdn.net/m/topic/blog_star2020/detail?username=ws327443752" >点我进入投票</a></div> <div class="time" th:text="${userName}"></div>   </div>  <div class="vote-leaderboard-wrapper page-container">     <div class="title"></div>     <ul id="voteLeaderboardList">               <li class="best-blogger-wrapper" th:each="cs ,csStat: ${lst}">               <div class="left">                   <span class="text" th:text="${cs.number}"></span>                 <span class="text" th:text="${cs.name}"></span>                </div>               <div class="right">                 <span class="code-age" th:text="码龄+${cs.codeLevel}+年"></span>                 <span class="vote-num"th:text="中奖概率 +${cs.vote} +'/'+ ${sum}"></span>               </div>             </li>           </ul>   </div>
/**      * 展示页面      * @param request      * @return      */     @RequestMapping("blockchain")     public String index(HttpServletRequest request){         csdnService.getCsdnContent();         request.setAttribute("lst",csdnService.csdnList);         request.setAttribute("sum",csdnService.sum);         request.setAttribute("userName",csdnService.userName);         return "2020csdn";     }      /**      * 获取csdn投票相关数据      */     public void getCsdnContent() {         csdnList=new ArrayList<Csdn>();         sum=0;         Map<String, Object> params = new HashMap<String, Object>();         params.put("username" , "ws327443752");         params.put("page" , "1");         params.put("pageSize" , "200");         String json = HttpUtil.post("https://bss.csdn.net/m/topic/blog_star2020/getRanking", params);         JSONObject jsonObject= JSONUtil.parseObj(json);         JSONArray ja=  jsonObject.getJSONArray("data");          for (int i = 0; i < ja.size(); i++) {             Csdn csdn=new Csdn();             JSON jsonStr = (JSON) ja.get(i);             String uName = jsonStr.getByPath("nick_name").toString();             csdn.setName(uName);             String voteNum = jsonStr.getByPath("voteNum").toString();             csdn.setVote(Integer.parseInt(voteNum));             sum+=csdn.getVote();             String level = jsonStr.getByPath("level").toString();             csdn.setLevel(Integer.parseInt(level));             String codeLevel = jsonStr.getByPath("codeLevel").toString();             csdn.setCodeLevel(Integer.parseInt(codeLevel));             int number = Integer.parseInt(jsonStr.getByPath("number").toString());             csdn.setNumber(number);             csdnList.add(csdn);         }     }

1.抽奖接口

抽奖接口主要是保证投票数和中奖率的正比关系。代码如下所示:

/**      * 抽奖接口      * @return      */     @RequestMapping("lottery")     @ResponseBody     public String lottery(){         String id = csdnService.handleLottery();         return id;     }     /**      * 抽奖方法      * @param orignalRates 商品中奖概率列表,保证顺序和实际物品对应      * @return 中奖商品索引      */     public  int lottery(List<Double> orignalRates) {          if (orignalRates == null || orignalRates.isEmpty()) {             return -1;         }          int size = orignalRates.size();          // 计算总概率,这样可以保证不一定总概率是1         double sumRate = 0d;         for (double rate : orignalRates) {             sumRate += rate;         }          // 计算每个物品在总概率的基础下的概率情况         List<Double> sortOrignalRates = new ArrayList<>(size);         Double tempSumRate = 0d;         for (double rate : orignalRates) {             tempSumRate += rate;             sortOrignalRates.add(tempSumRate / sumRate);         }          // 根据区块值来获取抽取到的物品索引         double nextDouble = Math.random();         sortOrignalRates.add(nextDouble);         Collections.sort(sortOrignalRates);          return sortOrignalRates.indexOf(nextDouble);     }      /**      * 触发抽奖逻辑      * @return      */     public String handleLottery() {         List<NameDTO> nameDTOS = new ArrayList<>();          for (int i = 0; i < csdnList.size(); i++) {             double f1 = new BigDecimal((float)csdnList.get(i).getVote()/sum).setScale(4, BigDecimal.ROUND_HALF_UP).doubleValue();             nameDTOS.add(new NameDTO(i + 1, csdnList.get(i).getName(), csdnList.get(i).getNumber() + "", f1));         }          // 存储概率         List<Double> orignalRates = new ArrayList<>(nameDTOS.size());         for (NameDTO gift : nameDTOS) {             double probability = gift.getProbability();             if (probability < 0) {                 probability = 0;             }             orignalRates.add(probability);         }          // 统计         Map<Integer, Integer> count = new HashMap<>();          // 次数         double num = 1;         for (int i = 0; i < num; i++) {             int orignalIndex = lottery(orignalRates);             Integer value = count.get(orignalIndex);             count.put(orignalIndex, value == null ? 1 : value + 1);         }          String id=null;         for (Map.Entry<Integer, Integer> entry : count.entrySet()) {             id=nameDTOS.get(entry.getKey()).getNo();         }         return id;     }

3.定时触发智能合约抽奖,并自动公布结果

这里是结合宝塔的定时器进行时间的调度,不单独在项目中进行时间调度工作。注意我们这里的url为bclottery_wa7ndmvt2,相当于加了一个密码,来定时触发智能合约抽奖,并自动公布结果。如下图所示: (四)基于<a href=区块链blockchain的自动抽奖系统从0到1实现” /> 我们宝塔设置指定的时间来访问url触发智能合约。宝塔安装教程参考: https://blog.csdn.net/ws327443752/article/details/108134423

/**      * 定时触发智能合约抽奖,并自动公布结果      *      这里是结合宝塔的定时器进行时间的调度,不单独在项目中进行时间调度工作。注意我们这里的url为bclottery_wa7ndmvt2,相当于加了一个密码      * @return      */     @RequestMapping("bclottery_wa7ndmvt2")     @ResponseBody     public void bcLottery(HttpServletRequest request){         // 先判断是否进入top100       if(csdnService.getRanking()) {           // 触发智能合约抽奖           String res = csdnService.handle("request");           if (res.contains("transactionHash")) {               // 获取合约结果               res = csdnService.handle("get");               // 拿到结果进行对比后进行页面公布               res = csdnService.getUserNameById(Integer.parseInt(res));               csdnService.userName = "中奖用户为:"+res;           }       }else {           csdnService.userName="博主未进top100,没有触发抽奖合约,本次抽奖失效!";         }     }      /**      * 执行合约      *      * @param param 合约参数      * @return      */     public String handle(String param) {         String url =WEBASE_FRONT_URL+"/WeBASE-Front/trans/handle";         String body = "{n" +                 "    "user":"0xf0d04e0cc9b16528207027f1d5020e402096b44e",n" +                 "    "contractName":"APISampleOracle",n" +                 "    "contractAddress":"0x5ffbf18cfbe8c5b8fee09ccde4f5165007a6043e",n" +                 "    "funcName":"" + param + "",n" +                 "    "contractAbi":[{"inputs":[{"internalType":"address","name":"oracleAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"Fulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"Requested","type":"event"},{"inputs":[],"name":"EXPIRY_TIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"int256","name":"_result","type":"int256"}],"name":"__callback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"checkIdFulfilled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"get","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"getById","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUrl","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"request","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"result","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"_url","type":"string"}],"name":"setUrl","outputs":[],"stateMutability":"nonpayable","type":"function"}] ,n" +                 "    "groupId" :"1",n" +                 "    "useCns": falsen" +                 "}";         String res = HttpUtil.post(url, body);         if (param.equals("get")) {             // 处理格式             res = res.replace("[", "").replace("]", "").replace("000000000000000000", "");         }         return res;     }      /**      * 通过用户id获取用户名(csdn)      * @param id 用户的排名id      * @return      */     public String getUserNameById(int id) {         String[] name = {null};         csdnList.stream().filter(csdn -> csdn.getNumber() == id).forEach(csdn -> {             name[0] = csdn.getName();         });         return name[0];     }   /**      * 获取排名,看看是否进top100      * @return      */     public boolean getRanking() {         String html = HttpUtil.get("http://csdn.itrhx.com/");         Document doc = Jsoup.parse(html);         Elements els = doc.getElementsByTag("tr");         for (int i=0;i&lt;els.size();i++         ) {             if (els.get(i).html().contains("ws327443752")&&i&lt;=100) {                 return true;             }         }         return false;     }

下图是模拟测试的抽奖结果展示: (四)基于<a href=区块链blockchain的自动抽奖系统从0到1实现” /> (四)基于<a href=区块链blockchain的自动抽奖系统从0到1实现” />

如果合约被定时执行了,那么我们可以在Truora中看到如下图所示的信息: (四)基于<a href=区块链blockchain的自动抽奖系统从0到1实现” />

4.项目整体代码地址

https://gitee.com/bckj_1/csdn

总结

我们的抽奖的项目核心就是抽奖的逻辑和页面的展示以及最关键的智能合约的调用。到本篇文章就完结了,项目代码已经开源到了gitee, 方便大家研究,有兴趣的小伙伴可以关注一下!

部分转自网络,侵权联系删除www.interchains.cchttps://www.interchains.cc/21427.html

区块链毕设网(www.interchains.cc)全网最靠谱的原创区块链毕设代做网站 部分资料来自网络,侵权联系删除! 最全最大的区块链源码站 ! QQ3039046426
区块链知识分享网, 以太坊dapp资源网, 区块链教程, fabric教程下载, 区块链书籍下载, 区块链资料下载, 区块链视频教程下载, 区块链基础教程, 区块链入门教程, 区块链资源 » (四)基于区块链的自动抽奖系统从0到1实现

提供最优质的资源集合

立即查看 了解详情