Token Uzantılarını Kullanarak Dinamik Meta Veri NFT'leri
Token Uzantı programı sayesinde, meta veri uzantılarını kullanarak NFT'ler ve dijital varlıklar yaratabilirsiniz. Bu uzantılar, (meta veri işaretçisi ve token meta verisi) istediğiniz her türlü meta veriyi doğrudan zincir üzerinde kaydetmenize imkan tanır. Tüm bunlar, özelleştirilebilir bir anahtar-değer veri deposu içinde, token'ın mint hesabında yer alır ve maliyetleri ve karmaşıklığı azaltır.
Bu özellik, özellikle web3 oyunları için harikadır çünkü artık zincir üzerindeki bir anahtar-değer deposunda "ek meta veri alanları" bulundurabiliyoruz. Bu sayede oyunların NFT'nin kendisi içinde (örneğin bir oyun karakterinin istatistikleri veya envanteri) benzersiz durumu kaydetmesini/erişmesini sağlar.
Zincir Üstü Programın İnşası
Bu geliştirici kılavuzunda, Token Uzantılarına dayalı NFT'ler ve özel meta verileri nasıl oluşturacağınızı göstereceğiz. Bunu Anchor programı kullanarak gerçekleştireceğiz. Bu program, bir oyun oyuncusunun seviyesini ve topladığı kaynakları bir NFT içinde saklayacak.
Bu NFT, Anchor programı tarafından oluşturulacak, bu nedenle JavaScript istemcisinden mint etmesi oldukça kolaydır. Her NFT, Token Metadata arayüzü aracılığıyla sağlanan bazı temel yapıya sahip olacaktır:
- varsayılan zincir üstü alanlar -
name,symbolveuriuri, NFT'nin offchain meta verilerini içeren bir offchain json dosyasına bir bağlantıdır
- ayrıca tanımladığımız özel "ilave alanlar" da olacaktır
Bu alanların tümü, NFT'nin mint hesabına işaret eden meta veri uzantısı kullanılarak kaydedilir ve böylece herkes veya her program tarafından erişilebilir hale gelir.
Bu örneğin video yürüyüşünü Solana Vakfı Youtube kanalında bulabilirsiniz:
Oyunlardaki Diğer Kullanım Durumları
Bu tür özelleştirilebilir zincir üstü meta verilere sahip NFT'ler, oyun geliştiricileri için birçok ilginç olasılık açar. Özellikle bu meta verilerin doğrudan etkileşime geçilmesi veya bir zincir üstü program tarafından yönetilmesi mümkündür.
Bu oyunla ilgili bazı kullanım durumları şunları içerebilir:
- oyuncunun seviyesini ve XP'sini kaydetmek
- mevcut silah ve zırh
- mevcut görev
- liste devam ediyor!
NFT Mint Etme
NFT'yi oluşturmak için aşağıdaki adımları izlememiz gerekmektedir:
- Bir mint hesabı oluşturun
- Mint hesabını başlatın
- Bir meta veri işaretçisi hesabı oluşturun
- Meta veri işaretçisi hesabını başlatın
- Meta veri hesabını oluşturun
- Meta veri hesabını başlatın
- İlişkili token hesabını oluşturun
- Token'ı ilişkili token hesabına mint edin
- Mint yetkisini dondurun
Rust Program Kodu
Token uzantı programını kullanarak NFT'yi mint etmek için kullanılan rust kodu aşağıdaki gibidir:
// arzu edilen uzantılar ile mint hesabı için gereken alanı hesaplayın
let space = ExtensionType::try_calculate_account_len::<Mint>(
&[ExtensionType::MetadataPointer])
.unwrap();
// Meta veri hesabı için gereken alan.
// Meta veriyi mint hesabının en sonuna koyarız, böylece
// ek bir hesap yaratmamıza gerek kalmaz.
// Sonra meta veri işaretçisi geri mint hesabına işaret eder.
// Bu teknikle, hem mint bilgileri hem de meta veri için sadece bir hesaba ihtiyaç vardır.
let meta_data_space = 250;
let lamports_required = (Rent::get()?).minimum_balance(space + meta_data_space);
msg!(
"Mint ve meta veri hesap boyutu ve maliyeti: {} lamports: {}",
space as u64,
lamports_required
);
system_program::create_account(
CpiContext::new(
ctx.accounts.token_program.to_account_info(),
system_program::CreateAccount {
from: ctx.accounts.signer.to_account_info(),
to: ctx.accounts.mint.to_account_info(),
},
),
lamports_required,
space as u64,
&ctx.accounts.token_program.key(),
)?;
// Mint'i token programına atayın
system_program::assign(
CpiContext::new(
ctx.accounts.token_program.to_account_info(),
system_program::Assign {
account_to_assign: ctx.accounts.mint.to_account_info(),
},
),
&token_2022::ID,
)?;
// Meta veri işaretçisini başlatın (Mint'i başlatmadan önce bunu yapmalısınız)
let init_meta_data_pointer_ix =
spl_token_2022::extension::metadata_pointer::instruction::initialize(
&Token2022::id(),
&ctx.accounts.mint.key(),
Some(ctx.accounts.nft_authority.key()),
Some(ctx.accounts.mint.key()),
)
.unwrap();
invoke(
&init_meta_data_pointer_ix,
&[
ctx.accounts.mint.to_account_info(),
ctx.accounts.nft_authority.to_account_info()
],
)?;
// Mint cpi'yi başlatın
let mint_cpi_ix = CpiContext::new(
ctx.accounts.token_program.to_account_info(),
token_2022::InitializeMint2 {
mint: ctx.accounts.mint.to_account_info(),
},
);
token_2022::initialize_mint2(
mint_cpi_ix,
0,
&ctx.accounts.nft_authority.key(),
None).unwrap();
// Meta veri hesabı için mint yetkisi olarak bir PDA kullanıyoruz çünkü
// NFT'yi programdan güncelleyebilmek istiyoruz.
let seeds = b"nft_authority";
let bump = ctx.bumps.nft_authority;
let signer: &[&[&[u8]]] = &[&[seeds, &[bump]]];
msg!("Meta veri başlatıldı {0}", ctx.accounts.nft_authority.to_account_info().key);
// Meta veri hesabını başlatın
let init_token_meta_data_ix =
&spl_token_metadata_interface::instruction::initialize(
&spl_token_2022::id(),
ctx.accounts.mint.key,
ctx.accounts.nft_authority.to_account_info().key,
ctx.accounts.mint.key,
ctx.accounts.nft_authority.to_account_info().key,
"Beaver".to_string(),
"BVA".to_string(),
"https://arweave.net/MHK3Iopy0GgvDoM7LkkiAdg7pQqExuuWvedApCnzfj0".to_string(),
);
invoke_signed(
init_token_meta_data_ix,
&[ctx.accounts.mint.to_account_info().clone(), ctx.accounts.nft_authority.to_account_info().clone()],
signer,
)?;
// Meta veri hesabını, bu durumda oyuncu seviyesini içeren ek bir alan ile güncelleyin
invoke_signed(
&spl_token_metadata_interface::instruction::update_field(
&spl_token_2022::id(),
ctx.accounts.mint.key,
ctx.accounts.nft_authority.to_account_info().key,
spl_token_metadata_interface::state::Field::Key("level".to_string()),
"1".to_string(),
),
&[
ctx.accounts.mint.to_account_info().clone(),
ctx.accounts.nft_authority.to_account_info().clone(),
],
signer
)?;
// İlişkili token hesabını oluşturun
associated_token::create(
CpiContext::new(
ctx.accounts.associated_token_program.to_account_info(),
associated_token::Create {
payer: ctx.accounts.signer.to_account_info(),
associated_token: ctx.accounts.token_account.to_account_info(),
authority: ctx.accounts.signer.to_account_info(),
mint: ctx.accounts.mint.to_account_info(),
system_program: ctx.accounts.system_program.to_account_info(),
token_program: ctx.accounts.token_program.to_account_info(),
},
))?;
// Bir tane token'ı oyuncunun ilişkili token hesabına mint edin
token_2022::mint_to(
CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
token_2022::MintTo {
mint: ctx.accounts.mint.to_account_info(),
to: ctx.accounts.token_account.to_account_info(),
authority: ctx.accounts.nft_authority.to_account_info(),
},
signer
),
1,
)?;
// Mint yetkisini dondurun, böylece daha fazla token mint edilmeyecek ve NFT haline gelecek
token_2022::set_authority(
CpiContext::new_with_signer(
ctx.accounts.token_program.to_account_info(),
token_2022::SetAuthority {
current_authority: ctx.accounts.nft_authority.to_account_info(),
account_or_mint: ctx.accounts.mint.to_account_info(),
},
signer
),
AuthorityType::MintTokens,
None,
)?;
JavaScript İstemci Kodu
İstemciden NFT mint etmek çok kolaydır:
const nftAuthority = PublicKey.findProgramAddressSync(
[Buffer.from("nft_authority")],
program.programId,
);
const mint = new Keypair();
const destinationTokenAccount = getAssociatedTokenAddressSync(
mint.publicKey,
publicKey,
false,
TOKEN_2022_PROGRAM_ID,
);
const transaction = await program.methods
.mintNft()
.accounts({
signer: publicKey,
systemProgram: SystemProgram.programId,
tokenProgram: TOKEN_2022_PROGRAM_ID,
tokenAccount: destinationTokenAccount,
mint: mint.publicKey,
rent: web3.SYSVAR_RENT_PUBKEY,
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
nftAuthority: nftAuthority[0],
})
.signers([mint])
.transaction();
console.log("işlem", transaction);
const txSig = await sendTransaction(transaction, connection, {
signers: [mint],
skipPreflight: true,
});
console.log(`https://explorer.solana.com/tx/${txSig}?cluster=devnet`);
Hızlı Başlangıç Örneği
Yukarıdaki örnek, Solana Oyunları Ön Ayarı'na dayanmaktadır ve bu, size JavaScript ve Unity istemcisini içeren bir iskelet oluşturur ve Solana Anchor programı ile etkileşim için yapılandırma içerir.
Aşağıdaki komut ile kendiniz çalıştırabilirsiniz:
npx create-solana-game gameName
Yerel Ortamınızı Ayarlayın
Bu örneği yerel olarak çalıştırmak için, Solana geliştirme için yerel ortamınızı ayarlamış olduğunuzdan emin olmalısınız; bu, Anchor CLI'yi yüklemeyi ve yapılandırmayı içerir.
Eğer henüz yapmadıysanız, daha önce bağlantılı olan ayar kılavuzunu takip edebilirsiniz.
Proje Yapısı
Anchor projesi şöyle yapılandırılmıştır:
Giriş noktası lib.rs dosyasındadır. Burada program kimliğini ve talimatları tanımlarız. Talimatlar, talimatlar klasöründe tanımlanmıştır. Durum, durum klasöründe tanımlanmıştır.
Böylece çağrılar lib.rs dosyasına gelir ve ardından talimatlara iletilir. Talimatlar, verileri almak ve güncellemek için durumu çağırır.
NFT'yi mint etme talimatını talimatlar klasöründe bulabilirsiniz.
├── src
│ ├── instructions
│ │ ├── chop_tree.rs
│ │ ├── init_player.rs
│ │ ├── mint_nft.rs
│ │ └── update_energy.rs
│ ├── state
│ │ ├── game_data.rs
│ │ ├── mod.rs
│ │ └── player_data.rs
│ ├── lib.rs
│ └── constants.rs
│ └── errors.rs
Anchor Programı
create-solana-game aracından oluşturulan Anchor programının ayarını bitirmek için:
cd programyazarak program dizinine gidinanchor buildyazarak programı derleyinanchor deployyazarak programı dağıtın- Terminalden program kimliğini alarak
lib.rs,anchor.tomlve Unity projesindeAnchorServiceile eğer JavaScript kullanıyorsanızanchor.tsdosyalarına kopyalayın - Tekrar derleyin ve dağıtın
NextJS İstemcisi
create-solana-game aracından oluşturulan NextJS istemcisinin ayarını bitirmek için:
programIddeğeriniapp/utils/anchor.tsdosyasına kopyalayıncd appyazarak uygulama dizinine gidin- Node bağımlılıklarını yüklemek için
yarn installyazın - İstemciyi başlatmak için
yarn devyazın - Anchor programında değişiklik yaptıktan sonra, türleri istemciye kopyaladığınızdan emin olun ki kullanabilirsiniz. TypeScript türlerini
target/idlklasöründe bulabilirsiniz.
Bu Örneği Yerel Olarak Çalıştırın
Anchor'ın test komutu --detach bayrağı ile birlikte, Solana yerel test doğrulayıcınızı başlatır ve yapılandırır, programın dağıtılması sağlanır (ve testler tamamlandıktan sonra doğrulayıcıyı çalışır durumda tutar):
cd program
anchor test --detach
Daha sonra Solana Explorer adresini yerel test doğrulayıcınızı kullanacak şekilde ayarlayabilirsiniz (bu, anchor test komutunu çalıştırdığınızda başlar) böylece işlemleri görebilirsiniz:
https://explorer.solana.com/?cluster=custom&customUrl=http%3A%2F%2Flocalhost%3A8899
Program, net üzerinde de zaten dağıtılmış durumda, böylece devnet üzerinde deneyebilirsiniz. JavaScript istemcisinin ayrıca NFT'yi mint etmek için bir düğmesi de bulunmaktadır. JavaScript istemcisini başlatmak için:
cd app
yarn install
yarn dev
Unity Projesini Açın
Öncelikle Unity 2021.3.32.f1 (veya benzeri) sürümü ile Unity projesini açın, ardından GameScene veya LoginScene sahnesini açın ve oynat düğmesine basın. Sol alt köşedeki editör giriş düğmesini kullanın.
Eğer devnet SOL alamıyorsanız, konsoldan adresinizi kopyalayıp, devnet SOL alma rehberindeki talimatları takip edebilirsiniz.
Unity'de Solana Test Doğrulayıcısına Bağlanın
Devnet SOL elde etme sorununu yaşamamak için, Unity içinden çalışan yerel test doğrulayıcınıza bağlanabilirsiniz. Cüzdan sahibi oyun nesnesine bu bağlantıları ekleyin:
http://localhost:8899
ws://localhost:8900
JavaScript İstemcisini Çalıştırın
JavaScript istemcisini başlatmak ve oyunla ve programla web tarayıcınızı kullanarak etkileşime geçmek için:
- repodaki
appdizinini açın - Node bağımlılıklarını yükleyin
- geliştirme sunucusunu başlatmak için
devkomutunu çalıştırın
cd app
yarn install
yarn dev
Programı değiştirmeye ve kendi programınıza bağlanmaya başlamak için aşağıdaki adımları izleyin.