-
-
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); | |
} | |
} |
@evantancy , may i know which tool you are using to measure gas ?
@jikdo hey, i'm using hardhat-gas-reporter and there's also foundry which i haven't tried but looks very promising
Hi, the console.log() inside .sol files are not appearing in my windows terminal. Has anyone come across the same problem?
Yes, same for me as well
Don't for get to change it to
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.1;
pragma solidity ^0.8.1; Works for me
Using
pragma solidity 0.8.0;
on VSCode with WSL 2 throws an error.Changing it to
pragma solidity ^0.8.0;
works for me.Greets, Stefan
Also ^0.8.1 works just fine
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.
Hi, I was just wondering why do we use

_setTokenURI
instead of overriding thetokenURI
function? I've tried minting a single token using both methods and_setTokenURI
seems to consume significantly more gas. Contract code can be found here