如何通過 ERC721 啟動管理相關元數據/圖像
我有一個在 rinkeby 上工作的智能合約,它正在鑄造 ERC721 代幣。目標是允許鑄幣一周,然後在一周後發布元數據和圖像。
當我部署它時,我使用https://gateway.pinata.cloud/ipfs/作為我輸入契約的 baseUri。
接下來,我模擬延遲的元數據/圖像發布:
生成令牌後,我執行 curl POST 以將圖像添加到 IPFS 並獲取其雜湊值。
然後,我通過 UI 手動將圖像固定到 pinata,並使用固定的圖像 uri 創建元數據。
元數據中的圖像連結在我的瀏覽器中解析。
接下來,我執行第二個 curl POST 以將 JSON 元數據添加到 IPFS。
我通過 UI 手動將元數據固定到 pinata:https ://gateway.pinata.cloud/ipfs/Qmf43nycxRXdwdq3GqT7SKU3MvRyBvbpjzufzZR8ASkMGb
此時,Opensea 沒有顯示任何圖像,並且其元數據無法驗證:
image_url 元數據屬性驗證失敗,因為 ipfs 連結使用雜湊,而 im 使用整數令牌值。我無法弄清楚如何彌補這一差距,因為雜湊是在契約之外生成的,而且看起來契約是在元數據中生成此連結的原因。
誰能照亮我的困境?謝謝!:D
你沒有為 NFT 設置 TokenURI,所以 NFT 獲取 URI 時,使用的是 BaseURI + TokenID。看源碼。
/** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory _tokenURI = _tokenURIs[tokenId]; string memory base = baseURI(); // If there is no base URI, return the token URI. if (bytes(base).length == 0) { return _tokenURI; } // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). if (bytes(_tokenURI).length > 0) { return string(abi.encodePacked(base, _tokenURI)); } // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI. return string(abi.encodePacked(base, tokenId.toString())); }
它返回 URI:https ://gateway.pinata.cloud/ipfs/0
這當然不理想,理想的URI應該是:https ://gateway.pinata.cloud/ipfs/Qmf43nycxRXdwdq3GqT7SKU3MvRyBvbpjzufzZR8ASkMGb
我想你在這裡看到了問題的原因。
接下來你需要做的是呼叫 _setTokenUri 來儲存來自 IPFS 的 CID,這樣你就可以在讀取 NFT 時獲得正確的 IPFS 連結。
/** * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token"); _tokenURIs[tokenId] = _tokenURI; }
這個函式是內部函式,你應該提供一個外部函式來使用它,但是必須注意安全,否則任何人都可以修改它!