Update TokenURI and the metadata struct

This commit is contained in:
EmperorOrokuSaki 2022-12-05 20:53:23 +03:30
parent a590717021
commit afff3f6f7a
1 changed files with 48 additions and 35 deletions

View File

@ -4,6 +4,7 @@ pragma solidity ^0.8.7;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/utils/Base64.sol";
import "./FleekAccessControl.sol"; import "./FleekAccessControl.sol";
contract FleekERC721 is ERC721, FleekAccessControl { contract FleekERC721 is ERC721, FleekAccessControl {
@ -13,17 +14,21 @@ contract FleekERC721 is ERC721, FleekAccessControl {
struct Build { struct Build {
string commit_hash; string commit_hash;
string git_repository; string git_repository;
string author;
} }
struct Site { struct App {
bytes32 external_url; // IPFS HASH string name; // Name of the site
string description; // Description about the site
bytes32 image; // Preview Image IPFS Link
bytes32 external_url; // Site URL
bytes32 ENS; // ENS ID bytes32 ENS; // ENS ID
uint256 current_build; // THE CURRENT BUILD NUMBER (increments by one with each change, starts at zero) uint256 current_build; // The current build number (Increments by one with each change, starts at zero)
mapping(uint256 => Build) builds; // MAPPING TO BUILD DETAILS FOR EACH BUILD NUMBER mapping(uint256 => Build) builds; // Mapping to build details for each build number
} }
Counters.Counter private _tokenIds; Counters.Counter private _tokenIds;
mapping(uint256 => Site) private _sites; mapping(uint256 => App) private _apps;
constructor( constructor(
string memory _name, string memory _name,
@ -40,23 +45,30 @@ contract FleekERC721 is ERC721, FleekAccessControl {
function mint( function mint(
address to, address to,
string memory name,
string memory description,
bytes32 image,
bytes32 external_url, bytes32 external_url,
bytes32 ENS, bytes32 ENS,
string memory commit_hash, string memory commit_hash,
string memory git_repository string memory git_repository,
string memory author
) public payable requireCollectionOwner returns (uint256) { ) public payable requireCollectionOwner returns (uint256) {
uint256 tokenId = _tokenIds.current(); uint256 tokenId = _tokenIds.current();
_mint(to, tokenId); _mint(to, tokenId);
addTokenController(tokenId, to); addTokenController(tokenId, to);
_tokenIds.increment(); _tokenIds.increment();
Site storage site = _sites[tokenId]; App storage app = _apps[tokenId];
site.external_url = external_url; app.name = name;
site.ENS = ENS; app.description = description;
app.image = image;
app.external_url = external_url;
app.ENS = ENS;
// The mint interaction is considered to be the first build of the site. Updates from now on all increment the current_build by one and update the mapping. // The mint interaction is considered to be the first build of the site. Updates from now on all increment the current_build by one and update the mapping.
site.current_build = 0; app.current_build = 0;
site.builds[0] = Build(commit_hash, git_repository); app.builds[0] = Build(commit_hash, git_repository, author);
return tokenId; return tokenId;
} }
@ -64,10 +76,11 @@ contract FleekERC721 is ERC721, FleekAccessControl {
function upgradeTokenBuild( function upgradeTokenBuild(
uint256 tokenId, uint256 tokenId,
string memory commit, string memory commit,
string memory repository string memory repository,
string memory author
) public payable requireTokenOwner(tokenId) { ) public payable requireTokenOwner(tokenId) {
_requireMinted(tokenId); _requireMinted(tokenId);
setTokenBuild(tokenId, commit, repository); setTokenBuild(tokenId, commit, repository, author);
} }
function tokenURI( function tokenURI(
@ -75,27 +88,26 @@ contract FleekERC721 is ERC721, FleekAccessControl {
) public view virtual override returns (string memory) { ) public view virtual override returns (string memory) {
_requireMinted(tokenId); _requireMinted(tokenId);
address owner = ownerOf(tokenId); address owner = ownerOf(tokenId);
Site storage site = _sites[tokenId]; App storage app = _apps[tokenId];
/*
/ Note: I do not think this is the way this function is supposed to be written.
/ I recommend returning a IPFS URL per OpenSea's own documentation:
/ https://docs.opensea.io/docs/metadata-standards#implementing-token-uri
*/
bytes memory dataURI = abi.encodePacked( bytes memory dataURI = abi.encodePacked(
'{', '{',
'"owner":"', owner, '",', '"name":"', app.name, '",',
'"ENS":"', site.ENS, '",', '"description":"', app.description, '",',
'"external_url":"', site.external_url, '",', '"owner":"', abi.encodePacked(owner), '",',
'"build:{', '"ENS":"', app.ENS, '",',
'"id":"', site.current_build, '",', '"external_url":"', app.external_url, '",',
'"commit_hash":"', site.builds[site.current_build].commit_hash, '",', '"image":"', app.image, '",',
'"repository":"', site.builds[site.current_build].git_repository, '"' '"attributes": [',
'}', '{"trait_type": "ENS", "value":"', app.ENS,'"},',
'{"trait_type": "Commit Hash", "value":"', app.builds[app.current_build].commit_hash,'"},',
'{"trait_type": "Repository", "value":"', app.builds[app.current_build].git_repository,'"},',
'{"trait_type": "Author", "value":"', app.builds[app.current_build].author,'"},',
'{"trait_type": "Version", "value":"', app.current_build,'"}',
']',
'}' '}'
); );
return string(abi.encodePacked(_baseURI(), dataURI)); return string(abi.encodePacked(_baseURI(), Base64.encode(dataURI)));
} }
function addTokenController( function addTokenController(
@ -129,7 +141,7 @@ contract FleekERC721 is ERC721, FleekAccessControl {
bytes32 _tokenExternalURL bytes32 _tokenExternalURL
) public virtual payable requireTokenController(tokenId) { ) public virtual payable requireTokenController(tokenId) {
_requireMinted(tokenId); _requireMinted(tokenId);
_sites[tokenId].external_url = _tokenExternalURL; _apps[tokenId].external_url = _tokenExternalURL;
} }
function setTokenENS( function setTokenENS(
@ -137,16 +149,17 @@ contract FleekERC721 is ERC721, FleekAccessControl {
bytes32 _tokenENS bytes32 _tokenENS
) public virtual payable requireTokenController(tokenId) { ) public virtual payable requireTokenController(tokenId) {
_requireMinted(tokenId); _requireMinted(tokenId);
_sites[tokenId].ENS = _tokenENS; _apps[tokenId].ENS = _tokenENS;
} }
function setTokenBuild( function setTokenBuild(
uint256 tokenId, uint256 tokenId,
string memory _commit_hash, string memory _commit_hash,
string memory _git_repository string memory _git_repository,
string memory _author
) public virtual payable requireTokenController(tokenId) { ) public virtual payable requireTokenController(tokenId) {
_requireMinted(tokenId); _requireMinted(tokenId);
_sites[tokenId].builds[++_sites[tokenId].current_build] = Build(_commit_hash, _git_repository); _apps[tokenId].builds[++_apps[tokenId].current_build] = Build(_commit_hash, _git_repository, _author);
} }
function burn(uint256 tokenId) public virtual payable requireTokenController(tokenId) { function burn(uint256 tokenId) public virtual payable requireTokenController(tokenId) {
@ -156,8 +169,8 @@ contract FleekERC721 is ERC721, FleekAccessControl {
); );
super._burn(tokenId); super._burn(tokenId);
if (_sites[tokenId].external_url.length != 0) { if (_apps[tokenId].external_url.length != 0) {
delete _sites[tokenId]; delete _apps[tokenId];
} }
} }
} }