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