美文网首页
20230313SimpleAuction代码及相关注释反思

20230313SimpleAuction代码及相关注释反思

作者: 李荣强Justin | 来源:发表于2023-03-12 13:53 被阅读0次

//SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.17;

///@title for Auction

///@dev rongqiang.li

contract SimpleAuction{

//定义了一个可以支付的公共状态变量,受益人

    address payable public beneficiary;

    //定了一个公共的状态变量,拍卖结束时间,uint类型

    uint public auctionEndTime;

    //定义了一个公共状态变量,地址类型,用于记录最高出价者的账户地址

    address public highestBidder;

    //定义了一个公共状态变量,uint类型,用于记录最高出价

    uint public highestBid;

    //定义了一个mapping,key为地址类型,value为uint类型,用于记录拍卖未得者的地址以及该返回金额

    mapping(address =>uint)pendingReturns;

    // 定义了一个bool类型的变量,用于记录拍卖是否结束

    bool ended;

    //定义了一个事件,当最高单价提高时,通知当前最高价出价者,以及出价金额

    event HighestBidIncreased(address bidder,uint amount);

    // 定义了一个事件,用于当拍卖结束时,通知当前获胜者的地址,以及出价金额

    event AuctionEnded(address winner,uint amount);

    // 定义了一个错误,用于判断拍卖已经结束时,如果还有人继续拍卖,则获得这个异常提醒

    error AuctionAlreadyEnded();

    //定义了一个出价不足,没有超过当前最高价的错误,用于当有人出价时,如果出价并没有超过当前出的最高价,则获得这个错误提醒.

    error BidNotHighEnough(uint highest);

    // 定义了一个拍卖未结束的error

    error AuctionNotYetEnded();

    //如果拍卖已经结束,但是还是有人试图再次调用拍卖结束方法时,抛出这个错误

    error AuctionEndAlreadyCalled();

    /*

    该合约的构造函数,接收两个参数,一个是拍卖时间,以秒计算,一个是受益人地址,必须要可以接受转账*/

    constructor(uint biddTime,address payable beneficiaryAddress){

beneficiary = beneficiaryAddress;

        auctionEndTime = block.timestamp + biddTime;// 将当前的区块时间戳+加上拍卖总时长,得到拍卖的结束时间

    }

function bid()external payable{

//判断当前区块时间是否大于拍卖结束时间,如果拍卖已经结束,则抛出AuctionAlreadyEnded 错误

        if(block.timestamp > auctionEndTime)

revert AuctionAlreadyEnded();

        //判断当前调用房的出价,如果小于等于当前的最高出价,则抛出BidNotHighEnough,并把当前最高出价作为参数传递

        if(msg.value <= highestBid)

revert BidNotHighEnough(highestBid);

        if(highestBid!=0){

//如果highestBid!=0 说明已经有人第一次出价,并且高于之前的最高价,那么就应该把之前最高价的出价人的资金返还到它的地址上

            pendingReturns[highestBidder] += highestBid;

        }

//走到这里说明当前合约调用方的出价是符合要求的,那么就记录下当前合约调用方的地址作为当前最高价的出价人,以及当前最高价

        highestBidder = msg.sender;

        highestBid = msg.value;

        //同时发送一个最高价提高的一个事件,将最新的最高价出价人,以及出价金额告知所有在监听的人

        emit HighestBidIncreased(msg.sender,msg.value);

    }

function withdraw()external returns (bool){

//根据调用方地址从mapping中取出其已经出价的总金额,作为提现金额

        uint amount = pendingReturns[msg.sender];

        if(amount<=0){

//如果取出当前调用方的待领取金额为0,说明他没有参与过这个拍卖或者它就是拍卖的赢家,那么就不需要提款,直接返回提款成功.

            return true;

        }

//如果退回金额大于0,说明这个地址要进行提款,首先提款之前,将其待提款金额归零.

        //然后调用转账函数,将该合约中的金额,转账给调用方的地址,金额就是之前我们取出的金额.

        if(payable(msg.sender).send(amount)){

pendingReturns[msg.sender] =0;

return true;

        }

//如果转账失败,则将带提取金额重新设置为之前的金额,返回false,告诉对方提款失败

        //同时payable函数是将当前msg.sender转换为可转账函数,从而去执行send方法,如果转换失败,也会返回false,则还是转账失败

        pendingReturns[msg.sender] = amount;

return false;

    }

function auctionEnd()external {

//如果当前时间戳没有到结束时间,而有调用方调用了合约结束的函数,那么就抛出AuctionNotYetEnded error

        if(block.timestamp < auctionEndTime){

revert AuctionNotYetEnded();

        }

//如果已经结束了,还有人调用这个结束函数,则抛出AuctionEndAlreadyCalled error

        if(ended){

revert AuctionEndAlreadyCalled();

        }

//到了这里说明时间也到了,并且结束标志还没有设置为结束,则将结束标志设置为结束,并且发出拍卖结束事件,告诉当前拍卖的最高价以及拍卖获得人.

        ended =true;

        emit AuctionEnded(highestBidder,highestBid);

        beneficiary.transfer(highestBid);// 最后将当前拍卖金额转账给收益人.

    }

}

相关文章

网友评论

      本文标题:20230313SimpleAuction代码及相关注释反思

      本文链接:https://www.haomeiwen.com/subject/tsafrdtx.html