Solana DokümantasyonuProgram geliştirme

Rust ile Program Geliştirme

Solana programları öncelikle Rust programlama dili kullanılarak geliştirilir. Bu sayfa, Anchor çerçevesini kullanmadan Rust'ta Solana programları yazmaya odaklanmaktadır, bu yaklaşım genellikle "native Rust" programları yazmak olarak adlandırılır.

Native Rust geliştirme, geliştiricilere Solana programları üzerinde doğrudan kontrol sağlar. Ancak, bu yaklaşım Anchor çerçevesini kullanmaya kıyasla daha fazla manuel kurulum ve şablon kod gerektirir. Bu yöntem şu geliştiriciler için önerilir:

  • Program mantığı ve optimizasyonlar üzerinde ayrıntılı kontrol arayanlar
  • Daha üst düzey çerçevelere geçmeden önce temel kavramları öğrenmek isteyenler

Yeni başlayanlar için Anchor çerçevesi ile başlamanızı öneririz. Daha fazla bilgi için Anchor bölümüne bakın.

Ön Koşullar

Ayrıntılı kurulum talimatları için kurulum sayfasını ziyaret edin.

Başlamadan önce, aşağıdakilerin kurulu olduğundan emin olun:

  • Rust: Solana programları oluşturmak için programlama dili.
  • Solana CLI: Solana geliştirme için komut satırı aracı.

Başlarken

Aşağıdaki örnek, Rust ile yazılmış ilk Solana programınızı oluşturmak için temel adımları kapsar. Program günlüğüne "Hello, world!" yazdıran minimal bir program oluşturacağız.

Yeni Bir Program Oluşturma

İlk olarak, standart cargo init komutunu --lib bayrağı ile kullanarak yeni bir Rust projesi oluşturun.

Terminal
cargo init hello_world --lib

Proje dizinine gidin. Varsayılan src/lib.rs ve Cargo.toml dosyalarını görmelisiniz

Terminal
cd hello_world

Ardından, solana-program bağımlılığını ekleyin. Bu, bir Solana programı oluşturmak için gereken minimum bağımlılıktır.

Terminal
cargo add solana-program@1.18.26

Sonraki adımda, aşağıdaki kod parçasını Cargo.toml dosyasına ekleyin. Bu konfigürasyonu eklemezseniz, programı derlediğinizde target/deploy dizini oluşturulmayacaktır.

Cargo.toml
[lib]
crate-type = ["cdylib", "lib"]

Cargo.toml dosyanız aşağıdaki gibi görünmelidir:

Cargo.toml
[package]
name = "hello_world"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib", "lib"]
[dependencies]
solana-program = "1.18.26"

Şimdi, src/lib.rs dosyasının içeriğini aşağıdaki kodla değiştirin. Bu, program çağrıldığında program günlüğüne "Hello, world!" yazdıran minimal bir Solana programıdır.

msg! makrosu, Solana programlarında program günlüğüne mesaj yazdırmak için kullanılır.

lib.rs
use solana_program::{
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, msg, pubkey::Pubkey,
};
entrypoint!(process_instruction);
pub fn process_instruction(
_program_id: &Pubkey,
_accounts: &[AccountInfo],
_instruction_data: &[u8],
) -> ProgramResult {
msg!("Hello, world!");
Ok(())
}

Programı derleyin

Şimdi, programı cargo build-sbf komutunu kullanarak derleyin.

Terminal
cargo build-sbf

Bu komut, iki önemli dosya içeren bir target/deploy dizini oluşturur:

  1. Bir .so dosyası (örn., hello_world.so): Bu, "akıllı sözleşme" olarak ağa dağıtılacak derlenmiş Solana programıdır.
  2. Bir keypair dosyası (örn., hello_world-keypair.json): Bu keypair'in açık anahtarı, programı dağıtırken program kimliği olarak kullanılır.

Program kimliğini görmek için terminalinizde aşağıdaki komutu çalıştırın. Bu komut, belirtilen dosya yolundaki keypair'in açık anahtarını yazdırır:

Terminal
solana address -k ./target/deploy/hello_world-keypair.json

Örnek çıktı:

4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz

Programı test edin

Şimdi, programı solana-program-test paketi kullanarak test edin. Aşağıdaki bağımlılıkları Cargo.toml dosyasına ekleyin.

Terminal
cargo add solana-program-test@1.18.26 --dev
cargo add solana-sdk@1.18.26 --dev
cargo add tokio --dev

Aşağıdaki testi, program kodunun altında olacak şekilde src/lib.rs dosyasına ekleyin. Bu, merhaba dünya programını çağıran bir test modülüdür.

lib.rs
#[cfg(test)]
mod test {
use solana_program_test::*;
use solana_sdk::{
instruction::Instruction, pubkey::Pubkey, signature::Signer, transaction::Transaction,
};
#[tokio::test]
async fn test_hello_world() {
let program_id = Pubkey::new_unique();
let mut program_test = ProgramTest::default();
program_test.add_program("hello_world", program_id, None);
let (mut banks_client, payer, recent_blockhash) = program_test.start().await;
// Create instruction
let instruction = Instruction {
program_id,
accounts: vec![],
data: vec![],
};
// Create transaction with instruction
let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey()));
// Sign transaction
transaction.sign(&[&payer], recent_blockhash);
let transaction_result = banks_client.process_transaction(transaction).await;
assert!(transaction_result.is_ok());
}
}

Testi cargo test-sbf komutunu kullanarak çalıştırın. Program günlüğünde "Hello, world!" görüntülenecektir.

Terminal
cargo test-sbf

Örnek çıktı:

Terminal
running 1 test
[2024-10-18T21:24:54.889570000Z INFO solana_program_test] "hello_world" SBF program from /hello_world/target/deploy/hello_world.so, modified 35 seconds, 828 ms, 268 µs and 398 ns ago
[2024-10-18T21:24:54.974294000Z DEBUG solana_runtime::message_processor::stable_log] Program 1111111QLbz7JHiBTspS962RLKV8GndWFwiEaqKM invoke [1]
[2024-10-18T21:24:54.974814000Z DEBUG solana_runtime::message_processor::stable_log] Program log: Hello, world!
[2024-10-18T21:24:54.976848000Z DEBUG solana_runtime::message_processor::stable_log] Program 1111111QLbz7JHiBTspS962RLKV8GndWFwiEaqKM consumed 140 of 200000 compute units
[2024-10-18T21:24:54.976868000Z DEBUG solana_runtime::message_processor::stable_log] Program 1111111QLbz7JHiBTspS962RLKV8GndWFwiEaqKM success
test test::test_hello_world ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.13s

Programı Dağıt

Sonraki adım, programı dağıtmak. Yerel geliştirme yaparken, solana-test-validator kullanabiliriz.

Öncelikle, Solana CLI'yi yerel Solana kümesini kullanacak şekilde yapılandırın.

Terminal
solana config set -ul

Örnek çıktı:

Config File: /.config/solana/cli/config.yml
RPC URL: http://localhost:8899
WebSocket URL: ws://localhost:8900/ (computed)
Keypair Path: /.config/solana/id.json
Commitment: confirmed

Yeni bir terminal açın ve yerel validator'ı başlatmak için solana-test-validators komutunu çalıştırın.

Terminal
solana-test-validator

Test validator'ı çalışırken, ayrı bir terminalde solana program deploy komutunu çalıştırarak programı yerel validator'a dağıtın.

Terminal
solana program deploy ./target/deploy/hello_world.so

Örnek çıktı:

Program Id: 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz
Signature:
5osMiNMiDZGM7L1e2tPHxU8wdB8gwG8fDnXLg5G7SbhwFz4dHshYgAijk4wSQL5cXiu8z1MMou5kLadAQuHp7ybH

Program kimliğini ve işlem imzasını Solana Explorer üzerinde inceleyebilirsiniz. Solana Explorer'daki kümenin de localhost olması gerektiğini unutmayın. Solana Explorer'daki "Custom RPC URL" seçeneği varsayılan olarak http://localhost:8899 şeklindedir.

Programı Çağır

Şimdi, bir Rust istemcisi kullanarak programı nasıl çağıracağımızı göstereceğiz.

Önce bir examples dizini ve bir client.rs dosyası oluşturun.

Terminal
mkdir -p examples
touch examples/client.rs

Aşağıdakileri Cargo.toml dosyasına ekleyin.

Cargo.toml
[[example]]
name = "client"
path = "examples/client.rs"

solana-client bağımlılığını ekleyin.

Terminal
cargo add solana-client@1.18.26 --dev

Aşağıdaki kodu examples/client.rs dosyasına ekleyin. Bu, işlem ücretlerini ödemek için yeni bir keypair'i fonlayan ve ardından merhaba dünya programını çağıran bir Rust istemci komut dosyasıdır.

example/client.rs
use solana_client::rpc_client::RpcClient;
use solana_sdk::{
commitment_config::CommitmentConfig,
instruction::Instruction,
pubkey::Pubkey,
signature::{Keypair, Signer},
transaction::Transaction,
};
use std::str::FromStr;
#[tokio::main]
async fn main() {
// Program ID (replace with your actual program ID)
let program_id = Pubkey::from_str("4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz").unwrap();
// Connect to the Solana devnet
let rpc_url = String::from("http://127.0.0.1:8899");
let client = RpcClient::new_with_commitment(rpc_url, CommitmentConfig::confirmed());
// Generate a new keypair for the payer
let payer = Keypair::new();
// Request airdrop
let airdrop_amount = 1_000_000_000; // 1 SOL
let signature = client
.request_airdrop(&payer.pubkey(), airdrop_amount)
.expect("Failed to request airdrop");
// Wait for airdrop confirmation
loop {
let confirmed = client.confirm_transaction(&signature).unwrap();
if confirmed {
break;
}
}
// Create the instruction
let instruction = Instruction::new_with_borsh(
program_id,
&(), // Empty instruction data
vec![], // No accounts needed
);
// Add the instruction to new transaction
let mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey()));
transaction.sign(&[&payer], client.get_latest_blockhash().unwrap());
// Send and confirm the transaction
match client.send_and_confirm_transaction(&transaction) {
Ok(signature) => println!("Transaction Signature: {}", signature),
Err(err) => eprintln!("Error sending transaction: {}", err),
}
}

Komut dosyasını çalıştırmadan önce, yukarıdaki kod parçacığındaki program kimliğini kendi programınızın kimliği ile değiştirin.

Aşağıdaki komutu çalıştırarak program kimliğinizi alabilirsiniz.

Terminal
solana address -k ./target/deploy/hello_world-keypair.json
#[tokio::main]
async fn main() {
- let program_id = Pubkey::from_str("4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz").unwrap();
+ let program_id = Pubkey::from_str("YOUR_PROGRAM_ID).unwrap();
}
}

İstemci komut dosyasını aşağıdaki komutla çalıştırın.

Terminal
cargo run --example client

Örnek çıktı:

Transaction Signature: 54TWxKi3Jsi3UTeZbhLGUFX6JQH7TspRJjRRFZ8NFnwG5BXM9udxiX77bAACjKAS9fGnVeEazrXL4SfKrW7xZFYV

Program günlüğünde "Hello, world!" mesajını görmek için işlem imzasını Solana Explorer (yerel küme) üzerinde inceleyebilirsiniz.

Programı güncelleme

Solana programları aynı program kimliğine yeniden dağıtılarak güncellenebilir. src/lib.rs dosyasındaki programı "Hello, world!" yerine "Hello, Solana!" yazdıracak şekilde güncelleyin.

lib.rs
pub fn process_instruction(
_program_id: &Pubkey,
_accounts: &[AccountInfo],
_instruction_data: &[u8],
) -> ProgramResult {
- msg!("Hello, world!");
+ msg!("Hello, Solana!");
Ok(())
}

Güncellenmiş programı cargo test-sbf komutunu çalıştırarak test edin.

Terminal
cargo test-sbf

Program günlüğünde "Hello, Solana!" mesajını görmelisiniz.

Terminal
running 1 test
[2024-10-23T19:28:28.842639000Z INFO solana_program_test] "hello_world" SBF program from /code/misc/delete/hello_world/target/deploy/hello_world.so, modified 4 minutes, 31 seconds, 435 ms, 566 µs and 766 ns ago
[2024-10-23T19:28:28.934854000Z DEBUG solana_runtime::message_processor::stable_log] Program 1111111QLbz7JHiBTspS962RLKV8GndWFwiEaqKM invoke [1]
[2024-10-23T19:28:28.936735000Z DEBUG solana_runtime::message_processor::stable_log] Program log: Hello, Solana!
[2024-10-23T19:28:28.938774000Z DEBUG solana_runtime::message_processor::stable_log] Program 1111111QLbz7JHiBTspS962RLKV8GndWFwiEaqKM consumed 140 of 200000 compute units
[2024-10-23T19:28:28.938793000Z DEBUG solana_runtime::message_processor::stable_log] Program 1111111QLbz7JHiBTspS962RLKV8GndWFwiEaqKM success
test test::test_hello_world ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.14s

Güncellenmiş bir .so dosyası oluşturmak için cargo build-sbf komutunu çalıştırın.

Terminal
cargo build-sbf

solana program deploy komutunu kullanarak programı yeniden dağıtın.

Terminal
solana program deploy ./target/deploy/hello_world.so

İstemci kodunu tekrar çalıştırın ve program günlüğünde "Hello, Solana!" mesajını görmek için işlem imzasını Solana Explorer'da inceleyin.

Terminal
cargo run --example client

Programı Kapatma

Solana programınızı kapatarak hesaba tahsis edilen SOL'u geri alabilirsiniz. Bir programı kapatmak geri alınamaz, bu nedenle dikkatle yapılmalıdır.

Bir programı kapatmak için solana program close <PROGRAM_ID> komutunu kullanın. Örneğin:

Terminal
solana program close 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz
--bypass-warning

Örnek çıktı:

Closed Program Id 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz, 0.1350588 SOL
reclaimed

Bir program kapatıldıktan sonra, program kimliğinin tekrar kullanılamayacağını unutmayın. Daha önce kapatılmış bir program kimliği ile program dağıtmaya çalışmak hata ile sonuçlanacaktır.

Error: Program 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz has been closed, use
a new Program Id

Bir programı kapattıktan sonra aynı kaynak koduyla yeniden dağıtmanız gerekiyorsa, yeni bir program kimliği oluşturmalısınız. Program için yeni bir keypair oluşturmak için aşağıdaki komutu çalıştırın:

Terminal
solana-keygen new -o ./target/deploy/hello_world-keypair.json --force

Alternatif olarak, mevcut keypair dosyasını (örneğin ./target/deploy/hello_world-keypair.json) silebilir ve yeni bir keypair dosyası oluşturacak olan cargo build-sbf komutunu tekrar çalıştırabilirsiniz.

Is this page helpful?

İçindekiler

Sayfayı Düzenle