[[NFT Standards]] [[final]] ## [[Simple-explanantion]] [[ERC20]] is fungible token = tradeable [[ERC721]] is non fungible token = collectible For physical coins, a gold coin is not fungible with a copper coin, because their differing characteristics give them different values to collectors. This standard can't [[scale]] **ERC721 tokens can be used in any exchange, but their value is a result of the uniqueness and rareness associated with each token. The standard defines the functions `name` , `symbol` , `totalSupply` , `balanceOf` , `ownerOf` , `approve` , `takeOwnership` , `transfer` , `tokenOfOwnerByIndex` , and `tokenMetadata` . It also defines two events: `Transfer` and `Approval` . Source for this part: https://medium.com/crypto-currently/the-anatomy-of-erc721-e9db77abfc24 ##  [[Functions-simplified]] [[ERC721]] standard allows each unit to be [[unique]] [[collectible]] item with its own serial number [[ID]] **ERC20 Functions** Functions of token standard makes it easier for existing wallets to display simple information about the token. These functions let the smart contract that fits this standard act like a common cryptocurrency such as Bitcoin or Ethereum by defining functions that let users perform actions such as sending tokens to others and checking balances of accounts. - [[name]] - tell outside contracts and apps the name of the token - [[symbol]] - helps in providing compatibity with the ERC720 token standard. Provides outside programs with the token's shorter name or symbol - [[totalSupply]] - returns the total number of coins available on blockchain - [[balanceOf ]]- find the numbers of tokens that a given address owns **Ownership Functions** Define how contract will handle token ownership and how it can be transferred. The most notable are [[takeOwnership]] = withdraw and [[Transfer]] = send functions. Both are essential for letting users transfer tokens. - [[ownerOf]] - returns the address of the owner of a token. We can determine the owner of a token using its ID which this function gives - [[approve ]]- approves and gives another entity permission to transfer a token on the owners behalf - [[takeOwnership]] - acts like withdraw function, can be used to when a user has been approved to own certain amount of tokens and wish to withdraw X amount of tokens from someone else balanace - [[Transfer]] - transfering tokens, lets the owner send to another user, can be initiated after the receiving account has been approved to own the token by sending account - [[tokenOfOwnerByIndex ]](optional but reccommended) - this contract keep record of every unique ID of the token as user may own more tokens, user can be retrieved by its index in the list of tokens owned **Metadata Functions** Storing data on blockchain that tell the defining characteristic of each token is expensive and not recommended. We can store references like IPFS hash or HTTPS link (URL) to each token attributes on the chain in order the dapp outside of the chain can execute logic and findd the information about the token. These data are metadata [[tokenMetadata]] (optional but recommended) - discover the tokens metadata or link to them **Events** Fired whenevenr a contract calls them, are broadcasted to any listening programs - dapps once they ve been fired. Dapps are listening those events so they can execute the logic once the event is fired. [[Transfer]] - functions and broadcasted when the token ownership changes, details which account sent the token and received by token ID [[approval]] - when user approves another user to take the ownership of a token, shows which account owns the token by ID, which is approoved to have its ownership transferred Find snippets of code here: https://medium.com/crypto-currently/the-anatomy-of-erc721-e9db77abfc24 ## history of the standard Ethereum [Request for Comments](https://en.wikipedia.org/wiki/Request_for_Comments) 721, or ERC721, is an [Ethereum Improvement Proposal](https://github.com/ethereum/EIPs) introduced by Dieter Shirley in late 2017. It’s a proposed standard that would allow smart contracts to operate as tradeable tokens similar to [ERC20](https://news.earn.com/the-anatomy-of-erc20-6ab09d4206a5). ERC721 tokens are unique in that the tokens are non-fungible. ## ERC721 = non fungible token that can hold metadata ### ERC-721 Non Fungible Token Standard Token standard that is used to identify something or someone in a unique way. Perfect for being used as collectible item, access keys, lottery standards... **This standard has [[uinit26]] = tokenId. The [[contract-address]], uint26 tokenId must be unique. dApp usually have "converter" that uses the tokenId as input and outputs image - the NFT itself.** ## Token Standards are summarised and compared in the following ways: 1) [[Ownership]] - How is the token ownership handled? 2) [[Creation]] - How are tokens created? 3) [[Transfer]] & [[Allowance]] - How tokens are transferred, how do we allow other addresses (contracts or extrnally owned accounts) transfer capability? 4) [[Burn]] - How do we burn or destroy a token? ## Token Ownership [[token-ownership]] ``mapping(address => uint256) balances`` uint256 = record of how many tokens each address of the ERC721 Contract holds - If you want to transfer [[ERC721]] then balance is verified through balances mapping so you don’t send more than you have ## Functionalities [[fuctionalities]] **balanceOf(address _owner)**= external view returns (uint256) **ownerOf(uint256_tokenId) ** = external view returns (address) **safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes data)** external payable **safeTransferFrom(address _from, address _to, uint256 _tokenId)** external payable **transferFrom(address _from, address _to, uint256 _tokenId)** external payable **approve(address \_approved, uint256 _tokenId)** external payable function **setApprovalForAll(address _operator, bool _approved)** external function **getApproved(uint256 _tokenId)** external view returns (address; function **isApprovedForAll(address _owner, address _operator)** external view returns (bool) ## [[Fuctions]] [[Event-simplified]] [[simplified]] - transfer token between accounts - get (display) current balance of an account - get specific token - total supply of the token available on the network - approve amount of token from an account can be moved by 3rd party account ## [[Events]] of this standard - **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) Source for this part https://ethereum.org/en/developers/docs/standards/tokens/erc-721/ # ERC-721 Security TL:DR just missleading name of function ## Intro The ERC-721 was supposed to have transfer security function to ensure tokens wouldn’t be stuck in recipient contracts that weren't designed to handle them. Safe functions prevent tokens to get stuck that's why we call them `safeTransfer`. This function may cause reentrancy vunerabilities which means the `safeTransfer` function in code is not making the contract safe - prevent it from other vunerabilities it's actually `unsafeTransfer`. This function was initially named as `transfer` ## Full disclosure "When the ERC-721 standard was being drafted, back in the beginning of 2018, a suggestion was made to implement transfer security to ensure that tokens wouldn't be stuck in recipient contracts that weren't designed to handle them. To do this, the proposal authors modified the behavior of the transfer function to check the recipient for whether they were capable of supporting the token transfer. They also introduced the unsafeTransfer function which would bypass this check, should the sender so desire. However, due to concerns about backwards compatibility, the functions were renamed in a subsequent commit. This made the transfer function behave the same for both an ERC-20 and an ERC-721 token. However, now the recipient checking needed to be moved elsewhere. As such, the safe class of functions was introduced: safeTransfer and safeTransferFrom. This was a solution for a legitimate problem, as there have been numerous examples of ERC-20 tokens being accidentally transferred to contracts that never expected to receive tokens (one particularly common mistake was to transfer tokens to the token contract itself, locking it forever). It's no surprise then that when the ERC-1155 standard was being drafted, it took inspiration from the ERC-721 standard by including recipient checks not only on transfer but on mint as well. These standards mostly sat dormant for the next few years while ERC-20 maintained its popularity, but recently a spike in gas costs, as well as interest in NFTs, means that the ERC-721 and ERC-1155 standards have seen a spike in developer usage. With all this renewed interest, it sure is fortunate that these standards were designed with safety in mind, right?" -Samczsun Source: https://www.paradigm.xyz/2021/08/the-dangers-of-surprising-code Code: https://github.com/ethereum/EIPs/commit/74dadccc858545aa89edaf6ec1cb5857cd261083 ### [[ERC721]] Benchmark "The standard enforces to emit a `Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId)` every time a token is transferred. Events can be used to get the list of tokens owned by a user. This approach queries the `Transfer` events emitted by the smart contract that holds the tokens. As we will see later, quering for events is a slow operation that might fail. ERC721 describes an optional enumeration extension to make the list of tokens fully discoverable. The [ERC721Enumerable](https://vrde.github.io/erc721-benchmark/) interface defines a new method `tokenOfOwnerByIndex(address _owner, uint256 _index)`. This combined with `balanceOf` allow us to iterate over the tokens of a user to get the token ids. This approach is much faster and reliable." Link: https://vrde.github.io/erc721-benchmark/ ## [[further reading]] Walking Through the ERC721 Full Implementation - A Deep Dive into Managing ERC721 Assets https://medium.com/blockchannel/walking-through-the-erc721-full-implementation-72ad72735f3c OpenZeppelin implementation https://docs.openzeppelin.com/contracts/3.x/api/token/erc721#IERC721Metadata OpenZeppelin Contract https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC721/ERC721.sol Full implementation https://eips.ethereum.org/EIPS/eip-721 Exploring Non-Fungible Token with Zeppelin Library (ERC721) https://medium.com/coinmonks/exploring-non-fungible-token-with-zeppelin-library-erc721-399cb180cfaf A Simple ERC-721 Example https://medium.com/coinmonks/a-simple-erc-721-example-c3f72b5aa19 ERC-721 Token - Refence Implementation by 0xCert https://github.com/0xcert/ethereum-erc721 ERC-721 Solmate https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC721.sol Optimising ERC-721 Solmate walkthrough https://mirror.xyz/0x3fcAf7DDf64E6e109B1e2A5CC17875D4a5993F39/B3PKWKWZTk_lgLRS9oLY2sYCcYLHKdFQPyVrzDg0hZo