我们已经部署并交互过 SPL tokens,但它们都没有名称、符号或附加的任何元数据。相反,我们通过其 mint 账户地址来识别每个代币。相比之下,ERC20 代币包含读取代币名称和符号的函数(但值得注意的是,这些只是为了方便人类阅读,没有什么能阻止不同的代币拥有相同的名称或符号)。ERC721 和 ERC1155 也包含一个 tokenURI 函数,该函数返回一个指向链下元数据的 URI。
但正如我们目前所见,SPL mint 账户没有名称、符号或 URI 字段。
在 Solana 上,主要有两种解决方案:
- Metaplex Token Metadata 标准
- SPL Token-2022
Metaplex Token Metadata 标准:这是 Solana 上为代币添加元数据最广泛使用的方法。当你在钱包中看到带有图片的 NFT,或者带有名称和符号的代币(比如著名的 “dog wif hat” 模因币)时,它们很可能使用的是这个标准。它通过一个链接到你代币的独立 metadata 账户来工作。这与 ERC-721 的工作方式正好相反——在 ERC-721 中,是代币合约指向元数据,但在 Metaplex 中,是 metadata 账户指向代币的 mint。

此图展示了 SPL Token Mint、Metadata 账户和用于附加元数据的链下 JSON 之间的关系
SPL Token-2022: 这是一个独立于原始 SPL Token 程序的程序,它内置了对代币元数据和其他高级功能的支持。虽然它更现代,但在撰写本文时,它还没有像 Metaplex 标准那样被广泛采用。
我们今天将重点讨论 Metaplex 解决方案,并在另一篇文章中介绍 Token-2022。
我们将分两部分来讲解 Metaplex 解决方案:在本文中,我们将介绍 Metaplex,并探讨它如何处理 SPL 代币的元数据。在下一篇文章中,我们将使用 Anchor 为 SPL 代币实现 Metaplex 元数据。
什么是 Metaplex,它是如何提供代币元数据的?
Metaplex 是构建在 Solana 上的一套开放标准和工具。这些标准由 Metaplex Foundation 维护,并已成为在 Solana 上创建和管理数字资产的主要方式。
在实际应用中:
- 当你在 Phantom 钱包中看到带有图片的 NFT 或代币时,该图片链接很可能来自 Metaplex 元数据
- 当代币在你的钱包中显示名称和符号而不仅仅是一个地址时,它极有可能使用的是 Metaplex 元数据
- Solana 上流行的 NFT 集合(如 DeGods 或 Okay Bears)使用的都是 Metaplex 标准
它的外观如下所示:https://explorer.solana.com/address/EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm/metadata

Metaplex 提供了几种工具,但我们目前的重点是 Token Metadata Program,它允许你将元数据附加到任何 SPL 代币上。
Metaplex Token Metadata Program
Metaplex Token Metadata Program 的地址为 metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s,用于向 SPL 代币添加额外的元数据,如名称、符号、图片和描述。它创建并管理 metadata accounts(元数据账户),这些账户存储与特定 SPL mint 绑定的结构化元数据。
就像 SPL Token Program 拥有所有的 mint 账户和 ATA 一样,Metaplex Token Metadata Program 拥有其名下的所有 metadata 账户。它是一个可执行且可升级的程序。
从高层次来看,该程序允许我们:
- 为 SPL 代币 mint 创建一个 metadata 账户,以便在此账户中存储名称、符号和 URI 等结构化数据
- 通过特定指令更新这些数据
我们将在下文的“Metaplex Token Metadata Program Instructions”部分更详细地介绍这些指令。
现在让我们来看看这些 metadata 账户是如何构建和创建的。
Metaplex Metadata 账户
Metaplex metadata 账户是一个程序派生地址(PDA),通过 Metaplex Token Metadata Program 创建,用于向 SPL 代币附加额外数据。该 PDA 是使用三个种子派生出来的:字符串 "metadata"、token_metadata_program_id 和 mint_account_address。
只有 mint 地址是可变的;"metadata" 字符串和程序 ID 是固定的。这确保了对于给定的 mint 账户只能派生出一个 metadata 账户。
虽然 metadata 账户存储了关于代币的基本链上信息,但它也可以包含一个指向链下资源的 URI。例如,一个 NFT 的 metadata 账户可能在链上存储代币名称和符号,而 URI 则指向一个包含完整描述、图片和附加属性的 JSON 文件,该文件存储在 IPFS、Arweave 或 Web 服务器上。
下图展示了 Metaplex Token Metadata Program 和 Metadata 账户之间的关系。

下图展示了与我们讨论 metadata 账户相关的字段,如果这些目前还难以理解,请不用担心,稍后我们将进行解释。

metadata 账户存储关于 mint 账户的元数据(名称、符号、图片等)。由于 metadata 账户的地址可以直接由 mint 账户的地址派生出来,因此钱包可以轻松发现该 metadata 账户(如果存在的话)。
从上图可以看出,每个键代表的含义如下:
key:这是一个账户鉴别器(目前为 MetadataV1)。虽然变量名key的描述性不是很强(更准确的名称应该是version或discriminator),但这是 Metaplex 在其代码库中使用的名称。它指示了当前使用的元数据结构版本,并让钱包和工具能够正确解析该账户。由于 PDA 的派生机制将 mint 地址作为唯一非固定值的种子,因此每个 mint 只能有一个 metadata 账户。update_authority:有权更新 metadata 账户的钱包地址。该 update authority 是在 metadata 账户创建时设置的,之后只有该权限拥有者可以修改元数据。update authority 可以将其权利转移给另一个地址,或者通过将权限设置为 null 来永久放弃控制权,从而使元数据变得不可变。每次更新操作都需要来自当前权限地址的有效签名,这防止了未经授权修改代币元数据的行为。我们将在本文后面讨论用于更新和转移权限的具体指令。mint:指向该元数据所描述的 SPL 代币 mint 账户。这将元数据与实际代币链接起来。data:该字段代表 SPL 代币资产数据。它包含以下内容:name:代币名称(例如 “Circle US Dollar Stablecoin”)。长度限制为 32 字节,因此名称必须简明扼要。定义见此处。symbol:代币的简短标识符(例如 “USDC”)。长度限制为 10 字节,通常为大写。uri:指向包含扩展元数据的链下 JSON 文件的链接,类似于 ERC721 和 ERC1155 中 NFT URI 的工作方式。该 JSON 遵循标准化格式,并包含描述、图片、动画 URL、属性等字段。URI 的大小限制为 200 字节。我们稍后将更详细地深入探讨这个 JSON。seller_fee_basis_points:这表示应用于代币二次销售的版税费用,以基点表示(其中 1% 等于 100 个基点)。市场平台利用这一信息来确定在出售代币时应向创作者汇款的金额。该版税信息对市场平台而言是一项建议,而非强制性规则,这些值的允许范围是从 0 到 10,000(即 0% 到 100%)。creators:一个最多包含 5 个地址 的数组,作为代币的创作者,每个地址被分配一定比例的卖家费用(版税)。这些百分比的总和必须等于 100。对creators字段的这种使用方式是对市场平台的建议,而非严格规则。- 此外,
data还可以包含一个适用于 NFT 的可选collection字段。该字段包含两条信息:一个公钥和一个布尔标志。公钥是作为集合标识符的另一个 NFT 的 mint 地址。与通常基于合约来实现集合的 Ethereum 不同,Metaplex 使用一个特殊的 NFT 来代表整个集合。这个“集合 NFT”使用与普通 NFT 相同的 metadata 账户,但其 metadata 账户包含一个额外的collection_details字段,以将其标识为一个集合。布尔标志(第二条信息)由集合的 update authority 设置,用于验证该 NFT 合法地属于该集合。这个链上验证系统允许钱包和市场平台按集合对 NFT 进行分组和展示。
primary_sale_happened:这是一个布尔标志,用于跟踪初始销售是否已经发生。一旦设置为 true,就无法撤销。这会影响一些市场平台的版税分配,因为大多数市场平台仅在首次销售发生后才开始强制执行版税。is_mutable:决定了元数据在创建后是否可以被更新。如果设置为 false,元数据将永久冻结(意味着无法再进行任何更新,即使是 update authority 也不行)。edition_nonce: 一个用于 master edition 的可选字段,这是一项允许创建 NFT 限量版副本的高级功能。这对于理解元数据如何工作并不是必要的。如果你对这个功能感兴趣,可以在 Metaplex 文档 中了解更多信息。token_standard:一个用于标识代币类型的枚举,它可以是以下任意一种:Fungible(标准的 SPL 代币),NonFungible(没有版本的独特 NFT),FungibleAsset(带有元数据的同质化代币,可以是与 ERC1155 用例相似的游戏内物品)
Metaplex Token Metadata Program Instructions
Metaplex Token Metadata Program 包含几个我们可以从程序或客户端调用的指令。通过它们,我们为 SPL 代币创建和管理元数据。
这些指令包括:
CreateMetadataAccountV3:该指令为 SPL 代币 mint 创建一个新的 metadata 账户。它将名称、符号、URI 和创作者信息等元数据附加到代币上。这是赋予代币除了 mint 地址之外的身份信息的主要方式。这里的V3仅仅意味着这是该指令的第三个版本。只有代币的 mint authority 才能为其创建元数据,这可以防止任何人将未经授权的元数据附加到他们无法控制的代币上。UpdateMetadataAccountV2:该指令更新现有代币的元数据。只要元数据被标记为可变且 update authority 对交易进行了签名,它就可以修改名称、符号、URI、创作者、将权限转移到新地址以及其他属性等字段。只有指定的 update authority 才能修改元数据,该权限是在首次创建元数据时设置的。UpdatePrimarySaleHappenedViaToken:该指令标记 NFT 的首次销售已经发生。一旦设置为 true,就无法撤销。这会影响某些市场平台中的版税分配,因为大多数市场平台仅在首次销售之后才开始强制执行版税。只有 update authority 可以调用此指令。SignMetadata:该指令允许元数据中列出的创作者通过对元数据进行签名来验证其身份。当创作者签名时,他们的“验证”状态将变为 true,这有助于买家确认代币的真实性。CreateMasterEditionV3:该指令为 NFT 创建一个 master edition 账户。每个 mint 只能调用一次,并且仅当供应量严格为 1 时才能调用。它将普通的 NFT 转换为可以生产限量版副本的 master edition。如前所述,只有该 mint 的 update authority 才能调用此指令。MintNewEditionFromMasterEditionViaToken:该指令从一个 master edition 创建一个新的限量版 NFT。新版本拥有自己的 mint 和元数据,但与 master edition 相关联。SetAndVerifyCollection:该指令将 NFT 链接到一个集合并在一步中对其进行验证。它需要该集合的 update authority 签署交易,以确认该 NFT 是该集合的官方组成部分。VerifySizedCollectionItem:该指令验证某个 NFT 属于一个 sized collection。Sized collection 会跟踪它们所包含的物品的确切数量,这有助于在市场平台中进行准确展示。VerifyCollection:该指令验证 NFT 属于一个集合。它需要该集合的 update authority 进行签名,以确认 NFT 在该集合中的成员身份。UnverifyCollection:该指令移除 NFT 在某个集合中的验证状态。它需要集合的 update authority 或 NFT 的 update authority 进行签名。Utilize:该指令跟踪启用了“使用”功能的 NFT 的使用情况。这允许 NFT 在过期或改变状态之前具有有限的使用次数。ApproveUseAuthority:该指令将使用 NFT 的权限委派给另一个地址,允许其他人使用该 NFT 指定的次数。RevokeUseAuthority:该指令撤销先前授予的使用权限,防止被委派者进一步使用该 NFT。ApproveCollectionAuthority:该指令将验证集合物品的权限委派给另一个地址。RevokeCollectionAuthority:该指令撤销先前委派的集合权限。BurnNft:该指令销毁一个 NFT,同时破坏该代币及其元数据。这是不可逆的,并且会将该 NFT 从流通中移除。
较少使用的 Metaplex Token Metadata 指令
以下指令较少使用,但仍然是 Metaplex Token Metadata Program 的一部分:
CreateMetadataAccount:CreateMetadataAccountV3的旧版本。CreateMetadataAccountV2:CreateMetadataAccountV3的旧版本。UpdateMetadataAccount:UpdateMetadataAccountV2的旧版本。CreateMasterEdition:CreateMasterEditionV3的旧版本。CreateMasterEditionV2:CreateMasterEditionV3的旧版本。VerifySizedCollectionItem:这将一个物品验证为 NFT 集合的一部分。SetAndVerifySizedCollectionItem:这会在一条指令中设置并验证一个物品作为 NFT 集合的一部分。FreezeDelegatedAccount:冻结受委派的账户。ThawDelegatedAccount:解冻先前被冻结的受委派账户。RemoveCreatorVerification:移除创作者对 NFT 的验证。PuffMetadata:通过用空字节填充较短的字段,将 metadata 账户扩展到其最大大小。当元数据字段(如 name、symbol、URI)短于其允许的最大长度时,此指令将用零填充剩余空间。最大大小为:name(32 字节)、symbol(10 字节)和 URI(200 字节)。
结论
总结一下:Metaplex Token Metadata Program 通过一个绑定到 mint 的独立 metadata 账户,赋予 SPL 代币名称、符号和图片等身份信息。该账户是一个 PDA 并存储结构化字段,包括一个指向链下 JSON 的 URI。我们详细剖析了每个字段的含义及其如何影响钱包和市场平台处理代币的方式。最后,我们浏览了该程序提供的各项指令以及它们各自的功能。
在下一个教程中,我们将为一个 SPL 代币创建元数据。
本文是 Solana 教程系列的一部分。