Standaard SPL Tokens bevatten geen metadata zoals een naam, symbool of afbeelding. Het Metaplex Token Metadata Program lost dit op door een metadata-account te maken dat gekoppeld is aan elke token mint.
Deze gids behandelt het Metaplex Token Metadata Program dat kan worden gebruikt voor standaard SPL Tokens en Token-2022. Om de Token-2022 Metadata Extension te gebruiken, zie de Metadata Extension gids die metadata rechtstreeks op het mint account opslaat.
Hoe Token Metadata Werkt
Het Token Metadata Program maakt een Program Derived Address (PDA) aan voor elke token mint. Dit metadata-account slaat on-chain informatie op zoals de naam en het symbool van de token, plus een URI die verwijst naar off-chain JSON-metadata (afbeeldingen, beschrijvingen, enz.).
┌─────────────────┐ ┌─────────────────────┐│ Mint Account │ │ Metadata Account ││ │ │ (PDA) ││ - Supply │◄──────│ - Name ││ - Decimals │ │ - Symbol ││ - Authority │ │ - URI │└─────────────────┘ │ - Seller Fee ││ - Creators │└─────────────────────┘
De metadata PDA wordt afgeleid van seeds:
["metadata", program_id, mint_address]
Token Maken met Metadata
De createV1 instructie maakt zowel het mint account als de metadata aan in één
transactie.
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 Metadata Ophalen
Om te leren hoe je metadata voor bestaande tokens ophaalt, zie het Fetch Token Metadata cookbook recept.
Token Metadata Bijwerken
De update authority kan de metadata wijzigen als het account muteerbaar is.
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 Standaarden
Het Token Metadata Program ondersteunt verschillende token standaarden:
| Standaard | Beschrijving | Toepassing |
|---|---|---|
Fungible | Standaard fungible token met metadata | Valuta's, punten |
FungibleAsset | Fungible token die een uniek actief vertegenwoordigt | Semi-fungible items |
NonFungible | NFT met Master Edition | 1/1 kunstwerk |
ProgrammableNonFungible | NFT met afgedwongen royalty's | Creator royalty's |
NonFungibleEdition | Geprinte kopie van een NFT | Beperkte oplages |
ProgrammableNonFungibleEdition | Geprinte kopie met afgedwongen royalty's | Beperkte oplages |
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 Metadata Formaat
Het uri veld verwijst naar een JSON-bestand met uitgebreide metadata. Het
standaardformaat volgt de
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"}]}}
Bewaar je metadata JSON op een betrouwbare, permanente opslagoplossing zoals Arweave, IPFS of een toegewijde CDN. Als de URI ontoegankelijk wordt, kunnen wallets en explorers de metadata van je token niet weergeven.
Metadata Account Structuur
Het on-chain metadata account bevat:
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
- Stel passende mutabiliteit in: Gebruik
isMutable: falsevoor tokens die nooit mogen veranderen - Gebruik betrouwbare URI-hosting: Off-chain metadata moet op permanente opslag staan
- Verifieer creators: Creator-adressen moeten geverifieerd worden om authenticiteit te bevestigen
- Overweeg royalty's: Stel
sellerFeeBasisPointsin voor royalty's bij secundaire verkoop (marktplaatsen kunnen deze al dan niet afdwingen)
Is this page helpful?