我們將一步一步地瀏覽合約,在每一步中,我們將首先看一個解釋高層次過程的K線走勢圖,然後再看代碼。
在文章的最後,我們將使用Remix IDE 和Metamask 部署合約到Polygon 測試網,並創建+ 上傳NFT 到市場。
你可以在這裡看到完整的代碼 。
什麼是NFT?
NFT(Non-fungible) 或多或少意味著它是獨一無二的,不能被其他東西取代。例如,比特幣是可替代的——用一個比特幣換另一個比特幣,你將擁有完全相同的東西。然而,獨一無二的交易卡是不可替代的。如果你將其換成另一張卡,你將擁有完全不同的東西。
通常用於虛擬世界中的藝術或物品,但它可以是任何數字或真實的。例如,NFT 可以作為現實世界中房屋的參考,並且所有權是可公開追踪的。
讓我們開始看看創建和銷售NFT 的過程。要理解Solidity 代碼,你需要對Solidity 有基本的了解,或者 如果你不了解所有內容,可以查看Solidity 文檔。
NFT -> createToken ()
首先,必須先創建NFT,然後才能在市場或其他地方進行交易。
在上圖中,你可以看到該 createToken() 方法調用了合約的三個方法, 這ERC721URIStorage 是OpenZeppelin 合約存儲庫中經過良好測試和維護的合約之一 。該 方法將接收 作為IPFS 的URI 的參數,例如:createToken()tokenURI
https://ipfs.io/ipfs/Qme7ss3ARVgxv6rXqVPiikMJ8u2NLgmgszg13pYrDKEoiu
在該 _safeMint() 方法中將生成NFT,並將發送者設置為所有者。之後,該 _setTokenURI() 方法會將上面的IPFS URI 設置為令牌URI。
在該 _setApprovalForAll() 方法內,市場合約將獲得為所有者管理NFT 的津貼。這意味著市場合約將被允許在收到付款給買方後出售NFT 並轉移所有權。至少它將返回從1 開始的newItemId,並為每個新的NFT 遞增。
function createToken(string memory tokenURI) public returns (uint) { _tokenIds.increment(); uint256 newItemId = _tokenIds.current(); _safeMint(msg.sender, newItemId); _setTokenURI(newItemId, tokenURI); setApprovalForAll(contractAddress, true); return newItemId;}
接下來,我們需要將創建的NFT 添加到市場。
NFTMarket -> addItemToMarket()
經過兩次需求檢查後,我們將創建一個新的 MarketItem 並將其推送到一個包含市場所有NFT 的數組中,然後將NFT 轉移到市場,然後,我們會發出一個包含新MarketItem 詳細信息的事件。
function addItemToMarket( address nftContract, uint256 tokenId, uint256 price) public payable nonReentrant { require(price > 0, “Price must be at least 1 wei”); require(msg.value == listingPrice, “Price must be equal to listing price”); _itemIds.increment(); uint256 itemId = _itemIds.current(); idToMarketItem[itemId] = MarketItem( itemId, nftContract, tokenId, payable(msg.sender), payable(address(0)), price ); IERC721(nftContract).safeTransferFrom(msg.sender, address(this), tokenId); emit MarketItemCreated( itemId, nftContract, tokenId, msg.sender, address(0), price );}
接下來,我們需要接收買家可以查看和購買的未售出NFT 清單。
NFTMarket -> getUnsoldItems()
我們讀取市場上所有NFT 的數量,遍歷項目,並檢查市場合約是否是當前所有者,如果是,則將其添加到項目數組中,最後返回所有未售出的項目。
function getUnsoldItems() public view returns (MarketItem[] memory) { uint itemCount = _itemIds.current(); uint unsoldItemCount = _itemIds.current() – _itemsSold.current(); uint currentIndex = 0; MarketItem[] memory items = new MarketItem[](unsoldItemCount); for (uint i = 0; i
至少我們想出售該物品並將所有權轉讓給買方。
NFTMarket -> sellItemAndTransferOwnership()
該 sellItemAndTransferOwnership() 方法有一個修飾符,可以防止合約直接或間接調用自己。我們要求發件人需要支付確切的要價。我們將NFT 從市場轉移給買方,並將支付的金額發送給NFT 的所有者。
function sellItemAndTransferOwnership( address nftContract, uint256 itemId) public payable nonReentrant { uint price = idToMarketItem[itemId].price; uint tokenId = idToMarketItem[itemId].tokenId; require(msg.value == price, “Please submit the asking price in order to complete the purchase”); idToMarketItem[itemId].seller.transfer(msg.value); IERC721(nftContract).transferFrom(address(this), msg.sender, tokenId); idToMarketItem[itemId].owner = payable(msg.sender); _itemsSold.increment(); payable(owner).transfer(listingPrice);}
那是主要過程。
我們還有其他方法可以通過給定的id 獲取市場項目的詳細信息, getMarketItemById() 並通過所有者/創建者顯示NFT getItemsByOwner()。
一個有趣的輔助方法是 getLatestPrice() 你可以調用市場合約。它繼承自價格ConsumerV3 合約。這裡我們將地址傳遞 0xd0D5e3DB44DE05E9F294BB0a3bEEaF030DE24Ada 給 AggregatorV3Interface 這個地址是Polygon測試網(孟買)上MATIC 的美元價格。
如果你將這些合約部署到另一個網絡和/或想要使用不同的價格饋送,你可以查看 鍊鍊接文檔 以獲取你需要添加到的地址 AggregatorV3Interface。
這是一個偽代碼示例,說明如何計算NFT 的價格並顯示當前的美元價值:
const latestPrice = NFTMarket.getLatestPrice()const priceInUsd = (item.price/(10**18)) * (latestPrice/10**8)
在部署這些合約時,你首先需要部署市場合約,然後在部署NFT 合約時將市場合約地址傳遞給它。
這是一個包含(幾乎)完整過程的K線走勢圖。
完整的過程可視化(為簡單起見,未包括每個細節)
現在我們要部署我們的合約並通過Remix IDE 運行一些方法。你可以從 這裡獲得完整的代碼。
打開 Remix IDE。
在 contracts > Market.sol.
將此處的完整代碼粘貼 到新文件中。
現在我們要編譯我們的合約。
切換到編譯選項卡。
選擇版本0.8.0 和
點擊 Compile Market.sol。
如果一切順利,你將在編譯選項卡上看到一個綠色的成功圖標。
我正在使用Chrome 和Metamask 擴展進行部署。你可以在此處下載並安裝Metamask 。之後,打開Metamask 並按照提供的步驟設置Metamask。
請將Polygon Mumbai-測試網絡添加到Metamask。
你可以查看Polygon 文檔 或在此處執行接下來的兩個步驟。
打開Metamask 並:
打開網絡列表
單擊添加網絡。忽略我的網絡列表,我已經配置了幾個。
在你的瀏覽器中打開一個新選項卡以添加網絡。
添加網絡名稱,我選擇Polygon 測試網絡。
2. 添加新的RPC URL https://rpc-mumbai.maticvigil.com/。
3.將Chain ID設置為80001(請忽略我的錯誤信息,我已經配置了網絡)。
(可選)添加貨幣符號MATIC。
現在你需要獲得一些測試MATIC 以支付部署費用。你可以 在這裡得到它們。只需將你的賬戶地址粘貼為錢包地址,提交後你將收到MATIC 進行測試,它沒有任何實際價值。
現在我們部署我們的合約。
切換到部署和運行事務選項卡。
選擇注入的Web3。
從下拉列表中選擇 NFTMarket 合約。
單擊部署。
Metamask 會彈出並要求你確認部署,請點擊確認。片刻之後,你將在Deployed Contracts 下看到一個條目。
接下來,我們部署NFT 合約。
從下拉列表中選擇NFT 合約。
將地址複製到市場合約。
將復制的地址傳遞到輸入中。
單擊部署。Metamask 將再次要求確認。
恭喜你部署了與區塊鏈交互以運行NFT 市場的所有內容。
現在我們想運行我們之前在理論上經歷過的方法。
打開NFT 合約。
例如,將IPFS 地址粘貼 https://ipfs.io/ipfs/Qme7ss3ARVgxv6rXqVPiikMJ8u2NLgmgszg13pYrDKEoiu 到該字段中。
單擊 createToken 以運行該方法。Metamask 將再次彈出,因為我們將向區塊鏈寫入一些內容。橙色按鈕將在區塊鏈上生成交易並收取費用。
如果你 tokenURI 在NFT 合約面板底部的字段中輸入1,你可以檢查是否一切正常,你將收到相同的IPFS URI。
現在我們將NFT 添加到Marketplace。
粘貼 100000000000000000 Wei 到價值字段中,即0.1 MATIC — 你為上市而支付給市場合約的費用。你可以在這裡找到一個單位轉換器 。
打開 addItemToMarket 方法。
在此處將地址粘貼到你的NFT 合約中。
為我們要上傳到市場的代幣ID 添加1。
添加你要為NFT 設置的價格,為簡單起見,我剛剛粘貼了 100000000000000000 Wei 上面的內容。
此按鈕上的紅色表示該方法被標記為應付,你需要向這些方法發送(在本例中為一些MATIC)。
感謝你的閱讀。如果你有任何疑問,歡迎你寫評測。