上篇文章讲过NFT的元数据。每一个NFT都有一个json格式的metadata与之对应,metadata有一个参数指定了NFT的图案。所以只要访问这个NFT的metadata,然后就能得到图像地址,就可以显示出NFT的图案了。
一般的NFT,metadata与图片都是保存到非区块链的。例如中心化服务器,或者去中心化的IPFS。这样的话就有可能导致资料遗失。如果所有数据都保存到区块链上,则能够完美解决这个问题。但是,在区块链上保存大量数据非常昂贵,所以这么做,必须尽量减少存储的数据量。
查看 opensea metadata标准 发现还有一个image_data可供使用。
我们可以使用SVG图案档。SVG的本质其实就是一段文字,因此我们可以根据一定的要求随时“拼凑”出来。
tokenURI()我们需要做如下处理
function tokenURI(uint256 tokenId)
public
view
override(ERC721)
returns (string memory)
{
require(
_exists(tokenId),
"ERC721Metadata: URI query for nonexistent token"
);
string memory json = Base64.encode(
bytes(
string(
abi.encodePacked(
'{"name": "FDF NFT #',
uint2str(tokenId),
'",',
'"image_data": "',
fdfSVG.getSvgImage(tokenId),
'"',
"}"
)
)
)
);
return string(abi.encodePacked("data:application/json;base64,", json));
}
上面拼接json时有一句 fdfSVG.getSvgImage(tokenId) 这个方法作用是根据传入的tokenId返回一个svg数据。
下面贴出完整代码
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
library Base64 {
string internal constant TABLE_ENCODE =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
bytes internal constant TABLE_DECODE =
hex"0000000000000000000000000000000000000000000000000000000000000000"
hex"00000000000000000000003e0000003f3435363738393a3b3c3d000000000000"
hex"00000102030405060708090a0b0c0d0e0f101112131415161718190000000000"
hex"001a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132330000000000";
function encode(bytes memory data) internal pure returns (string memory) {
if (data.length == 0) return "";
// load the table into memory
string memory table = TABLE_ENCODE;
// multiply by 4/3 rounded up
uint256 encodedLen = 4 * ((data.length + 2) / 3);
// add some extra buffer at the end required for the writing
string memory result = new string(encodedLen + 32);
assembly {
// set the actual output length
mstore(result, encodedLen)
// prepare the lookup table
let tablePtr := add(table, 1)
// input ptr
let dataPtr := data
let endPtr := add(dataPtr, mload(data))
// result ptr, jump over length
let resultPtr := add(result, 32)
// run over the input, 3 bytes at a time
for {
} lt(dataPtr, endPtr) {
} {
// read 3 bytes
dataPtr := add(dataPtr, 3)
let input := mload(dataPtr)
// write 4 characters
mstore8(
resultPtr,
mload(add(tablePtr, and(shr(18, input), 0x3F)))
)
resultPtr := add(resultPtr, 1)
mstore8(
resultPtr,
mload(add(tablePtr, and(shr(12, input), 0x3F)))
)
resultPtr := add(resultPtr, 1)
mstore8(
resultPtr,
mload(add(tablePtr, and(shr(6, input), 0x3F)))
)
resultPtr := add(resultPtr, 1)
mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
resultPtr := add(resultPtr, 1)
}
// padding with '='
switch mod(mload(data), 3)
case 1 {
mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
}
case 2 {
mstore(sub(resultPtr, 1), shl(248, 0x3d))
}
}
return result;
}
function decode(string memory _data) internal pure returns (bytes memory) {
bytes memory data = bytes(_data);
if (data.length == 0) return new bytes(0);
require(data.length % 4 == 0, "invalid base64 decoder input");
// load the table into memory
bytes memory table = TABLE_DECODE;
// every 4 characters represent 3 bytes
uint256 decodedLen = (data.length / 4) * 3;
// add some extra buffer at the end required for the writing
bytes memory result = new bytes(decodedLen + 32);
assembly {
// padding with '='
let lastBytes := mload(add(data, mload(data)))
if eq(and(lastBytes, 0xFF), 0x3d) {
decodedLen := sub(decodedLen, 1)
if eq(and(lastBytes, 0xFFFF), 0x3d3d) {
decodedLen := sub(decodedLen, 1)
}
}
// set the actual output length
mstore(result, decodedLen)
// prepare the lookup table
let tablePtr := add(table, 1)
// input ptr
let dataPtr := data
let endPtr := add(dataPtr, mload(data))
// result ptr, jump over length
let resultPtr := add(result, 32)
// run over the input, 4 characters at a time
for {
} lt(dataPtr, endPtr) {
} {
// read 4 characters
dataPtr := add(dataPtr, 4)
let input := mload(dataPtr)
// write 3 bytes
let output := add(
add(
shl(
18,
and(
mload(add(tablePtr, and(shr(24, input), 0xFF))),
0xFF
)
),
shl(
12,
and(
mload(add(tablePtr, and(shr(16, input), 0xFF))),
0xFF
)
)
),
add(
shl(
6,
and(
mload(add(tablePtr, and(shr(8, input), 0xFF))),
0xFF
)
),
and(mload(add(tablePtr, and(input, 0xFF))), 0xFF)
)
)
mstore(resultPtr, shl(232, output))
resultPtr := add(resultPtr, 3)
}
}
return result;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import {Base64} from "./Base64.sol";
interface FdfSVG {
function getSvgImage(uint256 tokenId) external pure returns (string memory) ;
}
contract FdfMetadataNFT is ERC721, ERC721Enumerable {
FdfSVG public fdfSVG;
constructor() ERC721("FDFOnChainNFT", "FDFOCNFT") {
fdfSVG = FdfSVG(0x23D6D1d1cd44CCD4fF6A3b786DebDEF273195f8A);
for (uint i=1000; i < 1100; i++) {
_safeMint( 0x3dc0252648774a3280ECe2Ff4AeD70A370f535D8, i);
}
}
function mint(address to, uint256 tokenId) public {
_safeMint(to, tokenId);
}
function tokenURI(uint256 tokenId)
public
view
override(ERC721)
returns (string memory)
{
require(
_exists(tokenId),
"ERC721Metadata: URI query for nonexistent token"
);
string memory json = Base64.encode(
bytes(
string(
abi.encodePacked(
'{"name": "FDF NFT #',
uint2str(tokenId),
'",',
'"image_data": "',
fdfSVG.getSvgImage(tokenId),
'"',
"}"
)
)
)
);
return string(abi.encodePacked("data:application/json;base64,", json));
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal override(ERC721, ERC721Enumerable) {
super._beforeTokenTransfer(from, to, tokenId);
}
function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
function uint2str(uint256 _i)
internal
pure
returns (string memory _uintAsString)
{
if (_i == 0) {
return "0";
}
uint256 j = _i;
uint256 len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint256 k = len;
while (_i != 0) {
k = k - 1;
uint8 temp = (48 + uint8(_i - (_i / 10) * 10));
bytes1 b1 = bytes1(temp);
bstr[k] = b1;
_i /= 10;
}
return string(bstr);
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import {Base64} from "./Base64.sol";
contract FdfSVG {
constructor(){}
function getSvgImage(uint256 tokenId) external pure returns (string memory) {
string memory svgA = "<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 1200 1200' xml:space='preserve'><style type='text/css'> </style> <g><path class='st0' d='M425.59,943.4c-2.39-78.3-4.68-153.65-7.01-230.19c8.42-1.82,13.15-3.71,17.89-3.75c204.05-1.68,408.1-3.22,612.15-4.62c6.92-0.05,13.86,1.43,22.93,2.43c2.71,80.68,5.38,159.91,8.14,242.13c-29.1,3.15-55.04,5.95-83.8,9.06c-9.06-51.39-39.45-83.05-88.58-84.93c-49.42-1.89-81.18,28.62-96.29,78.6C683.73,949.25,556.97,946.38,425.59,943.4z'/><path class='st0' d='M1070.89,648.47c-142.88,0-277.62,0-414.63,0c0-54.48,0-107,0-161c18.42,0,35.34,0.17,52.25-0.03c64.54-0.77,128.96,2.51,192.32,14.49c56.55,10.69,107.36,34.87,141.52,83.6C1054.19,602.44,1059.9,623.64,1070.89,648.47z'/><path class='st0' d='M406.73,759.3c0,60.1,0,120.11,0,183.44c-11.3,0.51-21.89,1-31.79,1.45c-22.15-64.81-55.61-93.22-106.25-91.95c-47.5,1.19-79.45,32.08-100.44,98.34c-29.19-0.06-59.26,14.13-91.73-5.5c1.77-10.55,3.71-22.04,5.48-32.59c57.46-25.81,63.26-54.03,17.55-90.66c8.48-31.25,17.13-63.69,26.12-96.03c3.6-12.96,10.72-21.02,26.08-20.88c82.04,0.76,164.08,0.88,246.13,1.35c1.83,0.01,3.65,1.54,8.12,3.57c0.48,8.3,1.03,17.95,1.78,31.02c-29.19,3.21-56.2,6.19-86.16,9.48c13.28,14.39,28.13,7.74,40.98,8.73C376.64,760.13,390.83,759.3,406.73,759.3z'/> <path class='st0' d='M1069.54,690.58c-310.97,2.36-620.28,4.72-933.82,7.1c20.31-52.44,45.33-97.51,87.23-130.82c50.54-40.18,113.01-42.87,176.48-56.15c0,20.55,0.5,36.67-0.11,52.74c-1.17,30.65-3.64,61.26-4.27,91.91c-0.4,19.54,3.28,23.44,23.59,23.24c39.9-0.39,79.79-2.36,119.68-3.71c12.3-0.41,24.61-1.45,36.9-1.25c33.88,0.54,67.01-3.42,100.53-9.14c29.94-5.11,61.33-2.55,92.05-2.01c55.29,0.98,110.56,3.34,165.85,4.44c40,0.79,80.02,0.6,120.03,0.54C1068.13,667.44,1075.34,672.47,1069.54,690.58z'/><path class='st0' d='M646.18,487.93c-2.21,58.63-4.28,113.41-6.34,167.97c-21.58,6.58-199.93,8.33-229.99,2.14c0-48.31,0-96.92,0-147.53C487.04,490.71,564.06,487.23,646.18,487.93z'/><path class='st0' d='M272.33,1037.38c-49.54,0.29-86.7-38.55-86.83-90.73c-0.11-43.38,40.95-82.25,86.59-81.99c46.34,0.26,84.72,39.17,85.53,86.72C358.41,997.55,319.18,1037.11,272.33,1037.38z'/><path class='st0' d='M980.36,964.03c-0.14,43.66-34.53,78.94-77.05,79.04c-42.24,0.1-77.35-35.44-77.73-78.67c-0.37-42.64,33.5-80.34,72.15-80.3C945.18,884.13,980.5,918.31,980.36,964.03z'/><path class='st0' d='M86.59,893.99c3.05-18.29,5.75-34.51,8.65-51.88c14.58,0.48,20.7,8.54,22.28,20.14C119.18,874.41,110.83,882.87,86.59,893.99z'/></g><g><path d='M444.25,353.02c0-0.58,0.45-1.74,0.91-3.19v-2.9l2.74-74.8v-1.45l0.45-1.45c0.45-1.45,1.83-2.03,3.19-2.03c1.83,0,3.2,0.29,3.65,1.16c1.37,0.87,1.83,2.32,1.83,3.77v13.34c-0.45,12.18-0.91,27.54-0.91,45.81l-0.45,22.9v22.9c0,11.31-0.46,24.64-0.92,40.01l-1.37,40.3c0,2.03,0,3.19-0.45,4.06c-0.45,1.45-2.28,2.32-5.02,2.32c-2.29,0-4.11-0.87-4.57-2.32c-0.45-0.87-0.45-2.03-0.45-3.48l0.91-49.87c0.46-21.16,0.92-37.4,0.92-48.13l-4.11-0.58h-55.67c-3.19,0-5.93,0.58-7.76,1.45v102.34c0,2.03-1.36,2.9-4.56,2.9c-3.2,0.29-5.02-0.58-5.48-3.19c-0.45-0.87-0.45-2.61-0.45-4.64V333.31c0-16.52,0.45-33.05,1.37-49.28c0-1.74,0.45-3.77,0.91-6.38l0.92-6.38v-1.74c1.36-1.45,2.74-2.03,4.11-2.03c2.28,0,3.65,0.87,4.56,2.32l0.45,2.03v2.03c-1.36,16.53-1.83,41.17-1.83,74.22l0.46,2.32v2.03L444.25,353.02z'/><path d='M487.13,385.2c-1.37,9.86-3.65,23.49-5.93,40.59l-5.02,32.18c0,1.74-0.46,3.19-0.92,4.06c-6.84,1.45-8.21,0.87-8.67-0.29l-0.46-2.03v-2.03l2.74-19.13c7.76-60.01,18.25-109.88,32.39-149.02l5.94-13.92c1.36-2.03,2.74-3.19,4.56-3.19c2.74,0,4.11,1.16,4.56,3.77c14.6,55.95,31.94,116.55,51.56,181.2c0.45,2.32,0.91,4.06,0.91,5.22v1.45c-1.83,2.03-3.19,2.61-4.56,2.61c-4.57-2.32-5.48-4.06-5.93-6.38l-24.64-83.21c-0.45-2.03-1.37-3.48-1.83-4.35c-1.37-0.29-4.56-0.29-8.67-0.29c-12.32,0-23.27,0.87-33.77,2.32L487.13,385.2z M509.49,297.65c-9.58,25.8-15.51,48.7-18.26,68.71v0.29l0.92,0.58l18.7-1.16c7.3-0.58,13.69-1.16,18.71-1.45l-9.58-35.08l-9.13-31.31L509.49,297.65z'/><path d='M583.87,415.64l0.45,22.9v25.22c0,0.87-0.92,1.74-3.2,2.61h-0.45l-0.91,0.29c-3.65,0-5.02-2.61-5.94-4.35v-4.64c-0.45-26.38-0.45-52.76,0-79.44l1.83-39.14l1.37-18.55v-25.51l-0.45-25.51c0-6.09,1.37-6.38,10.49-6.96c59.78,0,94.46,22.9,104.49,68.42c1.37,8.7,1.37,15.94-0.45,22.03c-9.58,29.28-53.84,51.32-99.02,55.95l-8.21,1.16V415.64z M651.4,383.46c22.82-13.05,33.31-28.41,31.03-46.39c-1.83-16.82-14.6-44.65-36.04-55.37c-15.97-8.99-33.31-13.34-52.02-13.34l-7.76,0.58c-0.45,1.45-0.45,2.9-0.45,4.64l0.45,2.32v2.32c1.37,22.9,0.91,46.68-0.91,71.9c-0.46,6.67-0.92,14.5-1.37,23.77l-0.45,23.77c0,0.29,0.45,2.03,0.91,5.22C609.88,400.57,631.78,394.19,651.4,383.46z'/><path d='M707.07,415.64l0.45,22.9v25.22c0,0.87-0.92,1.74-3.2,2.61h-0.45l-0.91,0.29c-3.65,0-5.02-2.61-5.94-4.35v-4.64c-0.45-26.38-0.45-52.76,0-79.44l1.83-39.14l1.37-18.55v-25.51l-0.45-25.51c0-6.09,1.37-6.38,10.49-6.96c59.78,0,94.46,22.9,104.49,68.42c1.37,8.7,1.37,15.94-0.45,22.03c-9.58,29.28-53.84,51.32-99.02,55.95l-8.21,1.16V415.64z M774.59,383.46c22.82-13.05,33.31-28.41,31.03-46.39c-1.83-16.82-14.6-44.65-36.04-55.37c-15.97-8.99-33.31-13.34-52.02-13.34l-7.76,0.58c-0.45,1.45-0.45,2.9-0.45,4.64l0.45,2.32v2.32c1.37,22.9,0.92,46.68-0.91,71.9c-0.46,6.67-0.92,14.5-1.37,23.77l-0.45,23.77c0,0.29,0.45,2.03,0.91,5.22C733.07,400.57,754.97,394.19,774.59,383.46z'/><path d='M879.09,349.83c1.36-0.58,2.28-1.16,2.74-2.03l41.98-69.29l8.67-13.04c1.37-0.87,3.2-1.45,5.48-1.45c2.28,0.58,3.2,2.03,2.74,4.06l-55.21,91.32c-0.91,1.45-1.37,3.48-1.37,6.09c0.92,28.7,1.37,57.11,1.37,85.82l0.45,4.64v6.09l-0.45,1.45c-0.45,1.45-1.83,2.61-4.11,2.9c-3.65-0.87-4.56-1.45-5.02-2.03c-0.45-1.16-0.91-2.03-0.91-2.9c-0.45-0.87-0.45-2.03-0.45-4.06V422.6l-0.46-34.79v-21.46c0-2.9-0.45-5.22-1.36-6.67l-34.68-66.1c-2.28-4.64-5.93-11.6-10.04-20.88c-0.46-0.87-0.46-2.03-0.46-3.48c0-1.16,0.92-2.03,3.2-2.32c1.83,0,3.2,0.29,4.56,1.16l1.37,2.03c16.88,31.6,30.57,57.4,40.16,77.12L879.09,349.83z'/></g><g><path d='M275.84,681.31c-0.72-1.42-1.34-2.49-1.87-3.21c-0.54-0.71-0.98-1.54-1.33-2.49c-1.07-2.85-2.05-5.69-2.93-8.54c-0.9-2.85-2.06-5.7-3.47-8.55c-3.2-7.59-8.01-13.05-14.41-16.37c-1.78,0.96-3.29,2.38-4.54,4.27c-1.25,1.9-2.4,4.04-3.46,6.41c-9.26,22.31-16.19,45.57-20.81,69.77c-4.63,24.21-8.54,48.89-11.74,74.04c-1.78,14.24-1.6,28.25,0.54,42.01c0.35,2.38,1.07,5.46,2.14,9.26c1.07,3.81,2.48,7.36,4.27,10.68c1.78,3.33,3.73,6.17,5.87,8.55c2.13,2.38,4.27,3.56,6.41,3.56c3.91,0,8-2.14,12.27-6.41c4.27-4.27,8.36-9.49,12.27-15.66c3.91-6.16,7.47-12.34,10.67-18.51c3.2-6.17,5.51-11.39,6.94-15.66c3.2-9.49,6.04-18.98,8.54-28.48c2.49-9.49,4.44-19.46,5.87-29.9c0.35-2.37,1.25-5.93,2.67-10.68c2.14,0.96,3.47,2.02,4.01,3.21c0.53,1.19,0.8,2.26,0.8,3.2c-1.78,22.79-5.6,44.14-11.47,64.08c-5.87,19.93-15.57,37.5-29.08,52.69c-7.83,8.55-16.72,12.82-26.68,12.82c-6.77,0-12.99-1.89-18.68-5.7c-5.69-3.79-10.67-8.9-14.94-15.31c-4.27-6.41-7.66-13.64-10.14-21.72c-2.49-8.07-4.09-16.37-4.8-24.92c-1.79-22.78-1.25-44.97,1.6-66.57c2.84-21.6,7.82-42.83,14.94-63.72c3.55-9.97,8.18-19.93,13.88-29.9c4.98-7.59,10.41-13.64,16.27-18.15c5.87-4.51,12.54-6.76,20.01-6.76c1.41,0,2.67,0.12,3.73,0.36c1.07,0.24,1.95,0.36,2.67,0.36c3.91,0.96,6.94,2.26,9.07,3.92c2.14,1.67,4.09,4.16,5.88,7.48c2.84,4.27,4.98,8.9,6.4,13.88c1.42,4.98,2.49,10.32,3.2,16.02c0.35,1.43,0.54,2.97,0.54,4.63C276.91,676.92,276.55,678.94,275.84,681.31z'/><path d='M445,879.23c-1.78-11.39-3.47-22.54-5.07-33.46c-1.6-10.91-3.29-21.83-5.07-32.75c-1.79-10.91-3.47-21.83-5.07-32.75c-1.6-10.91-3.65-21.83-6.14-32.75c-13.52,0.96-26.77,1.78-39.75,2.49c-12.99,0.71-26.24,1.55-39.76,2.49c-0.36,1.9-0.89,4.27-1.6,7.12c-2.49,19.93-4.19,38.34-5.07,55.18c-0.89,16.85-1.33,35.49-1.33,55.89c-0.72,5.23-2.59,8.9-5.6,11.03c-3.03,2.14-6.32,3.2-9.88,3.2c-8.19,0-13.79-2.49-16.81-7.47c-3.02-4.98-5.07-12.22-6.13-21.72c-1.07-12.81-1.25-25.63-0.54-38.45c0.71-12.82,2.13-25.63,4.27-38.45c3.91-20.88,8.54-41.05,13.88-60.52c5.33-19.46,11.74-38.68,19.21-57.67c4.98-9.97,11.12-18.87,18.41-26.7c7.29-7.83,15.56-11.75,24.82-11.75c7.82,0,14.94,4.98,21.34,14.95c6.41,9.97,12.19,22.78,17.35,38.45c5.15,15.66,9.61,33,13.34,51.98c3.74,18.99,6.94,37.5,9.61,55.53c2.67,18.04,4.71,34.53,6.14,49.48c1.41,14.95,2.49,25.98,3.2,33.11c0,1.42,0.17,2.97,0.53,4.63c0.36,1.67,0.36,3.21,0,4.63C448.91,877.81,447.49,879.23,445,879.23z M421.52,736.13c-1.07-6.64-2.67-14.47-4.8-23.5c-2.14-9.01-4.63-18.15-7.47-27.41c-2.85-9.26-5.96-18.03-9.34-26.34c-3.38-8.3-7.03-14.83-10.94-19.58c-1.07-0.95-2.22-2.02-3.47-3.21c-1.25-1.18-2.4-2.25-3.46-3.2c-3.2-0.47-5.34,0-6.41,1.42s-2.14,2.85-3.2,4.27s-2.13,3.09-3.2,4.98c-2.85,5.23-5.52,11.87-8,19.93c-2.5,8.08-4.72,16.5-6.67,25.27c-1.96,8.79-3.74,17.33-5.34,25.63c-1.6,8.31-2.75,15.55-3.46,21.71c-0.36,0.96-0.45,2.14-0.27,3.56c0.17,1.42,0.27,2.61,0.27,3.56c3.91,0,9.42-0.11,16.54-0.36c7.11-0.23,14.58-0.71,22.41-1.42c7.82-0.71,15.12-1.53,21.88-2.49C413.34,738.03,418.32,737.08,421.52,736.13z'/><path d='M529.31,696.97c0.71-1.89,1.24-3.56,1.6-4.98c0.35-1.42,0.71-3.08,1.07-4.98c2.49-9.49,5.15-18.98,8.01-28.48c2.84-9.49,6.58-18.26,11.21-26.34c3.91-6.64,9.25-9.97,16.01-9.97c7.12,0,12.62,3.2,16.54,9.61c3.91,6.41,6.75,13.65,8.54,21.71c8.89,34.65,15.3,68.71,19.22,102.17c3.91,33.46,7.11,68.24,9.6,104.31v7.12c0.71,8.54-1.96,14.01-8,16.37c-1.07,0.48-2.85,0.71-5.34,0.71c-3.2,0-5.69-0.47-7.47-1.42c-5.69-2.37-9.07-7.36-10.14-14.95c-0.36-5.21-0.98-14.24-1.87-27.05c-0.89-12.82-2.05-27.41-3.47-43.79c-1.42-16.38-2.93-33.58-4.54-51.62c-1.6-18.03-3.29-34.89-5.07-50.55c-1.79-15.66-3.56-29.07-5.34-40.23c-1.78-11.15-3.38-17.91-4.8-20.29c-1.07,0.96-2.32,2.38-3.73,4.27c-1.43,2.85-2.76,5.69-4,8.55c-1.25,2.85-2.41,5.69-3.47,8.54c-2.49,7.6-4.45,15.31-5.87,23.14c-1.43,7.83-3.03,15.79-4.8,23.85c-1.07,5.23-2.14,10.68-3.2,16.37c-1.07,5.7-2.14,11.16-3.2,16.38c-0.72,2.38-1.33,4.52-1.87,6.41c-0.53,1.9-1.69,3.56-3.46,4.98c-2.49,2.38-4.63,3.56-6.41,3.56c-1.78,0-3.47-1.07-5.07-3.2c-1.6-2.14-3.03-4.74-4.27-7.83c-1.25-3.08-2.22-6.29-2.93-9.61c-0.72-3.31-1.25-5.93-1.6-7.83c-1.78-10.91-3.47-21.83-5.07-32.75c-1.6-10.92-3.83-21.83-6.67-32.75c-0.72,1.9-1.25,3.45-1.6,4.63c-0.36,1.19-0.72,2.26-1.07,3.21c-1.79,9.02-3.2,17.92-4.27,26.7c-1.07,8.79-2.13,17.92-3.2,27.41c-1.79,19.47-3.83,38.69-6.14,57.67c-2.32,18.99-4.54,38.21-6.67,57.67c-0.36,2.38-0.98,6.41-1.87,12.11c-0.89,5.69-2.13,11.51-3.73,17.44c-1.6,5.94-3.39,11.16-5.34,15.66c-1.96,4.52-4,6.76-6.14,6.76c-2.13,0-3.92-1.66-5.33-4.98c-1.07-2.37-1.79-5.09-2.14-8.19c-0.36-3.08-0.72-6.29-1.07-9.61c-0.36-8.07-0.54-15.9-0.54-23.5c0-7.59,0.36-15.42,1.07-23.5c0.7-9.01,1.95-21.95,3.73-38.8c1.78-16.84,4.18-34.17,7.2-51.97c3.02-17.8,6.41-34.53,10.14-50.19c3.73-15.66,7.91-27.06,12.54-34.17c2.85-4.27,5.61-6.88,8.27-7.83c2.67-0.95,5.95-1.42,9.87-1.42c4.27,0.96,7.65,4.04,10.14,9.26c1.07,2.85,2.13,5.69,3.2,8.54c1.07,2.85,1.95,5.7,2.67,8.55c1.41,5.23,2.67,10.68,3.73,16.37c1.07,5.7,2.31,11.16,3.74,16.38c0.71,2.85,1.24,4.75,1.6,5.69L529.31,696.97z'/><path d='M688.34,805.9c-6.76,0-12.72-2.6-17.88-7.83c-5.16-5.22-8.27-14.24-9.34-27.05c1.07-1.42,2.31-2.14,3.74-2.14c1.41,0,2.67,0.71,3.73,2.14c4.27,5.23,7.74,9.38,10.41,12.46c2.67,3.09,5.42,4.63,8.27,4.63c4.98,0,10.22-3.31,15.74-9.97c5.51-6.64,10.58-14.6,15.2-23.85s8.54-18.74,11.74-28.48c3.2-9.72,5.33-17.68,6.4-23.85c1.78-8.54,2.14-16.37,1.07-23.5c-0.72-6.64-2.32-12.34-4.8-17.09c-2.49-4.74-5.69-9.01-9.61-12.81c-2.85-3.31-6.4-4.98-10.67-4.98c-4.98,0-9.87,1.67-14.67,4.98c-4.8,3.32-9.34,7.6-13.61,12.81c-4.27,5.23-8.19,10.93-11.74,17.09c-3.56,6.17-6.41,12.11-8.54,17.8c-1.07,2.38-1.96,4.63-2.67,6.76c-0.72,2.14-1.51,5.11-2.4,8.9c-0.89,3.8-1.69,8.79-2.4,14.95c-0.72,6.17-1.42,14.24-2.13,24.21c0,1.9-0.19,3.56-0.54,4.98c-0.36,1.43-0.53,3.09-0.53,4.98c-0.72,10.45-1.16,20.77-1.34,30.97c-0.18,10.21-0.45,20.77-0.8,31.68c-0.36,7.12-0.62,14.24-0.8,21.36c-0.18,7.12-0.45,14.49-0.8,22.07c-0.72,5.23-1.87,10.09-3.47,14.6s-4.72,6.76-9.34,6.76c-4.98,0-8.27-2.49-9.87-7.48c-1.6-4.98-2.4-10.08-2.4-15.31c0-30.85,0.88-61.46,2.67-91.85c1.78-30.37,3.73-60.98,5.87-91.85c0.71-8.07,1.6-16.37,2.67-24.92c1.07-8.54,1.95-17.09,2.67-25.63c0.36-1.89,0.62-3.56,0.8-4.98c0.17-1.42,0.44-3.08,0.8-4.98c1.07-3.79,3.2-6.16,6.41-7.12c7.12,0,11.56,2.61,13.34,7.83c1.78,5.23,2.67,11.87,2.67,19.93c0.35,5.69,0.44,11.51,0.26,17.44c-0.18,5.94-0.26,11.99-0.26,18.16c1.41-0.47,2.31-1.3,2.67-2.49c0.35-1.18,0.88-2.25,1.6-3.2c4.98-11.39,11.82-20.65,20.54-27.77c8.72-7.12,18.05-10.68,28.02-10.68c8.88,0,16.89,3.09,24.01,9.26c16.36,12.82,23.48,32.75,21.35,59.81c-1.07,11.87-3.56,23.97-7.47,36.31c-3.92,12.35-8.99,23.5-15.21,33.46c-6.23,9.97-13.53,18.04-21.88,24.21C707.46,802.82,698.29,805.9,688.34,805.9z'/><path d='M803.6,667.78c1.78,13.3,2.85,26.34,3.2,39.16s0.71,25.63,1.07,38.45c1.41,1.42,3.55,2.14,6.4,2.14h33.62c4.62,0,8.54,0.96,11.74,2.85c1.42,0.96,2.49,1.9,3.2,2.85c-0.72,2.38-1.86,4.04-3.46,4.98c-1.6,0.96-3.3,1.67-5.07,2.14c-2.85,0.96-5.79,1.67-8.8,2.13c-3.03,0.48-5.96,1.19-8.8,2.14c-3.56,0.96-7.03,1.55-10.41,1.78c-3.38,0.25-6.67,0.6-9.87,1.07c-1.43,0.48-2.67,0.71-3.74,0.71c-1.07,0-2.13,0.24-3.2,0.71c-0.72,12.35-1.25,24.21-1.6,35.6c-0.36,11.39,0.17,22.79,1.6,34.17c0,0.96,0.08,1.9,0.26,2.85c0.18,0.96,0.27,1.9,0.27,2.85c0.71,3.8,1.78,6.76,3.2,8.9c1.42,2.14,4.09,3.45,8.01,3.92h10.14c8.89-2.37,17.52-5.34,25.88-8.9c8.36-3.56,16.45-8.66,24.28-15.31c2.14-1.89,4.36-3.56,6.67-4.98c2.31-1.42,4.71-2.37,7.2-2.85c1.41,0.96,1.78,2.38,1.07,4.27c-2.14,7.12-6.59,14.13-13.34,21c-6.76,6.89-14.41,12.94-22.95,18.16c-8.54,5.23-17.17,9.38-25.88,12.46c-8.72,3.09-16.1,4.63-22.14,4.63c-8.54,0-15.83-3.2-21.88-9.61c-6.05-6.41-10.93-14.35-14.67-23.85c-3.74-9.49-6.41-19.69-8.01-30.62c-1.6-10.91-2.59-21.11-2.93-30.61c0-45.57,2.67-89.94,8.01-133.14c0.71-2.85,0.71-5.7,0-8.55c-1.07-8.07,1.24-14.24,6.93-18.51c4.27-2.85,7.65-4.5,10.14-4.98c3.91-1.42,7.82-2.13,11.74-2.13c26.68-2.85,53.18-4.27,79.51-4.27c4.62,0,8.72,1.42,12.27,4.27c5.34,3.8,8.18,9.5,8.54,17.09c0.35,7.6-2.14,13.77-7.48,18.51c-2.13,1.9-4.62,3.33-7.47,4.27c-2.13,0.48-4.18,0.96-6.14,1.42c-1.96,0.48-3.83,0.71-5.6,0.71c-11.74,0.96-23.66,1.55-35.75,1.78C827.25,667.67,815.34,667.78,803.6,667.78z'/><path d='M936.48,697.68c1.07,0,1.95-1.18,2.67-3.56c1.42-3.79,2.67-7.59,3.74-11.39c1.07-3.79,2.48-7.59,4.27-11.39c4.98-11.86,11.82-21.24,20.54-28.12c8.72-6.88,18.23-10.32,28.55-10.32c8.89,0,17.52,3.56,25.88,10.68c8.36,7.12,14.14,16.85,17.35,29.19c2.48,10.45,3.2,19.7,2.13,27.77c-1.07,11.39-3.12,22.55-6.14,33.46c-3.02,10.92-7.03,21-12.01,30.26c-4.98,9.26-10.94,17.33-17.88,24.21c-6.93,6.89-14.67,11.75-23.22,14.6c-1.07,0.48-2.05,0.71-2.93,0.71c-0.89,0-1.69,0.24-2.4,0.71l-1.6,2.14c1.78,2.38,3.74,4.27,5.87,5.69c2.14,1.42,4.09,3.33,5.87,5.7c1.78,1.9,3.55,3.68,5.34,5.34c1.78,1.67,3.55,3.45,5.33,5.34c1.78,1.9,3.64,3.8,5.6,5.69c1.96,1.9,3.82,3.8,5.61,5.69c1.78,2.38,3.55,4.4,5.33,6.05c1.78,1.67,3.55,3.45,5.34,5.34c1.78,2.38,3.55,4.63,5.33,6.76c1.78,2.14,3.2,4.63,4.27,7.48c-0.36,3.33-1.33,5.69-2.93,7.12c-1.6,1.42-3.29,2.61-5.07,3.56c-2.14,0.96-3.74,1.42-4.8,1.42c-1.79,0-4.54-1.42-8.27-4.27c-3.73-2.85-6.32-4.98-7.74-6.41c-7.47-7.59-14.85-15.18-22.14-22.78c-7.3-7.59-14.5-15.42-21.61-23.5c-1.78-1.89-3.46-3.79-5.07-5.7c-1.6-1.89-3.3-4.02-5.07-6.41l-3.2-6.41c-0.72-2.85-0.18-4.98,1.6-6.41c2.49-2.37,4.8-3.56,6.94-3.56c1.78-0.47,3.28-0.82,4.54-1.07c1.24-0.23,2.75-0.59,4.54-1.07c7.11-0.47,13.69-3.92,19.74-10.32c6.05-6.41,11.56-14,16.55-22.79c4.97-8.78,9.25-18.26,12.8-28.48c3.55-10.2,6.04-19.34,7.47-27.41c1.07-8.07,1.42-15.42,1.07-22.07c-0.72-8.07-3.38-16.13-8-24.21c-4.63-8.07-10.32-12.11-17.08-12.11c-5.69,0-11.12,1.9-16.27,5.7c-5.17,3.8-9.88,8.66-14.14,14.6c-4.27,5.94-8.01,12.58-11.2,19.93c-3.2,7.36-5.52,14.36-6.94,21c-1.78,7.6-3.38,15.2-4.8,22.78c-1.43,7.6-3.02,15.2-4.8,22.79c-0.72,4.75-1.07,8.31-1.07,10.68c-0.72,10.45-1.16,20.89-1.33,31.33c-0.18,10.45-0.45,20.89-0.8,31.32c-0.36,7.12-0.63,14.36-0.8,21.72c-0.18,7.36-0.45,14.6-0.8,21.71c-0.72,4.75-1.96,9.5-3.74,14.24c-1.78,4.75-4.8,7.12-9.07,7.12c-3.56,0-6.41-1.9-8.54-5.7c-2.49-4.74-3.74-10.43-3.74-17.09c0-18.98,0.27-38.91,0.8-59.8c0.53-20.88,1.41-42.01,2.67-63.37c1.24-21.36,2.93-42.47,5.07-63.37c2.13-20.88,4.62-40.81,7.47-59.8c0.17,8.79,0.08,17.45-0.27,25.99V697.68z'/></g><path class='st0' d='M1136.29,1056.82H139.63c-1.01,0-1.83-0.82-1.83-1.83v-19.73c0-1.01,0.82-1.83,1.83-1.83h996.66c1.01,0,1.83,0.83,1.83,1.83v19.73C1138.13,1056,1137.3,1056.82,1136.29,1056.82z'/><text style='white-space:pre' x='128.356' y='262.274' fill='#1e00e7' font-family='"Kelly Slab"' font-size='55'>#";
string memory svgB = "</text><path d='M60.146 520.686l349.431 4.914 65.648 81.33c0 3.26-351.281-6.234-351.281-6.234-3.26 0-67.058-80.01-63.798-80.01z' transform='matrix(.589 -.808497 .762745 .651 -339.374725 97.441727)' stroke-opacity='.55' paint-order='fill' fill='#eef0ea' fill-opacity='.39' stroke='rgba(255, 255, 255, 0)'/></svg>";
return string(abi.encodePacked(svgA, uint2str(tokenId), svgB));
}
function uint2str(uint256 _i)
internal
pure
returns (string memory _uintAsString)
{
if (_i == 0) {
return "0";
}
uint256 j = _i;
uint256 len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint256 k = len;
while (_i != 0) {
k = k - 1;
uint8 temp = (48 + uint8(_i - (_i / 10) * 10));
bytes1 b1 = bytes1(temp);
bstr[k] = b1;
_i /= 10;
}
return string(bstr);
}
}
接下来在rinkeby部署合约
合约地址为 0x23D6D1d1cd44CCD4fF6A3b786DebDEF273195f8A
接下来部署NFT合约
合约地址 0xB81A99A0179e9CbC96a5289584001bD9c393E1AA
在testopensea上查看效果