Bird
Raised Fist0
Blockchain / Solidityprogramming~10 mins

ERC-721 implementation in Blockchain / Solidity - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - ERC-721 implementation
Contract Start
↓
Define ERC-721 Interface
↓
Implement Metadata Functions
↓
Manage Token Ownership Mapping
↓
Implement Transfer Functions
↓
Mint New Tokens
↓
Burn Tokens
↓
Contract End
This flow shows the main steps in creating an ERC-721 contract: starting the contract, defining interfaces, managing ownership, enabling transfers, minting, and burning tokens.
Execution Sample
Blockchain / Solidity
pragma solidity ^0.8.0;

contract SimpleERC721 {
    mapping(uint256 => address) private _owners;
    function ownerOf(uint256 tokenId) public view returns (address) {
        return _owners[tokenId];
    }
}
This code defines a simple ERC-721 contract with a mapping to track token owners and a function to get the owner of a token.
Execution Table
StepActionVariable/FunctionInputState ChangeOutput
1Contract deployed_ownersemptymapping initialized emptynone
2Mint tokenminttokenId=1, to=0xABC_owners[1] = 0xABCnone
3Call ownerOfownerOftokenId=1no change0xABC
4Mint tokenminttokenId=2, to=0xDEF_owners[2] = 0xDEFnone
5Call ownerOfownerOftokenId=2no change0xDEF
6Transfer tokentransferFromfrom=0xABC, to=0x123, tokenId=1_owners[1] = 0x123none
7Call ownerOfownerOftokenId=1no change0x123
8Burn tokenburntokenId=2delete _owners[2]none
9Call ownerOfownerOftokenId=2no changeaddress(0) (no owner)
10EndN/AN/AN/AExecution complete
💡 Execution stops after all steps complete; tokens minted, transferred, and burned as shown.
Variable Tracker
VariableStartAfter Step 2After Step 4After Step 6After Step 8Final
_owners[1]empty0xABC0xABC0x1230x1230x123
_owners[2]emptyempty0xDEF0xDEFemptyempty
Key Moments - 3 Insights
Why does ownerOf return address(0) after burning a token?
Because burning deletes the token's owner from the _owners mapping, so ownerOf returns the default zero address as shown in step 9.
How does transferFrom update ownership?
In step 6, transferFrom changes _owners[tokenId] from the old owner to the new owner, updating the mapping accordingly.
What happens if you call ownerOf for a token that was never minted?
It returns address(0) because the token ID is not in the _owners mapping, similar to a burned token as shown in step 9.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the owner of tokenId 1 after step 6?
A0x123
B0xABC
C0xDEF
Daddress(0)
💡 Hint
Check the 'State Change' column at step 6 where _owners[1] is updated to 0x123.
At which step does the owner of tokenId 2 become address(0)?
AStep 4
BStep 8
CStep 9
DStep 6
💡 Hint
Look at step 9 where ownerOf returns address(0) after the burn in step 8.
If we mint tokenId 3 to 0x999 at step 11, what will _owners[3] be after that?
Aempty
Baddress(0)
C0x999
D0x123
💡 Hint
Minting sets _owners[tokenId] to the new owner address, as shown in steps 2 and 4.
Concept Snapshot
ERC-721 is a standard for unique tokens.
Key parts: owner mapping, transfer functions, mint and burn.
ownerOf(tokenId) returns owner address or zero if none.
transferFrom changes ownership.
mint assigns new tokens.
burn deletes tokens.
Full Transcript
This visual execution traces a simple ERC-721 contract in Solidity. It starts with an empty ownership mapping. Minting tokens assigns owners to token IDs. ownerOf returns the current owner or zero address if none. Transferring tokens updates the owner mapping. Burning tokens removes ownership, making ownerOf return zero address. The execution table shows each step's action and state changes. Variable tracking highlights how ownership changes over time. Key moments clarify common confusions about ownership after burning and transfers. The quiz tests understanding of ownership at different steps. This helps beginners see how ERC-721 token ownership is managed step-by-step.

Practice

(1/5)
1.

What is the main purpose of the ERC-721 standard in blockchain?

easy
A. To create fungible tokens like cryptocurrencies
B. To manage smart contract ownership
C. To create unique, non-fungible tokens (NFTs)
D. To enable fast transaction processing

Solution

  1. Step 1: Understand ERC-721 token type

    ERC-721 defines a standard for unique tokens, unlike fungible tokens which are identical.
  2. Step 2: Identify the purpose of ERC-721

    It is used to create NFTs, which are unique digital assets on the blockchain.
  3. Final Answer:

    To create unique, non-fungible tokens (NFTs) -> Option C
  4. Quick Check:

    ERC-721 = Unique NFTs [OK]
Hint: ERC-721 is for unique tokens, not identical ones [OK]
Common Mistakes:
  • Confusing ERC-721 with ERC-20 fungible tokens
  • Thinking ERC-721 manages contract ownership
  • Assuming ERC-721 speeds up transactions
2.

Which of the following is the correct way to inherit OpenZeppelin's ERC721 contract in Solidity?

contract MyNFT is ? {}
easy
A. SafeMath
B. ERC721
C. Ownable
D. ERC20

Solution

  1. Step 1: Identify the correct base contract for NFTs

    ERC721 is the OpenZeppelin contract for NFTs, ERC20 is for fungible tokens.
  2. Step 2: Confirm inheritance syntax

    Using is ERC721 correctly inherits the NFT functionality.
  3. Final Answer:

    ERC721 -> Option B
  4. Quick Check:

    Inherit ERC721 for NFTs [OK]
Hint: Use ERC721 to inherit NFT features [OK]
Common Mistakes:
  • Using ERC20 instead of ERC721
  • Confusing Ownable with ERC721
  • Trying to inherit SafeMath for NFTs
3.

What will be the output of the following Solidity function when called?

function mintToken(address to, uint256 tokenId) public {
    _mint(to, tokenId);
}

// Assume _mint works as expected and tokenId = 1, to = 0x123...

What happens after calling mintToken(0x123..., 1)?

medium
A. A new NFT with tokenId 1 is assigned to address 0x123...
B. The tokenId 1 is burned from address 0x123...
C. The function throws a syntax error
D. The tokenId 1 is transferred from 0x123... to the caller

Solution

  1. Step 1: Understand the _mint function

    _mint creates a new token with the given tokenId and assigns it to the 'to' address.
  2. Step 2: Analyze the function call

    Calling mintToken with address 0x123... and tokenId 1 creates that NFT for 0x123....
  3. Final Answer:

    A new NFT with tokenId 1 is assigned to address 0x123... -> Option A
  4. Quick Check:

    mintToken creates NFT for 'to' address [OK]
Hint: _mint assigns new token to given address [OK]
Common Mistakes:
  • Thinking _mint burns tokens
  • Assuming _mint transfers tokens
  • Expecting syntax errors from correct code
4.

Identify the error in this Solidity snippet for minting an ERC-721 token:

function mint(address to, uint256 tokenId) public {
    _mint(tokenId, to);
}

medium
A. Function must be named mintToken, not mint
B. _mint cannot be called inside a public function
C. tokenId must be a string, not uint256
D. _mint parameters are reversed; should be (to, tokenId)

Solution

  1. Step 1: Check _mint function parameter order

    OpenZeppelin's _mint expects (address to, uint256 tokenId).
  2. Step 2: Compare with given code

    The code uses _mint(tokenId, to), reversing the parameters.
  3. Final Answer:

    _mint parameters are reversed; should be (to, tokenId) -> Option D
  4. Quick Check:

    _mint(to, tokenId) correct order [OK]
Hint: _mint needs (address, tokenId) order [OK]
Common Mistakes:
  • Swapping parameters of _mint
  • Thinking _mint can't be public
  • Confusing tokenId type
5.

You want to create an ERC-721 contract that only allows the contract owner to mint new tokens. Which of these Solidity code snippets correctly enforces this?

contract MyNFT is ERC721, Ownable {
    function mint(address to, uint256 tokenId) public {
        ?
        _mint(to, tokenId);
    }
}
hard
A. require(msg.sender == owner(), "Not owner");
B. require(to == owner(), "Not owner");
C. require(tokenId > 0, "Invalid tokenId");
D. require(msg.sender != owner(), "Owner cannot mint");

Solution

  1. Step 1: Understand ownership check

    Only the contract owner should mint, so check if msg.sender equals owner().
  2. Step 2: Analyze each require statement

    require(msg.sender == owner(), "Not owner"); correctly checks sender is owner; others check wrong conditions.
  3. Final Answer:

    require(msg.sender == owner(), "Not owner"); -> Option A
  4. Quick Check:

    Owner check uses msg.sender == owner() [OK]
Hint: Check msg.sender equals owner() before minting [OK]
Common Mistakes:
  • Checking 'to' address instead of sender
  • Allowing anyone to mint without checks
  • Using wrong require conditions
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard