// contracts/NFT.sol // SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity ^0.8.3; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/utils/math/SafeMath.sol"; import "hardhat/console.sol"; import "./UnicornAdmin.sol"; contract UnicornNFT is UnicornAdmin,ERC721URIStorage { using SafeMath for uint256; struct Unicorn { string name; uint256 genes; uint64 birthTime; uint64 cooldownEndTime; uint32 mumId; uint32 dadId; uint16 generation; uint16 cooldownIndex; } Unicorn[] internal allUnicorns; mapping(uint256 => address) public unicornToOwner; mapping(address => uint256) ownerUnicornCount; mapping(string => bool) public unicornNameExists; modifier onlyOwnerOf(uint256 _unicornId) { require(msg.sender == unicornToOwner[_unicornId],"Not unicorn owner"); _; } constructor () ERC721 ("Crypto Unicorn Collection", "CRYUNI"){ allUnicorns.push( Unicorn({ name: "initialUnicorn", genes: 0, birthTime: 0, cooldownEndTime: 0, mumId: 0, dadId: 0, generation: 0, cooldownIndex: 0 }) ); } mapping(uint256 => address) UnicornApprovals; function setUnicornURI(string memory _tokenURI, uint256 _unicornId) public onlyOwnerOf(_unicornId) { _setTokenURI(_unicornId, _tokenURI); } function setNewName(string memory _name, uint256 _unicornId) public onlyOwnerOf(_unicornId){ Unicorn storage unicorn = allUnicorns[_unicornId]; unicorn.name = _name ; } function balanceOf(address _owner) public view override returns (uint256 _balance) { return ownerUnicornCount[_owner]; } function ownerOf(uint256 _unicornId) public view override returns (address _owner) { return unicornToOwner[_unicornId]; } function _transfer( address _from, address _to, uint256 _unicornId ) internal override { ownerUnicornCount[_to] = ownerUnicornCount[_to].add(1); ownerUnicornCount[msg.sender] = ownerUnicornCount[msg.sender].sub(1); unicornToOwner[_unicornId] = _to; emit Transfer(_from, _to, _unicornId); } function transfer(address _to, uint256 _unicornId) public onlyOwnerOf(_unicornId) { _transfer(msg.sender, _to, _unicornId); } function approve(address _to, uint256 _unicornId) public onlyOwnerOf(_unicornId) override { UnicornApprovals[_unicornId] = _to; emit Approval(msg.sender, _to, _unicornId); } function takeOwnership(uint256 _unicornId) public { require(UnicornApprovals[_unicornId] == msg.sender,"Not approved"); address owner = ownerOf(_unicornId); _transfer(owner, msg.sender, _unicornId); } }