Neolastics
About
Stats
Public Functions
21
Event Types
5
Code Size
60,830 bytes
Library Use
Uses SafeMath for uint256.
Uses Address for address.
Uses EnumerableSet for EnumerableSet.UintSet.
Uses EnumerableMap for EnumerableMap.UintToAddressMap.
Uses Strings for uint256.
Events (5) keyboard_arrow_up
Constants (5) keyboard_arrow_up
State Variables (12) keyboard_arrow_up
Functions
supportsInterface keyboard_arrow_up
mint keyboard_arrow_up
Requirements help
Source Code
function mint(address to) public virtual returns (uint256 newTokenId) {
require(msg.sender == curve, "NEOLASTICS: Minter is not the curve");
/*
Neolastic generative art takes first 9 bytes of 32 to calculate colours for the 9 tiles.
Thus: you *can* get duplicates. But they are rare.
You can predict totalEverMinted + timestamp to *some* extent
but hard to do so, unless explicitly manipulated by miners.
The minter's address is used as additional 'salt'.
Thus sufficiently "psuedo-random" to ensure that it's unreasonable to manipulate.
*/
bytes32 hashed = keccak256(
abi.encodePacked(totalEverMinted, block.timestamp, to)
);
uint256 tokenId = uint256(hashed);
_mint(to, tokenId);
// this can overflow, and should overflow (since by the time it overflows, timestamp will change)
// but practically impossible to overflow.
// could theoretically mint a duplicate if it overflows in one block, but practically impossible with economic constraints.
totalEverMinted += 1; // for unique hashes per block
emit Minted(tokenId, totalEverMinted, block.timestamp, to, totalSupply());
return tokenId;
}
generateSVGofTokenById keyboard_arrow_up
generateSVGFromHash keyboard_arrow_up
Source Code
function generateSVGFromHash(bytes32 _hash)
public
view
virtual
returns (string memory)
{
bytes memory bhash = abi.encodePacked(_hash);
// tile example
// <rect x=0 y=0 width="100" height="100" style='fill:#fac901; strokeWidth:3; stroke:black'/>
/*
Each byte is a number between 0-255. If divided by 51, you get a number between 0-5.
Most of the time it will be 0-4, but 1/256 chance it is 5. Which is rare. Green.
Tiles are drawn from top-bottom, then left to right
1 4 7
2 5 8
3 6 9
*/
string memory svg = string(
abi.encodePacked(
"<svg width='300' height='300'>",
string(
abi.encodePacked(
"<rect x='0' y='0' width='100' height='100' style='fill:",
palette[toUint8(bhash, 0) / 51],
";stroke-width:3;stroke:black'/>"
)
), // tile 1
string(
abi.encodePacked(
"<rect x='0' y='100' width='100' height='100' style='fill:",
palette[toUint8(bhash, 1) / 51],
";stroke-width:3;stroke:black'/>"
)
), // tile 2
string(
abi.encodePacked(
"<rect x='0' y='200' width='100' height='100' style='fill:",
palette[toUint8(bhash, 2) / 51],
";stroke-width:3;stroke:black'/>"
)
), // tile 3
string(
abi.encodePacked(
"<rect x='100' y='0' width='100' height='100' style='fill:",
palette[toUint8(bhash, 3) / 51],
";stroke-width:3;stroke:black'/>"
)
), // tile 4
string(
abi.encodePacked(
"<rect x='100' y='100' width='100' height='100' style='fill:",
palette[toUint8(bhash, 4) / 51],
";stroke-width:3;stroke:black'/>"
)
), // tile 5
string(
abi.encodePacked(
"<rect x='100' y='200' width='100' height='100' style='fill:",
palette[toUint8(bhash, 5) / 51],
";stroke-width:3;stroke:black'/>"
)
), // tile 6
string(
abi.encodePacked(
"<rect x='200' y='0' width='100' height='100' style='fill:",
palette[toUint8(bhash, 6) / 51],
";stroke-width:3;stroke:black'/>"
)
), // tile 7
string(
abi.encodePacked(
"<rect x='200' y='100' width='100' height='100' style='fill:",
palette[toUint8(bhash, 7) / 51],
";stroke-width:3;stroke:black'/>"
)
), // tile 8
string(
abi.encodePacked(
"<rect x='200' y='200' width='100' height='100' style='fill:",
palette[toUint8(bhash, 8) / 51],
";stroke-width:3;stroke:black'/>"
)
), // tile 9
"</svg>"
)
);
return svg;
}
burn keyboard_arrow_up
Requirements help
Source Code
function burn(address burner, uint256 tokenId) public virtual {
require(msg.sender == curve, "NEOLASTICS: Burner is not the curve"); // only curve can burn it
require(burner == ownerOf(tokenId), "NEOLASTICS: Not the correct owner");
// checking if token exists in the _burn function (don't need to check here)
_burn(tokenId);
emit Burned(tokenId, burner, totalSupply());
}
balanceOf keyboard_arrow_up
Source Code
function balanceOf(address owner) public view override returns (uint256) {
require(owner != address(0), "ERC721: balance query for the zero address");
return _holderTokens[owner].length();
}
ownerOf keyboard_arrow_up
name keyboard_arrow_up
symbol keyboard_arrow_up
tokenURI keyboard_arrow_up
Requirements help
null
Source Code
function tokenURI(uint256 tokenId)
public
view
override
returns (string memory)
{
require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
string memory _tokenURI = _tokenURIs[tokenId];
// If there is no base URI, return the token URI.
if (bytes(_baseURI).length == 0) {
return _tokenURI;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
if (bytes(_tokenURI).length > 0) {
return string(abi.encodePacked(_baseURI, _tokenURI));
}
// If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
return string(abi.encodePacked(_baseURI, tokenId.toString()));
}
baseURI keyboard_arrow_up
tokenOfOwnerByIndex keyboard_arrow_up
totalSupply keyboard_arrow_up
tokenByIndex keyboard_arrow_up
approve keyboard_arrow_up
Requirements help
Source Code
function approve(address to, uint256 tokenId) public virtual override {
address owner = ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
msg.sender == owner || isApprovedForAll(owner, msg.sender),
"ERC721: approve caller is not owner nor approved for all"
);
_approve(to, tokenId);
}
getApproved keyboard_arrow_up
Requirements help
null
Source Code
function getApproved(uint256 tokenId) public view override returns (address) {
require(_exists(tokenId), "ERC721: approved query for nonexistent token");
return _tokenApprovals[tokenId];
}
setApprovalForAll keyboard_arrow_up
Requirements help
Source Code
function setApprovalForAll(address operator, bool approved)
public
virtual
override
{
require(operator != msg.sender, "ERC721: approve to caller");
_operatorApprovals[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
isApprovedForAll keyboard_arrow_up
transferFrom keyboard_arrow_up
Requirements help
Source Code
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
//solhint-disable-next-line max-line-length
require(
_isApprovedOrOwner(msg.sender, tokenId),
"ERC721: transfer caller is not owner nor approved"
);
_transfer(from, to, tokenId);
}
safeTransferFrom keyboard_arrow_up
Requirements help
Source Code
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
safeTransferFrom keyboard_arrow_up
Requirements help
Source Code
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory _data
) public virtual override {
require(
_isApprovedOrOwner(msg.sender, tokenId),
"ERC721: transfer caller is not owner nor approved"
);
_safeTransfer(from, to, tokenId, _data);
}
Internal Functions
Internal functions are parts of the contract that can't be used directly, but instead are used by the public functions listed above.
internal ERC721.toUint8 keyboard_arrow_up
Requirements help
Source Code
function toUint8(bytes memory _bytes, uint256 _start)
internal
pure
returns (uint8)
{
require(_start + 1 >= _start, "toUint8_overflow");
require(_bytes.length >= _start + 1, "toUint8_outOfBounds");
uint8 tempUint;
assembly {
tempUint := mload(add(add(_bytes, 0x1), _start))
}
return tempUint;
}
internal ERC721._safeTransfer keyboard_arrow_up
Requirements help
Source Code
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory _data
) internal virtual {
_transfer(from, to, tokenId);
require(
_checkOnERC721Received(from, to, tokenId, _data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
internal ERC721._exists keyboard_arrow_up
internal ERC721._isApprovedOrOwner keyboard_arrow_up
Requirements help
null
Source Code
function _isApprovedOrOwner(address spender, uint256 tokenId)
internal
view
returns (bool)
{
require(_exists(tokenId), "ERC721: operator query for nonexistent token");
address owner = ownerOf(tokenId);
return (spender == owner ||
getApproved(tokenId) == spender ||
isApprovedForAll(owner, spender));
}
internal ERC721._mint keyboard_arrow_up
Requirements help
Source Code
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_holderTokens[to].add(tokenId);
_tokenOwners.set(tokenId, to);
emit Transfer(address(0), to, tokenId);
}
internal ERC721._burn keyboard_arrow_up
Source Code
function _burn(uint256 tokenId) internal virtual {
address owner = ownerOf(tokenId);
// Clear approvals
_approve(address(0), tokenId);
// Clear metadata (if any)
if (bytes(_tokenURIs[tokenId]).length != 0) {
delete _tokenURIs[tokenId];
}
_holderTokens[owner].remove(tokenId);
_tokenOwners.remove(tokenId);
emit Transfer(owner, address(0), tokenId);
}
internal ERC721._transfer keyboard_arrow_up
Requirements help
Source Code
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(
ownerOf(tokenId) == from,
"ERC721: transfer of token that is not own"
);
require(to != address(0), "ERC721: transfer to the zero address");
// Clear approvals from the previous owner
_approve(address(0), tokenId);
_holderTokens[from].remove(tokenId);
_holderTokens[to].add(tokenId);
_tokenOwners.set(tokenId, to);
emit Transfer(from, to, tokenId);
}
internal ERC721._setBaseURI keyboard_arrow_up
internal ERC721._checkOnERC721Received keyboard_arrow_up
Source Code
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory _data
) private returns (bool) {
if (!to.isContract()) {
return true;
}
bytes memory returndata = to.functionCall(
abi.encodeWithSelector(
IERC721Receiver(to).onERC721Received.selector,
msg.sender,
from,
tokenId,
_data
),
"ERC721: transfer to non ERC721Receiver implementer"
);
bytes4 retval = abi.decode(returndata, (bytes4));
return (retval == _ERC721_RECEIVED);
}
internal ERC721._approve keyboard_arrow_up
internal ERC165.constructor keyboard_arrow_up
internal ERC165._registerInterface keyboard_arrow_up
Requirements help
Source Code
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}