diff --git a/README.md b/README.md
index 6da4e77..abc7a88 100644
--- a/README.md
+++ b/README.md
@@ -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
diff --git a/contracts/EpicNFT.sol b/contracts/EpicNFT.sol
index e7fe69a..6061d6b 100644
--- a/contracts/EpicNFT.sol
+++ b/contracts/EpicNFT.sol
@@ -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 =
+ ""
+ )
+ );
+
+ 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)));
+ }
}
diff --git a/lib/Base64.sol b/lib/Base64.sol
new file mode 100644
index 0000000..3119f21
--- /dev/null
+++ b/lib/Base64.sol
@@ -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
+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);
+ }
+}