3. Solana 上的 NFT 架构

Solana NFT 架构深度解析

在以太坊上,一个 NFT 通常只是 ERC-721 合约中的一个 ID。但在 Solana 上,由于采用账户模型程序复用的设计哲学,NFT 的架构要复杂得多,但也更加灵活。

一个完整的 Solana NFT 实际上是由多个账户组合而成的。理解这些账户之间的连接关系是开发的关键。


1. 底层构建块:SPL Token 层

Solana 的 NFT 建立在 SPL Token Program 之上。 这意味着在最底层,NFT 依然是一个标准的 Token,只是参数设置比较特殊。

核心账户组件

┌─────────────────────────────────────────────────────────┐ │ SPL Token 层 │ ├─────────────────────────────────────────────────────────┤ │ Mint Account (铸币账户) │ Token Account (持有账户) │ │ ├─ supply: 1 │ ├─ owner: 持有者地址 │ │ ├─ decimals: 0 │ ├─ mint: Mint 地址 │ │ └─ mint_authority: │ └─ amount: 1 │ │ None │ │ └─────────────────────────────────────────────────────────┘
  1. Mint Account: 定义了代币的物理属性。
    • supply: 1 & decimals: 0:确保了唯一性和不可分割性。
    • mint_authority: None:确保了固定供应,不能增发。
  2. Token Account: 记录了所有权。
    • 对于 NFT,这个账户的余额只能是 1 或 0。
    • 通常用户的钱包地址持有的是这个 Token Account 的所有权。

2. 元数据层:Metaplex 层

SPL Token 层只处理“数量”和“转账”,它不知道这个代币叫什么名字,长什么样。 于是 Metaplex 协议 介入了。它通过 PDA (程序派生地址) 将额外的描述性账户“挂载”到了 Mint Account 上。

┌─────────────────────────────────────────────────────────┐ │ Metaplex 层 │ ├─────────────────────────────────────────────────────────┤ │ Metadata Account │ Master Edition │ │ ├─ name: "Cool Cat" │ ├─ supply: 0 (不可复制) │ │ ├─ symbol: "CAT" │ └─ max_supply: Some(0) │ │ ├─ uri → JSON URL │ │ │ ├─ creators[] │ Collection │ │ └─ seller_fee_basis │ ├─ key: collection mint │ │ _points (版税) │ └─ verified: bool │ └─────────────────────────────────────────────────────────┘
  1. Metadata Account: 存储名称、符号、URI(指向链下图片)、版税设置和创作者列表。它是 NFT 的“身份证”。
  2. Master Edition: 证明这是 NFT 的“原版”。它接管了 Mint Authority,不仅防止增发,还用于控制是否允许“打印”复制品(Edition)。对于 1/1 的艺术品,通常不允许打印。

3. PDA 地址推导:如何找到这些账户?

这种多账户结构之所以行得通,是因为账户地址是确定性的。 你不需要在数据库里记录 Metadata 账户的地址,只要知道 NFT 的 Mint 地址,就可以通过算法推导出来。

typescript
// Metadata Account 地址推导公式 PDA = hash( "metadata", // 固定前缀 METAPLEX_PROGRAM_ID, // Metaplex 程序 ID mint_address // NFT 的 Mint 地址 ); // Master Edition 地址推导公式 PDA = hash( "metadata", METAPLEX_PROGRAM_ID, mint_address, "edition" // 额外后缀 );

这种设计极大地简化了索引和查询。钱包软件只需要扫描 Mint 地址,就能自动找到对应的头像和名称。


4. 链下元数据 (Off-chain Metadata)

由于 Solana 链上存储虽然比以太坊便宜,但存几 MB 的图片依然太贵且不现实。 因此,链上的 Metadata Account 只存储一个 URI 字符串,指向一个存储在去中心化存储网络(如 Arweave 或 IPFS)上的 JSON 文件。

标准 JSON 格式:

json
{ "name": "Cyber Samurai #888", "symbol": "SAMURAI", "description": "A legendary warrior from the future.", "image": "https://arweave.net/tx_id_of_image.png", "attributes": [ { "trait_type": "Weapon", "value": "Katana" }, { "trait_type": "Background", "value": "Neo Tokyo" } ], "properties": { "files": [{ "uri": "...", "type": "image/png" }] } }

存储方案对比:

  • Arweave: 一次付费,永久存储。Solana NFT 的首选。
  • IPFS: 需要持续付费(Pinning Service)来维持数据在线。如果停止付费,图片可能会消失(404)。
  • AWS S3: 中心化存储。虽然快且便宜,但不抗审查,如果不续费会被删除。不建议用于高价值 NFT。

5. Collection 机制:防伪的关键

任何人都可以下载一张无聊猿的图片,发一个一模一样的 NFT。名字、图片都一样,怎么分辨真假?

答案是 Collection (集合验证)

Collection 本身也是一个 NFT。当你创建一个系列时:

  1. 你在 NFT 的 Metadata 中声明它属于某个 Collection Mint 地址。
  2. 关键步骤:Collection 的所有者(Authority)必须对这个声明进行签名验证 (Verify)
  3. 验证成功后,链上数据 verified 字段变为 true

市场(如 Magic Eden)和钱包(如 Phantom)只认 verified = true 的 NFT。骗子虽然可以指向同一个 Collection 地址,但无法获得 Collection 私钥的签名,因此显示为“未验证”,一眼假。

JSPlayground
EDITOR ACTIVE
Initializing JS Environment...

NFT 架构分层解析

移动鼠标悬停查看详情 (Hover to inspect)
Extends
Layer 2: Metaplex (Metadata)
Metadata PDA
Name, URI, Royalty
Master Edition
Supply=1 Check
PDA = SHA256("metadata" + ProgramID + MintAddress)
Layer 1: SPL Token (Base)
Mint Account
Decimals: 0
Token Account
Balance: 1
负责资产的 所有权转账。不包含图片链接。