1.基于指定概率分布的随机抽奖合约

Attention:init时需设置奖励列表数组、概率数组、活动结束时的区块高度 ,由于伪随机数的正态分布特性,尽量将大奖设置在数组两端,这样落点区间概率理论上会更小

直接上代码吧:

'use strict';
//POWERED BY BBSee
//FORK ME ON GITHUBvar Contract = function () {LocalContractStorage.defineProperty(this, "possibilities", null);//概率数组LocalContractStorage.defineProperty(this, "award1", null);//奖励列表LocalContractStorage.defineProperty(this, "fee", null);//抽取奖励的最低费用LocalContractStorage.defineProperty(this, "creator", null);//合約发起人LocalContractStorage.defineProperty(this, "balance", null);//奖池余额LocalContractStorage.defineProperty(this, "winners", null);//获奖者,为保证效率仅记录最近的1000条(包括中奖人,中奖时间戳,中奖数量)LocalContractStorage.defineProperty(this, "bigwinners", null);//最高奖历史获得者,同上LocalContractStorage.defineProperty(this, "interval", null);//奖励在0-10的随机数上的概率区间LocalContractStorage.defineProperty(this, "oneNasWei", null);LocalContractStorage.defineProperty(this, "endHeight", null);//活动结束时间LocalContractStorage.defineProperty(this, "defaultfee", null);//活动结束时间
};Object.prototype.getKeyByValue = function (value) {for (var prop in this) {if (this.hasOwnProperty(prop)) {if (this[prop] == value)return prop;}}
}
Contract.prototype = {init: function (fee,award,possibilities,endHeight) {var awardArr=this._str2arr(award);//奖励列表,单位时NAS,转账时请转换为Wei,var possibilitiesArr=this._str2arr(possibilities)//奖励机率var end=new BigNumber(endHeight);if(end%1 !=0 ||end<=Blockchain.block.height){throw new Error("Invalid block height");};//概率个数和奖励个数不匹配时无法执行if(awardArr.length !=possibilitiesArr.length){throw new Error("Unmatched awards and possibilities");}var possAmount= 0;var possibility=0;for(var i=0;i<possibilitiesArr.length;i++){possibility=possibilitiesArr[i];//概率为负数时无法执行if(possibility<0){throw new Error("possibility could not be negative");};possAmount=possAmount+possibility;};for(var x=0;x<awardArr.length;x++){if(awardArr[x]<0){throw new Error("Invalid award amount,amout could not be nagative!");}};//概率不足100%时无法执行合约if(possAmount !=100){throw new Error("Miscalculated percent possibilities,the sum of possibilities does not equal to 100--yours: "+possibilities+"|"+possAmount);};this.oneNasWei=new BigNumber(Math.pow(10,18));//NAS2Weithis.fee=new BigNumber(fee*this.oneNasWei);this.defaultfee=new BigNumber(fee*this.oneNasWei);this.award1=awardArr;this.possibilities=possibilitiesArr;this.creator = Blockchain.transaction.from;//合约的创建者this.balance=0;//奖池余额this.endHeight=endHeight;this.winners={};//所有中奖者,仅仅保留1000条this.bigwinners={};//最大奖获得者仅保留最近1000条this.interval=this._random_interval(possibilitiesArr);//奖励在0-10的随机数上散布的概率区间return "Contract has been deployed";},//向合约充值用于发放奖励charge :function(){var amount=new BigNumber(Blockchain.transaction.value);this.balance=this.balance+amount;return true;},//开一个福袋open:function(){BigNumber.config({ ERRORS: false });var amount = new BigNumber(Blockchain.transaction.value);//开袋转账var endTime=new BigNumber(Blockchain.block.height);//活动结束时间if(endTime<this.endHeight){this.fee=this.defaultfee/2;}else{this.fee=this.defaultfee;};var user_=Blockchain.transaction.from;//当费用小于约定费用时无法继续执行合约if (amount<this.fee ) {throw new Error("Oops,opening bag failed,your applying fee is not enough.");   } else {//如果余额小于设置的奖项最大值则不能启动合约if(this.balance<this.award1[0]*this.oneNasWei){throw new Error("Opps,the balance of pond is not enough,so you cloud not open this bag");};var rand=Math.random()*10;var awardIndex=-1;for(var i=0;i<this.interval.length;i++){if(rand<=this.interval[i]){awardIndex=i;break;};};var returnment={};var award="award";var fault="fault";var user="user";var grade="grade";var amount_="amount";var rewardAmountNas=this.award1[awardIndex];//return "奖励:"+this.award[awardIndex]+"|awardIndex:"+awardIndex+"|"+"随机数:"+rand+"区间:"+this.interval;var rewardAmountWei=new BigNumber(this.oneNasWei*rewardAmountNas);if(rewardAmountNas==0){returnment[award]=false;returnment[fault]="00N";return returnment;//return "{\"award\":false,\"fault\":\"00N\"}";//ERR CODE:00N-you got nothing}var timestamp = Date.parse(new Date());this._cleanRecord();var record=[rewardAmountNas,timestamp];//中奖记录单位为NASvar records=[];let winnerMap=this.winners;if(!winnerMap[user_]){records[0]=record;winnerMap[user_]=records;}else{records=winnerMap[user_];records[records.length]=record;winnerMap[user_]=records;}records=[];this.winners=winnerMap;if(awardIndex==0){let bigwinnerMap=this.bigwinners;if(!bigwinnerMap[user_]){records[0]=record;bigwinnerMap[user_]=records;}else{records=bigwinnerMap[user_];records[records.length]=record;bigwinnerMap[user_]=records;}this.bigwinners=bigwinnerMap;//}var result=this._rewards(user_,rewardAmountWei);this._cleanRecord;if(result){returnment[award]=true;returnment[amount_]=rewardAmountNas;returnment[user]=user_;returnment[grade]=awardIndex+1;return returnment;//return "{\"award\":true,\"amount\":"+rewardAmountNas+",\"user\":\""+user+"\",\"grade\":"+(awardIndex+1)+"}";//获得奖励}else{returnment[award]=false;returnment[fault]="00T";return returnment;//return "{\"award\":false,\"fault\":\"00T\"}";//transfer failed,我们不承担用户由于网络错误和区块确认失败等原因造成奖金转账失败的损失}}},//查询所有的获奖者queryAllWinnrs: function(limit){if(limit !=null&&(limit<0||!this._numCheck(limit))){throw new Error("Invalid limit condition,it could not be nagative or bigger than 1000.");};let records=this.winners;var returnment ={};if(this.winners==null){return returnment};if(limit==null){for(var key in records){returnment[this._dataDesensitization(key)]=records[key];};}else{var arr=new Array();for(var key in records){arr=records[key];returnment[this._dataDesensitization(key)]=arr.slice(0,limit);};}return returnment;},//查询所有大奖的获得者queryBigWinners:function(limit){if(limit!=null&&(limit<0||!this._numCheck(limit))){throw new Error("Invalid limit condition,it could not be nagative or bigger than 1000.");};let records=this.bigwinners;var returnment ={};if(this.bigwinners==null){return returnment};if(limit==null){for(var key in records){returnment[this._dataDesensitization(key)]=records[key];};}else{var arr=new Array();for(var key in records){arr=records[key];returnment[this._dataDesensitization(key)]=arr.slice(0,limit);arr=[];};}return returnment;},//查询用户自己的中奖记录,limit限制查询结果数queryOwn: function(limit){if(limit !=null&&(limit<0||!this._numCheck(limit))){throw new Error("Invalid limit condition,it could not be nagative or bigger than 1000.");};var user=Blockchain.transaction.from;let records=this.winners;var returnment=[];if(this.winners==null||records[user]==null){return returnment};returnment=records[user];if(limit>returnment.length){limit=returnment.length;};if(limit==null){return returnment;}else{return returnment.slice(0,limit);           };} ,//按事件出现概率顺序的概率数组,和事件数组,返回对应顺序的具体大小值范围_random_interval(possibilitiesArr){var possivalue=new BigNumber(0);var num=new BigNumber(0);var rdi=[];for(var i=0;i<possibilitiesArr.length;i++){possivalue=new BigNumber(possibilitiesArr[i]/100);num=10*possivalue;if(rdi.length==0){rdi[0]=num;}else{rdi[i]=rdi[i-1]+num;}}return rdi;},//脱敏用户地址_dataDesensitization(address){var sign='******';var front=address.substring(0,3);var end=address.substring(address.length-3,address.length);return front+sign+end;},//字符串转换成数组_str2arr(str){var strArr=str.split(",");var dataIntArr=[]; strArr.forEach(function(data,index,arr){  dataIntArr.push(+data);  });  return dataIntArr;},//发放奖励_rewards(to,amount){BigNumber.config({ ERRORS: false });//var gas=new BigNumber(Blockchain.transaction.gasLimit);let r = Blockchain.verifyAddress(to);if (r == 0) {throw new Error("The address " + to + " is invalid")}var amountWei=new BigNumber(amount);var result=Blockchain.transfer(to,amountWei);var contract=Blockchain.transaction.to;Event.Trigger("transfer", {Transfer: {from: contract,to: to,value: amountWei}});if(result){this.balance=this.balance-amountWei;}return result;},_cleanRecord(){var winnersLength=Object.getOwnPropertyNames(this.winners).length-1000;var bigwinnersLength=Object.getOwnPropertyNames(this.bigwinners).length-1000;var counter=0;if(winnersLength>0){for(var key in this.winners){if(counter==winnersLength){break;}delete this.winners[key];counter+=1;}};if(bigwinnersLength>0){for(var key in this.bigwinners){if(counter==bigwinnersLength){break;}delete this.bigwinners[key];counter+=1;}}},//数字验证_numCheck(num){var reg=/^[0-9]{1,4}$/;   return reg.test(num);},takeout: function (amount) {var from = Blockchain.transaction.from;let value = new BigNumber(amount*Math.pow(10,18));if (from == this.creator) {var result = Blockchain.transfer(from, value);if (!result) {throw new Error("transfer failed.");}return result;Event.Trigger("BankVault", {Transfer: {from: Blockchain.transaction.to,to: from,value: value.toString()}} );}else{var returnment="Permission denied";return returnment;};}
};
module.exports = Contract;

交流群:216672921 、801978245

星云链NAS区块链随机抽奖合约【算法】相关推荐

  1. 区块链研习 | 区块链里所说的“智能合约”是什么? 本文作者:敖萌 编辑:温晓桦 2017-10-11 20:31 导语:谈到区块链,必然离不开“智能合约”这个词。我们在本系列的第一篇文章中提到“智能

    区块链研习 | 区块链里所说的"智能合约"是什么? 本文作者:敖萌 编辑:温晓桦 2017-10-11 20:31 导语:谈到区块链,必然离不开"智能合约"这个 ...

  2. php区块链源码带语音播报|区块链理财|区块链游戏l抽奖功能|自动分红

    介绍: php区块链源码带语音播报|区块链理财|区块链游戏|抽奖功能|自动分红: 亲测搭建完美运行,搭建方式如下 测试环境:Apache 2.4.46或 Linux+nginx1.15.10 数据库: ...

  3. 区块链和区块链联盟_区块链是安全主题吗?

    区块链和区块链联盟 区块链目前是个大新闻. 有会议,初创公司,展览,开源项目(实际上,发生在区块链上的几乎所有东西都是开源的,以太坊,Zcash和比特币为例): 我们现在所需要的只是时髦经营的以区块链 ...

  4. 问道区块链_区块链学习_v1.0.0_持续更新。。。

    本系列内容参考图 创建 共识网络 调用 部署 挖矿 消耗 编写 超级链组件 节点 多节点 账号 智能合约 合约账号 燃料耗品代币 开发者 区块 尊重原创,转载请注明出处https://blog.csd ...

  5. 【问链财经-区块链基础知识系列】 第二十七课 区块链与分布式账本的异同

    编者按:在加密货币和区块链领域,有一个业内人士常挂在嘴边的新术语:分布式账本技术(简称DLT).但具有讽刺意味的是,恰恰是比特币和各种区块链试图颠覆的实体们,例如银行,政府和大公司,对分布式账本技术情 ...

  6. 链客区块链技术面试题目专题(三)

    想知道更多区块链技术问答,请百度[链客区块链技术问答社区],有专业的区块链技术问答. 以太坊是不是不分测试地址和正式链地址. 答:以太坊的官网有一个正式链和三个测试链,我用的比较多的测试链是rinke ...

  7. 区块链技术 ——区块链概述

    今天讲点基础的,讲一讲区块链的基础知识.在这个项目横生的乱象中,有时候最基础的一些知识,反而会让我们更加清晰的看到一些项目的本质. 区块链技术是一种综合应用了分布式数据存储,如何购买比特币?点对点传输 ...

  8. 美丽链——看区块链如何重塑内衣业!!

    IMC导读:在BTN(Business Travel News)最近于旧金山举行的对谈活动上,当一位成员提到"区块链"时,一位内衣业从业者开玩笑表示他最不需要的科技热词就是这个. ...

  9. 什么是区块链,区块链又是什么?

    有关区块链的介绍:          最近接触到了较多的人,他们都有提到过区块链,本来我之前对区块链也有一定的了解,但是并不是很清楚,于是今天又去看了关于区块链的相关书籍和网站,以下是我所看到的部分, ...

最新文章

  1. SSH安装后提示sshd_server account 用户
  2. 对SQLSERVER进行性能监控
  3. 图片上传成功但是图片显示不出来_小程序上传图片到腾讯云
  4. python安装numpy-python安装numpy和pandas的方法步骤
  5. UNITY把3D模型显示在UI层级上的思路
  6. Python之30秒就能学会的漂亮短程序代码
  7. LeetCode动态规划 杨辉三角
  8. 将普通文章内容替换为微信图文消息符合的内容
  9. 企业内部IT报修是如何操作的?
  10. java8堆内存模型_「GC系列」JVM堆内存分代模型及常见的垃圾回收器
  11. Tensorrt-caffee模型tensorrt部署教程
  12. 数据结构合并两个有序链表
  13. Java汉字转GB2312编码【工具类】
  14. cmd运行记事本java文件
  15. Android Q 上的Biometric生物识别
  16. 50 行代码爬取链家租房信息
  17. 寻仙服务器维护到几点,寻仙10月14日上午服务器例行维护公告
  18. 算法——归并和归并排序
  19. 树状数组再进阶(区间修改+区间查询)
  20. diy直立双足机器人_动手制作机器人,双足移动机器人DIY

热门文章

  1. iOS 优雅的处理网络数据,你真的会吗?不如看看这篇.
  2. Redis Geospatial 地理位置 类型
  3. 氟林流体-工业泵在湿法腐蚀清洗设备中的应用
  4. 程序员笔试知识点整理
  5. 机器学习-吴恩达网易云课堂笔记
  6. [附源码]java毕业设计银行OA系统
  7. java 图片存进mysql_Java操作mysql存储图片
  8. Linux学习--如何通过Shell脚本实现发送邮件通知功能?
  9. Elasticsearch:ingest pipelines - 使用技巧和窍门
  10. Docker架构镜像及容器管理