NFT Development Certification Exam — Questions and Answers
Question 1: What information from a confirmed transaction receipt can the frontend use to link the user to a block explorer?
- The transaction hash (Correct answer)
- The contract's source code
- The gas oracle URL
- The user's seed phrase
Correct answer: The transaction hash
The transaction hash builds an explorer URL (e.g., etherscan.io/tx/<hash>) for the user to view their mint.
Question 2: When deleting a token-specific royalty, which OpenZeppelin function is used?
- _removeFee
- _burnRoyalty
- _resetTokenRoyalty (Correct answer)
- _clearRoyalty
Correct answer: _resetTokenRoyalty
_resetTokenRoyalty removes a per-token override so the token falls back to the default royalty.
Question 3: Below are NFT's risks and problems, with the except:
- Copyright
- Covid-19 (Correct answer)
- Power Consumption
- Proof of work
Correct answer: Covid-19
Covid-19 is a global health pandemic and not a direct risk or problem inherent to NFT technology or its development. NFT risks and problems typically include high power consumption (especially with Proof of Work blockchains), complex copyright issues regarding digital ownership, and the scalability challenges associated with certain blockchain consensus mechanisms.
Question 4: Which approach attempts stronger royalty enforcement than EIP-2981 alone?
- Increasing the fee denominator
- Disabling supportsInterface
- Transfer-restricting allowlists like operator filters (Correct answer)
- Using ERC-20 instead of ERC-721
Correct answer: Transfer-restricting allowlists like operator filters
Operator filter registries and transfer restrictions try to block non-royalty-honoring marketplaces, going beyond EIP-2981's signaling.
Question 5: Why should an upgradeable NFT contract avoid constructors and use an initializer instead?
- Constructors are banned in Solidity 0.8
- Initializers are cheaper to call
- Constructor code runs in the implementation's context, not the proxy, so proxy state would be uninitialized (Correct answer)
- Constructors cannot accept parameters
Correct answer: Constructor code runs in the implementation's context, not the proxy, so proxy state would be uninitialized
Because the proxy delegatecalls to the implementation, constructor logic never runs in proxy storage, so an initializer function is required.
Question 6: What is a key risk of using transfer instead of safeTransfer to an unaware contract?
- Automatic burning
- Faster confirmation
- Higher gas refunds
- Tokens may become permanently locked (Correct answer)
Correct answer: Tokens may become permanently locked
Sending to a contract that cannot handle tokens without the safe variant can permanently lock them.
Question 7: Why do auditors recommend emitting events on all state-changing NFT functions?
- To enable off-chain monitoring and incident detection (Correct answer)
- To enforce access control
- To reduce gas
- To prevent reentrancy
Correct answer: To enable off-chain monitoring and incident detection
Events provide an auditable, indexable trail that supports monitoring and post-incident analysis.
Question 8: An auditor is using a tool like Echidna or Foundry's fuzzer that automatically generates a large volume of random inputs to test a contract's functions against a set of defined properties (invariants). What type of security analysis is being performed?
- Manual Code Review
- Fuzzing (Dynamic Analysis) (Correct answer)
- Formal Verification
- Static Analysis
Correct answer: Fuzzing (Dynamic Analysis)
This process describes fuzzing, a form of dynamic analysis. Fuzzing tools execute the contract code with a wide range of random or unexpected inputs to find edge cases where the contract's behavior violates predefined rules or properties (e.g., 'the total supply should never decrease').
Question 9: What is a key risk when integrating a marketplace that allows arbitrary external contract calls in order fulfillment?
- Shorter token names
- Higher royalty payouts
- Slower image loading
- Malicious orders could trigger phishing approvals or drain wallets (Correct answer)
Correct answer: Malicious orders could trigger phishing approvals or drain wallets
Allowing arbitrary calls during fulfillment can be abused to trick users into harmful approvals or transfers, so such flows need strict validation.
Question 10: What is an integer overflow risk in a pre-0.8.0 Solidity NFT contract counter?
- A uint wrapping past its max back to zero, potentially resetting token IDs or balances (Correct answer)
- The compiler refusing to deploy
- Metadata URIs being truncated
- Functions becoming view-only
Correct answer: A uint wrapping past its max back to zero, potentially resetting token IDs or balances
Before Solidity 0.8.0, arithmetic wrapped silently, so a counter could overflow and corrupt IDs or accounting.
Question 11: In a Merkle tree allowlist, what must a user provide at mint time to prove they are on the list?
- A signed transaction from the contract owner
- Their wallet's private key signature
- The full array of all allowlisted addresses
- A Merkle proof consisting of sibling hashes along the tree path (Correct answer)
Correct answer: A Merkle proof consisting of sibling hashes along the tree path
A Merkle proof is an array of sibling hashes from the leaf up to the root, enabling anyone to recompute and verify the root without storing the full list on-chain.
Question 12: What is the main security concern with an upgradeable NFT contract using a proxy?
- A compromised admin can change logic, including transfers and ownership (Correct answer)
- Higher royalties
- No metadata support
- Slower transfers
Correct answer: A compromised admin can change logic, including transfers and ownership
Upgradeability concentrates power in the admin/upgrade key, which if compromised can alter contract behavior.
Question 13: When a user rejects the MetaMask signature prompt, what error pattern should the frontend handle gracefully?
- A CSS parse error
- A user-rejection error (code 4001) without treating it as a crash (Correct answer)
- A database timeout
- A 404 not found
Correct answer: A user-rejection error (code 4001) without treating it as a crash
EIP-1193 returns code 4001 for user rejection, which should be handled as a normal cancellation, not a fatal error.
Question 14: Which storage approach makes NFT image data most resistant to disappearing?
- A personal web server
- A single AWS bucket
- Email attachment
- Arweave permanent storage (Correct answer)
Correct answer: Arweave permanent storage
Arweave offers pay-once permanent storage, making hosted assets highly durable.
Question 15: A bulk listing feature signs many orders at once. Which approach lets the user approve them with a single signature?
- Using the buyer's signature instead
- Constructing a Merkle tree of orders and signing the root (Correct answer)
- Skipping signatures entirely
- Signing each order in a separate popup
Correct answer: Constructing a Merkle tree of orders and signing the root
Bulk signing builds a Merkle tree of order hashes so one signature over the root authorizes all included orders.
Question 16: Why is hardcoding a contract ABI's full source unnecessary, and a minimal 'human-readable ABI' often sufficient on the frontend?
- The full ABI breaks MetaMask
- Only the function and event signatures the app calls are needed to encode/decode calls (Correct answer)
- ABIs are illegal to include
- ABIs must be base64 only
Correct answer: Only the function and event signatures the app calls are needed to encode/decode calls
The frontend only needs the signatures of the functions and events it interacts with to encode calls.
Question 17: In an allowlist mint, what data structure efficiently verifies eligibility on-chain with minimal storage?
- A mapping of all addresses to true
- A Merkle tree with the root stored on-chain (Correct answer)
- A full array of every allowed address
- An off-chain JSON file only
Correct answer: A Merkle tree with the root stored on-chain
A Merkle root lets the contract verify membership proofs without storing every address.
Question 18: A contract calls safeTransferFrom to a recipient contract that returns the wrong magic value. What happens?
- The transfer reverts (Correct answer)
- Transfer succeeds silently
- The token is burned
- Gas is refunded fully
Correct answer: The transfer reverts
If onERC721Received/onERC1155Received doesn't return the expected selector, the transfer reverts.
Question 19: Which of the following frontend updates is best implemented by listening for a `Transfer` event from the NFT smart contract?
- Displaying a 'Mint Successful!' message and the new token ID immediately after the transaction is confirmed on the blockchain. (Correct answer)
- Confirming the user has enough ETH to cover the minting cost and gas.
- Showing the total supply of the NFT collection.
- Enabling the 'Mint' button only after the user connects their wallet.
Correct answer: Displaying a 'Mint Successful!' message and the new token ID immediately after the transaction is confirmed on the blockchain.
Smart contract events, like the standard ERC-721 `Transfer` event, are the ideal mechanism for a frontend to react to state changes on the blockchain. By listening for this event, the dApp can get immediate confirmation when the mint transaction is successfully mined, and it can receive data from the event (like the new `tokenId`) to update the UI without requiring the user to refresh the page.
Question 20: What problem does the ERC-721 Enumerable extension solve?
- Metadata encryption
- Gas-free transfers
- Listing all tokens and tokens owned by an address on-chain (Correct answer)
- Royalty payments
Correct answer: Listing all tokens and tokens owned by an address on-chain
ERC721Enumerable adds totalSupply and indexing so tokens can be enumerated on-chain.
Question 21: A developer is migrating a project from ERC-721 to ERC-1155 to save on transaction costs. What is the primary architectural change they will leverage in the ERC-1155 standard to achieve this?
- Removing the approval mechanism to reduce function calls.
- Utilizing the `safeBatchTransferFrom` function to transfer multiple token types in a single transaction. (Correct answer)
- Deploying a separate smart contract for each token type.
- Implementing a more complex metadata JSON structure.
Correct answer: Utilizing the `safeBatchTransferFrom` function to transfer multiple token types in a single transaction.
The core advantage of ERC-1155 for gas savings is its batch functionality. Functions like `safeBatchTransferFrom` allow multiple different tokens (or quantities of the same token) to be sent in a single atomic transaction, significantly reducing the gas cost compared to the one-by-one transfers required by ERC-721.
Question 22: What is 'lazy minting' in NFT development?
- Deferring on-chain minting until the first purchase or claim (Correct answer)
- Minting tokens on a testnet before mainnet
- Minting tokens without any metadata
- Pre-minting all tokens at contract deployment
Correct answer: Deferring on-chain minting until the first purchase or claim
Lazy minting defers the actual on-chain transaction until a buyer claims the NFT, so the creator avoids upfront gas costs.
Question 23: An artist mints a 1-of-1 artwork with rich provenance and per-token metadata. Which standard is most conventional?
- ERC-721A only
- ERC-1155
- ERC-20
- ERC-721 (Correct answer)
Correct answer: ERC-721
ERC-721 is the conventional choice for unique 1-of-1 collectibles with distinct metadata.
Question 24: A developer is implementing EIP-2981 for an NFT collection. A marketplace needs to determine the royalty payment for a token with `tokenId` 789 that just sold for 10 ETH. Which function signature must the marketplace call on the NFT contract to get this information?
- calculateRoyalty(uint256 _tokenId, uint256 _salePrice, address _currency) external view returns (uint256 royaltyAmount)
- onSale(uint256 _tokenId, uint256 _salePrice) external payable
- getRoyalty(uint256 _tokenId) external view returns (address receiver, uint256 percentage)
- royaltyInfo(uint256 _tokenId, uint256 _salePrice) external view returns (address receiver, uint256 royaltyAmount) (Correct answer)
Correct answer: royaltyInfo(uint256 _tokenId, uint256 _salePrice) external view returns (address receiver, uint256 royaltyAmount)
EIP-2981 specifies a single, universal function, `royaltyInfo`, which takes the token ID and the total sale price as inputs. It returns the address that should receive the royalty and the absolute amount of the royalty to be paid.
Question 25: A reviewer flags that an NFT contract's owner can change the metadata base URI at any time. What is the primary concern?
- Reentrancy
- Gas griefing
- Stack too deep error
- Centralization / rug-pull risk on immutable assets (Correct answer)
Correct answer: Centralization / rug-pull risk on immutable assets
Mutable metadata controlled by a single owner undermines the claimed immutability of the NFT and is a centralization risk.
Question 26: Which of the following describes a 'lazy minting' process in the context of NFTs?
- A function that allows the contract owner to mint tokens with a single transaction but delays their delivery to the recipient.
- A minting process that is intentionally slowed down by the contract to prevent bots.
- The NFT's metadata is created, but the on-chain token is only minted when the first purchase or transfer occurs. (Correct answer)
- Minting NFTs directly to a Layer 2 network to be bridged to the mainnet later.
Correct answer: The NFT's metadata is created, but the on-chain token is only minted when the first purchase or transfer occurs.
Lazy minting is a technique where the expensive on-chain minting transaction is deferred until the moment of the first sale. The NFT's data and a signed voucher from the creator are stored off-chain. The first buyer pays the gas fee to execute the minting function, which verifies the signature and creates the token on their behalf, saving the creator from having to pay gas upfront for unsold items.
Question 27: Why is hardcoding a privileged owner address without a transfer/renounce mechanism risky?
- It disables event logging
- A compromised or lost key permanently controls or bricks the contract with no recovery path (Correct answer)
- It forces all functions to be payable
- It makes the contract larger than the size limit
Correct answer: A compromised or lost key permanently controls or bricks the contract with no recovery path
Without ownership transfer or renounce functions, a lost or stolen key leaves the contract permanently mismanaged.
Question 28: An NFT contract's royalty logic relies on an unbounded loop over all token holders. What audit finding does this represent?
- Signature replay
- Denial-of-service via gas limit (Correct answer)
- Front-running
- Integer overflow
Correct answer: Denial-of-service via gas limit
Unbounded loops can exceed the block gas limit, causing transactions to permanently fail and locking functionality.
Question 29: Which approach helps reduce gas costs when minting many NFTs at once?
- Batch minting using ERC-1155 or ERC721A (Correct answer)
- Using more events
- Increasing the gas limit only
- Minting each in a separate transaction
Correct answer: Batch minting using ERC-1155 or ERC721A
Batch-minting standards like ERC721A and ERC-1155 optimize storage writes to lower per-token gas costs.
Question 30: Which standard's balanceOf takes only an address and returns a count of owned tokens?
- ERC-721 (Correct answer)
- ERC-165
- ERC-1820
- ERC-1155
Correct answer: ERC-721
ERC-721 balanceOf(owner) returns how many tokens an address owns; ERC-1155 also needs a token ID.
Question 31: The Ethereum platform has the advantages listed below, except?
- Alternate Cash Settlements (Correct answer)
- Smart Contracts
Correct answer: Alternate Cash Settlements
The Ethereum platform's primary advantages include its robust support for Smart Contracts, which enable decentralized applications and automated agreements. While it facilitates transactions, 'Alternate Cash Settlements' is not a specific, defining advantage of Ethereum. Its strength lies in its programmable blockchain capabilities, not just alternative payment methods.
Question 32: Why is using block.timestamp or blockhash for NFT trait randomness considered insecure?
- It is not supported in Solidity
- Miners or validators can influence or predict it (Correct answer)
- It costs too much gas
- It is too slow
Correct answer: Miners or validators can influence or predict it
On-chain values like blockhash are predictable or manipulable, so a service like Chainlink VRF is preferred.
Question 33: After a user mints an NFT with token ID 77, the frontend needs to display its image. What is the standard, two-step process for retrieving this image URL?
- Call the `tokenURI(77)` function on the contract, then make an HTTP/IPFS request to the returned URI to fetch and parse the metadata JSON. (Correct answer)
- Call a `getImage(77)` function on the contract, then append the result to 'https://ipfs.io/ipfs/'.
- Make an HTTP request to `[contract_address]/77.json`, then parse the `image` field.
- Query the blockchain for transaction logs of token 77 to find the image data.
Correct answer: Call the `tokenURI(77)` function on the contract, then make an HTTP/IPFS request to the returned URI to fetch and parse the metadata JSON.
The standard ERC-721 and ERC-1155 patterns involve calling a `tokenURI` (or `uri`) function with the token ID. This function returns a URL (often an IPFS or HTTPS link) that points to a JSON metadata file. The frontend must then fetch this JSON file, parse it, and extract the value of the `image` key to get the final, displayable image URL.
Question 34: What is the benefit of using a dedicated RPC provider (e.g., Alchemy/Infura) for read calls instead of relying only on the injected wallet provider?
- It mints NFTs faster
- Higher reliability and rate limits for data reads independent of the user's wallet (Correct answer)
- It encrypts the user's seed phrase
- It removes the need for a signer on writes
Correct answer: Higher reliability and rate limits for data reads independent of the user's wallet
Dedicated RPC providers offer reliable, higher-throughput reads decoupled from the user's wallet connection.
Question 35: What is 'minting' an NFT?
- Selling a token on a marketplace
- Creating a new token and recording it on-chain (Correct answer)
- Approving a transfer
- Burning a token permanently
Correct answer: Creating a new token and recording it on-chain
Minting is the process of generating a new token and writing it to the blockchain.
Question 36: Why is on-chain (fully generative) NFT art notable compared to off-chain images?
- It is always soulbound
- It costs no gas
- The artwork is generated and stored entirely on the blockchain (Correct answer)
- It cannot have royalties
Correct answer: The artwork is generated and stored entirely on the blockchain
On-chain art stores the generative logic/data on-chain, removing dependence on external hosting.
Question 37: Can you purchase NFTs with bitcoin?
- No (Correct answer)
- Yes
Correct answer: No
No, you cannot directly purchase NFTs with Bitcoin. Most NFTs are created and traded on the Ethereum blockchain or other compatible networks that use their native cryptocurrencies. To buy an NFT, you would typically need to use Ethereum (ETH) or another supported cryptocurrency, often requiring a conversion from Bitcoin first.
Question 38: An ERC-721 contract uses _mint instead of _safeMint in a public function. Why might an auditor flag this?
- _mint is deprecated
- _mint costs more gas
- _mint cannot set token URIs
- _mint skips the onERC721Received recipient check (Correct answer)
Correct answer: _mint skips the onERC721Received recipient check
_safeMint verifies contract recipients can handle NFTs, while _mint can send tokens to contracts that will lock them.
Question 39: Which gas consideration favors a default royalty over per-token royalties?
- Per-token data is never stored
- A default avoids writing storage for every token (Correct answer)
- Defaults require more storage slots
- Per-token royalties are free to set
Correct answer: A default avoids writing storage for every token
Using a single default avoids the storage write cost of recording a royalty for each individual token.
Question 40: How does OpenZeppelin let you override royalties for one specific token?
- _setTokenRoyalty (Correct answer)
- _overrideFee
- setTokenURI
- _mintWithRoyalty
Correct answer: _setTokenRoyalty
_setTokenRoyalty assigns a per-token receiver and fee that takes precedence over the default.
Question 41: What is a front-running risk when revealing NFT metadata after a mint?
- The token supply doubles
- The reveal transaction will always revert
- Metadata gets stored twice
- Observers can read pending reveal transactions and snipe rare tokens before reveal (Correct answer)
Correct answer: Observers can read pending reveal transactions and snipe rare tokens before reveal
If rarity can be computed from a pending reveal, attackers can front-run to acquire or avoid specific tokens.
Question 42: When implementing a burn function that should permanently reduce supply, why avoid reusing burned tokenIds?
- It increases royalties
- Reusing ids can confuse provenance and off-chain indexers (Correct answer)
- It causes the contract to self-destruct
- Burned ids automatically re-mint
Correct answer: Reusing ids can confuse provenance and off-chain indexers
Reusing burned ids breaks token history and confuses marketplaces and indexers tracking provenance.
Question 43: What is the main advantage of lazy minting?
- Minting gas is deferred until first purchase (Correct answer)
- Tokens mint automatically each block
- It prevents all royalties
- It removes the need for metadata
Correct answer: Minting gas is deferred until first purchase
Lazy minting defers the on-chain mint (and its gas) until a buyer actually purchases the NFT.
Question 44: If royaltyInfo is called with a salePrice of 0, what royaltyAmount results with a percentage-based implementation?
- The denominator value
- It reverts
- The full default fee
- 0 (Correct answer)
Correct answer: 0
A percentage of zero is zero, so a zero sale price yields a zero royalty amount.
Question 45: What does a 'proxy pattern' enable in smart contract development?
- Upgrading contract logic while preserving state and address (Correct answer)
- Bypassing gas fees
- Reducing the token supply automatically
- Hiding the contract from explorers
Correct answer: Upgrading contract logic while preserving state and address
Proxy patterns separate storage from logic, allowing the logic contract to be upgraded without losing data or changing the address.
Question 46: A marketplace honoring EIP-2981 typically calls royaltyInfo at what point?
- When the NFT is burned
- Never; it guesses the amount
- During sale settlement to compute and route the royalty (Correct answer)
- Only at mint time
Correct answer: During sale settlement to compute and route the royalty
Compliant marketplaces query royaltyInfo at sale time to determine how much to pay the receiver.
Question 47: When a creator wants royalties paid in the sale currency (e.g., USDC), how does EIP-2981 handle it?
- royaltyAmount is in the same unit as the salePrice the marketplace passes (Correct answer)
- It requires a separate currency parameter
- It rejects non-ETH sales
- It always converts to ETH
Correct answer: royaltyAmount is in the same unit as the salePrice the marketplace passes
Because the amount matches the salePrice unit, passing a USDC salePrice yields a USDC-denominated royalty.
Question 48: A developer lists an NFT for sale but the marketplace cannot transfer it on completion. What is the most likely cause?
- The token ID is even instead of odd
- The marketplace operator was never granted approval via setApprovalForAll or approve (Correct answer)
- The buyer used the wrong wallet color
- The NFT has no name
Correct answer: The marketplace operator was never granted approval via setApprovalForAll or approve
Without an approval granted to the marketplace contract, it lacks permission to transfer the token to the buyer.
Question 49: What is the purpose of listening to a contract's 'Transfer' event after a mint transaction confirms on the frontend?
- To compile Solidity
- To detect the newly minted tokenId and update the UI (Correct answer)
- To pay gas fees
- To deploy the contract
Correct answer: To detect the newly minted tokenId and update the UI
The Transfer event from the zero address signals a mint and exposes the new tokenId for UI updates.
Question 50: What is the purpose of a reentrancy guard (e.g., nonReentrant) in an NFT auction contract?
- Prevent nested calls from re-entering before state finalizes (Correct answer)
- Reduce gas costs
- Enable upgradeability
- Validate signatures
Correct answer: Prevent nested calls from re-entering before state finalizes
A reentrancy guard uses a mutex to block a function from being re-entered during an external call.
NFT Development Certification Exam
The NFT Development Certification Exam exam validates essential knowledge and skills required for certification or licensure in this field.
Exam Rules
- You can skip questions and return to them later
- Flag questions for review before submitting
- No feedback shown until you submit the entire exam
- Unanswered questions count as wrong — answer everything
- 10 pretest questions are mixed in and don't affect your score
- Timer auto-submits when time runs out
- Your progress is auto-saved every 30 seconds