[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-b68e5b2c-eaaa-422b-b269-fd18faa8437f":3,"$fXTdW2EmIpTzrc5nI-SA33LKDxX6-A3nGfGfkLZYd_4E":43},{"id":4,"title":5,"description":6,"categoryId":7,"moduleId":8,"tags":9,"prompt":10,"icon":11,"source":12,"sourceUrl":13,"authorId":14,"authorName":15,"isPublic":16,"stars":17,"runs":18,"createdAt":19,"updatedAt":19,"module":20,"category":27,"packages":34},"b68e5b2c-eaaa-422b-b269-fd18faa8437f","nft-standards","掌握ERC-721和ERC-1155 NFT标准、元数据最佳实践和高级NFT功能。","cat_life_career","mod_other","sickn33,other","---\nname: nft-standards\ndescription: \"Master ERC-721 and ERC-1155 NFT standards, metadata best practices, and advanced NFT features.\"\nrisk: unknown\nsource: community\ndate_added: \"2026-02-27\"\n---\n\n# NFT Standards\n\nMaster ERC-721 and ERC-1155 NFT standards, metadata best practices, and advanced NFT features.\n\n## Do not use this skill when\n\n- The task is unrelated to nft standards\n- You need a different domain or tool outside this scope\n\n## Instructions\n\n- Clarify goals, constraints, and required inputs.\n- Apply relevant best practices and validate outcomes.\n- Provide actionable steps and verification.\n- If detailed examples are required, open `resources\u002Fimplementation-playbook.md`.\n\n## Use this skill when\n\n- Creating NFT collections (art, gaming, collectibles)\n- Implementing marketplace functionality\n- Building on-chain or off-chain metadata\n- Creating soulbound tokens (non-transferable)\n- Implementing royalties and revenue sharing\n- Developing dynamic\u002Fevolving NFTs\n\n## ERC-721 (Non-Fungible Token Standard)\n\n```solidity\n\u002F\u002F SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin\u002Fcontracts\u002Ftoken\u002FERC721\u002Fextensions\u002FERC721URIStorage.sol\";\nimport \"@openzeppelin\u002Fcontracts\u002Ftoken\u002FERC721\u002Fextensions\u002FERC721Enumerable.sol\";\nimport \"@openzeppelin\u002Fcontracts\u002Faccess\u002FOwnable.sol\";\nimport \"@openzeppelin\u002Fcontracts\u002Futils\u002FCounters.sol\";\n\ncontract MyNFT is ERC721URIStorage, ERC721Enumerable, Ownable {\n    using Counters for Counters.Counter;\n    Counters.Counter private _tokenIds;\n\n    uint256 public constant MAX_SUPPLY = 10000;\n    uint256 public constant MINT_PRICE = 0.08 ether;\n    uint256 public constant MAX_PER_MINT = 20;\n\n    constructor() ERC721(\"MyNFT\", \"MNFT\") {}\n\n    function mint(uint256 quantity) external payable {\n        require(quantity > 0 && quantity \u003C= MAX_PER_MINT, \"Invalid quantity\");\n        require(_tokenIds.current() + quantity \u003C= MAX_SUPPLY, \"Exceeds max supply\");\n        require(msg.value >= MINT_PRICE * quantity, \"Insufficient payment\");\n\n        for (uint256 i = 0; i \u003C quantity; i++) {\n            _tokenIds.increment();\n            uint256 newTokenId = _tokenIds.current();\n            _safeMint(msg.sender, newTokenId);\n            _setTokenURI(newTokenId, generateTokenURI(newTokenId));\n        }\n    }\n\n    function generateTokenURI(uint256 tokenId) internal pure returns (string memory) {\n        \u002F\u002F Return IPFS URI or on-chain metadata\n        return string(abi.encodePacked(\"ipfs:\u002F\u002FQmHash\u002F\", Strings.toString(tokenId), \".json\"));\n    }\n\n    \u002F\u002F Required overrides\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 tokenId,\n        uint256 batchSize\n    ) internal override(ERC721, ERC721Enumerable) {\n        super._beforeTokenTransfer(from, to, tokenId, batchSize);\n    }\n\n    function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) {\n        super._burn(tokenId);\n    }\n\n    function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) {\n        return super.tokenURI(tokenId);\n    }\n\n    function supportsInterface(bytes4 interfaceId)\n        public\n        view\n        override(ERC721, ERC721Enumerable)\n        returns (bool)\n    {\n        return super.supportsInterface(interfaceId);\n    }\n\n    function withdraw() external onlyOwner {\n        payable(owner()).transfer(address(this).balance);\n    }\n}\n```\n\n## ERC-1155 (Multi-Token Standard)\n\n```solidity\n\u002F\u002F SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin\u002Fcontracts\u002Ftoken\u002FERC1155\u002FERC1155.sol\";\nimport \"@openzeppelin\u002Fcontracts\u002Faccess\u002FOwnable.sol\";\n\ncontract GameItems is ERC1155, Ownable {\n    uint256 public constant SWORD = 1;\n    uint256 public constant SHIELD = 2;\n    uint256 public constant POTION = 3;\n\n    mapping(uint256 => uint256) public tokenSupply;\n    mapping(uint256 => uint256) public maxSupply;\n\n    constructor() ERC1155(\"ipfs:\u002F\u002FQmBaseHash\u002F{id}.json\") {\n        maxSupply[SWORD] = 1000;\n        maxSupply[SHIELD] = 500;\n        maxSupply[POTION] = 10000;\n    }\n\n    function mint(\n        address to,\n        uint256 id,\n        uint256 amount\n    ) external onlyOwner {\n        require(tokenSupply[id] + amount \u003C= maxSupply[id], \"Exceeds max supply\");\n\n        _mint(to, id, amount, \"\");\n        tokenSupply[id] += amount;\n    }\n\n    function mintBatch(\n        address to,\n        uint256[] memory ids,\n        uint256[] memory amounts\n    ) external onlyOwner {\n        for (uint256 i = 0; i \u003C ids.length; i++) {\n            require(tokenSupply[ids[i]] + amounts[i] \u003C= maxSupply[ids[i]], \"Exceeds max supply\");\n            tokenSupply[ids[i]] += amounts[i];\n        }\n\n        _mintBatch(to, ids, amounts, \"\");\n    }\n\n    function burn(\n        address from,\n        uint256 id,\n        uint256 amount\n    ) external {\n        require(from == msg.sender || isApprovedForAll(from, msg.sender), \"Not authorized\");\n        _burn(from, id, amount);\n        tokenSupply[id] -= amount;\n    }\n}\n```\n\n## Metadata Standards\n\n### Off-Chain Metadata (IPFS)\n\n```json\n{\n  \"name\": \"NFT #1\",\n  \"description\": \"Description of the NFT\",\n  \"image\": \"ipfs:\u002F\u002FQmImageHash\",\n  \"attributes\": [\n    {\n      \"trait_type\": \"Background\",\n      \"value\": \"Blue\"\n    },\n    {\n      \"trait_type\": \"Rarity\",\n      \"value\": \"Legendary\"\n    },\n    {\n      \"trait_type\": \"Power\",\n      \"value\": 95,\n      \"display_type\": \"number\",\n      \"max_value\": 100\n    }\n  ]\n}\n```\n\n### On-Chain Metadata\n\n```solidity\ncontract OnChainNFT is ERC721 {\n    struct Traits {\n        uint8 background;\n        uint8 body;\n        uint8 head;\n        uint8 rarity;\n    }\n\n    mapping(uint256 => Traits) public tokenTraits;\n\n    function tokenURI(uint256 tokenId) public view override returns (string memory) {\n        Traits memory traits = tokenTraits[tokenId];\n\n        string memory json = Base64.encode(\n            bytes(\n                string(\n                    abi.encodePacked(\n                        '{\"name\": \"NFT #', Strings.toString(tokenId), '\",',\n                        '\"description\": \"On-chain NFT\",',\n                        '\"image\": \"data:image\u002Fsvg+xml;base64,', generateSVG(traits), '\",',\n                        '\"attributes\": [',\n                        '{\"trait_type\": \"Background\", \"value\": \"', Strings.toString(traits.background), '\"},',\n                        '{\"trait_type\": \"Rarity\", \"value\": \"', getRarityName(traits.rarity), '\"}',\n                        ']}'\n                    )\n                )\n            )\n        );\n\n        return string(abi.encodePacked(\"data:application\u002Fjson;base64,\", json));\n    }\n\n    function generateSVG(Traits memory traits) internal pure returns (string memory) {\n        \u002F\u002F Generate SVG based on traits\n        return \"...\";\n    }\n}\n```\n\n## Royalties (EIP-2981)\n\n```solidity\nimport \"@openzeppelin\u002Fcontracts\u002Finterfaces\u002FIERC2981.sol\";\n\ncontract NFTWithRoyalties is ERC721, IERC2981 {\n    address public royaltyRecipient;\n    uint96 public royaltyFee = 500; \u002F\u002F 5%\n\n    constructor() ERC721(\"Royalty NFT\", \"RNFT\") {\n        royaltyRecipient = msg.sender;\n    }\n\n    function royaltyInfo(uint256 tokenId, uint256 salePrice)\n        external\n        view\n        override\n        returns (address receiver, uint256 royaltyAmount)\n    {\n        return (royaltyRecipient, (salePrice * royaltyFee) \u002F 10000);\n    }\n\n    function setRoyalty(address recipient, uint96 fee) external onlyOwner {\n        require(fee \u003C= 1000, \"Royalty fee too high\"); \u002F\u002F Max 10%\n        royaltyRecipient = recipient;\n        royaltyFee = fee;\n    }\n\n    function supportsInterface(bytes4 interfaceId)\n        public\n        view\n        override(ERC721, IERC165)\n        returns (bool)\n    {\n        return interfaceId == type(IERC2981).interfaceId ||\n               super.supportsInterface(interfaceId);\n    }\n}\n```\n\n## Soulbound Tokens (Non-Transferable)\n\n```solidity\ncontract SoulboundToken is ERC721 {\n    constructor() ERC721(\"Soulbound\", \"SBT\") {}\n\n    function _beforeTokenTransfer(\n        address from,\n        address to,\n        uint256 tokenId,\n        uint256 batchSize\n    ) internal virtual override {\n        require(from == address(0) || to == address(0), \"Token is soulbound\");\n        super._beforeTokenTransfer(from, to, tokenId, batchSize);\n    }\n\n    function mint(address to) external {\n        uint256 tokenId = totalSupply() + 1;\n        _safeMint(to, tokenId);\n    }\n\n    \u002F\u002F Burn is allowed (user can destroy their SBT)\n    function burn(uint256 tokenId) external {\n        require(ownerOf(tokenId) == msg.sender, \"Not token owner\");\n        _burn(tokenId);\n    }\n}\n```\n\n## Dynamic NFTs\n\n```solidity\ncontract DynamicNFT is ERC721 {\n    struct TokenState {\n        uint256 level;\n        uint256 experience;\n        uint256 lastUpdated;\n    }\n\n    mapping(uint256 => TokenState) public tokenStates;\n\n    function gainExperience(uint256 tokenId, uint256 exp) external {\n        require(ownerOf(tokenId) == msg.sender, \"Not token owner\");\n\n        TokenState storage state = tokenStates[tokenId];\n        state.experience += exp;\n\n        \u002F\u002F Level up logic\n        if (state.experience >= state.level * 100) {\n            state.level++;\n        }\n\n        state.lastUpdated = block.timestamp;\n    }\n\n    function tokenURI(uint256 tokenId) public view override returns (string memory) {\n        TokenState memory state = tokenStates[tokenId];\n\n        \u002F\u002F Generate metadata based on current state\n        return generateMetadata(tokenId, state);\n    }\n\n    function generateMetadata(uint256 tokenId, TokenState memory state)\n        internal\n        pure\n        returns (string memory)\n    {\n        \u002F\u002F Dynamic metadata generation\n        return \"\";\n    }\n}\n```\n\n## Gas-Optimized Minting (ERC721A)\n\n```solidity\nimport \"erc721a\u002Fcontracts\u002FERC721A.sol\";\n\ncontract OptimizedNFT is ERC721A {\n    uint256 public constant MAX_SUPPLY = 10000;\n    uint256 public constant MINT_PRICE = 0.05 ether;\n\n    constructor() ERC721A(\"Optimized NFT\", \"ONFT\") {}\n\n    function mint(uint256 quantity) external payable {\n        require(_totalMinted() + quantity \u003C= MAX_SUPPLY, \"Exceeds max supply\");\n        require(msg.value >= MINT_PRICE * quantity, \"Insufficient payment\");\n\n        _mint(msg.sender, quantity);\n    }\n\n    function _baseURI() internal pure override returns (string memory) {\n        return \"ipfs:\u002F\u002FQmBaseHash\u002F\";\n    }\n}\n```\n\n## Resources\n\n- **references\u002Ferc721.md**: ERC-721 specification details\n- **references\u002Ferc1155.md**: ERC-1155 multi-token standard\n- **references\u002Fmetadata-standards.md**: Metadata best practices\n- **references\u002Fenumeration.md**: Token enumeration patterns\n- **assets\u002Ferc721-contract.sol**: Production ERC-721 template\n- **assets\u002Ferc1155-contract.sol**: Production ERC-1155 template\n- **assets\u002Fmetadata-schema.json**: Standard metadata format\n- **assets\u002Fmetadata-uploader.py**: IPFS upload utility\n\n## Best Practices\n\n1. **Use OpenZeppelin**: Battle-tested implementations\n2. **Pin Metadata**: Use IPFS with pinning service\n3. **Implement Royalties**: EIP-2981 for marketplace compatibility\n4. **Gas Optimization**: Use ERC721A for batch minting\n5. **Reveal Mechanism**: Placeholder → reveal pattern\n6. **Enumeration**: Support walletOfOwner for marketplaces\n7. **Whitelist**: Merkle trees for efficient whitelisting\n\n## Marketplace Integration\n\n- OpenSea: ERC-721\u002F1155, metadata standards\n- LooksRare: Royalty enforcement\n- Rarible: Protocol fees, lazy minting\n- Blur: Gas-optimized trading\n\n## Limitations\n- Use this skill only when the task clearly matches the scope described above.\n- Do not treat the output as a substitute for environment-specific validation, testing, or expert review.\n- Stop and ask for clarification if required inputs, permissions, safety boundaries, or success criteria are missing.\n","","imported","https:\u002F\u002Fgithub.com\u002Fsickn33\u002Fantigravity-awesome-skills","user_system_seed","SkillOPIC",true,242,1114,"2026-05-16 13:30:58",{"id":8,"name":21,"slug":22,"icon":23,"description":24,"sort":25,"createdAt":26},"其他","other","mdi-page-next-outline","其他类型Skill",5,"2026-05-16 12:53:40",{"id":7,"name":28,"slug":29,"icon":30,"description":31,"moduleId":8,"sort":32,"skillCount":33,"createdAt":26},"职场发展","career","mdi-briefcase-outline","面试准备、简历优化、职业规划",4,575,[35],{"id":36,"skillId":4,"version":37,"fileName":38,"fileSize":39,"filePath":40,"fileHash":41,"manifest":42,"createdAt":19},"58d85a87-e81a-4a0d-b42e-bba3b874ba5f","1.0.0","nft-standards.zip",3644,"uploads\u002Fskills\u002Fb68e5b2c-eaaa-422b-b269-fd18faa8437f\u002Fnft-standards.zip","13baf986682f9f8f2f9d164f06613af2e58bb656c14fe2eebd569a2b4acf7907","[{\"path\":\"SKILL.md\",\"isDirectory\":false,\"size\":11720}]",{"code":44,"message":45,"data":46},200,"success",{"items":47,"stats":48,"page":51},[],{"averageRating":49,"totalRatings":49,"ratingCounts":50},0,[49,49,49,49,49],{"limit":52,"offset":49,"hasMore":53,"nextOffset":52,"ratedOnly":16},15,false]