deploy dynamic NFTs

This commit is contained in:
Ruidy 2022-04-07 10:09:30 -04:00
parent 333b90241d
commit 541495ac89
3 changed files with 204 additions and 7 deletions

View file

@ -2,9 +2,12 @@
Demo NFT collection for learning purposes.
## OPenSea Testnet
1. https://testnets.opensea.io/collection/squarenft-cd2xk3yh7v
2. https://testnets.opensea.io/collection/squarenft-bndes4idpq
## OpenSea Testnet
1. https://testnets.opensea.io/collection/squarenft-cd2xk3yh7v
2. https://testnets.opensea.io/collection/squarenft-bndes4idpq
3. https://testnets.opensea.io/collection/squarenft-lemz9demvy
4. https://testnets.opensea.io/collection/squarenft-1xkwn34mdz
## Square NFT

View file

@ -4,6 +4,7 @@ pragma solidity ^0.8.0;
import "hardhat/console.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "../lib/Base64.sol";
contract EpicNFT is ERC721URIStorage {
using Counters for Counters.Counter;
@ -13,14 +14,129 @@ contract EpicNFT is ERC721URIStorage {
console.log("My first NFT contract! EPIC!!!");
}
string baseSvg1 =
"<svg xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='xMinYMin meet' viewBox='0 0 350 350'><style>.base { fill:";
string baseSvg2 =
"; font-family: serif; font-size: 24px; }</style><rect width='100%' height='100%' fill='black' /><text x='50%' y='50%' class='base' dominant-baseline='middle' text-anchor='middle'>";
string[] colors = [
"red",
"green",
"blue",
"white",
"yellow",
"cyan",
"pink",
"magenta",
"silver",
"gold"
];
string[] levels = [
"Epic",
"Legendary",
"Heroic",
"Cool",
"Fantastic",
"Terrible",
"Crazy",
"Wild",
"Terrifying",
"Spooky"
];
string[] classes = [
"Assassin",
"Cleric",
"Rogue",
"Ninja",
"Lord",
"Wizard",
"Warrior",
"Berserker",
"Necromander",
"Summoner",
"Bard",
"Lancer"
];
string[] jobs = [
"Soldier",
"Healer",
"Explorer",
"Merchant",
"Developer",
"BlackSmith",
"Hitman",
"Cook",
"Hunter",
"Sailor"
];
function mint() public {
uint256 tokenID = _tokenIds.current();
_safeMint(msg.sender, tokenID);
_setTokenURI(
tokenID,
"data:application/json;base64,ewogICAgIm5hbWUiOiAiRXBpY0xvcmRIYW1idXJnZXIiLAogICAgImRlc2NyaXB0aW9uIjogIkFuIE5GVCBmcm9tIHRoZSBoaWdobHkgYWNjbGFpbWVkIHNxdWFyZSBjb2xsZWN0aW9uIiwKICAgICJpbWFnZSI6ICJkYXRhOmltYWdlL3N2Zyt4bWw7YmFzZTY0LFBITjJaeUI0Yld4dWN6MGlhSFIwY0RvdkwzZDNkeTUzTXk1dmNtY3ZNakF3TUM5emRtY2lJSEJ5WlhObGNuWmxRWE53WldOMFVtRjBhVzg5SW5oTmFXNVpUV2x1SUcxbFpYUWlJSFpwWlhkQ2IzZzlJakFnTUNBek5UQWdNelV3SWo0TkNpQWdJQ0E4YzNSNWJHVStMbUpoYzJVZ2V5Qm1hV3hzT2lCM2FHbDBaVHNnWm05dWRDMW1ZVzFwYkhrNklITmxjbWxtT3lCbWIyNTBMWE5wZW1VNklERTBjSGc3SUgwOEwzTjBlV3hsUGcwS0lDQWdJRHh5WldOMElIZHBaSFJvUFNJeE1EQWxJaUJvWldsbmFIUTlJakV3TUNVaUlHWnBiR3c5SW1Kc1lXTnJJaUF2UGcwS0lDQWdJRHgwWlhoMElIZzlJalV3SlNJZ2VUMGlOVEFsSWlCamJHRnpjejBpWW1GelpTSWdaRzl0YVc1aGJuUXRZbUZ6Wld4cGJtVTlJbTFwWkdSc1pTSWdkR1Y0ZEMxaGJtTm9iM0k5SW0xcFpHUnNaU0krUlhCcFkweHZjbVJJWVcxaWRYSm5aWEk4TDNSbGVIUStEUW84TDNOMlp6ND0iCn0="
string memory color = pickRandomWord(colors, "color", tokenID);
string memory first = pickRandomWord(levels, "first", tokenID);
string memory second = pickRandomWord(classes, "second", tokenID);
string memory third = pickRandomWord(jobs, "third", tokenID);
string memory finalWord = string(
abi.encodePacked(color, first, second, third)
);
string memory finalSvg = string(
abi.encodePacked(
baseSvg1,
color,
baseSvg2,
first,
second,
third,
"</text></svg>"
)
);
string memory json = Base64.encode(
bytes(
string(
abi.encodePacked(
'{"name": "',
finalWord,
'", "description": "A highly acclaimed collection of squares.", "image": "data:image/svg+xml;base64,',
Base64.encode(bytes(finalSvg)),
'"}'
)
)
)
);
string memory tokenUri = string(
abi.encodePacked("data:application/json;base64,", json)
);
console.log("\n--------------------");
console.log(tokenUri);
console.log("--------------------\n");
_safeMint(msg.sender, tokenID);
_setTokenURI(tokenID, tokenUri);
console.log("NFT %s minted to %s", tokenID, msg.sender);
_tokenIds.increment();
}
function pickRandomWord(
string[] memory words,
string memory position,
uint256 tokenID
) public pure returns (string memory) {
uint256 rand = random(
string(abi.encodePacked(position, Strings.toString(tokenID)))
);
rand = rand % words.length;
return words[rand];
}
function random(string memory input) internal pure returns (uint256) {
return uint256(keccak256(abi.encodePacked(input)));
}
}

78
lib/Base64.sol Normal file
View file

@ -0,0 +1,78 @@
/**
*Submitted for verification at Etherscan.io on 2021-09-05
*/
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// [MIT License]
/// @title Base64
/// @notice Provides a function for encoding some bytes in base64
/// @author Brecht Devos <brecht@loopring.org>
library Base64 {
bytes internal constant TABLE =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/// @notice Encodes some bytes to the base64 representation
function encode(bytes memory data) internal pure returns (string memory) {
uint256 len = data.length;
if (len == 0) return "";
// multiply by 4/3 rounded up
uint256 encodedLen = 4 * ((len + 2) / 3);
// Add some extra buffer at the end
bytes memory result = new bytes(encodedLen + 32);
bytes memory table = TABLE;
assembly {
let tablePtr := add(table, 1)
let resultPtr := add(result, 32)
for {
let i := 0
} lt(i, len) {
} {
i := add(i, 3)
let input := and(mload(add(data, i)), 0xffffff)
let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
out := shl(8, out)
out := add(
out,
and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF)
)
out := shl(8, out)
out := add(
out,
and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF)
)
out := shl(8, out)
out := add(
out,
and(mload(add(tablePtr, and(input, 0x3F))), 0xFF)
)
out := shl(224, out)
mstore(resultPtr, out)
resultPtr := add(resultPtr, 4)
}
switch mod(len, 3)
case 1 {
mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
}
case 2 {
mstore(sub(resultPtr, 1), shl(248, 0x3d))
}
mstore(result, encodedLen)
}
return string(result);
}
}