Solidity
智能合約能否根據tokenID自動生成tokenURI
如果我們不想使用其他方法,有沒有一種方法可以讓智能合約使用 erc721 代幣的 tokenID 自動生成 tokenURI。我是新手,所以需要一些指導。
是的,這是可能的,因為你有功能
_mint()
&_setTokenURI()
。以下是一個簡單的範例,旨在執行相同的操作:
堅固性
// contracts/GameItem.sol // SPDX-License-Identifier: MIT pragma solidity <0.8.0; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; contract GameItem is ERC721 { using Counters for Counters.Counter; Counters.Counter private _tokenIds; string private tempURI; constructor( string memory name, string memory symbol, string memory _tempURI ) ERC721(name, symbol) { tempURI = _tempURI; } function awardItem(address player) public returns (uint256) { _tokenIds.increment(); uint256 newItemId = _tokenIds.current(); _mint(player, newItemId); _setTokenURI( newItemId, string(abi.encodePacked(tempURI, uintToString(newItemId))) ); return newItemId; } function uintToString(uint256 v) internal pure returns (string memory str) { uint256 maxlength = 100; bytes memory reversed = new bytes(maxlength); uint256 i = 0; while (v != 0) { uint256 remainder = v % 10; v = v / 10; reversed[i++] = bytes1(uint8(48 + remainder)); } bytes memory s = new bytes(i); for (uint256 j = 0; j < i; j++) { s[j] = reversed[i - 1 - j]; } str = string(s); } }
松露測試
const GameItem = artifacts.require("GameItem"); contract("Redroad", async (addresses) => { const [admin, _] = addresses; it("works correctly.", async () => { let id = []; const gItem = await GameItem.new( "Invincible Collectible", "ICB", "http://www.myserver.com/tokenId=" ); await gItem.awardItem(admin); await gItem.awardItem(admin); console.log(await gItem.tokenURI("1")); console.log(await gItem.tokenURI("2")); }); });
以下是 的輸出
truffle test
:Contract: GameItem http://www.myserver.com/tokenId=1 http://www.myserver.com/tokenId=2 ✓ works correctly. (229ms)
參考資料來自: