(4) Implementation of automatic lottery system from 0 to 1 based on blockchain

Xiang Biao 2021-04-09 12:42:04 阅读数:66

本文一共[544]字,预计阅读时长:1分钟~
implementation automatic lottery based blockchain

Preface

We've written a core chapter on the contract , And the deployment test was successful , Now let's write an automatic lottery system based on blockchain DAPP,java Language development , The project has few functions , So take the framework springboot+thymeleaf.

One 、 Core functions

1. The page display

Page display is mainly to display real-time voting ranking list information , There is also the display of the winning information in the lottery , The core code is as follows :

<div class="detail-title"></div> <div class="time"> Automatic lottery system based on blockchain </div> <div class="time">1 month 11 Japan ——1 month 24 Daily voting contribution list , The vote is over ! When bloggers enter top100, It triggers smart contracts , The system draws a lottery automatically, and one user wins the lottery 88 Cash bonus </div> <div class="time"><a href="https://bss.csdn.net/m/topic/blog_star2020/detail?username=ws327443752" > I'm going to vote </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=" Code age +${cs.codeLevel}+ year "></span> <span class="vote-num"th:text=" Winning probability +${cs.vote} +'/'+ ${sum}"></span> </div> </li> </ul> </div>
/** * Display page * @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"; } /** * obtain csdn Voting data */ 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. Lottery interface

The lottery interface is mainly to ensure the proportional relationship between the number of votes and the winning rate . The code is as follows :

/** * Lottery interface * @return */ @RequestMapping("lottery") @ResponseBody public String lottery(){ String id = csdnService.handleLottery(); return id; } /** * Lottery method * @param orignalRates List of winning probability of products , Make sure the order corresponds to the actual item * @return Winning product index */ public int lottery(List<Double> orignalRates) { if (orignalRates == null || orignalRates.isEmpty()) { return -1; } int size = orignalRates.size(); // Calculate the total probability , This ensures that the total probability may not be 1 double sumRate = 0d; for (double rate : orignalRates) { sumRate += rate; } // Calculate the probability of each item on the basis of the total probability List<Double> sortOrignalRates = new ArrayList<>(size); Double tempSumRate = 0d; for (double rate : orignalRates) { tempSumRate += rate; sortOrignalRates.add(tempSumRate / sumRate); } // According to the block value to get the extracted item index double nextDouble = Math.random(); sortOrignalRates.add(nextDouble); Collections.sort(sortOrignalRates); return sortOrignalRates.indexOf(nextDouble); } /** * Trigger lottery logic * @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)); } // Storage probability List<Double> orignalRates = new ArrayList<>(nameDTOS.size()); for (NameDTO gift : nameDTOS) { double probability = gift.getProbability(); if (probability < 0) { probability = 0; } orignalRates.add(probability); } // Statistics Map<Integer, Integer> count = new HashMap<>(); // frequency 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. Time triggered smart contract lottery , And automatically publish the results

Here is the time scheduling combined with the timer of the pagoda , Don't do time scheduling alone in a project . Pay attention to our url by bclottery_wa7ndmvt2, It's like adding a password , To trigger the smart contract lottery on a regular basis , And automatically publish the results . As shown in the figure below : Insert picture description here We set the pagoda to visit at a specified time url Trigger smart contracts . Pagoda installation tutorial reference : https://blog.csdn.net/ws327443752/article/details/108134423

/** * Time triggered smart contract lottery , And automatically publish the results * Here is the time scheduling combined with the timer of the pagoda , Don't do time scheduling alone in a project . Pay attention to our url by bclottery_wa7ndmvt2, It's like adding a password * @return */ @RequestMapping("bclottery_wa7ndmvt2") @ResponseBody public void bcLottery(HttpServletRequest request){ // Judge whether to enter first top100 if(csdnService.getRanking()) { // Trigger the smart contract lottery String res = csdnService.handle("request"); if (res.contains("transactionHash")) { // Get the contract results res = csdnService.handle("get"); // Get the results for comparison and then publish the page res = csdnService.getUserNameById(Integer.parseInt(res)); csdnService.userName = " The winning users are :"+res; } }else { csdnService.userName=" The blogger didn't enter top100, There's no draw contract triggered , The lottery is invalid !"; } } /** * Execute the contract * * @param param Contract parameters * @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\": false\n" + "}"; String res = HttpUtil.post(url, body); if (param.equals("get")) { // Processing formats res = res.replace("[", "").replace("]", "").replace("000000000000000000", ""); } return res; } /** * Through users id Get username (csdn) * @param id User Rankings 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]; } /** * Get ranking , Let's see if we get into 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<els.size();i++ ) { if (els.get(i).html().contains("ws327443752")&&i<=100) { return true; } } return false; }

The following picture shows the lottery results of the simulation test : Insert picture description here  Insert picture description here

If the contract is executed regularly , So we can do that Truora See the information shown in the figure below : Insert picture description here

4. Project overall code address

https://gitee.com/bckj_1/csdn

summary

The core of our lucky draw project is the logic of the lucky draw, the display of the page and the call of the most critical smart contract . By the end of this article , The project code has been open source to gitee, It's convenient for you to study , Interested partners can pay attention to !

版权声明:本文为[Xiang Biao]所创,转载请带上原文链接,感谢。 https://netfreeman.com/2021/04/20210409123259974k.html