solidity实战练习4——英式拍卖(常见的拍卖形式)

//SPDX-License-Identifier:MIT
pragma solidity ^0.8.24;

interface IERC721 {
    function safeTransferFrom(
        address from,
        address to,
        uint tokenId
    ) external;

    function transferFrom(
        address,
        address,
        uint
    ) external;
}

contract EnglishAuction{
    address payable public seller;//卖家
    uint public immutable startTime;//开始时间
    uint public immutable startPrise;//结束时间
    uint public immutable lastTime;//持续时间
    IERC721 nft;//nft 变量能够存储一个已经部署的符合 IERC721 接口的合约地址
    uint nftId;//nft编号


    constructor (  //给部分状态变量进行赋值
        uint _startPrise ,
        uint _nftId,
        address _nft

        ){
        seller=payable(msg.sender);    //后面需要往seller里面转账,因此这里需要带上payable    
        startPrise=_startPrise;  //起始价
        nft=IERC721(_nft);
        nftId= _nftId;
    }
    uint endTime ;
    bool public isStart = false;
    bool public isEnded = false;
    uint public  higestPrise = startPrise;//将最高价初始化为起始价
    address public higestbider; //最高价的出价人
    mapping (address=>uint) public bids;//这个映射用来记录所有参与竞拍的人员,之后需要将所有的人员的代币全部悉数返回
    
    event start(string );//定义事件来记录开始
    event bid(address,uint);//定义事件来记录某地址参与拍卖
    event withdraw(address,uint );//定义事件来记录参与者但未获得竞拍品转走自己的余额
    event end(address,uint);//定义事件记录结束
    modifier checkIsStart() {//函数修改器
        require(isStart,"not begin");
        _;//交给调用函数
    }

    function Start(uint _startTime,uint _lastTime) public  {//所有者才能参与调用
        require(msg.sender == seller,"You have no rights to call this funciton");
        require(!isStart,"The auction have started");
        nft.transferFrom(msg.sender, address(this), nftId);//开始之后将nft的所有者暂时任命为本合约
        endTime=_lastTime+_startTime;//确定好结束时间
        isStart=true;//确认开始
        emit start("Auction has started");//触发事件start
    }

    function Bid() external payable checkIsStart {//参与拍卖
        require(block.timestamp < endTime,"the auction time is over");
        require(msg.value>=higestPrise,"your bid is too low");//确保参与人转到合约里面的主币要比当前最高的出价大
        
        if(higestbider!=address(0))
        {
            bids[higestbider]+= higestPrise;
        }

        higestbider=msg.sender;//更新最高价的信息
        higestPrise=msg.value;
        bids[higestbider]=msg.value;//bid记录竞拍人信息
        emit bid(msg.sender,msg.value);
    }

    function End() public checkIsStart
    {   
        require(block.timestamp > endTime,"the auction time is continuing");
        require(!isEnded, "ended");
        seller.transfer(higestPrise);//竞拍获胜者向所有者转账
        nft.transferFrom(address(this),msg.sender, nftId);//将nft所有者转给竞拍获胜者
        isEnded = true;//表示结束
        emit end(higestbider,higestPrise);//触发事件记录竞拍获胜者
    }

    function Withdraw(address payable withdrawer)public checkIsStart {//竞拍获胜者撤资
        require(bids[withdrawer]!=0,"you have never been in this auction");
        withdrawer.transfer(bids[withdrawer]);
        bids[withdrawer]=0;
        emit withdraw(withdrawer,bids[withdrawer]);
    } 
 
}

猜你喜欢

转载自blog.csdn.net/2303_79193185/article/details/140387921