链上拥有,是某地址按合约规则控制代币记录。
它可以被全网验证,但不自动等于拥有图片文件、现实物品或著作权。
Chapter 13 · NFT
因为 NFT 不是“防复制图片”。它是一套由智能合约维护的可识别、可授权、可转移的链上记录; 图片、元数据、版权与市场,只是与这条记录连接的不同层。
它可以被全网验证,但不自动等于拥有图片文件、现实物品或著作权。
钱包和市场因为读得懂相同函数与事件,才可以共同展示和转移不同项目的 NFT。
挂单签名、合约授权和购买交易是三件事;每一步承担不同风险。
Mental model
当钱包展示一张 NFT 图片时,你看到的是多套系统合作后的结果,不是“图片被放进钱包”。
钱包先连接以太坊节点,读取某个 NFT 合约的状态;合约告诉它某个 tokenId 由谁控制,
还可能返回一条元数据 URI;钱包再取得 JSON 元数据,最后根据其中的
image 或 animation_url 加载媒体。
本课最小定义: NFT 是智能合约中一个可被识别并按规则转移的代币记录。 “非同质化”说的是记录的身份与替代关系,不是在宣称它天然稀有、昂贵、原创或永远可用。
NFT 身份 = chainId + contract address + tokenId
Fungibility
同质化讨论“数量”;非同质化讨论“哪一个”。
你的一枚 ETH 与别人的一枚 ETH,在协议记账时可以按相同单位相加。NFT 则需要 tokenId 来区分具体记录:一张编号座位、一份证书、一个游戏角色或一项会员资格, 都可能因为身份、历史与属性不同而不能被任意一枚同类代币等价替换。
| 问题 | 同质化资产 | 非同质化资产 |
|---|---|---|
| 核心查询 | 这个地址有多少单位? | 这个具体 tokenId 由谁控制? |
| 最小状态 | balance[address] = amount | owner[tokenId] = address |
| 互换关系 | 同一标准单位通常等价 | 每个身份可以有不同属性、历史或权利 |
| 价值含义 | 标准只定义记账与转移接口,不定义市场价格。 | |
Interactive · Identity
切换条件,观察真正决定身份的字段
同一枚 NFT:网络、合约地址与 tokenId 都相同;媒体和当前所有者不是身份主键。
Ownership layers
“我拥有这个 NFT”至少可能混合四个不同命题。先拆层,才知道哪一层由谁保证。
链上所有权是最明确的一层:标准合约可以回答某个 tokenId 的 owner,或某地址对某类 ERC-1155 代币的余额。至于名称、图片、文件可用性、商用许可、线下兑换与会员服务, 都要沿着数据和协议继续检查。
Interactive · Failure path
“NFT 还在”与“内容还能看”可以同时一真一假
四层目前都可用,但它们仍由不同机制保障:共识、合约代码、内容存储和外部协议不能画成等号。
通常由合约状态与账户签名决定,可以通过节点独立查询。
URI、内容哈希和存储节点分别回答“指向哪里”“字节是否相同”“现在能否取得”。
要看许可证、发行条款与适用法律;代币转移本身不自动写出这些权利。
ERC-721
ERC-721 统一了“查询、授权、转移与事件”这组接口,让任何兼容钱包和市场都能用同一种语言操作不同 NFT 合约。
标准的核心不是图片,而是 ownerOf(tokenId):
它返回当前被合约认可的所有者地址。balanceOf(owner) 只告诉你这个地址持有几枚,
不告诉你分别是哪几个 tokenId;枚举通常需要事件索引或可选扩展。
[1]
实现通常把 #42 的 owner 写成 Alice,并发出从零地址来的 Transfer 事件。
Transfer(0x0, Alice, 42)
owner 不变;只是给某地址单枚权限,或给 operator 该集合的管理权限。
approve(Market, 42)
调用者必须是 owner、单枚获批者或已获批 operator;转移后单枚 approval 被清除。
Transfer(Alice, Bob, 42)
burn 不是 ERC-721 核心函数名要求,但实现常用转往零地址的事件语义表示销毁。
Transfer(Bob, 0x0, 42)
ownerOf(id)对有效 tokenId 返回一个地址,是 ERC-721 所有权判断的核心入口。
safeTransferFrom接收方若是合约,需要返回规定的接收确认值,否则交易回滚,避免代币被锁进不兼容合约。
approve给一个地址移动指定 tokenId 的权限;该单枚授权在转移时被重置。
setApprovalForAll允许 operator 管理该 owner 在这一个 NFT 合约内的全部代币,不是整个钱包的所有 NFT。
tokenURI(id)属于可选元数据扩展;返回 URI,不保证 URI 内容不可变或永久在线。
supportsInterface通过 ERC-165 查询接口支持情况,帮助应用识别 ERC-721、元数据扩展等能力。
setApprovalForAll 的范围可能覆盖你在同一集合合约里的每一枚代币。
签名前必须核对 operator 地址、合约地址与撤销路径;“只是连接钱包”不需要这种权限。
safeTransferFrom 只检查接收合约是否按接口表示“会接收”,
不验证交易价格、公平性、项目真实性、元数据质量或版权。
ERC-1155
ERC-1155 不再假设“一个 tokenId 只对应一个 owner”,而是记录“某地址持有这个 id 的多少份”。
同一合约里,id 100 可以代表只发行 1 份的传奇道具,id 200 可以代表发行 500 份的入场券, id 300 还可以代表可堆叠的 20 瓶药水。标准允许同一合约管理同质化、半同质化与非同质化资产, 但不会替项目替你定义每个 id 的经济含义。 [2]
项目约定总量为 1,可作为非同质化对象使用。
Alice × 1同一批次 500 份;每份在当前规则下可以互换。
Alice × 3可堆叠消耗品;合约直接记录每个地址的数量。
Alice × 20Interactive · State model
切换标准,比较身份、余额与转移参数
查询 #42 时,核心问题是 ownerOf(42) 返回哪个地址。
ownerOf[42] = Alice
函数参数包含 from、to 与 tokenId,不包含“转几份”。
safeTransferFrom(Alice, Bob, 42)
ERC-721 的非同质化来自每个 tokenId 的独立身份;同一 tokenId 在正常状态下只有一个 owner。
| 维度 | ERC-721 | ERC-1155 |
|---|---|---|
| 核心状态 | ownerOf(id) | balanceOf(account, id) |
| 一个 id 的持有人 | 一个当前 owner | 可以有多个地址,各自持有不同数量 |
| 一个合约的资产类型 | 通常一个 NFT 集合 | 可以包含多种 id 与多种数量模型 |
| 批量操作 | 核心标准没有批量转移 | 提供 safeBatchTransferFrom 与 balanceOfBatch |
| 接收保护 | ERC721Receiver 回调 | ERC1155TokenReceiver 单笔或批量回调 |
| 授权粒度 | 单枚 approve + 集合 operator | 标准核心采用 operator 全局授权(针对该 1155 合约) |
Metadata & storage
多数 NFT 合约不把原始图片字节直接塞进每个 token 的链上存储,而是返回一条元数据 URI。
ERC-721 的可选元数据扩展定义了 tokenURI(tokenId);
这条 URI 可以指向 JSON,JSON 再用 image 指向媒体。
因此“合约在链上”不能自动推出“图片也在链上”。
[1]
ERC-1155 使用元数据扩展的 uri(id)。返回模板如果含有
{id},客户端必须把它替换成不带 0x、使用小写字母、左侧补零到
64 位的十六进制 token id。例如十进制 42 会以末尾
…002a 的 64 位形式进入 URI。这个规则让同一合约的不同 id
能共用一套路径模板。
[2]
{
"name": "Orbit Key #42",
"description": "一枚教学示例 NFT",
"image": "ipfs://bafy…/art.png",
"attributes": [
{ "trait_type": "Tier", "value": "Genesis" }
]
}
容易部署与更新,但域名、服务器、权限或文件路径变化会影响访问;同一 URL 的内容也可能被替换。
CID 由内容产生,字节改变通常意味着 CID 改变;但 CID 不是存储位置,也不保证永远有人提供这些字节。
把元数据或生成逻辑直接写入链上,能减少外部存储依赖,但通常更昂贵,也仍需检查升级与渲染逻辑。
非同质化指的是代币身份,不要求画面永远不变。同一枚 token 可以按链上状态、游戏进度或外部数据改变元数据。 关键不是“会不会变”,而是谁能触发变化、依据什么数据、变化规则是否可验证、管理员能否绕过规则。
NFT marketplace
一个 NFT 市场不是一份“商品数据库”,而是前端、索引器、订单系统与结算合约的组合。
常见设计里,挂单是一份由卖家签名的订单:它可以在链下传播,不会立即转移 NFT。 买家提交履约交易后,结算合约才验证签名、所有权、授权、时间与订单状态, 并在同一笔交易里交换 NFT 与付款。具体协议也可能采用链上挂单、托管或拍卖,所以不要把一种流程当成唯一实现。 [7]
Interactive · Settlement
挂单不是转移 · 结算才改状态
索引器读取合约事件与当前状态,取得 tokenId、owner 和元数据,再把可搜索页面展示给用户。页面不是所有权来源。
连接钱包网站能请求账户信息;单纯连接本身不应给出 NFT 转移权限。
授权 operator通常是链上交易,需要 Gas;范围与撤销方式由代币标准和合约决定。
签署订单许多协议把订单签名放在链下,因此挂单本身可能不花 Gas,但签名仍有法律与资产安全含义。
履约交易结算合约检查订单尚未过期、取消或成交,并验证 owner 与 approval 仍满足条件。
原子交换在同一笔交易中移动 NFT 与付款;任一关键检查失败,整个调用回滚。
事件索引成交后市场根据 Transfer 与协议事件更新页面;显示延迟不改变链上最终状态。
成交金额可能被拆成卖家所得、市场费用与创作者版税。ERC-2981 只标准化
royaltyInfo(tokenId, salePrice) 的查询方式,告诉市场“建议付给谁、多少”;
标准本身不能强制每次普通转移都支付版税,因为转移不一定代表销售。
支付仍依赖市场是否实现并尊重该机制。
[4]
Claims & boundaries
区块链擅长证明“某合约按自己的规则记录了什么”,不擅长凭空证明现实世界的作者、真品、版权与价格。
可推出:该合约当前把这一 tokenId 记在你的地址下。
链上可验证CID 能校验内容,但仍要有人继续保存与提供数据。
结论过度是否获得复制、改编、商用等权利取决于许可或转让协议。
需外部协议图片可复制;应核对网络、合约、tokenId、发行方与铸造来源。
身份不足还可能有其他合约、相同媒体、衍生版本或可改变的铸造权限。
范围不足版税信息可被标准化表达,但支付是否发生仍依赖成交路径与市场执行。
不自动强制仿冒合约可以复制名称、图片和描述;品牌官网、已知部署地址与铸造历史才是额外证据。
恶意 operator、钓鱼签名或危险订单可获得转移能力;连接、签名与链上授权必须分别识别。
代码漏洞、升级代理、管理员权限、铸造上限与暂停开关都会改变“规则不会变”的假设。
服务器下线、未 pin 的 IPFS 内容、可变 baseURI 或渲染服务失效,会让代币仍在但展示改变。
货币单位、价格小数、有效期、费用、买卖方向或捆绑资产理解错误,都可能造成不可逆成交。
链上所有权不创造买家。地板价、历史成交与挂单深度都不保证你能按预期价格退出。
更精确的“数字所有权”: 你能够用账户授权去控制一条公开状态记录,第三方可以按相同合约规则独立验证, 并且这条记录可以被其他兼容应用读取与转移。它是可验证的协议控制权,不是对一切关联事物的总括所有权。
Verification checklist
不先问“会涨吗”,先问“我究竟在验证哪一层”。下面这张清单既适合购买前,也适合研究项目时使用。
从第一项开始。勾选只在当前页面内计算,不会保存。
Synthesis
13.01 · Complete
真正成熟的判断不是问“这张图是真是假”,而是依次核对: 这是什么链上的哪个合约与 tokenId,合约允许谁做什么,元数据与媒体由谁保存, 相关权利如何约定,市场订单又会怎样改变状态。
← 回顾上一课 · DeFi 核心应用如何协作