ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

智能合约经典代码实战(一)——盲拍合约

2021-10-15 16:00:50  阅读:207  来源: 互联网

标签:实战 value length uint fake msg 盲拍 合约 public


由于学业上的需求,所以速成了一波Solidity。紧接着我会进行几篇经典代码的实战笔记的撰写,主要是写一些复现过程中出现的问题,以作记录。小白一枚,合理探讨,大佬勿喷……

合约使用场景:当我们需要对某一件事物进行竞拍的时候,存在一种盲拍的方式。也就是说,所有有资格出价竞拍的用户在规定时间内都可以进行出价,但是价格都是不对外公开的,只有等竞拍到时间才会公布获胜者以及出价金额,其余代币会返回给发送者。

在线IDE:Remix

 

pragma solidity ^0.7.0;  //不知道什么原因,原文给的版本,我的remix不识别address payable,所以调高了solc版本,相应的一些全局变量会有一些更改,不影响大局。

contract BlindAuction {
   //竞拍者:盲拍所递交的加密代码+msg.value(货币) struct Bid { bytes32 blindedBid; uint deposit; }   //可支付地址,即可以使用transfer这样一类的交易函数 address payable public beneficiary;
  //竞拍截止时间 uint public biddingEnd;
  //明牌截止时间 uint public revealEnd;
  //本次拍卖结束标志 bool public ended;
  //通过Hash将地址与Bid结构的竞拍者信息进行映射 mapping(address => Bid[]) public bids;
  //最高价者 address public highestBidder;
  //最高价 uint public highestBid;
  //为了方便返款,通过映射的方式记录 mapping(address => uint) pendingReturns;   //当竞拍结束后,会调用这个事件,记录到区块链中 event AuctionEnded(address winner, uint highestBid);   //修改器,用来限制时间 modifier onlyBefore(uint _time) { require(block.timestamp < _time); _; } modifier onlyAfter(uint _time) { require(block.timestamp > _time); _; }   //用来创建一个竞拍合约的 constructor ( uint _biddingTime, uint _revealTime, address payable _beneficiary ) payable public { beneficiary = _beneficiary; biddingEnd = block.timestamp + _biddingTime; revealEnd = biddingEnd + _revealTime; }   //竞拍函数:这里要详细说的一个点就是竞拍者将竞拍价格+fake属性+密钥通过keccak256进行编码加密。着重说明的是fake为false时是真正报价,fake为true时是用来迷惑其他报价者混淆真实数据。 function bid(bytes32 _blindedBid) public payable onlyBefore(biddingEnd) {
    //因为每个用户可以多次进行输入价格,所以每个地址所映射的用户有一个Bid结构数组用来存储相关数据。 bids[msg.sender].push(Bid({ blindedBid: _blindedBid, deposit: msg.value })); }   //明牌函数 function reveal( uint[] memory _values, bool[] memory _fake, bytes32[] memory _secret ) public onlyAfter(biddingEnd) onlyBefore(revealEnd) {
    //做相应的限制,要求数据的统一 uint length = bids[msg.sender].length; require(_values.length == length); require(_fake.length == length); require(_secret.length == length);     //返款总数 uint refund;
    //遍历账户下每一个出款记录,在保证数据的正确情况下将所有价格总计起来返还 for (uint i = 0; i < length; i++) { Bid storage bidToCheck = bids[msg.sender][i]; (uint value, bool fake, bytes32 secret) = (_values[i], _fake[i], _secret[i]); if (bidToCheck.blindedBid != keccak256(abi.encodePacked(value, fake, secret))) { continue; } refund += bidToCheck.deposit;
        //这里主要是用来判断资金是否充足,是否是更高价以用来更改数据 if (!fake && bidToCheck.deposit >= value) { if (placeBid(msg.sender, value)) refund -= value; }
        //先更改合约数据 bidToCheck.blindedBid = bytes32(0); }
      //再进行货币交易,防止重复还款 msg.sender.transfer(refund); }     //内部函数,用来出价的,选择最高价 function placeBid(address bidder, uint value) internal returns (bool success) { if (value <= highestBid) { return false; } if (highestBidder != address(0)) { pendingReturns[highestBidder] += highestBid; } highestBid = value; highestBidder = bidder; return true; }     //退款函数,还是要注意先判断条件、再修改内部状态数据、最后进行货币交易 function withdraw() public { uint amount = pendingReturns[msg.sender]; if (amount > 0) { pendingReturns[msg.sender] = 0; msg.sender.transfer(amount); } }     //竞拍事件结束,修改竞拍事件状态,发送事件宣布结果,并最后发送款项给受益方 function auctionEnd() public onlyAfter(revealEnd) { require(!ended); emit AuctionEnded(highestBidder, highestBid); ended = true; beneficiary.transfer(highestBid); } }

 

标签:实战,value,length,uint,fake,msg,盲拍,合约,public
来源: https://www.cnblogs.com/7ixia/p/15411368.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有