بيانات ميتابليكس الوصفية

الرموز القياسية SPL لا تتضمن بيانات وصفية مثل الاسم أو الرمز أو الصورة. برنامج Metaplex Token Metadata يحل هذه المشكلة من خلال إنشاء حساب بيانات وصفية مرتبط بكل سك رمزي.

يغطي هذا الدليل برنامج Metaplex Token Metadata الذي يمكن استخدامه للرموز القياسية SPL و Token-2022. لاستخدام امتداد البيانات الوصفية Token-2022، راجع دليل امتداد البيانات الوصفية الذي يخزن البيانات الوصفية مباشرة على حساب السك.

كيفية عمل البيانات الوصفية للرموز

ينشئ برنامج البيانات الوصفية للرموز Program Derived Address (PDA) لكل سك رمزي. يخزن حساب البيانات الوصفية هذا معلومات على السلسلة مثل اسم الرمز ورمزه، بالإضافة إلى URI يشير إلى بيانات JSON الوصفية خارج السلسلة (الصور، الأوصاف، إلخ).

┌─────────────────┐ ┌─────────────────────┐
│ Mint Account │ │ Metadata Account │
│ │ │ (PDA) │
│ - Supply │◄──────│ - Name │
│ - Decimals │ │ - Symbol │
│ - Authority │ │ - URI │
└─────────────────┘ │ - Seller Fee │
│ - Creators │
└─────────────────────┘

يتم اشتقاق PDA للبيانات الوصفية من البذور: ["metadata", program_id, mint_address]

إنشاء رمز مع البيانات الوصفية

تعليمة createV1 تنشئ كلاً من حساب السك وبياناته الوصفية في معاملة واحدة.

تايب سكريبت

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 connection
const rpc = createSolanaRpc("http://127.0.0.1:8899");
const rpcSubscriptions = createSolanaRpcSubscriptions("ws://127.0.0.1:8900");
// Generate keypairs
const payer = await generateKeyPairSigner();
const mint = await generateKeyPairSigner();
// Fund payer
await airdropFactory({ rpc, rpcSubscriptions })({
recipientAddress: payer.address,
lamports: lamports(1_000_000_000n),
commitment: "confirmed"
});
// Create fungible token with metadata
const 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 transaction
const { 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);

جلب البيانات الوصفية للرمز

لمعرفة كيفية جلب البيانات الوصفية للرموز الموجودة، راجع وصفة كتاب الطبخ جلب البيانات الوصفية للرمز.

تحديث البيانات الوصفية للرمز

يمكن لسلطة التحديث تعديل البيانات الوصفية إذا كان الحساب قابلاً للتغيير.

Kit
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 authority
const mintAddress = "YOUR_MINT_ADDRESS";
// Fetch current metadata to preserve existing values
const [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 signer
payer: 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 transaction
const { 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");

معايير الرموز

يدعم برنامج البيانات الوصفية للرموز معايير مختلفة للرموز:

المعيارالوصفحالة الاستخدام
Fungibleرمز قابل للاستبدال قياسي مع بيانات وصفيةالعملات، النقاط
FungibleAssetرمز قابل للاستبدال يمثل أصلاً فريداًعناصر شبه قابلة للاستبدال
NonFungibleرمز غير قابل للاستبدال مع إصدار رئيسيعمل فني 1/1
ProgrammableNonFungibleرمز غير قابل للاستبدال مع إتاوات مفروضةإتاوات المبدعين
NonFungibleEditionنسخة مطبوعة من رمز غير قابل للاستبدالإصدارات محدودة
ProgrammableNonFungibleEditionنسخة مطبوعة مع إتاوات مفروضةإصدارات محدودة
import { TokenStandard } from "@metaplex-foundation/mpl-token-metadata-kit";
// For fungible tokens
tokenStandard: TokenStandard.Fungible;
// For NFTs
tokenStandard: TokenStandard.NonFungible;
// For programmable NFTs (enforced royalties)
tokenStandard: TokenStandard.ProgrammableNonFungible;

تنسيق البيانات الوصفية خارج السلسلة

يشير حقل uri إلى ملف JSON يحتوي على بيانات وصفية موسعة. يتبع التنسيق القياسي معيار Metaplex للبيانات الوصفية للرموز:

token-metadata.json
{
"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"
}
]
}
}

قم بتخزين ملف JSON للبيانات الوصفية على حل تخزين موثوق ودائم مثل Arweave أو IPFS أو شبكة CDN مخصصة. إذا أصبح عنوان URI غير قابل للوصول، فلن تتمكن المحافظ والمستكشفات من عرض البيانات الوصفية لرمزك.

بنية حساب البيانات الوصفية

يحتوي حساب البيانات الوصفية على السلسلة على:

pub struct Metadata {
pub key: Key, // Account type identifier
pub update_authority: Pubkey, // Can update metadata
pub mint: Pubkey, // Associated mint
pub 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 shares
pub primary_sale_happened: bool, // Primary sale flag
pub is_mutable: bool, // Can metadata be updated
pub edition_nonce: Option<u8>, // Edition nonce
pub token_standard: Option<TokenStandard>, // Token type
pub collection: Option<Collection>, // Collection info
pub uses: Option<Uses>, // Use tracking
}

أفضل الممارسات

  1. تعيين قابلية التعديل المناسبة: استخدم isMutable: false للرموز التي لا يجب أن تتغير أبدًا
  2. استخدام استضافة URI موثوقة: يجب أن تكون البيانات الوصفية خارج السلسلة على تخزين دائم
  3. التحقق من المنشئين: يجب التحقق من عناوين المنشئين لتأكيد الأصالة
  4. مراعاة حقوق الملكية: قم بتعيين sellerFeeBasisPoints لحقوق الملكية من المبيعات الثانوية (قد تقوم الأسواق بفرضها أو لا)

Is this page helpful?

تدار بواسطة

© 2026 مؤسسة سولانا.
جميع الحقوق محفوظة.
تواصل معنا