본문 바로가기
WATTO 프로젝트/컨트렉트

NFT 경매

by gun_poo 2022. 2. 13.

NFT 관련 글이 길어 경매 파트는 따로 정리

 

event Start();
    event Bid(address indexed sender, uint amount);
    event Withdraw(address indexed bidder, uint amount);
    event End(address winner, uint amount);
    event Endedat(uint a);
    

    struct Auction {
            bool started;
            address owner;
            uint nftId;
            bool status;
            uint endAt;
            address highestBidder;
            uint highestBid;
            bool ended;
            
        }
    mapping(uint => Auction) auction;
    mapping(uint => mapping(address => uint)) public bids;
    
    function startAuction(uint nftId, address owner, uint _startingBid) public {
         auction[nftId].nftId = nftId;
         auction[nftId].owner = owner;
         auction[nftId].started = true;
         auction[nftId].highestBid = _startingBid;
         transferFrom(owner, address(this), nftId);
         auction[nftId].endAt = block.timestamp + 1 days;

         emit Endedat(auction[nftId].endAt);
      }

    function bid(uint nftId, address buyer, uint amount) public {
        require(auction[nftId].started, "not started");
        require(block.timestamp < auction[nftId].endAt, "ended");
        require(amount > auction[nftId].highestBid, "value < highest");

        if (auction[nftId].highestBidder != address(0)) {
            bids[nftId][auction[nftId].highestBidder] += auction[nftId].highestBid;

        }
        token.transferFrom(buyer, address(this), amount);
        auction[nftId].highestBidder = buyer;
        auction[nftId].highestBid = amount;

    }

    function withdraw(address addr, uint nftId) public {
        uint bal = bids[nftId][addr];
        bids[nftId][addr] = 0;
        token.transferFrom(address(this), addr , bal);
        emit Withdraw(addr, bal);
    }

    function end(uint nftId) public {
        require(auction[nftId].started, "not started");
        require(block.timestamp >= auction[nftId].endAt, "not ended");
        require(!auction[nftId].ended, "ended");

        auction[nftId].ended = true;
        if (auction[nftId].highestBidder != address(0)) {
            safeTransferFrom(address(this), auction[nftId].highestBidder, nftId);
            token.transferFrom(address(this), auction[nftId].owner, auction[nftId].highestBid);
        } else {
            safeTransferFrom(address(this), auction[nftId].owner, nftId);
        }
        emit End(auction[nftId].highestBidder, auction[nftId].highestBid);
    }

event 와 Auction 구조체 설정

 

mapping(uint => Auction) auction;
auction[uint] = Auction;
mapping(uint => mapping(address => uint)) public bids;
bids[uint][address] = uint;
uint 배열에 해당하는 address 값이 가르키는 uint => bids

function startAuction

function startAuction(uint nftId, address owner, uint _startingBid) public {
auction[nftId].nftId = nftId;
auction[nftId].owner = owner;
auction[nftId].started = true;
auction[nftId].highestBid = _startingBid;
transferFrom(owner, address(this), nftId);
  • nft의 소유주가 auction을 진행하기 위해서 nft 컨트렉트에게 nft를 먼저 전달한다.
auction[nftId].endAt = block.timestamp + 1 days;
  • 경매 기간 설정 : +1days; 부분
  • block.timestamp 보안 설정 필요

emit Endedat(auction[nftId].endAt);
}

function bid

  • 입찰 함수
function bid(uint nftId, address buyer, uint amount) public {
require(auction[nftId].started, "not started");
require(block.timestamp < auction[nftId].endAt, "ended");
require(amount > auction[nftId].highestBid, "value < highest");

if (auction[nftId].highestBidder != address(0)) {
bids[nftId][auction[nftId].highestBidder] += auction[nftId].highestBid;
  • 해당 nftId에 action[nftId].highestBidder가 제시한 bids 값에 갱신된 highestBid를 더해준다
}
token.transferFrom(buyer, address(this), amount);
  • ERC-20 transferForm을 이용해 입찰금 amount를 nft 컨트렉트로 전송시켜주고
auction[nftId].highestBidder = buyer;
auction[nftId].highestBid = amount;
  • 갱신
}

function withdraw

  • 최고 입찰자가 아닌 유저는 입찰금 회수 기능 제공
function withdraw(address addr, uint nftId) public {
uint bal = bids[nftId][addr];
  • 해당 nftId에 회수를 실행한 유저의 bids를 빼기 위해서 먼저 bal로 저장해주고
bids[nftId][addr] = 0;
  • bids를 초기화 시켜줌
token.transferFrom(address(this), addr , bal);
  • transferForm으로 저장시킨 bal 값을 전송
emit Withdraw(addr, bal);
  • event로 기록
}

function end

  • 입찰 종료 실행 함수 : 판매자만 호출 가능
function end(uint nftId) public {
require(auction[nftId].started, "not started");
require(block.timestamp >= auction[nftId].endAt, "not ended");
require(!auction[nftId].ended, "ended");
  • require 문으로 걸리는것들 거르고

auction[nftId].ended = true;
if (auction[nftId].highestBidder != address(0)) {
safeTransferFrom(address(this), auction[nftId].highestBidder, nftId);
  • nft 컨트렉트가 최고 입찰자에게 입찰에 해당하는 nftId 값을 추적해서 전달
token.transferFrom(address(this), auction[nftId].owner, auction[nftId].highestBid);
  • nft 컨트렉트가 경매를 시작한 판매자에게 최고 입찰금을 전달
} else {
safeTransferFrom(address(this), auction[nftId].owner, nftId);
}
emit End(auction[nftId].highestBidder, auction[nftId].highestBid);
  • End 이벤트로 기록
}

 

'WATTO 프로젝트 > 컨트렉트' 카테고리의 다른 글

Ethereum 기반 컨트렉트 klaytn 환경으로 변경  (0) 2022.02.14
NFT 컨트렉트  (0) 2022.02.13
Token_Swap  (0) 2022.02.13
WT_Token  (0) 2022.02.12
NWT_Token  (0) 2022.02.12

댓글