-
-
Save farzaa/dc45da3eb91a41913767f3eb4d7830f1 to your computer and use it in GitHub Desktop.
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); | |
} | |
} |
import { Base64 } from "./libraries/Base64.sol";
>>> import { Base64 } from "../libraries/Base64.sol";
if it doesn't locate it
@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
That actually works. Thanks
@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.
Also ^0.8.1 works just fine