Last active
November 19, 2022 22:44
-
-
Save farzaa/dc45da3eb91a41913767f3eb4d7830f1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pragma solidity 0.8.0; | |
import "@openzeppelin/contracts/utils/Strings.sol"; | |
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; | |
import "@openzeppelin/contracts/utils/Counters.sol"; | |
import "hardhat/console.sol"; | |
// We need to import the helper functions from the contract that we copy/pasted. | |
import { Base64 } from "./libraries/Base64.sol"; | |
contract MyEpicNFT is ERC721URIStorage { | |
using Counters for Counters.Counter; | |
Counters.Counter private _tokenIds; | |
string baseSvg = "<svg xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='xMinYMin meet' viewBox='0 0 350 350'><style>.base { fill: white; 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[] firstWords = ["YOUR_WORD", "YOUR_WORD", "YOUR_WORD", "YOUR_WORD", "YOUR_WORD", "YOUR_WORD"]; | |
string[] secondWords = ["YOUR_WORD", "YOUR_WORD", "YOUR_WORD", "YOUR_WORD", "YOUR_WORD", "YOUR_WORD"]; | |
string[] thirdWords = ["YOUR_WORD", "YOUR_WORD", "YOUR_WORD", "YOUR_WORD", "YOUR_WORD", "YOUR_WORD"]; | |
constructor() ERC721 ("SquareNFT", "SQUARE") { | |
console.log("This is my NFT contract. Woah!"); | |
} | |
function pickRandomFirstWord(uint256 tokenId) public view returns (string memory) { | |
uint256 rand = random(string(abi.encodePacked("FIRST_WORD", Strings.toString(tokenId)))); | |
rand = rand % firstWords.length; | |
return firstWords[rand]; | |
} | |
function pickRandomSecondWord(uint256 tokenId) public view returns (string memory) { | |
uint256 rand = random(string(abi.encodePacked("SECOND_WORD", Strings.toString(tokenId)))); | |
rand = rand % secondWords.length; | |
return secondWords[rand]; | |
} | |
function pickRandomThirdWord(uint256 tokenId) public view returns (string memory) { | |
uint256 rand = random(string(abi.encodePacked("THIRD_WORD", Strings.toString(tokenId)))); | |
rand = rand % thirdWords.length; | |
return thirdWords[rand]; | |
} | |
function random(string memory input) internal pure returns (uint256) { | |
return uint256(keccak256(abi.encodePacked(input))); | |
} | |
function makeAnEpicNFT() public { | |
uint256 newItemId = _tokenIds.current(); | |
string memory first = pickRandomFirstWord(newItemId); | |
string memory second = pickRandomSecondWord(newItemId); | |
string memory third = pickRandomThirdWord(newItemId); | |
string memory combinedWord = string(abi.encodePacked(first, second, third)); | |
string memory finalSvg = string(abi.encodePacked(baseSvg, combinedWord, "</text></svg>")); | |
// Get all the JSON metadata in place and base64 encode it. | |
string memory json = Base64.encode( | |
bytes( | |
string( | |
abi.encodePacked( | |
'{"name": "', | |
// We set the title of our NFT as the generated word. | |
combinedWord, | |
'", "description": "A highly acclaimed collection of squares.", "image": "data:image/svg+xml;base64,', | |
// We add data:image/svg+xml;base64 and then append our base64 encode our svg. | |
Base64.encode(bytes(finalSvg)), | |
'"}' | |
) | |
) | |
) | |
); | |
// Just like before, we prepend data:application/json;base64, to our data. | |
string memory finalTokenUri = string( | |
abi.encodePacked("data:application/json;base64,", json) | |
); | |
console.log("\n--------------------"); | |
console.log(finalTokenUri); | |
console.log("--------------------\n"); | |
_safeMint(msg.sender, newItemId); | |
// Update your URI!!! | |
_setTokenURI(newItemId, finalTokenUri); | |
_tokenIds.increment(); | |
console.log("An NFT w/ ID %s has been minted to %s", newItemId, msg.sender); | |
} | |
} |
@farzaa, hey
I think in random function, should be used a
encode
it's more secure, especially when we talk about generating random values.For example:
function runEncodePacked(string calldata str1, string calldata str2) internal pure returns(bytes32) { bytes memory encoded = abi.encodePacked(str1, str2); return keccak256(encoded); }
runEncodePacked("hello", "world") === runEncodePacked("hell", "oworld") The result would be the same 0xfa26db7ca85ead399216e7c6316bc50ed24393c3122b582735e7f3b0f91b93f0
I think the same thing too
so basically the essence is to maintain security.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
That actually works. Thanks