By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
NFT standards are the “blueprints” that tell the Ethereum Virtual Machine (EVM) how a non‑fungible token (NFT) should behave. By codifying metadata, ownership, and transfer rules, they let any wallet, marketplace, or game understand and move the same token type without custom logic. Real‑world example: A sneaker brand launches a limited‑edition shoe collection on OpenSea; each pair is an ERC‑721 token that buyers can view, trade, or use as an in‑game avatar accessory—all because the contract follows the same standard.
ownerOf
transferFrom
solidity contract MyArt is ERC721("MyArt", "ART") { function mint(address to, uint256 tokenId) external { _safeMint(to, tokenId); } }
solidity contract GameItems is ERC1155("ipfs://metadata/{id}.json") { function mint(address to, uint256 id, uint256 amount) external { _mint(to, id, amount, ""); } }
solidity function setUser(uint256 tokenId, address user, uint64 expires) external onlyOwner { _setUser(tokenId, user, expires); }
_safeTransfer
_transfer
IERC721Receiver.onERC721Received
solidity function onERC721Received(address, address, uint256, bytes calldata) external pure returns (bytes4) { return IERC721Receiver.onERC721Received.selector; }
tokenURI
uri
_mintBatch
solidity function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address, uint256) { return (creator, salePrice * 5 / 100); // 5 % royalty }
supportsInterface(bytes4 interfaceId)
operator
setApprovalForAll
ERC721.sol
ERC1155.sol
ERC4907.sol
npx hardhat compile
chai
ethers
balanceOf
setUser
bash npx hardhat run scripts/deploy.js --network goerli
js const nft = new ethers.Contract(address, abi, signer); await nft.mint(walletAddress, 1); const uri = await nft.tokenURI(1);
setApprovalForAll(marketplace, true)
Mistake: Using transferFrom instead of safeTransferFrom for ERC‑721. Correction: safeTransferFrom guarantees the receiver implements IERC721Receiver; otherwise the token could be forever stuck in a non‑compatible contract.
safeTransferFrom
IERC721Receiver
Mistake: Forgetting to override supportsInterface when mixing ERC‑721, ERC‑1155, and ERC‑4907. Correction: Call super.supportsInterface(interfaceId) for each parent contract so ERC‑165 queries return the correct bitmask.
supportsInterface
super.supportsInterface(interfaceId)
Mistake: Storing large JSON metadata on‑chain (e.g., string public metadata). Correction: Keep metadata off‑chain (IPFS or Arweave) and only store the URI; this saves >90 % gas per mint.
string public metadata
Mistake: Approving the zero address (0x0) as an operator, which effectively revokes all approvals. Correction: Always pass a valid marketplace or escrow contract address to setApprovalForAll.
0x0
Mistake: Assuming ERC‑1155 batch minting is free of re‑entrancy risk. Correction: Even batch functions should follow the Checks‑Effects‑Interactions pattern; update state before external calls.
“Explain the difference between ERC‑721 and ERC‑1155 in terms of gas and use‑case.” Interviewers expect you to cite batch minting, single‑ID vs multi‑ID storage, and why games favor ERC‑1155 for inventory items.
“How does ERC‑4907 enable a rental marketplace without transferring ownership?” Mention the user field, expiration timestamp, and that the original owner retains the ownerOf rights, allowing the contract to enforce time‑based access.
user
owner
“What security checks does _safeTransfer perform, and why are they important for composability?” Discuss the ERC‑721/1155 receiver interface check (onERC721Received/onERC1155Received) that prevents tokens from being locked in contracts that cannot handle them.
onERC721Received
onERC1155Received
“When auditing an NFT contract, what would you look for regarding royalty enforcement?” Verify that ERC‑2981 is correctly implemented, that the royalty fee is capped (e.g., ≤ 10 %), and that the contract does not allow the creator to change the royalty address after deployment (unless intended).
Scenario: A marketplace calls transferFrom to move a newly minted ERC‑721 token to a buyer, but the buyer’s address is a smart contract that does not implement onERC721Received. Answer: The transfer will succeed, but the token becomes locked because the contract cannot receive it safely. Use safeTransferFrom to avoid this.
Scenario: An ERC‑1155 contract allows anyone to call mintBatch without access control. Answer: This is a critical vulnerability; anyone can create unlimited tokens, diluting scarcity and potentially draining gas from users. Always restrict minting to an admin role (onlyOwner or AccessControl).
mintBatch
onlyOwner
AccessControl
Scenario: A developer sets expires = block.timestamp + 30 days for an ERC‑4907 rental. After 30 days the user still has access. Answer: The contract likely compares expires with block.timestamp incorrectly (e.g., using > instead of <). Fix the logic so the user is cleared when block.timestamp >= expires.
expires = block.timestamp + 30 days
expires
block.timestamp
>
<
block.timestamp >= expires
tx.origin
ipfs://
ar://
SafeMath
uint256
hardhat network reset
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.