Created
August 16, 2023 07:11
-
-
Save KcPele/14444919b3d7a8b706f3eb8c5ef1b217 to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.8.18+commit.87f61d96.js&optimize=false&runs=200&gist=
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.17; | |
/// @title ERC-721 Non-Fungible Token Standard | |
/// @dev See https://eips.ethereum.org/EIPS/eip-721 | |
/// Note: the ERC-165 identifier for this interface is 0x80ac58cd. | |
interface ERC721 /* is ERC165 */ { | |
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); | |
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); | |
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); | |
function balanceOf(address _owner) external view returns (uint256); | |
function ownerOf(uint256 _tokenId) external view returns (address); | |
function isApprovedForAll(address _owner, address _operator) external view returns (bool); | |
function setApprovalForAll(address _operator, bool _approved) external; | |
function approve(address _approved, uint256 _tokenId) external payable; | |
function getApproved(uint256 _tokenId) external view returns (address); | |
function transferFrom(address _from, address _to, uint256 _tokenId) external payable; | |
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes calldata data) external payable; | |
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable; | |
} | |
error ERC721Contract__AddressCannotBeZero(); | |
error ERC721Contract__TokenIdDoesNotExist(); | |
error ERC721Contract__MsgSenderIsNotTheOwner(); | |
error ERC721Contract__FromAddressISNotTheOwner(); | |
error ERC721Contract__ReceiverNotImplemented(); | |
contract ERC721Contract is ERC721 { | |
mapping(address => uint256) internal _balances; | |
mapping(uint256 => address) internal _owners; | |
mapping(address => mapping(address => bool)) private _operatorApprovals; | |
mapping(uint256 => address ) private _tokenApprovals; | |
modifier checkTokenExist (uint256 _tokenId) { | |
if(_owners[_tokenId] == address(0)){ | |
revert ERC721Contract__TokenIdDoesNotExist(); | |
} | |
_; | |
} | |
function balanceOf(address _owner) public view returns(uint256) { | |
if(_owner == address(0)){ | |
revert ERC721Contract__AddressCannotBeZero(); | |
} | |
return _balances[_owner]; | |
} | |
function ownerOf(uint256 _tokenId) public view checkTokenExist(_tokenId) returns(address){ | |
address owner = _owners[_tokenId]; | |
return owner; | |
} | |
function setApprovalForAll(address _operator, bool _approved) public { | |
_operatorApprovals[msg.sender][_operator] = _approved; | |
emit ApprovalForAll(msg.sender, _operator, _approved); | |
} | |
function isApprovedForAll(address _owner, address _operator) public view returns(bool){ | |
return _operatorApprovals[_owner][_operator]; | |
} | |
function approve(address _to, uint256 _tokenId) public payable { | |
address owner = ownerOf(_tokenId); | |
if(msg.sender != owner || !isApprovedForAll(owner, msg.sender)){ | |
revert ERC721Contract__MsgSenderIsNotTheOwner(); | |
} | |
_tokenApprovals[_tokenId] = _to; | |
emit Approval(owner, _to, _tokenId); | |
} | |
function getApproved(uint256 _tokenId) public view checkTokenExist(_tokenId) returns(address){ | |
return _tokenApprovals[_tokenId]; | |
} | |
function transferFrom(address _from, address _to, uint256 _tokenId) public checkTokenExist(_tokenId) payable { | |
address owner = ownerOf(_tokenId); | |
if(_to != address(0)){ | |
revert ERC721Contract__AddressCannotBeZero(); | |
} | |
if(msg.sender != owner || !isApprovedForAll(owner, msg.sender) || getApproved(_tokenId) != msg.sender){ | |
revert ERC721Contract__MsgSenderIsNotTheOwner(); | |
} | |
if(owner != _from){ | |
revert ERC721Contract__FromAddressISNotTheOwner(); | |
} | |
approve(address(0), _tokenId); | |
_balances[_from] -= 1; | |
_balances[_to] += 1; | |
_owners[_tokenId] = _to; | |
emit Transfer(_from, _to, _tokenId); | |
} | |
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes memory _data) public payable { | |
transferFrom(_from, _to, _tokenId); | |
if(!_checkOnERC721Received()){ | |
revert ERC721Contract__ReceiverNotImplemented(); | |
} | |
} | |
function safeTransferFrom(address _from, address _to, uint256 _tokenId) public payable { | |
safeTransferFrom(_from, _to, _tokenId, ""); | |
} | |
function _checkOnERC721Received() private pure returns(bool) { | |
return true; | |
} | |
function supportsInterface(bytes4 interfaceId) public pure virtual returns(bool) { | |
return interfaceId == 0x80ac58cd; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.17; | |
import "./ERC721Contract.sol"; | |
error SuperMarioWorld__TokenIdDoesNotExist(); | |
contract SuperMarioWorld is ERC721Contract { | |
string private _name; | |
string private _symbol; | |
uint256 private _tokenCount; | |
mapping(uint256 => string) private _tokenURIs; | |
constructor(string memory name, string memory symbol) { | |
_name = name; | |
_symbol = symbol; | |
} | |
function tokenURL(uint256 _tokenId) external view returns(string memory) { | |
if(_owners[_tokenId] == address(0)) { | |
revert SuperMarioWorld__TokenIdDoesNotExist(); | |
} | |
return _tokenURIs[_tokenId]; | |
} | |
function mint(string memory _tokenURI) external { | |
_tokenCount += 1; | |
_balances[msg.sender] += 1; | |
_owners[_tokenCount] = msg.sender; | |
_tokenURIs[_tokenCount] = _tokenURI; | |
emit Transfer(address(0), msg.sender, _tokenCount); | |
} | |
function supportsInterface(bytes4 _interfaceId) public pure override returns(bool) { | |
return _interfaceId == 0x80ac58cd || _interfaceId == 0x5b5e139f; | |
} | |
function getName() external view returns(string memory) { | |
return _name; | |
} | |
function getSymbol() external view returns(string memory){ | |
return _symbol; | |
} | |
function getTokenCount() external view returns(uint256) { | |
return _tokenCount; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment