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 |
댓글