Dokumentasi SolanaMengembangkan Program

Mengembangkan Program dalam Rust

Program Solana utamanya dikembangkan menggunakan bahasa pemrograman Rust. Halaman ini berfokus pada penulisan program Solana dalam Rust tanpa menggunakan framework Anchor, pendekatan yang sering disebut sebagai penulisan program "Rust native".

Pengembangan Rust native memberikan pengembang kontrol langsung atas program Solana mereka. Namun, pendekatan ini memerlukan lebih banyak pengaturan manual dan kode boilerplate dibandingkan dengan menggunakan framework Anchor. Metode ini direkomendasikan untuk pengembang yang:

  • Mencari kontrol yang lebih detail atas logika program dan optimisasi
  • Ingin mempelajari konsep dasar sebelum beralih ke framework tingkat yang lebih tinggi

Untuk pemula, kami merekomendasikan untuk memulai dengan framework Anchor. Lihat bagian Anchor untuk informasi lebih lanjut.

Prasyarat

Untuk petunjuk instalasi yang detail, kunjungi halaman instalasi.

Sebelum memulai, pastikan Anda telah menginstal hal-hal berikut:

  • Rust: Bahasa pemrograman untuk membangun program Solana.
  • Solana CLI: Alat command-line untuk pengembangan Solana.

Memulai

Contoh di bawah ini mencakup langkah-langkah dasar untuk membuat program Solana pertama Anda yang ditulis dalam Rust. Kita akan membuat program minimal yang mencetak "Hello, world!" ke log program.

Membuat program baru

Pertama, buat proyek Rust baru menggunakan perintah standar cargo new dengan flag --lib.

Terminal
$
cargo new hello_world --lib

Navigasikan ke direktori proyek. Anda akan melihat file default src/lib.rs dan Cargo.toml

Terminal
$
cd hello_world

Perbarui bidang edition di Cargo.toml menjadi 2021. Jika tidak, Anda mungkin mengalami error saat membangun program.

Tambahkan dependensi solana-program

Selanjutnya, tambahkan dependensi solana-program. Ini adalah dependensi minimum yang diperlukan untuk membangun program Solana.

Terminal
$
cargo add solana-program@2.2.0

Tambahkan crate-type

Selanjutnya, tambahkan snippet berikut ke Cargo.toml.

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

Jika Anda tidak menyertakan konfigurasi ini, direktori target/deploy tidak akan dibuat saat Anda membangun program.

File Cargo.toml Anda seharusnya terlihat seperti berikut:

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

Tambahkan kode program

Selanjutnya, ganti isi src/lib.rs dengan kode berikut. Ini adalah program Solana minimal yang mencetak "Hello, world!" ke log program ketika program dijalankan.

Makro msg! digunakan dalam program Solana untuk mencetak pesan ke log program.

src/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(())
}

Bangun program

Selanjutnya, bangun program menggunakan perintah cargo build-sbf.

Terminal
$
cargo build-sbf

Perintah ini menghasilkan direktori target/deploy yang berisi dua file penting:

  1. File .so (misalnya, hello_world.so): Ini adalah program Solana yang dikompilasi yang akan di-deploy ke jaringan sebagai "smart contract".
  2. File keypair (misalnya, hello_world-keypair.json): Kunci publik dari keypair ini digunakan sebagai ID program saat men-deploy program.

Untuk melihat ID program, jalankan perintah berikut di terminal Anda. Perintah ini mencetak kunci publik dari keypair pada jalur file yang ditentukan:

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

Contoh output:

4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz

Tambahkan dependensi pengujian

Selanjutnya, uji program menggunakan crate litesvm. Tambahkan dependensi berikut ke Cargo.toml.

Terminal
$
cargo add litesvm --dev
$
cargo add solana-sdk@2.2.0 --dev

Uji program

Tambahkan pengujian berikut ke src/lib.rs, di bawah kode program. Ini adalah modul pengujian yang memanggil program hello world.

src/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(())
}
#[cfg(test)]
mod test {
use litesvm::LiteSVM;
use solana_sdk::{
instruction::Instruction,
message::Message,
signature::{Keypair, Signer},
transaction::Transaction,
};
#[test]
fn test_hello_world() {
// Create a new LiteSVM instance
let mut svm = LiteSVM::new();
// Create a keypair for the transaction payer
let payer = Keypair::new();
// Airdrop some lamports to the payer
svm.airdrop(&payer.pubkey(), 1_000_000_000).unwrap();
// Load our program
let program_keypair = Keypair::new();
let program_id = program_keypair.pubkey();
svm.add_program_from_file(program_id, "target/deploy/hello_world.so")
.unwrap();
// Create instruction with no accounts and no data
let instruction = Instruction {
program_id,
accounts: vec![],
data: vec![],
};
// Create transaction
let message = Message::new(&[instruction], Some(&payer.pubkey()));
let transaction = Transaction::new(&[&payer], message, svm.latest_blockhash());
// Send transaction and verify it succeeds
let result = svm.send_transaction(transaction);
assert!(result.is_ok(), "Transaction should succeed");
let logs = result.unwrap().logs;
println!("Logs: {logs:#?}");
}
}

Jalankan pengujian menggunakan perintah cargo test. Log program akan menampilkan "Hello, world!".

Terminal
$
cargo test -- --no-capture

Contoh output:

Terminal
running 1 test
Logs: [
"Program 9528phXNvdWp5kkR4rgpoeZvR8ZWT5THVywK95YRprkk invoke [1]",
"Program log: Hello, world!",
"Program 9528phXNvdWp5kkR4rgpoeZvR8ZWT5THVywK95YRprkk consumed 211 of 200000 compute units",
"Program 9528phXNvdWp5kkR4rgpoeZvR8ZWT5THVywK95YRprkk success",
]
test test::test_hello_world ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s

Deploy program

Selanjutnya, deploy program. Saat mengembangkan secara lokal, kita dapat menggunakan solana-test-validator.

Pertama, konfigurasikan Solana CLI untuk menggunakan cluster Solana lokal.

Terminal
$
solana config set -ul

Contoh output:

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

Buka terminal baru dan jalankan perintah solana-test-validators untuk memulai validator lokal.

Terminal
$
solana-test-validator

Saat validator pengujian berjalan, jalankan perintah solana program deploy di terminal terpisah untuk men-deploy program ke validator lokal.

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

Contoh output:

Program Id: 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz
Signature:
5osMiNMiDZGM7L1e2tPHxU8wdB8gwG8fDnXLg5G7SbhwFz4dHshYgAijk4wSQL5cXiu8z1MMou5kLadAQuHp7ybH

Anda dapat memeriksa ID program dan tanda tangan transaksi di Solana Explorer.

Perhatikan bahwa cluster pada Solana Explorer juga harus localhost. Opsi "Custom RPC URL" pada Solana Explorer secara default adalah http://localhost:8899.

Membuat contoh klien

Selanjutnya, kita akan mendemonstrasikan cara memanggil program menggunakan klien Rust.

Pertama buat direktori examples dan file client.rs.

Terminal
$
mkdir -p examples && touch examples/client.rs

Tambahkan berikut ini ke Cargo.toml.

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

Tambahkan dependensi solana-client dan tokio.

Terminal
$
cargo add solana-client@2.2.0 --dev
$
cargo add tokio --dev

Menambahkan klien

Tambahkan kode berikut ke examples/client.rs. Ini adalah skrip klien Rust yang mendanai keypair baru untuk membayar biaya transaksi dan kemudian memanggil program hello world.

examples/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://localhost: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),
}
}

Mengganti ID program

Sebelum menjalankan kode klien, ganti ID program dalam cuplikan kode dengan ID program Anda.

Anda bisa mendapatkan ID program Anda dengan menjalankan perintah berikut.

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

Memanggil program

Jalankan skrip klien dengan perintah berikut.

Terminal
$
cargo run --example client

Contoh output:

Transaction Signature: 54TWxKi3Jsi3UTeZbhLGUFX6JQH7TspRJjRRFZ8NFnwG5BXM9udxiX77bAACjKAS9fGnVeEazrXL4SfKrW7xZFYV

Anda dapat memeriksa tanda tangan transaksi di Solana Explorer (klaster lokal) untuk melihat "Hello, world!" di log program.

Perbarui program

Program Solana dapat diperbarui dengan men-deploy ulang ke ID program yang sama. Perbarui program di src/lib.rs untuk mencetak "Hello, Solana!" alih-alih "Hello, world!".

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

Jalankan perintah cargo build-sbf untuk menghasilkan file .so yang diperbarui.

Terminal
$
cargo build-sbf

Uji program yang diperbarui dengan menjalankan perintah cargo test.

Terminal
$
cargo test -- --no-capture

Anda akan melihat "Hello, Solana!" di log program.

Terminal
running 1 test
Logs: [
"Program 5y8bHrnwfq2dLDgLn3WoTHb9dDuyorj9gyapW6aeyrpV invoke [1]",
"Program log: Hello, Solana!",
"Program 5y8bHrnwfq2dLDgLn3WoTHb9dDuyorj9gyapW6aeyrpV consumed 211 of 200000 compute units",
"Program 5y8bHrnwfq2dLDgLn3WoTHb9dDuyorj9gyapW6aeyrpV success",
]
test test::test_hello_world ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.08s

Deploy ulang program

Deploy ulang program menggunakan perintah solana program deploy yang sama.

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

Jalankan kode klien lagi dan periksa tanda tangan transaksi di Solana Explorer untuk melihat "Hello, Solana!" di log program.

Terminal
$
cargo run --example client

Tutup program

Anda dapat menutup program Solana untuk mendapatkan kembali SOL yang dialokasikan ke akun tersebut. Menutup program tidak dapat dibalik, jadi harus dilakukan dengan hati-hati.

Untuk menutup program, gunakan perintah solana program close <PROGRAM_ID>. Sebagai contoh:

Terminal
$
solana program close 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz --bypass-warning

Contoh output:

Closed Program Id 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz, 0.1350588 SOL
reclaimed

Perhatikan bahwa setelah program ditutup, ID program tersebut tidak dapat digunakan kembali. Upaya untuk men-deploy program dengan ID program yang sebelumnya telah ditutup akan menghasilkan error.

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

Men-deploy ulang program yang ditutup

Jika Anda perlu men-deploy ulang program dengan kode sumber yang sama setelah menutup program, Anda harus menghasilkan ID program baru. Untuk menghasilkan keypair baru untuk program, jalankan perintah berikut:

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

Atau, Anda dapat menghapus file keypair yang ada (misalnya ./target/deploy/hello_world-keypair.json) dan menjalankan cargo build-sbf lagi, yang akan menghasilkan file keypair baru.

Membuat program baru

Pertama, buat proyek Rust baru menggunakan perintah standar cargo new dengan flag --lib.

Terminal
$
cargo new hello_world --lib

Navigasikan ke direktori proyek. Anda akan melihat file default src/lib.rs dan Cargo.toml

Terminal
$
cd hello_world

Perbarui bidang edition di Cargo.toml menjadi 2021. Jika tidak, Anda mungkin mengalami error saat membangun program.

Tambahkan dependensi solana-program

Selanjutnya, tambahkan dependensi solana-program. Ini adalah dependensi minimum yang diperlukan untuk membangun program Solana.

Terminal
$
cargo add solana-program@2.2.0

Tambahkan crate-type

Selanjutnya, tambahkan snippet berikut ke Cargo.toml.

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

Jika Anda tidak menyertakan konfigurasi ini, direktori target/deploy tidak akan dibuat saat Anda membangun program.

Tambahkan kode program

Selanjutnya, ganti isi src/lib.rs dengan kode berikut. Ini adalah program Solana minimal yang mencetak "Hello, world!" ke log program ketika program dijalankan.

Makro msg! digunakan dalam program Solana untuk mencetak pesan ke log program.

Bangun program

Selanjutnya, bangun program menggunakan perintah cargo build-sbf.

Terminal
$
cargo build-sbf

Perintah ini menghasilkan direktori target/deploy yang berisi dua file penting:

  1. File .so (misalnya, hello_world.so): Ini adalah program Solana yang dikompilasi yang akan di-deploy ke jaringan sebagai "smart contract".
  2. File keypair (misalnya, hello_world-keypair.json): Kunci publik dari keypair ini digunakan sebagai ID program saat men-deploy program.

Untuk melihat ID program, jalankan perintah berikut di terminal Anda. Perintah ini mencetak kunci publik dari keypair pada jalur file yang ditentukan:

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

Contoh output:

4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz

Tambahkan dependensi pengujian

Selanjutnya, uji program menggunakan crate litesvm. Tambahkan dependensi berikut ke Cargo.toml.

Terminal
$
cargo add litesvm --dev
$
cargo add solana-sdk@2.2.0 --dev

Uji program

Tambahkan pengujian berikut ke src/lib.rs, di bawah kode program. Ini adalah modul pengujian yang memanggil program hello world.

Jalankan pengujian menggunakan perintah cargo test. Log program akan menampilkan "Hello, world!".

Terminal
$
cargo test -- --no-capture

Contoh output:

Terminal
running 1 test
Logs: [
"Program 9528phXNvdWp5kkR4rgpoeZvR8ZWT5THVywK95YRprkk invoke [1]",
"Program log: Hello, world!",
"Program 9528phXNvdWp5kkR4rgpoeZvR8ZWT5THVywK95YRprkk consumed 211 of 200000 compute units",
"Program 9528phXNvdWp5kkR4rgpoeZvR8ZWT5THVywK95YRprkk success",
]
test test::test_hello_world ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s

Deploy program

Selanjutnya, deploy program. Saat mengembangkan secara lokal, kita dapat menggunakan solana-test-validator.

Pertama, konfigurasikan Solana CLI untuk menggunakan cluster Solana lokal.

Terminal
$
solana config set -ul

Contoh output:

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

Buka terminal baru dan jalankan perintah solana-test-validators untuk memulai validator lokal.

Terminal
$
solana-test-validator

Saat validator pengujian berjalan, jalankan perintah solana program deploy di terminal terpisah untuk men-deploy program ke validator lokal.

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

Contoh output:

Program Id: 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz
Signature:
5osMiNMiDZGM7L1e2tPHxU8wdB8gwG8fDnXLg5G7SbhwFz4dHshYgAijk4wSQL5cXiu8z1MMou5kLadAQuHp7ybH

Anda dapat memeriksa ID program dan tanda tangan transaksi di Solana Explorer.

Perhatikan bahwa cluster pada Solana Explorer juga harus localhost. Opsi "Custom RPC URL" pada Solana Explorer secara default adalah http://localhost:8899.

Membuat contoh klien

Selanjutnya, kita akan mendemonstrasikan cara memanggil program menggunakan klien Rust.

Pertama buat direktori examples dan file client.rs.

Terminal
$
mkdir -p examples && touch examples/client.rs

Tambahkan berikut ini ke Cargo.toml.

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

Tambahkan dependensi solana-client dan tokio.

Terminal
$
cargo add solana-client@2.2.0 --dev
$
cargo add tokio --dev

Menambahkan klien

Tambahkan kode berikut ke examples/client.rs. Ini adalah skrip klien Rust yang mendanai keypair baru untuk membayar biaya transaksi dan kemudian memanggil program hello world.

Mengganti ID program

Sebelum menjalankan kode klien, ganti ID program dalam cuplikan kode dengan ID program Anda.

Anda bisa mendapatkan ID program Anda dengan menjalankan perintah berikut.

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

Memanggil program

Jalankan skrip klien dengan perintah berikut.

Terminal
$
cargo run --example client

Contoh output:

Transaction Signature: 54TWxKi3Jsi3UTeZbhLGUFX6JQH7TspRJjRRFZ8NFnwG5BXM9udxiX77bAACjKAS9fGnVeEazrXL4SfKrW7xZFYV

Anda dapat memeriksa tanda tangan transaksi di Solana Explorer (klaster lokal) untuk melihat "Hello, world!" di log program.

Perbarui program

Program Solana dapat diperbarui dengan men-deploy ulang ke ID program yang sama. Perbarui program di src/lib.rs untuk mencetak "Hello, Solana!" alih-alih "Hello, world!".

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

Jalankan perintah cargo build-sbf untuk menghasilkan file .so yang diperbarui.

Terminal
$
cargo build-sbf

Uji program yang diperbarui dengan menjalankan perintah cargo test.

Terminal
$
cargo test -- --no-capture

Anda akan melihat "Hello, Solana!" di log program.

Terminal
running 1 test
Logs: [
"Program 5y8bHrnwfq2dLDgLn3WoTHb9dDuyorj9gyapW6aeyrpV invoke [1]",
"Program log: Hello, Solana!",
"Program 5y8bHrnwfq2dLDgLn3WoTHb9dDuyorj9gyapW6aeyrpV consumed 211 of 200000 compute units",
"Program 5y8bHrnwfq2dLDgLn3WoTHb9dDuyorj9gyapW6aeyrpV success",
]
test test::test_hello_world ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.08s

Deploy ulang program

Deploy ulang program menggunakan perintah solana program deploy yang sama.

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

Jalankan kode klien lagi dan periksa tanda tangan transaksi di Solana Explorer untuk melihat "Hello, Solana!" di log program.

Terminal
$
cargo run --example client

Tutup program

Anda dapat menutup program Solana untuk mendapatkan kembali SOL yang dialokasikan ke akun tersebut. Menutup program tidak dapat dibalik, jadi harus dilakukan dengan hati-hati.

Untuk menutup program, gunakan perintah solana program close <PROGRAM_ID>. Sebagai contoh:

Terminal
$
solana program close 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz --bypass-warning

Contoh output:

Closed Program Id 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz, 0.1350588 SOL
reclaimed

Perhatikan bahwa setelah program ditutup, ID program tersebut tidak dapat digunakan kembali. Upaya untuk men-deploy program dengan ID program yang sebelumnya telah ditutup akan menghasilkan error.

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

Men-deploy ulang program yang ditutup

Jika Anda perlu men-deploy ulang program dengan kode sumber yang sama setelah menutup program, Anda harus menghasilkan ID program baru. Untuk menghasilkan keypair baru untuk program, jalankan perintah berikut:

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

Atau, Anda dapat menghapus file keypair yang ada (misalnya ./target/deploy/hello_world-keypair.json) dan menjalankan cargo build-sbf lagi, yang akan menghasilkan file keypair baru.

lib.rs
Cargo.toml
[package]
name = "hello_world"
version = "0.1.0"
edition = "2021"
[dependencies]

Is this page helpful?

Daftar Isi

Edit Halaman