写点什么

经典智能合约之智能拍卖

作者:timerring
  • 2023-05-28
    山东
  • 本文字数:1990 字

    阅读完需:约 7 分钟

实现一个简易的拍卖合约

角色分析:4 类角色(拍卖师 actioneer,委托人 seller,竞买人 bidder,买受人 buyer)


功能分析:拍卖的基本原则是价高者得,在设定的拍卖时限内,出价最高者最终获得拍卖得标物(提示:在数据结构上,不用太复杂的设计,只需能记录当前最高价的竞买人及其金额、拍卖结束时间即可。)


  • 竞拍功能:竞买人可以多次出价,价格必须高于当前记录的最高价,并将最高价和竞买人替换。

  • 竞拍结束:竞拍结束时,宣布胜利者。

状态变量定义和初始化

定义变量:委托人、拍卖师、买受人、竞拍结束标志、时间限制、竞拍最高金额。(提示:合约调用者为拍卖师,如果涉及到转账的角色需要用 addresspayable,构造函数可以初始化拍卖师[即 msg.sender]、拍卖时限、竞拍结束标志,竞买人在程序中选择不同 account,根据 account 和 msg.value 更新买受人和最高金额)

竞拍功能

只要竞拍未结束都可以发起竞拍(提示:从调用信息窗口选择买家,输入竞拍价格,用 msg.sender 和 msg.value 获得买家和价格信息)


但需要满足以下条件:竞拍未结束;竞拍时的价格一定要比之前的价格高;竞拍在时限内;


当竞拍被允许时,需要退钱给上一个买家,并替换原有的最高价格和买受人。

结束竞拍

判断是否超过时限,并且是第一次执行本操作,确认通过后,转账给委托人。

合约代码

pragma solidity ^0.8.4;contract auction {    uint auctionEndTime;    address public auctioneer;    address public buyer;    address payable public seller;    uint public auctionAmount;
// Allowed withdrawals of previous bids mapping(address => uint) pendingReturns;
// A sign to judge whether the auction is over // Set to true at the end, disallows any change. bool ended;
// Events that will be emitted on changes. event auctionAmountIncreased(address bidder, uint amount); event AuctionEnded(address winner, uint amount);
// Errors that describe failures. /// The auction has already ended. error AuctionAlreadyEnded(); /// There is already a higher or equal bid. error BidNotHighEnough(uint auctionAmount); /// The auction has not ended yet. error AuctionNotYetEnded(); /// The function auctionEnd has already been called. error AuctionEndAlreadyCalled();
constructor( uint biddingTime, address payable sellerAddress ) { seller = sellerAddress; auctionEndTime = block.timestamp + biddingTime; auctioneer = msg.sender; }
/// Bid function function bid() external payable { // Revert the call if the bidding period is over. if (block.timestamp > auctionEndTime) revert AuctionAlreadyEnded();
// Return money if the bid is not high enough if (msg.value <= auctionAmount) revert BidNotHighEnough(auctionAmount);
if (auctionAmount != 0) { pendingReturns[buyer] += auctionAmount; } buyer = msg.sender; auctionAmount = msg.value; emit auctionAmountIncreased(msg.sender, msg.value); }
/// End the auction and send the highest bid to the seller. function auctionEnd() external payable {
// Analyzing conditions if (block.timestamp < auctionEndTime) revert AuctionNotYetEnded(); if (ended) revert AuctionEndAlreadyCalled(); ended = true; emit AuctionEnded(buyer, auctionAmount); // transfer seller.transfer(auctionAmount); }}
复制代码


首先,按照要求 deploy 拍卖合约,按照要求设置相关参数,其中 seller 的地址是 0x78731D3Ca6b7E34aC0F824c42a7cC18A495cabaB ,竞拍的时间是 120


如下所示:



deploy 成功之后,进行初始查询,右下可知,auctioneer 即为合约调用者的地址,seller 地址与刚刚输入的地址一致。初始 buyer 地址默认为 0,出价金额也为 0。



然后进行第一次竞拍,切换至地址结尾为 35cb2 的账户,出价为 1949 wei,进行竞拍:



查询后可知,竞拍成功,并且出现在当前 buyer 位置:



然后进行第二次竞拍,切换至地址结尾为 C02db 的账户,出价为 6666 wei,进行竞拍:



查询后可知,竞拍成功,并且出现在当前 buyer 位置:



然后进行第三次竞拍,切换至地址结尾为 5E7f2 的账户,出价为 9999 wei,进行竞拍:



查询后可知,竞拍成功,并且出现在当前 buyer 位置:



最后,待拍卖时间结束后进行 auctionEnd,根据定义,价高者得,因此 winner 是出价 9999 wei 的账户,结果如下:



发布于: 刚刚阅读数: 2
用户头像

timerring

关注

公众号【AIShareLab】 2022-07-14 加入

他日若遂凌云志

评论

发布
暂无评论
经典智能合约之智能拍卖_区块链_timerring_InfoQ写作社区