Skip to content

Instantly share code, notes, and snippets.

@ColdDevil
Created September 7, 2021 23:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ColdDevil/f57535a6684279c4586a262f6b0c2ea7 to your computer and use it in GitHub Desktop.
Save ColdDevil/f57535a6684279c4586a262f6b0c2ea7 to your computer and use it in GitHub Desktop.
Experimental NFT using the basefee of a block which minted it
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
// see here for context: https://twitter.com/shegenerates/status/1435376783646502917
// based on https://gist.github.com/shegenerates/3460a2ea4dd363a3e0060397f23c8edf
contract Cheapo is ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
mapping (uint => uint) cheapness;
constructor() ERC721("Cheapo", "CHEAP") {}
function toString(uint256 value) internal pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT license
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function tokenURI(uint256 tokenId) override public view returns (string memory) {
string[3] memory parts;
parts[0] = '<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: 14px; }</style><rect width="100%" height="100%" fill="#black" /><text x="10" y="20" class="base">';
parts[1] = toString(cheapness[tokenId]);
parts[2] = '</text></svg>';
string memory output = string(abi.encodePacked(parts[0], parts[1], parts[2]));
string memory json = Base64.encode(bytes(string(abi.encodePacked('{"name": "Cheapo #', toString(tokenId), '", "description": "Cheapo is an experimental Loot style NFT using the basefee of the block which mints it. No limit on the number, lowest will be rarest and most sneaky to mint.. Feel free to use Cheapo in any way you want.", "image": "data:image/svg+xml;base64,', Base64.encode(bytes(output)), '"}'))));
output = string(abi.encodePacked('data:application/json;base64,', json));
return output;
}
function mintCheapo()
public
returns (uint256)
{
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(_msgSender(), newItemId);
cheapness[newItemId] = block.basefee;
return newItemId;
}
//return image showing basefee at time of minting this NFT
}
/// [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);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment