Standard-SPL-Tokens enthalten keine Metadaten wie Name, Symbol oder Bild. Das Metaplex Token Metadata-Programm löst dies, indem es ein Metadaten-Konto erstellt, das mit jedem Token-Mint verknüpft ist.
Dieser Leitfaden behandelt das Metaplex Token Metadata-Programm, das für Standard-SPL-Tokens und Token-2022 verwendet werden kann. Um die Token-2022 Metadata Extension zu verwenden, siehe den Metadata Extension-Leitfaden, der Metadaten direkt auf dem Mint- Konten speichert.
Wie Token-Metadaten funktionieren
Das Token Metadata-Programm erstellt eine Program Derived Address (PDA) für jeden Token-Mint. Dieses Metadaten-Konto speichert On-Chain-Informationen wie den Namen und das Symbol des Tokens sowie eine URI, die auf Off-Chain-JSON-Metadaten verweist (Bilder, Beschreibungen usw.).
┌─────────────────┐ ┌─────────────────────┐│ Mint Account │ │ Metadata Account ││ │ │ (PDA) ││ - Supply │◄──────│ - Name ││ - Decimals │ │ - Symbol ││ - Authority │ │ - URI │└─────────────────┘ │ - Seller Fee ││ - Creators │└─────────────────────┘
Die Metadaten-PDA wird aus folgenden Seeds abgeleitet:
["metadata", program_id, mint_address]
Token mit Metadaten erstellen
Die Anweisungen createV1 erstellt sowohl das Mint- Konten als auch seine
Metadaten in einer einzigen Transaktion.
Typescript
import {airdropFactory,appendTransactionMessageInstructions,createSolanaRpc,createSolanaRpcSubscriptions,createTransactionMessage,generateKeyPairSigner,lamports,pipe,sendAndConfirmTransactionFactory,setTransactionMessageFeePayerSigner,setTransactionMessageLifetimeUsingBlockhash,signTransactionMessageWithSigners} from "@solana/kit";import {getCreateV1InstructionAsync,TokenStandard} from "@metaplex-foundation/mpl-token-metadata-kit";// Create connectionconst rpc = createSolanaRpc("http://127.0.0.1:8899");const rpcSubscriptions = createSolanaRpcSubscriptions("ws://127.0.0.1:8900");// Generate keypairsconst payer = await generateKeyPairSigner();const mint = await generateKeyPairSigner();// Fund payerawait airdropFactory({ rpc, rpcSubscriptions })({recipientAddress: payer.address,lamports: lamports(1_000_000_000n),commitment: "confirmed"});// Create fungible token with metadataconst createInstruction = await getCreateV1InstructionAsync({mint,authority: payer,payer,name: "My Token",symbol: "MTK",uri: "https://example.com/token.json",sellerFeeBasisPoints: 0,tokenStandard: TokenStandard.Fungible});// Build and send transactionconst { value: latestBlockhash } = await rpc.getLatestBlockhash().send();const transactionMessage = pipe(createTransactionMessage({ version: 0 }),(tx) => setTransactionMessageFeePayerSigner(payer, tx),(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),(tx) => appendTransactionMessageInstructions([createInstruction], tx));const signedTransaction =await signTransactionMessageWithSigners(transactionMessage);await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTransaction,{ commitment: "confirmed" });console.log("Mint Address:", mint.address);
Token-Metadaten abrufen
Um zu erfahren, wie Sie Metadaten für vorhandene Tokens abrufen, siehe das Fetch Token Metadata Cookbook-Rezept.
Token-Metadaten aktualisieren
Die Upgrade-Authority kann die Metadaten ändern, wenn das Konten veränderbar ist.
import {appendTransactionMessageInstructions,createSolanaRpc,createSolanaRpcSubscriptions,createTransactionMessage,pipe,sendAndConfirmTransactionFactory,setTransactionMessageFeePayerSigner,setTransactionMessageLifetimeUsingBlockhash,signTransactionMessageWithSigners} from "@solana/kit";import {getUpdateV1InstructionAsync,findMetadataPda,fetchMetadata} from "@metaplex-foundation/mpl-token-metadata-kit";const rpc = createSolanaRpc("http://127.0.0.1:8899");const rpcSubscriptions = createSolanaRpcSubscriptions("ws://127.0.0.1:8900");// authority must be a KeyPairSigner with update authorityconst mintAddress = "YOUR_MINT_ADDRESS";// Fetch current metadata to preserve existing valuesconst [metadataAddress] = await findMetadataPda({ mint: mintAddress });const currentMetadata = await fetchMetadata(rpc, metadataAddress);// Update metadata (must provide all data fields)const updateInstruction = await getUpdateV1InstructionAsync({mint: mintAddress,authority, // Update authority signerpayer: authority,data: {name: "Updated Token Name",symbol: "UPD",uri: "https://example.com/updated-token.json",sellerFeeBasisPoints: 100, // 1%creators:currentMetadata.data.creators.__option === "Some"? currentMetadata.data.creators.value: null}});// Build and send transactionconst { value: latestBlockhash } = await rpc.getLatestBlockhash().send();const transactionMessage = pipe(createTransactionMessage({ version: 0 }),(tx) => setTransactionMessageFeePayerSigner(authority, tx),(tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx),(tx) => appendTransactionMessageInstructions([updateInstruction], tx));const signedTransaction =await signTransactionMessageWithSigners(transactionMessage);await sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions })(signedTransaction,{ commitment: "confirmed" });console.log("Metadata updated successfully");
Token-Standards
Das Token Metadata-Programm unterstützt verschiedene Token-Standards:
| Standard | Beschreibung | Anwendungsfall |
|---|---|---|
Fungible | Standard-Fungible-Token mit Metadaten | Währungen, Punkte |
FungibleAsset | Fungibler Token, der ein einzigartiges Asset repräsentiert | Semi-fungible Gegenstände |
NonFungible | NFT mit Master Edition | 1/1 Kunstwerk |
ProgrammableNonFungible | NFT mit durchgesetzten Lizenzgebühren | Creator-Lizenzgebühren |
NonFungibleEdition | Gedruckte Kopie eines NFT | Limitierte Auflagen |
ProgrammableNonFungibleEdition | Gedruckte Kopie mit durchgesetzten Lizenzgebühren | Limitierte Auflagen |
import { TokenStandard } from "@metaplex-foundation/mpl-token-metadata-kit";// For fungible tokenstokenStandard: TokenStandard.Fungible;// For NFTstokenStandard: TokenStandard.NonFungible;// For programmable NFTs (enforced royalties)tokenStandard: TokenStandard.ProgrammableNonFungible;
Off-Chain-Metadatenformat
Das Feld uri verweist auf eine JSON-Datei, die erweiterte Metadaten enthält.
Das Standardformat folgt dem
Metaplex Token Metadata Standard:
{"name": "My Token","symbol": "MTK","description": "A description of the token","image": "https://example.com/token-image.png","external_url": "https://example.com","attributes": [{"trait_type": "Category","value": "Utility"}],"properties": {"files": [{"uri": "https://example.com/token-image.png","type": "image/png"}]}}
Speichern Sie Ihre Metadaten-JSON-Datei auf einer zuverlässigen, dauerhaften Speicherlösung wie Arweave, IPFS oder einem dedizierten CDN. Wenn die URI nicht mehr erreichbar ist, können Wallets und Explorer die Metadaten Ihres Tokens nicht anzeigen.
Struktur des Metadaten-Kontos
Das On-Chain-Metadaten-Konto enthält:
pub struct Metadata {pub key: Key, // Account type identifierpub update_authority: Pubkey, // Can update metadatapub mint: Pubkey, // Associated mintpub name: String, // Token name (max 32 chars)pub symbol: String, // Token symbol (max 10 chars)pub uri: String, // URI to off-chain JSON (max 200 chars)pub seller_fee_basis_points: u16, // Royalty % (100 = 1%)pub creators: Option<Vec<Creator>>, // Creator list with sharespub primary_sale_happened: bool, // Primary sale flagpub is_mutable: bool, // Can metadata be updatedpub edition_nonce: Option<u8>, // Edition noncepub token_standard: Option<TokenStandard>, // Token typepub collection: Option<Collection>, // Collection infopub uses: Option<Uses>, // Use tracking}
Best Practices
- Legen Sie die passende Veränderbarkeit fest: Verwenden Sie
isMutable: falsefür Tokens, die sich niemals ändern sollten - Verwenden Sie zuverlässiges URI-Hosting: Off-Chain-Metadaten sollten auf dauerhaftem Speicher liegen
- Verifizieren Sie Creator: Creator-Adressen sollten verifiziert werden, um die Authentizität zu bestätigen
- Berücksichtigen Sie Lizenzgebühren: Legen Sie
sellerFeeBasisPointsfür Lizenzgebühren bei Zweitverkäufen fest (Marktplätze können diese durchsetzen oder auch nicht)
Is this page helpful?