1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145 | // 1. NFT市场
contract NFTMarket {
struct Listing {
address seller;
uint256 price;
bool active;
}
// 市场费率
uint256 public constant MARKET_FEE = 250; // 2.5%
// 商品列表
mapping(address => mapping(uint256 => Listing)) public listings;
// 上架NFT
function listNFT(
address nftContract,
uint256 tokenId,
uint256 price
) external {
IERC721 nft = IERC721(nftContract);
require(
nft.ownerOf(tokenId) == msg.sender,
"Not token owner"
);
require(
nft.getApproved(tokenId) == address(this),
"Not approved for marketplace"
);
listings[nftContract][tokenId] = Listing(
msg.sender,
price,
true
);
}
// 购买NFT
function buyNFT(address nftContract, uint256 tokenId) external payable {
Listing storage listing = listings[nftContract][tokenId];
require(listing.active, "Not listed");
require(msg.value >= listing.price, "Insufficient payment");
// 计算费用
uint256 marketFee = (msg.value * MARKET_FEE) / 10000;
uint256 sellerProceeds = msg.value - marketFee;
// 转移NFT
IERC721(nftContract).safeTransferFrom(
listing.seller,
msg.sender,
tokenId
);
// 支付费用
payable(listing.seller).transfer(sellerProceeds);
payable(owner()).transfer(marketFee);
// 删除listing
delete listings[nftContract][tokenId];
}
}
// 2. NFT拍卖
contract NFTAuction {
struct Auction {
address seller;
uint256 startPrice;
uint256 endTime;
address highestBidder;
uint256 highestBid;
bool ended;
}
mapping(address => mapping(uint256 => Auction)) public auctions;
// 创建拍卖
function createAuction(
address nftContract,
uint256 tokenId,
uint256 startPrice,
uint256 duration
) external {
IERC721 nft = IERC721(nftContract);
require(
nft.ownerOf(tokenId) == msg.sender,
"Not token owner"
);
require(
nft.getApproved(tokenId) == address(this),
"Not approved for auction"
);
auctions[nftContract][tokenId] = Auction(
msg.sender,
startPrice,
block.timestamp + duration,
address(0),
0,
false
);
}
// 出价
function bid(address nftContract, uint256 tokenId) external payable {
Auction storage auction = auctions[nftContract][tokenId];
require(!auction.ended, "Auction ended");
require(block.timestamp < auction.endTime, "Auction expired");
require(
msg.value > auction.highestBid,
"Bid too low"
);
// 退还之前的最高出价
if (auction.highestBidder != address(0)) {
payable(auction.highestBidder).transfer(auction.highestBid);
}
// 更新最高出价
auction.highestBidder = msg.sender;
auction.highestBid = msg.value;
}
// 结束拍卖
function endAuction(address nftContract, uint256 tokenId) external {
Auction storage auction = auctions[nftContract][tokenId];
require(!auction.ended, "Auction already ended");
require(
block.timestamp >= auction.endTime,
"Auction not yet ended"
);
auction.ended = true;
// 转移NFT
IERC721(nftContract).safeTransferFrom(
auction.seller,
auction.highestBidder,
tokenId
);
// 支付卖家
payable(auction.seller).transfer(auction.highestBid);
}
}
|