NFT鑄造競拍交易平臺dapp系統開發合約部署詳情

nice1022發表於2023-03-02

拍賣,顧名思義就是在規定的時間和場所,按照一定的章程和規則,將要拍賣的貨物向買主進行展示,公開叫價競購,最後由拍賣人把貨物賣給出價最高的買主的一種交易方式。傳統的拍賣一般都是實體物品,隨著nft的發展,拍賣從傳統的實物衍生到了nft數字藝術,也給疫情之下的拍賣行業尋求了一條轉型之路。


對於nft系統開發I34-合約I633-部署53I9更多的是嘗試建立和購買,拍賣接觸的相對較少,區塊鏈上有公鏈和測試鏈,公鏈是需要費用,測試鏈就不用,為了演示,今天就用一款開源的工具FInger NFT來給大家演示一下nft拍賣怎麼進行出價購買。


我們模擬一個拍賣合約,其中在這個程式中,並且初始便定義了商品資訊,跟拍賣時間和起拍價,對於這三個東西,我們都是可以直接修改的,自己根據需求定義一個函式,用於推送商品等。


//SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
 
//定義合約名為auction
contract auction{
 
    //定義拍賣行
    address payable public Auctioneer;
 
    //定義商品基本資訊
    mapping(uint256 => string) commodity;
 
    //定義商品處於的狀態
    mapping(uint256 => string) state;
 
    //狀態池
    mapping(uint256 => uint256) Astate;
 
    //定義商品的歸屬人
    mapping(uint256 => address) belong;
 
    //定義買方交易金額的買方地址
    mapping(uint256 => address payable) maxAdd;
 
    //定義買方支付的交易金額
    mapping(uint256 => uint256) bond;
 
    //定義拍賣開始時間
    uint256 timeStamp;
 
    //定義拍賣結束時間
    uint256 endtime;
 
    //定義起拍價
    uint256 StartPrice;
 
    //定義拍賣時長
    uint256 AuctionTime;
 
    //定義出價記錄的結構體
    struct Bidder {
        address addr; //出價者地址
        uint256 amount; //出價金額
        uint256 bidAt; //出價時間
    }
 
    //定義對映,用於記錄不同編號商品對應的出價記錄
    mapping(uint256 => Bidder[]) record;
 
    //單個出價記錄
    Bidder bidder;
 
    //出價記錄陣列
    Bidder[] bidders;
 
    //變數初始化
    constructor (address _owner){
        //拍賣發起人(拍賣行)
        Auctioneer = payable(_owner);
 
        //商品資訊初始化
        commodity[0] = "xuperchain Lamborghini";
        commodity[1] = "xuperchain Benz";
        commodity[2] = "xuperchain BMW";
 
        //商品的狀態初始化
        state[0] = "To be auctioned";          //定義待拍賣狀態
        state[1] = "Under auction";            //定義拍賣中狀態
        state[2] = "Successfully Sold";        //定義成功出售狀態
        state[3] = "Flow beat";                //定義流拍狀態
        
        //拍賣時長初始化
        AuctionTime = 10 minutes;
        
        //商品價格初始化
        StartPrice = 100;
    }
 
   
 
    //定義 Authentication 函式修飾器,開發v+hkkf5566,用於在執行函式時,用於判斷是否為合約發起人
    modifier Authentication{
        require (Auctioneer == msg.sender, "You're not an auction promoter");
        _;
    }
 
    /*
    @notice 將商品上架
    @dev 商品狀態必須為 "To be auctioned"
    @param uint8 numb -商品編號
    */
    function PutOnShelves(uint8 numb) public Authentication{
 
        //使用require對商品狀態進行判斷,當商品狀態不為0時,說明我們的商品已經上架過並進行了其他操作
        require (Astate[numb] == 0, "The goods are under auction or have been sold");
 
        //使用require判斷目前是否還有其他的商品正在進行拍賣
        require (timeStamp == 0 && endtime == 0, "Currently, there are goods under auction");
 
        //使用require判斷當前商品是否存在
        require(bytes(commodity[numb]).length != 0,"The current product does not exist");
 
        //修改商品狀態
        Astate[numb] = 1;
 
        //定義商品開始拍賣時間
        timeStamp= block.timestamp;
 
        //定義結束時間,為開始拍賣的十分鐘後
        endtime = block.timestamp + 10 minutes;
 
        //商品歸屬者轉移
        belong[numb] = Auctioneer;
    }
    
    /*
    @notice 實現買方對拍賣中的商品進行加價
    @dev 在 msg.value 中設定的加價的金額應該大於預設值 100
    @param uint8 numb -商品編號
    */
    function MarkUp (uint8 numb) public payable {
 
        //使用require對加價者身份進行判斷,拍賣方無法對已上架的商品進行加價
        require(msg.sender != Auctioneer ,"The product is already in the auction, you cannot increase the price");
 
        //使用require判斷當前時間是否在拍賣時間內
        require(block.timestamp < endtime && block.timestamp > timeStamp,"It'numb not auction time yet");
 
        //使用require對當前商品的狀態進行判斷,加價的商品需要是正在拍賣的商品
        require(Astate[numb] == 1, "The current commodity auction has ended");
 
        //對加價判斷是否為第一次出價
        if(bond[numb] == 0){
 
            //使用require判斷第一次加價的金額不能低於起拍價
            require(msg.value > StartPrice,"Your bid amount must be greater than the starting price");
        }
 
        //使用require對加價金額判斷不能低於上一次出價
        require(msg.value > bond[numb], "Your bid amount must be greater than the current price");
 
        //呼叫AmoutRollback函式,將上一個出價者的交易金額退回,並收取當前出價者的交易金額
        AmountRollback(numb);
 
        //呼叫AddTransaction函式,儲存商品的出價記錄
        AddTransaction(numb);
 
        //滿足以上條件則說明買方的價格滿足加價的要求,將當前的商品歸屬轉移至此買方的地址
        belong[numb] = msg.sender;
    }
 
    /*
    @notice 實現將買方支付的保證金退回
    @param uint8 numb -商品編號
    */
    function AmountRollback(uint8 numb) internal {
 
        //將上一個支付交易金額退回
        maxAdd[numb].transfer(bond[numb]);
 
        //收取當前出價者的交易金額
        bond[numb] = msg.value;
 
        //記錄出價者的地址
        maxAdd[numb] = payable(msg.sender);
    }
 
    /*
    @notice 實現記錄商品的交易記錄
    @param uint8 numb -商品編號
    */
    function AddTransaction(uint8 numb) internal {
 
        //將出價者的地址,金額,出價時間戳,新增進bidder
        bidder = Bidder(msg.sender,msg.value,block.timestamp);
        bidders.push(bidder);
        record[numb] = bidders;
    }
 
    /*
    @notice 實現修改商品的狀態為  ”成功出售狀態“ 或 ”流拍狀態“
    @param uint8 numb -商品編號
    */
    function closeAuction(uint8 numb) public Authentication{
 
        //使用require對當前時間跟拍賣發起時間進行比較,判斷當前是否處於拍賣結束
        require(block.timestamp > endtime, "Auction in progress");
 
        //透過if語句進行判斷,當前商品的歸屬是否是拍賣發起人
        if (belong[numb] == Auctioneer){
 
            //修改狀態為流拍
            Astate[numb] = 3;
        }else{
 
            //將商品狀態修改為成功拍賣
            Astate[numb] = 2;
        }
 
        //重置商品起拍時間
        timeStamp = 0;
 
        //重置商品結束拍賣時間
        endtime = 0;
    }
 
    /*
    @notice 實現獲取商品歸屬者
    @param uint8 numb -商品編號
    @return address -商品擁有者的地址
    */
    function getBelong(uint8 numb) public view Authentication returns(address){
        return belong[numb];
    }
 
    /*
    @notice 實現獲取當前地址
    */
    function getSender() public view returns(address){
        return msg.sender;
    }
 
    /*
    @notice 實現獲取對應商品的最高叫價
    @param uint8 numb -商品編號
    @return uint256 -商品最高叫價
    */
    function getMaxMoney(uint8 numb)public view returns(uint256){
 
        //使用require對商品的狀態進行判斷,需要對在拍賣的商品才能查詢當前最高叫價
        require (Astate[numb] == 1 ,"The current product is not available");
 
        //沒有買方出價,則返回商品初始價格
        if(bond[numb] == 0){
            return StartPrice;
        }else{
            return bond[numb];
        }
        
    }
    /*
    @notice 實現獲取對應商品的狀態
    @param uint8 numb -商品編號
    @return string -商品狀態
    */
    function getStatus(uint8 numb)public view returns(string memory){
        return state[Astate[numb]];
    }
 
    /*
    @notice 實現獲取對應編號的商品資訊
    @parma uint8 numb -商品編號
    @return string -商品的名稱
            uint256 -拍賣時長
            uint256 -起拍價格
            uint256 -拍賣結束時間
    */
    function getItemInformation(uint8 numb)public view returns(string memory,uint256,uint256,uint256){
 
        return (commodity[numb],AuctionTime,StartPrice,endtime);
    }
 
    /*
    @notice 實現獲取對應編號的拍賣記錄
    @dev 該方法只能有交易發起者呼叫
    @param uint8 numb -商品編號
    @return Bidder[] -交易記錄的陣列
    */
    function getRecord(uint8 numb) public view Authentication returns (Bidder[] memory){
        return record[numb];
    }
 
     /*
    @notice 實現拍賣發起人提取保證金
    @dev 該方法只能有交易發起者呼叫
    @param uint8 numb -商品編號
    */
    function getAuctionMoney(uint8 numb) public payable Authentication{
 
        //使用require判斷商品拍賣是否結束
        require(block.timestamp > endtime, "The current auction is not over yet. You can't extract");
 
        //使用require判斷商品是否成功出售
        require(Astate[numb] == 2 ,"Your product was not successfully sold");
 
        //使用require判斷保證金內是否還有餘額
        require(bond[numb] != 0, "You have initiated transaction amount withdrawal");
 
        //拍賣發起人提取保證金
        payable(msg.sender).transfer(bond[numb]);
 
        //重置保證金為0
        bond[numb] = 0;
    }
 
    /*
    @notice 銷燬合約
    @dev 該方法只能由合約發起者呼叫,並且該方法只有在拍賣全部結束後才能呼叫,呼叫後合約將被銷燬
    */
    function destroy() public virtual Authentication{
        for (uint256 i;i < 3;i++){
            require(Astate[i] != 1 && bond[i] == 0,"The goods are still in the auction or you haven't withdrawn the amount");
        }
    }
}



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70011332/viewspace-2937796/,如需轉載,請註明出處,否則將追究法律責任。

相關文章