本文将教各人如安在dApp中轻松实现投票时间节制。此刻跟着越来越多dApp开始走DAO蹊径,将更多权力交到用户手中,这种投票机制也变得愈发重要。详细步调如下:
//if voting is live and address hasn’t voted yet, count vote
//$voteMinutes minutes have elapsed, stop voting
require(msg.sender == owner);
oraclePayment = 0.1 * 10 ** 18; // 0.1 LINK
sendChainlinkRequestTo(oracle, req, oraclePayment);
//only the contract owner should be able to start voting
//Outputs current vote counts
votingLive = false;
举办投票并查察投票状态:
· 利用Getters函数查察投票状态
function fulfill(bytes32 _requestId) public recordChainlinkFulfillment(_requestId) {
jobId = “a7ab70d561d34eb49e9b1612fd2e044b”;
oracle = 0x2f90A6D021db21e1B2A077c5a37B3C7E75D15b7e;
}
我们在《奈何将智能合约和API毗连在一起》一文中提到,ChainlinkClient合约导出一个Chainlink.Request的数据布局,这个数据布局可以按照详细需求酿成差异的名目。示例中,我们在数据布局中添加的不是“get”请求,而是“until”。我们在结构函数中界说的Chainlink节点地点可以识别这个until字符串,节点收到请求后会在规按时间内暂停任务流水线(task pipeline)(注:规按时间指“voteMinutes”分钟时间)。
Chainlink.Request memory req = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
require(!voters[msg.sender], “Already voted!”);
votingLive = true;
return voters[msg.sender];
导入ChainlinkClient并利用“is”要害词担任,就可以轻松向Chainlink节点请求数据。然后,我们需要界说几个全局变量,个中包罗计时器预言机的地点,地点可以在Chainlinks (测试网)页面上查察。
· 将合约所有者配置成独一有权限提倡投票的人
yesCount = 0;
uint private noCount;
_;
bool private votingLive;
}
mapping(address => bool) public voters;
}
//Kovan alarm oracle
if(voteCast) {yesCount++;}
}
本示例中利用的代码可以在GitHub中查察,你还可以查察利便陈设的Remix。
}
votingLive = false;
虽然,这只是一个最根基的示例,你可以利用Chainlink“until”请求在任何时间点触发任何事件。这个示例只是一个初始框架,你可以在上面开拓其他需要时间节制成果的智能合约。
· 利用简朴的KYC确认每个地点只投一次票
return(yesCount, noCount);
合约界说和结构函数:
function vote(bool voteCast) public {
//initialize votes
//Increments appropriate vote counter if voting is live
我们合约的第一个函数startVote就需要向Chainlink提倡请求。在这里我们用到了onlyOwner修改器,确保只有合约所有者才有权限提倡投票。
import “github.com/smartcontractkit/chainlink/evm-contracts/src/v0.6/ChainlinkClient.sol”;
noCount = 0;
constructor() public {
· 将Chainlink成果包导入智能合约并担任
modifier onlyOwner {
function startVote(uint voteMinutes) public onlyOwner {
bytes32 private jobId;
这里就需要用到真正能实现投票的逻辑了。投票函数接管一个true/false的参数来检讨用户是否已经投过票,假如验证通过,则计较投票,并将他们mapping中地点对应的值更新为true,暗示他们已经投过票了。我们利用require表达式而不是if表达式来验证地点。这样一来,已经投过票的生意业务就会被拒绝。最后,由于以太坊生意业务不会返回功效,我们添加了一些简朴的view函数来查察今朝投票数量,并确认投票是否被统计。但愿本文可以或许让各人相识Chainlink在主网上的个中一个实用成果,并为你们的智能合约实现更大的代价。假如你想要相识Chainlink的其他成果,请存眷Chainlink宣布的可验证随机数生成东西Chainlink VRF、接入Chainlink喂价机制开拓活动性挖矿dApp或相识Chainlink预言机的最新研究成就公允排序处事。
}
//Start voting window then submit request to sleep for $voteMinutes
uint private yesCount;
owner = msg.sender;
setPublicChainlinkToken();
if(!voteCast) {noCount++;}
//Callback for startVote request
address payable owner;
contract ChainlinkTimedVote is ChainlinkClient
address private oracle;
· 名目化并提交Chainlink sleep(“until”)请求
上很多智能合约都需要通过外部计时器触发链上执行,因此dApp在链上提倡投票时就会碰着问题,因为投票凡是都有一个时间窗口。由于Solidity中没有计时器,因此智能合约的投票机制需要接入外部东西来启动或封锁投票窗口。其实在传统系统中,计时成果并不难实现,系统可以配置NTP时间与操纵系统时间同步,也可以用实物钟表或计时器计时,甚至还可以用sleep表达式在一段时间内暂停代码运行。Solidity智能合约中的事件由链下生意业务触发,,也就是说以太坊等需要接入链下闹钟触发事件或挪用函数。而好动静是,开拓者可以将Chainlink节点作为闹钟,靠得住地触发智能合约执行。
//address has voted, mark them as such向Chainlink发送请求,启动投票:
function getVotes() public view returns (uint yesVotes, uint noVotes) {
function haveYouVoted() public view returns (bool) {
//Lets user know if their vote has been counted
req.addUint(“until”, now + voteMinutes * 1 minutes);
在提交请求前,我们需要将votingLive配置成true,即乐成开启投票,投票函数会查察变量状态以答允或拒绝投票。然后我们就可以提交请求了,这时Chainlink节点会暂停任务流水线。这样,我们就能在until请求设定的时间竣事后挪用fulfill回调函数。当挪用fulfill函数时,设定的投票时间已经竣事,因此就可以将votingLive配置回false,将投票封锁。综上所述,我们要先建设一个“until”请求,请求中包括规按时间,并将其发送至某一节点,节点在规按时间内暂停后再挪用fulfill函数。Chainlink计时器/闹钟实现起来就是这么简朴!我们利用简朴的votingLive布尔逻辑,就可以在向Chainlink闹钟提交请求之前启动投票,并在暂停了一段时间后回调函数被挪用时封锁投票。在这个例子中我们仅仅利用了一个布尔标识符,可是你可以在其基本上开拓出其他的延时成果。
别的,我们还需要一个job spec ID和一些追踪投票的变量,而且将投票者地点mapping为一个布尔值,以确认地点是否投过票。最后,我们要界说一个修改器,划定只有合约所有者才有权限发送动静挪用函数。然后在结构函数中将合约所有者地点以及其他变量一同初始化。注:mapping不需要初始化,布尔范例默认值是false。
voters[msg.sender] = true;
uint private oraclePayment;
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。