7. Metaplex 代币元数据

7. Metaplex 代币元数据

虽然 Token-2022 提供了内置的元数据扩展,但 Metaplex 的 Token Metadata 程序仍然是 Solana 生态中最广泛使用的元数据方案,特别是在 NFT 领域。

7.1 为什么需要元数据

原生的 SPL Token 只存储数学信息:供应量、精度、权限。钱包显示代币时需要知道:

  • 代币名称(如 "USD Coin")
  • 符号(如 "USDC")
  • Logo 图片
  • 项目描述
  • 其他属性

没有元数据,用户在钱包中只会看到一串无意义的地址。


7.2 Metadata Account 结构

Metaplex 使用独立的 Metadata Account 存储代币信息。这个账户通过 PDA 机制与 Mint 账户关联:

Metadata PDA = findProgramAddress( ["metadata", METADATA_PROGRAM_ID, MINT_ADDRESS], METADATA_PROGRAM_ID )

核心字段:

tsx
interface Metadata { // 基础信息 name: string; // 代币名称(最多 32 字符) symbol: string; // 交易符号(最多 10 字符) uri: string; // 指向链下 JSON 的 URL // 权限控制 updateAuthority: PublicKey; // 谁可以修改元数据 isMutable: boolean; // 是否允许修改 // 版税(主要用于 NFT) sellerFeeBasisPoints: number; // 二次销售版税 (如 500 = 5%) creators: Creator[]; // 创作者及分成比例 // 集合(主要用于 NFT) collection: Collection | null; uses: Uses | null; }

7.3 使用 Metaplex SDK

安装依赖:

bash
npm install @metaplex-foundation/mpl-token-metadata @metaplex-foundation/umi @metaplex-foundation/umi-bundle-defaults

创建带元数据的代币:

tsx
// create-token-with-metaplex.ts import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'; import { mplTokenMetadata, createV1, TokenStandard } from '@metaplex-foundation/mpl-token-metadata'; import { generateSigner, percentAmount, keypairIdentity } from '@metaplex-foundation/umi'; import { loadWallet } from './config'; async function createTokenWithMetaplex() { // 初始化 Umi const umi = createUmi('https://api.devnet.solana.com') .use(mplTokenMetadata()); // 加载钱包 const wallet = loadWallet(); const umiKeypair = umi.eddsa.createKeypairFromSecretKey(wallet.secretKey); umi.use(keypairIdentity(umiKeypair)); // 生成 Mint 密钥对 const mint = generateSigner(umi); console.log('创建带 Metaplex 元数据的代币...'); // 创建代币(同时创建 Mint 和 Metadata) await createV1(umi, { mint, name: 'Solana University Token', symbol: 'SOLU', uri: 'https://arweave.net/your-metadata-json', sellerFeeBasisPoints: percentAmount(0), // 无版税 decimals: 6, tokenStandard: TokenStandard.Fungible, }).sendAndConfirm(umi); console.log('创建成功!'); console.log('Mint 地址:', mint.publicKey); } createTokenWithMetaplex();

7.4 更新元数据

如果元数据设置为可变(isMutable = true),可以后续更新:

tsx
// update-metadata.ts import { createUmi } from '@metaplex-foundation/umi-bundle-defaults'; import { mplTokenMetadata, updateV1, fetchMetadataFromSeeds } from '@metaplex-foundation/mpl-token-metadata'; import { publicKey, keypairIdentity } from '@metaplex-foundation/umi'; import { loadWallet } from './config'; async function updateMetadata(mintAddress: string) { const umi = createUmi('https://api.devnet.solana.com') .use(mplTokenMetadata()); const wallet = loadWallet(); const umiKeypair = umi.eddsa.createKeypairFromSecretKey(wallet.secretKey); umi.use(keypairIdentity(umiKeypair)); const mint = publicKey(mintAddress); // 获取当前元数据 const metadata = await fetchMetadataFromSeeds(umi, { mint }); console.log('当前名称:', metadata.name); // 更新元数据 await updateV1(umi, { mint, data: { ...metadata, name: 'Updated Token Name', symbol: 'NEW', }, }).sendAndConfirm(umi); console.log('更新成功!'); }

7.5 链下元数据 JSON 规范

URI 指向的 JSON 文件应遵循以下格式:

json
{ "name": "Solana University Token", "symbol": "SOLU", "description": "Solana 大学官方学习激励代币,用于奖励优秀学员", "image": "https://arweave.net/your-logo-image", "external_url": "https://academy.soldevcamp.com", "attributes": [], "properties": { "category": "currency", "files": [ { "uri": "https://arweave.net/your-logo-image", "type": "image/png" } ] } }

链下存储选择:

方案特点适用场景
Arweave永久存储,一次付费NFT、长期项目
IPFS + Pinata需要持续付费维护一般项目
AWS S3 / 云存储中心化,但便宜稳定开发测试、内部项目
TSPlayground
EDITOR ACTIVE
Initializing TS Environment...

Metaplex 身份构建器

Mint Address
7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU
Unknown Token (No Metadata)