1、NFT概述:什么是NFT、NFT与FT的区别、NFT的应用场景、ERC-721标准简介

各位同学,欢迎来到《Solidity语言NFT合约编写实战》的第一课。

在正式开始写代码之前,我觉得有必要先把NFT这个概念讲清楚。为什么?因为我见过太多人,代码写得飞起,但问起「NFT到底是什么」,反而支支吾吾。嗯,这其实挺危险的——你连自己在做什么都不清楚,怎么保证合约不出bug?

1.1 什么是NFT?

NFT,全称是Non-Fungible Token,中文叫「非同质化代币」。

说白了,就是「每个都不一样」的数字资产。

你想想看,现实世界里,你手里的1块钱和我手里的1块钱,能互换吗?当然能。它们价值相等,没有区别。这就是「同质化」。

但如果你有一张球星签名卡,我有一张普通卡片,能互换吗?不能。因为每张卡都是独一无二的,价值也不同。这就是「非同质化」。

核心定义:NFT是一种基于区块链的、不可互换的、唯一标识的数字资产。每个NFT都有独立的元数据和所有权记录。

我个人习惯把NFT理解成「数字世界的房产证」。你买的不只是一张图片或一段视频,而是链上那个唯一的所有权记录。图片可以复制,但链上的所有权证明,只有你有。

1.2 NFT与FT的区别

FT(Fungible Token)就是同质化代币,比如ETH、USDT。你手里的1个ETH和我手里的1个ETH,完全一样,可以互换。

那NFT和FT到底差在哪?我列个表,一目了然:

对比维度 FT(同质化代币) NFT(非同质化代币)
可互换性 可以互换,价值相等 不可互换,每个都不同
唯一性 没有唯一标识 每个都有唯一tokenId
可分割性 可分割(如0.1 ETH) 不可分割(最小单位是1个)
标准 ERC-20 ERC-721 / ERC-1155
典型用途 货币、支付、治理 数字艺术品、游戏道具、身份凭证

这里有个坑,我提醒一下:NFT虽然不可分割,但可以通过合约实现「分数化」。比如把一幅画分成10000份,每份代表1/10000的所有权。这在DeFi里很常见,但底层还是ERC-20的逻辑,不是NFT本身可分割。

避坑指南:我曾经在项目中遇到有人把NFT当FT用,试图transfer 0.5个NFT。结果交易直接revert。记住,NFT的最小单位就是1,没有小数。

1.3 NFT的应用场景

说实话,NFT刚火起来那会儿,我也觉得不就是「炒图片」吗?但深入做项目之后才发现,它的应用场景远比想象中广。

我挑几个典型的说说:

  • 数字艺术品与收藏品:这是最广为人知的。CryptoPunks、Bored Ape Yacht Club,都是典型代表。每个头像都是独一无二的,链上可追溯。
  • 游戏道具与虚拟资产:比如Axie Infinity里的宠物、The Sandbox里的土地。玩家真正拥有了游戏资产,而不是被中心化服务器控制。
  • 身份与凭证:比如ENS域名、出席证明(POAP)。这些NFT代表了你某个身份或经历,不可伪造。
  • 实体资产映射:把房产、奢侈品、票据等实体资产上链,变成NFT。嗯,这个方向还在探索,但潜力巨大。
  • 音乐与内容版权:音乐人可以把单曲发行成NFT,粉丝购买后拥有所有权,甚至参与版税分成。

我个人最看好的是「身份凭证」这个方向。你想想看,以后你的学历、工作经历、技能认证,都可以用NFT来证明。造假?不存在的,链上数据改不了。

1.4 ERC-721标准简介

好了,前面都是概念,现在咱们来点实在的——ERC-721。

ERC-721是以太坊上最早、最经典的NFT标准。它定义了NFT合约必须实现哪些接口,让不同项目之间可以互操作。

简单说,ERC-721规定了:

  • 每个NFT都有一个唯一的tokenId(uint256类型)
  • 每个tokenId对应一个所有者
  • 支持转账、授权、查询余额等基本操作

核心接口长这样:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface IERC721 {
    // 查询某个tokenId的所有者
    function ownerOf(uint256 tokenId) external view returns (address);

    // 查询某个地址拥有多少个NFT
    function balanceOf(address owner) external view returns (uint256);

    // 安全转账(带回调检查)
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    // 普通转账
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    // 授权操作
    function approve(address to, uint256 tokenId) external;
    function getApproved(uint256 tokenId) external view returns (address);
    function setApprovalForAll(address operator, bool approved) external;
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

这里有个细节,我特别想强调:safeTransferFrom和transferFrom的区别

safeTransferFrom在转账给合约地址时,会检查目标合约是否实现了onERC721Received接口。如果没有,交易会revert。这能防止NFT被锁死在合约里。

transferFrom不会做这个检查。所以,我个人建议:除非你明确知道自己在做什么,否则永远用safeTransferFrom

小技巧:写合约时,我习惯在内部函数里统一用_safeTransfer(OpenZeppelin提供的封装),这样既安全又省事。

另外,ERC-721还有一个扩展标准叫ERC-721 Metadata,它定义了tokenURI方法,用来返回每个NFT的元数据(比如图片链接、名称、描述)。这个我们后面写合约时会详细讲。

小结

这一章我们聊了NFT是什么、和FT的区别、有哪些应用场景,以及ERC-721标准的核心接口。

嗯,内容不算多,但都是基础中的基础。下一章,我们会真正动手写一个简单的ERC-721合约。到时候你会发现,理解了这些概念,写代码其实没那么难。

记住一句话:NFT的核心不是图片,而是所有权。搞懂这个,你就入门了。


公众号:蓝海资料掘金营,微信 deep3321