Metadata Pointer uzantısını nasıl kullanılır
Frequency Guidelines
İpucu: Metadata Pointer uzantısı kullanıldığında, Mint Hesabınızın metadata verilerini daha etkili bir şekilde yönetebilirsiniz.
Token Uzantıları Programı'ndan ve Token Metadata Arayüzü'nden önce, bir Mint Hesabına ekstra veri ekleme süreci, Metaplex Metadata Programı aracılığıyla bir Metadata Hesabı oluşturmayı gerektiriyordu.
MetadataPointer
uzantısı şimdi bir Mint Hesabının ilgili Metadata Hesabının adresini belirtmesine olanak tanır. Bu esneklik, Mint Hesabının, Token Metadata Arayüzünü uygulayan bir programa ait herhangi bir hesaba işaret etmesini sağlar.
Token Uzantıları Programı doğrudan Token Metadata Arayüzünü uygular ve bu arayüz TokenMetadata
uzantısı aracılığıyla erişilebilir hale getirilmiştir. TokenMetadata
uzantısıyla, Mint Hesabı artık metadata'yı tutabilir.
Bu kılavuzda, MetadataPointer
ve TokenMetadata
uzantılarını etkinleştiren bir Mint Hesabı oluşturma yöntemini göstereceğiz. Bu yapılandırma, metadata ekleme sürecini, tüm verileri tek bir hesapta depolayarak basitleştirir. İşte son script.
Token Metadata Arayüzü Genel Görünümü
Token Metadata Arayüzü, metadata ekleme sürecini standartlaştırmak ve basitleştirmek amacıyla tasarlanmıştır. Bu, metadata'nın işlenmesi için veri yapısını ve talimat setini tanımlar.
Ek Bilgi: Token Metadata Arayüzü, herhangi bir program tarafından uygulanabilir. Geliştiricilere özel Metadata Programları oluşturma esnekliği sağlar.
Metadata Arayüzü Alanları
Token Metadata Arayüzü, aşağıda ana hatlarıyla belirtilen standart bir veri alanı seti tanımlar TokenMetadata
. Ayrıca, additional_metadata
bölümünde, anahtar-değer çiftleri olarak biçimlendirilmiş özel veri alanlarının dahil edilmesine izin verir.
pub struct TokenMetadata {
/// Metadata güncellemesini imzalayabilen yetki
pub update_authority: OptionalNonZeroPubkey,
/// Belirli bir mint'e ait metadata'nın olup olmadığını belirlemek için kullanılan ilişkili mint
pub mint: Pubkey,
/// Token'ın daha uzun ismi
pub name: String,
/// Token için kısaltılmış sembol
pub symbol: String,
/// Daha zengin metadata'ya işaret eden URI
pub uri: String,
/// Token hakkında ek metadata, anahtar-değer çiftleri olarak. Program
/// aynı anahtarı iki kez saklamaktan kaçınmalıdır.
pub additional_metadata: Vec<(String, String)>,
}
Metadata Arayüzü Talimatları
Metadata Arayüzü aşağıdaki talimatları belirtir:
Initialize: Temel token metadata alanlarını (isim, sembol, URI) başlat.
UpdateField: Mevcut bir token metadata alanını günceller veya mevcut değilse
additional_metadata
'ya ekler. Ekstra alan için hesabın yeniden boyutlandırılmasını gerektirir.RemoveKey:
additional_metadata
içindeki bir anahtar-değer çiftini siler. Bu talimat, gerekli isim, sembol ve URI alanları için geçerli değildir.UpdateAuthority: Token metadata'sını değiştirmek için yetkilendirilen otoriteyi günceller.
Emit: Token metadata'sını
TokenMetadata
yapısının formatında yayar. Bu, hesap verilerinin farklı bir formatta saklanmasına olanak tanırken arayüz standartları ile uyumluluğu sürdürür.
Başlarken
Aşağıdaki başlangıç koduyla bu Solana Playground bağlantısını açarak başlayın.
// İstemci
console.log("Adresim:", pg.wallet.publicKey.toString());
const balance = await pg.connection.getBalance(pg.wallet.publicKey);
console.log(`Bakiyem: ${balance / web3.LAMPORTS_PER_SOL} SOL`);
Eğer Solana Playground'u ilk kez kullanıyorsanız, öncelikle bir Playground Cüzdanı oluşturmanız ve cüzdanınızı devnet SOL ile finanse etmeniz gerekecek.
İpucu: Eğer bir Playground cüzdanınız yoksa, editörde pg.wallet.publicKey
ile ilgili tüm tanımlarda bir tip hatası görebilirsiniz. Bu tip hatası, bir Playground cüzdanı oluşturduğunuzda temizlenecektir.
Devnet SOL almak için, Playground'un terminalinde solana airdrop
komutunu çalıştırın veya bu devnet faucet adresini ziyaret edin.
solana airdrop 5
Playground cüzdanını oluşturup fonladığınızda, başlangıç kodunu çalıştırmak için "Çalıştır" düğmesine tıklayın.
Bağımlılıkları Ekle
Hadi scriptimizi ayarlamaya başlayalım. @solana/web3.js
, @solana/spl-token
ve @solana/spl-token-metadata
kütüphanelerini kullanacağız.
Başlangıç kodunu aşağıdaki ile değiştirin:
import {
Connection,
Keypair,
SystemProgram,
Transaction,
clusterApiUrl,
sendAndConfirmTransaction,
} from "@solana/web3.js";
import {
ExtensionType,
TOKEN_2022_PROGRAM_ID,
createInitializeMintInstruction,
getMintLen,
createInitializeMetadataPointerInstruction,
getMint,
getMetadataPointerState,
getTokenMetadata,
TYPE_SIZE,
LENGTH_SIZE,
} from "@solana/spl-token";
import {
createInitializeInstruction,
createUpdateFieldInstruction,
createRemoveKeyInstruction,
pack,
TokenMetadata,
} from "@solana/spl-token-metadata";
// Playground cüzdanı
const payer = pg.wallet.keypair;
// Devnet kümesine bağlantı
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
// Gönderilecek işlem
let transaction: Transaction;
// Gönderilen işlemden dönen işlem imzası
let transactionSignature: string;
Mint Ayarı
Sonraki adımda, oluşturacağımız Mint Hesabı'nın özelliklerini tanımlayın.
// Mint Hesabı için yeni anahtar çifti oluştur
const mintKeypair = Keypair.generate();
// Mint Hesabı için adres
const mint = mintKeypair.publicKey;
// Mint Hesabı için ondalık
const decimals = 2;
// Yeni token'lar basma yetkisi
const mintAuthority = pg.wallet.publicKey;
// Metadata pointer ve token metadata'yı güncelleyebilecek yetki
const updateAuthority = pg.wallet.publicKey;
// Mint Hesabı'nda saklanacak metadata
const metaData: TokenMetadata = {
updateAuthority: updateAuthority,
mint: mint,
name: "OPOS",
symbol: "OPOS",
uri: "https://raw.githubusercontent.com/solana-developers/opos-asset/main/assets/DeveloperPortal/metadata.json",
additionalMetadata: [["description", "Sadece Solana Üzerinde Mümkündür"]],
};
Daha sonra, yeni Mint Hesabı'nın boyutunu belirleyin ve kira muafiyeti için gereken minimum lamportları hesaplayın.
Aşağıdaki kod parçasında, TokenMetadata
uzantısı için 4 byte ayırıyoruz ve daha sonra metadata'nın gerektirdiği alanı hesaplıyoruz.
// MetadataExtension için boyut 2 byte tür, 2 byte uzunluk
const metadataExtension = TYPE_SIZE + LENGTH_SIZE;
// Metadata boyutu
const metadataLen = pack(metaData).length;
// Uzantı ile birlikte Mint Hesabı'nın boyutu
const mintLen = getMintLen([ExtensionType.MetadataPointer]);
// Mint Hesabı için gereken minimum lamport
const lamports = await connection.getMinimumBalanceForRentExemption(
mintLen + metadataExtension + metadataLen,
);
Token Uzantıları ile birlikte, Mint Hesabı'nın boyutu etkinleştirilen uzantılara bağlı olarak değişiklik gösterecektir.
Talimatları Oluştur
Sonraki adımda, aşağıdakileri yapacak bir talimat seti oluşturalım:
- Yeni bir hesap oluştur
MetadataPointer
uzantısını başlat- Geri kalan Mint Hesabı verilerini başlat
TokenMetadata
uzantısını ve token metadata'sını başlat- Token metadata'sını özel bir alan ile güncelle
Öncelikle, Sistem Programını çağırarak bir hesap oluşturmak için talimatı oluşturun ve Token Uzantıları Programı'na sahiplik atayın.
// Yeni hesap oluşturmak için Sistem Programını çağıran talimat
const createAccountInstruction = SystemProgram.createAccount({
fromPubkey: payer.publicKey, // Lamportları yaratılan hesaba transfer edecek hesap
newAccountPubkey: mint, // Oluşturulacak hesabın adresi
space: mintLen, // Oluşturulacak hesaba tahsis edilecek byte miktarı
lamports, // Oluşturulan hesaba transfer edilen lamport miktarı
programId: TOKEN_2022_PROGRAM_ID, // Oluşturulan hesabın sahibi olarak atanan program
});
Sonraki adımda, Mint Hesabı için MetadataPointer
uzantısını başlatacak talimatı oluşturun. Bu örnekte, metadata pointer'ı Mint adresine işaret eder; bu da metadata'nın doğrudan Mint Hesabı'nda saklanacağını gösterir.
// MetadataPointer Uzantısını başlatmak için talimat
const initializeMetadataPointerInstruction =
createInitializeMetadataPointerInstruction(
mint, // Mint Hesabı adresi
updateAuthority, // Metadata adresini ayarlayabilen yetki
mint, // Metadata'yı tutan hesap adresi
TOKEN_2022_PROGRAM_ID,
);
Sonraki adımda, Mint Hesabı'nın geri kalan verilerini başlatacak talimatı oluşturun. Bu, orijinal Token Programı ile aynıdır.
// Mint Hesabı verilerini başlatmak için talimat
const initializeMintInstruction = createInitializeMintInstruction(
mint, // Mint Hesabı Adresi
decimals, // Mint'in Ondalık Sayısı
mintAuthority, // Atanan Mint Yetkilisi
null, // Opsiyonel Dondurma Yetkilisi
TOKEN_2022_PROGRAM_ID, // Token Uzantıları Programı ID'si
);
Daha sonra, TokenMetadata
uzantısını ve gerekli metadata alanlarını (isim, sembol, URI) başlatacak talimatı oluşturun.
Bu talimatta, metadata'nın Mint Hesabı'nın adresi kullanılarak metadata
olarak atanmaz, bu da Mint'in kendisinin "Metadata Hesabı" olduğunu gösterir.
// Metadata Hesabı verilerini başlatmak için talimat
const initializeMetadataInstruction = createInitializeInstruction({
programId: TOKEN_2022_PROGRAM_ID, // Token Uzantıları Programı "Metadata Program" olarak
metadata: mint, // Metadata'yı tutan hesap adresi
updateAuthority: updateAuthority, // Metadata'yı güncelleyebilen yetki
mint: mint, // Mint Hesabı adresi
mintAuthority: mintAuthority, // Atanan Mint Yetkilisi
name: metaData.name,
symbol: metaData.symbol,
uri: metaData.uri,
});
Daha sonra, UpdateField
talimatını kullanarak metadata'yı özel bir alan ile güncelleyecek talimatı oluşturun.
Bu talimat, mevcut bir alanın değerini güncelleyebilir veya mevcut değilse additional_metadata
'ya ekleyebilir. Not: Hesabı ek veri almak için daha fazla alan ayırmanız gerekebilir. Bu örnekte, hesabı oluştururken tüm kira için gerekli lamportları önceden tahsis ettik.
// Metadata'yı güncellemek, özel alan eklemek için talimat
const updateFieldInstruction = createUpdateFieldInstruction({
programId: TOKEN_2022_PROGRAM_ID, // Token Uzantıları Programı "Metadata Program" olarak
metadata: mint, // Metadata'yı tutan hesap adresi
updateAuthority: updateAuthority, // Metadata'yı güncelleyebilen yetki
field: metaData.additionalMetadata[0][0], // anahtar
value: metaData.additionalMetadata[0][1], // değer
});
İşlemi Gönder
Sıradaki adımda, talimatları yeni bir işleve ekleyin ve ağına gönderin. Bu, MetadataPointer
ve TokenMetadata
uzantıları etkinleştirilmiş bir Mint Hesabı oluşturacak ve metadata'yı Mint Hesabı'nda depolayacaktır.
Bazı token uzantısı talimatları, minti başlatmadan önce atomik sıraya dizilmelidir. Diğerleri ise sonrasında. Bu talimatların "dışı" yanlış sıralandığında işleminiz başarısız olabilir.
// Yeni işleme talimatları ekleyin
transaction = new Transaction().add(
createAccountInstruction,
initializeMetadataPointerInstruction,
// not: yukarıdaki talimatlar, minti başlatmadan önce gereklidir
initializeMintInstruction,
initializeMetadataInstruction,
updateFieldInstruction,
);
// İşlemi gönder
transactionSignature = await sendAndConfirmTransaction(
connection,
transaction,
[payer, mintKeypair], // İmzalayanlar
);
console.log(
"\nMint Hesabı Oluştur:",
`https://solana.fm/tx/${transactionSignature}?cluster=devnet-solana`,
);
Mint Hesabından Metadata Okuma
Metadata'nın Mint Hesabı'nda depolandığını kontrol edin.
Başlangıç olarak, Mint Hesabı'nı alarak MetadataPointer
uzantısı kısmını hesap verilerinden okuyun:
// Mint bilgilerini al
const mintInfo = await getMint(
connection,
mint,
"confirmed",
TOKEN_2022_PROGRAM_ID,
);
// Metadata pointer durumunu al ve kaydet
const metadataPointer = getMetadataPointerState(mintInfo);
console.log("\nMetadata Pointer:", JSON.stringify(metadataPointer, null, 2));
Daha sonra, hesap verilerinin metadata kısmını okuyun:
// Metadata durumunu al ve kaydet
const metadata = await getTokenMetadata(
connection,
mint, // Mint Hesabı adresi
);
console.log("\nMetadata:", JSON.stringify(metadata, null, 2));
Scripti Çalıştır
butonuna tıklayarak çalıştırın. Ardından işlem detaylarını SolanaFM'de kontrol edebilirsiniz.
Ayrıca aşağıdaki gibi bir konsol çıktısı görmelisiniz:
Metadata Pointer: {
"authority": "3z9vL1zjN6qyAFHhHQdWYRTFAcy69pJydkZmSFBKHg1R",
"metadataAddress": "BFqmKEm12CrDbcFAncjL34Anu5w18LruxQrgvy7aExzV"
}
Metadata: {
"updateAuthority": "3z9vL1zjN6qyAFHhHQdWYRTFAcy69pJydkZmSFBKHg1R",
"mint": "BFqmKEm12CrDbcFAncjL34Anu5w18LruxQrgvy7aExzV",
"name": "OPOS",
"symbol": "OPOS",
"uri": "https://raw.githubusercontent.com/solana-developers/opos-asset/main/assets/DeveloperPortal/metadata.json",
"additionalMetadata": [
[
"description",
"Sadece Solana Üzerinde Mümkündür"
]
]
}
Özel Alanı Kaldır
Metadata'dan özel bir alanı silmek için, Token Metadata Arayüzü'nden RemoveKey
talimatını kullanın.
Önemli Uyarı: idempotent
bayrağı, anahtarın hesapta yoksa işlemin başarısız olup olmayacağını belirler. Eğer idempotent bayrağı true
olarak ayarlanmışsa, talimat anahtar yoksa hata vermez.
// Metadata'dan bir anahtarı kaldırma talimatı
const removeKeyInstruction = createRemoveKeyInstruction({
programId: TOKEN_2022_PROGRAM_ID, // Token Uzantıları Programı "Metadata Program" olarak
metadata: mint, // Metadata'nın adresi
updateAuthority: updateAuthority, // Metadata'yı güncelleyebilen yetki
key: metaData.additionalMetadata[0][0], // Metadata'dan kaldırılacak anahtar
idempotent: true, // idempotent bayrağı `true` olarak ayarlandıysa, talimat anahtar yoksa hata vermez
});
// Yeni işleme talimatı ekle
transaction = new Transaction().add(removeKeyInstruction);
// İşlemi gönder
transactionSignature = await sendAndConfirmTransaction(
connection,
transaction,
[payer],
);
console.log(
"\nEk Metadata Alanını Kaldır:",
`https://solana.fm/tx/${transactionSignature}?cluster=devnet-solana`,
);
// Metadata durumunu al ve kaydet
const updatedMetadata = await getTokenMetadata(
connection,
mint, // Mint Hesabı adresi
);
console.log("\nGüncellenmiş Metadata:", JSON.stringify(updatedMetadata, null, 2));
console.log(
"\nMint Hesabı:",
`https://solana.fm/address/${mint}?cluster=devnet-solana`,
);
Scripti Çalıştır
butonuna tıklayarak çalıştırın. Ardından işlem detaylarını ve Mint Hesabını SolanaFM'de kontrol edebilirsiniz.
Ayrıca aşağıdaki gibi bir konsol çıktısı görmelisiniz:
Güncellenmiş Metadata: {
"updateAuthority": "Ehqz1TAMboGbY5oBWqKKWmv5hhvQuwcpkaWbVjkU96cZ",
"mint": "9wdvSnsqgYo4HFBYMtiCvVNQfFBYdzSeACjLuxVCDcjB",
"name": "OPOS",
"symbol": "OPOS",
"uri": "https://raw.githubusercontent.com/solana-developers/opos-asset/main/assets/DeveloperPortal/metadata.json",
"additionalMetadata": []
}