实现一个繁难的拍卖合约

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

功能分析:拍卖的根本准则是价高者得,在设定的拍卖时限内,出价最高者最终取得拍卖得标物(提醒:在数据结构上,不必太简单的设计,只需能记录以后最高价的竞买人及其金额、拍卖完结工夫即可。)

  • 竞拍性能:竞买人能够屡次出价,价格必须高于以后记录的最高价,并将最高价和竞买人替换。
  • 竞拍完结:竞拍完结时,发表胜利者。

状态变量定义和初始化

定义变量:委托人、拍卖师、买受人、竞拍完结标记、工夫限度、竞拍最高金额。(提醒:合约调用者为拍卖师,如果波及到转账的角色须要用address
payable,构造函数能够初始化拍卖师[即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的账户,后果如下: