- A+
所属分类:NFT
本文主要讲述搭建基于bsc链上的nft market教程,实现功能类似opensea。可以实现NFT的铸造,权限控制,交易,拍卖等功能。同时可以自定义拍卖和交易的手续费,原创作者收益等。相关功能都是基于BSC上的合约功能实现。大致的系统架构是类似于opensea,首先都nft进行colledction分类,不同的collection实现不同模式的nft功能。同一collection下的nft item具备相关的属性。同一collection下的的nft创建不同的分类加一区分,同时nft item关联不同的属性。
相关的合约如下:
ERC721接口类定义:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;
import "./IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}
实现类:
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
}
}
实现nft market核心功能的合约代码
contract ERC721Suika is ERC721Mochi, ReentrancyGuard {
using SafeMath for uint256;
using Address for address payable;
using Address for address;
constructor(
EIP20 _payment_token, address _owner, address payable _admin,
uint256 _commissionRate, uint256 _royaltiesCommissionRate, string memory name, string memory symbol, bool _anyoneCanMint)
ERC721Mochi(_owner, name, symbol, _anyoneCanMint)
{
admin = _admin;
contract_owner = _owner;
require(_commissionRate<=100, "ERC721Suika: Commission rate has to be between 0 and 100");
commissionRate = _commissionRate;
royaltiesCommissionRate = _royaltiesCommissionRate;
payment_token = _payment_token;
}
function sell(uint256 tokenId, uint256 price, address payable wallet) public {
// onlyOwner
require(ownerOf(tokenId)==msg.sender, "ERC721Suika: Only owner can sell this item");
// cannot set a price if auction is activated
require(!auctions[tokenId].open, "ERC721Suika: Cannot sell an item which has an active auction");
// set sell price for index
sellBidPrice[tokenId] = price;
// If price is zero, means not for sale
if (price>0) {
// approve the Index to the current contract
approve(address(this), tokenId);
// set wallet payment
_wallets[tokenId] = wallet;
}
}
function buy(uint256 tokenId) public nonReentrant {
// is on sale
require(!auctions[tokenId].open && sellBidPrice[tokenId]>0, "ERC721Suika: The collectible is not for sale");
// transfer ownership
address owner = ownerOf(tokenId);
require(msg.sender!=owner, "ERC721Suika: The seller cannot buy his own collectible");
// we need to call a transferFrom from this contract, which is the one with permission to sell the NFT
callOptionalReturn(this, abi.encodeWithSelector(this.transferFrom.selector, owner, msg.sender, tokenId));
// calculate amounts
uint256 amount4admin = sellBidPrice[tokenId].mul(commissionRate).div(100);
uint256 amount4creator = sellBidPrice[tokenId].mul(royaltiesCommissionRate).div(100);
uint256 amount4owner = sellBidPrice[tokenId].sub(amount4admin).sub(amount4creator);
// to owner
require(payment_token.transferFrom(msg.sender, _wallets[tokenId], amount4owner), "Transfer failed.");
// to creator
if (amount4creator>0) {
require(payment_token.transferFrom(msg.sender, creators[tokenId], amount4creator), "Transfer failed.");
}
// to admin
if (amount4admin>0) {
require(payment_token.transferFrom(msg.sender, admin, amount4admin), "Transfer failed.");
}
emit Sale(tokenId, owner, msg.sender, sellBidPrice[tokenId]);
emit Commission(tokenId, owner, sellBidPrice[tokenId], commissionRate, amount4admin);
emit Royalty(tokenId, owner, sellBidPrice[tokenId], royaltiesCommissionRate, amount4creator);
soldFor[tokenId] = sellBidPrice[tokenId];
// close the sell
sellBidPrice[tokenId] = 0;
delete _wallets[tokenId];
}
}
以上合约代码可以实现nft的铸造,权限控制,market买卖交易。
至此,完成币搭建基于BSC链的NFT Market合约实现。
pdf+视频币安智能链BSC发币教程下载:
pdf+视频币安智能链BSC发币教程下载地址:
本文是全系列中第14 / 17篇:NFT发行
- 币安链BSC上NFT发行教程——BSC链铸造nft并转账(空投)到其他钱包地址【pdf+视频BSC链NFT发行教程下载】
- 币安链BSC上NFT发行教程——NFT元数据模板,支持上线opensea并交易【pdf+视频BSC链NFT发行教程下载】
- 波场链TRX上NFT发行教程——web页面上传NFT头像到IPFS链【pdf+视频TRX链NFT发行教程下载】
- 币安链BSC上NFT发行教程——两种方式在BSC币安链上铸造NFT及部署NFT合约【pdf+视频BSC链NFT发行教程下载】
- 币安链BSC上NFT发行教程——NFT单品铸造完成后无法在tp钱包显示图片故障处理及解决方法【pdf+视频BSC链NFT发行教程下载】
- 币安链BSC上NFT发行教程——自动创建tokenid的NFT合约源码实现【pdf+视频BSC链NFT发行教程下载】
- 比特币NFTs: Ordinals NFT 图片怎么从rawTransaction原始交易中解析
- NFTScan | 06.12~06.18 NFT 市场热点汇总
- Safe 多签钱包签名消息, 支持签名登录 Opensea
- 币安BSC智能链发币教程——扫描所有NFT,根据NFT持有情况分红代币【pdf+视频BSC发币教程下载】
- 币安链BSC上NFT发行教程——NFT根据拍卖次数指数型递增增加价格【pdf+视频BSC链NFT发行教程下载】
- 币安链BSC上NFT发行教程——NFT合约中的代理人针对所有NFT的授权功能【pdf+视频BSC链NFT发行教程下载】
- 如何使用 Circom 和 SnarkJS 实现极简 NFT zkRollup
- 币安BSC智能链NFT Market搭建教程——搭建基于BSC链的NFT Market合约实现【pdf+视频BSC NFT教程下载】
- 波场链TRX上NFT发行教程——NFT中元数据合约源代码实现【pdf+视频TRX链NFT发行教程下载】
- 波场链TRX上NFT发行教程——部署波场链上的NFT合约【pdf+视频TRX链NFT发行教程下载】
- 波场链TRX上NFT发行教程——使用腾讯云存储代替ipfs存储的实现方式【pdf+视频TRX链NFT发行教程下载】
- 我的微信
- 这是我的微信扫一扫
- 我的电报
- 这是我的电报扫一扫