当前位置:首页区块链区块链研究实验室|在以太坊上建立了一个可验证的随机彩票智能合同

区块链研究实验室|在以太坊上建立了一个可验证的随机彩票智能合同

区块链研究实验室|在以太坊上建立了一个可验证的随机彩票智能合同

以太坊上,真正的随机性几乎是不可能的。这是因为事务需要由网络上的多个节点进行验证。如果智能契约特性确实是随机的,那么使用该特性来验证事务将为每个节点产生不同的结果,这意味着该事务将永远不会被确认。

ETHereum生态系统最大的玩家之一的最新声明引起了人们对这个问题的兴奋。通过使用一个名为可验证随机函数(VRF)的系统,ETHereum智能契约现在可以生成随机数。

这意味着,一些概念似乎很适合智能契约,但却无法实现,因为它们现在需要随机数。

其中一个概念就是彩票。

建立彩票智能合同

我们的彩票分为三个阶段。第一种是开放式的,任何人都可以提交一个新的号码,只需要支付一小笔费用。第二个是关闭的,没有新的数字可以提交,随机数正在生成。第三个已经完成,数字已经产生,获胜者已经被授予。

如果没有人中奖,彩票合同可以延长以增加奖金。

定义阶段

该阶段应该限制操作,以便只能执行允许的操作。例如,唯一允许新提交的阶段是开放阶段。如果彩票关闭或终止,合同将禁止新的提交。

使用enum,我们可以定义任意数量的相。我们称之为莲花态。在状态函数中,我们定义如下:

1 enumLootterystate {Open, Closed, Finished} 2 Lootterystatepublicstate;

现在已经定义了枚举,我们可以在函数中设置require语句,以确保契约的当前状态符合我们的期望。

由于这些require语句在整个契约中可能看起来类似,所以我们尽量减少它们。我们可以定义一个执行require语句的修饰符,并将其分配给我们想要的任何函数。

1 . modifierisstate (LotteryState_state) {2 the require (state = = _state, “Wrongstateforthisaction”);3 _;4}

现在,当我们定义这个函数时,我们可以添加这个修饰符来确保Loottery的当前状态是我们期望的状态。

提交的数字

任何人都可以提交一个数字,只要他们支付最低的入场费。但是每个参赛者不能同时提交相同的数字。应该允许新提交的惟一状态是open状态。

这是我们的SubmitNumber函数:

1 functionsubmitnumber (uint_number) publicpayableisState (LotteryState)。打开){2请求(MSG。Valuegt;= entryFee“Minimumentryfeerequired”);3 . require(条目[_number])。添加(MSG)发件人),“不能提交thesamenumbermoremore”);4个数字。推动(_number);5个条目+ +;6应付(业主())。转移(ownerCut);7 emitnewentry (MSG)发送器,_number;8}

第1行定义了名称、单个_number参数以及它是public和应付的事实。它还添加isState修饰符以确保彩票是打开的。

第2行确保支付了正确的注册费,第3行确保消息的发送者没有提交号码并将其添加到流程中的条目中。

变量项指的是一个映射,它定义了猜测的次数和所输入的数字的一组地址。定义如下:

1映射(uint = AMPL gt;EnumerableSet。AddressSet)条目;

AddressSet引用OpenZeppelin EnumerableSet协议,该协议为基本类提供了额外的功能。

一旦检查完成,接下来的四行数字将被添加到猜测中,所有者将获得一小部分报酬,并发出NewEntry事件。

输入的数字

如果您读过关于如何使用VRF的文章,您就会知道生成随机数并不像调用单个函数(math)那么简单。例如,JaaScript中的random()。

要生成随机数,必须向VRF协调器请求随机性,并实现VRF可以回调响应的函数。为此,我们需要定义一个VRF用户(在这里可以找到创建VRF用户的详细信息),在图2中我们将其称为RandomNumberGenerator。

1实用主义^ 0.6.2;2、3、导入。/ VRFConsumerBase。索尔”;4 .导入”/彩票。索尔”;8地址请求者;9 bytes32keyhash;10 uint256fee;11 .构造函数(address_rfCoordinator)构造函数(address_rfCoordinator) address s_link bytes32_keyHash, uint256_fee) 13 rfconsumerbase (_rfCoordinator _link) public {14 keyhash = _keyHash;15费用= _fee;16} 1718 functionrandomness (bytes32_requestId uint256_randomness)外部覆盖{19 Loottery (requester)NumberDrawn (_requestId _randomness);functionrequest (uint256_seed) publicreturns (bytes32requestId)= bytes32 (0), “Musthaealidkeyhash”);请求者=味精。发送者;25 returnthis。RequestRandomness (keyHash, fee, _seed);26日27}}

我们的Loottery将在构建时将此契约的地址作为注入参数。当绘制数字时,它调用request函数。这要求VRF提供随机性,然后VRF对第18行上的filfullRandomness提供响应。您可以在图2中看到调用我们的number彩票契约的调用。让我们定义这些特性:

1 functiondrawnumber (uint256_seed) publiconlyOwnerisState (LotteryState)。打开){2 _changestate (LotteryState)。关闭);3 randomnumberrequestid = RandomNumberGenerator (RandomNumberGenerator.)请求(_seed);4 emitnumberrequested (randomNumberRequestId);5} 6 7 functionnumberdraw (bytes32_randomNumberRequestId uint_randomNumber) publiconlyRandomGeneratorisState (LotteryState)关闭){8 if (_randomNumberRequestId = = randomNumberRequestId) {9 winningnumber = _randomNumber;10 emitnumberdrawn (_randomNumberRequestId, _randomNumber);11 _(条目[_randomNumber]);12 _changestate (LotteryState。完成);14日13}}

在我们定义的第1行中,drawNumber只能由彩票所有者调用,并且只能在彩票打开时调用。

第7行上的吸引数是一个函数,一旦VRF接收到一个随机数,它就会吸引回主机Omness。它确保请求ID是从请求返回的ID,发出一个事件,支付获胜者,并将票证的状态更改为Finished。

完整的代码表示:

1 .语用性AMPL gt;= 0.6.2;2、3、导入“@ openzeppelin/contract /access/Ownable”索尔”;4 .导入“@ openzeppelin/contracts/utils/EnumerableSet”索尔”;5 .导入“@ openzeppelin/contract /utils/Address”索尔”;6 .导入“@ openzeppelin/contract /math/SafeMath SOL”;7 .导入”/ RandomNumberGenerator。索尔”;9 . contractLootteryisownable {1011 usingenumerablesetforenumerableset。AddressSet;12 usingaddressforaddress;13 usingsafemathforuint;enumLootterystate{打开,关闭,完成}1617映射(uint = AMPL gt;EnumerableSet。AddressSet)条目;18 uint[]数字;19 Lootterystatepublicstate;20 uintpublicnumberofentries;21 uintpublicentryfee;22 uintpublicownERCut;23 uintpublicwinningnumber;24 addressrandomnumbergenerator;25 bytes32randomnumberrequestid;2627年eentLootterystatechanged (LotteryStatenewState);28 eentnewentry (addressplayer uintnumber);29 eentnumberrequested (bytes32requestId);绘制的事件编号(bytes32requestId uintwinningNumber);34需要3132 / / modifiers33modifierisState (LotteryState_state) {(state = = _state,“Wrongstateforthisaction”);35 _;require (MSG) sender = = randomNumberGenerator, “Mustbecorrectgenerator”);40 _;41} / 4243 / constructor44constructor (uint_entryFee uint_ownerCut, address_randomNumberGenerator)0,“Entryfeemustbegreaterthan0”);46 . the require (_ownerCut AMPL lt;_entryFee EntryfeemustbegreaterthanownERCut);47 . require (_randomNumberGenerator!)= address (0), “Randomnumbergeneratormustbealidaddress”);48 . require (_randomNumberGenerator isContract(),“Randomnumbergeneratormustbesmartcontract”);49 entryfee = _entryFee;50ownERCut = _ownerCut;51 randomnumbergenerator = _randomNumberGenerator;52 _changestate (LotteryState。开放);53} / 5455 / functions56functionsubmitNumber (uint_number) publicpayableisState (LotteryState)打开){57请求(MSG。Valuegt;= entryFee“Minimumentryfeerequired”);请求(条目[_number])。添加(MSG)发件人),“不能提交thesamenumbermoremore”);数字是59。推动(_number);60个条目+ +;61应付(业主())。转移(ownerCut);emitnewentry (MSG)发送器,_number;} 6465 functiondrawnumber (uint256_seed) publiconlyOwnerisState (LotteryState)打开){66 _changestate (LotteryState)。关闭);67 randomnumberrequestid = RandomNumberGenerator (RandomNumberGenerator.)请求(_seed);68年emitnumberrequested (randomNumberRequestId);} 7071 functionrolloer () publiconlyOwnerisState (LotteryState)完成)rolloernewLoottery73 / {72} 7475 functionnumberdrawpubliconlyrandomgeneratorisstate (bytes32_randomNumberRequestId, uint_randomNumber) (LotteryState。关闭)76 if (_randomNumberRequestId = = randomNumberRequestId) {77 winningnumber = _randomNumber;78 emitnumberdrawn (_randomNumberRequestId _randomNumber);79 _(条目[_randomNumber]);80 _changestate (LotteryState。完成);function_(EnumerableSet addresssetstoragewinner) priate {85 uintbalance = address (this)平衡;86 for (uintindex = 0;Indexlt;赢家。长度();指数++){87应付(赢家。(索引))。传输(平衡。Di(赢家。长度()));88} 89} 9091 function_changestate (LotteryState_newState) priate {92 state = _newState;93 emitLootterystatechanged(状态);95 94}}

这是一个原始的实现,但它表明了区块链上可验证随机性的出现如何降低了彩票等契约的复杂性。以前的彩票契约需要哈希机制、基于时间的机制、基于块的机制等等,所有这些机制都很脆弱。

区块链研究实验室|在以太坊上建立了一个可验证的随机彩票智能合同1

跟踪二维码添加我,拉你进技术交流群

扫描的代码

注意我们的

获得

温馨提示:

文章标题:区块链研究实验室|在以太坊上建立了一个可验证的随机彩票智能合同

文章链接:https://www.btchangqing.cn/31651.html

更新时间:2020年06月04日

本站大部分内容均收集于网络,若内容若侵犯到您的权益,请联系我们,我们将第一时间处理。

区块链研究实验室|在以太坊上建立了一个可验证的随机彩票智能合同2
区块链

加拿大正式监管虚拟货币公司。五年修正案的新要求是什么?

2020-6-4 11:45:12

区块链

比特币的暴跌并未给机构投资者带来恐慌

2020-6-4 11:49:13

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索