Τεκμηρίωση SolanaΑνάπτυξη προγραμμάτων

Ανάπτυξη προγραμμάτων σε Rust

Τα προγράμματα Solana αναπτύσσονται κυρίως χρησιμοποιώντας τη γλώσσα προγραμματισμού Rust. Αυτή η σελίδα επικεντρώνεται στη συγγραφή προγραμμάτων Solana σε Rust χωρίς τη χρήση του πλαισίου Anchor, μια προσέγγιση που συχνά αναφέρεται ως συγγραφή προγραμμάτων "native Rust".

Η ανάπτυξη σε native Rust παρέχει στους προγραμματιστές άμεσο έλεγχο των προγραμμάτων Solana τους. Ωστόσο, αυτή η προσέγγιση απαιτεί περισσότερη χειροκίνητη ρύθμιση και πρότυπο κώδικα σε σύγκριση με τη χρήση του πλαισίου Anchor. Αυτή η μέθοδος συνιστάται για προγραμματιστές που:

  • Αναζητούν λεπτομερή έλεγχο της λογικής του προγράμματος και βελτιστοποιήσεις
  • Θέλουν να μάθουν τις βασικές έννοιες πριν προχωρήσουν σε πλαίσια υψηλότερου επιπέδου

Για αρχάριους, συνιστούμε να ξεκινήσετε με το πλαίσιο Anchor. Δείτε την ενότητα Anchor για περισσότερες πληροφορίες.

Προαπαιτούμενα

Για λεπτομερείς οδηγίες εγκατάστασης, επισκεφθείτε τη σελίδα εγκατάστασης.

Πριν ξεκινήσετε, βεβαιωθείτε ότι έχετε εγκαταστήσει τα εξής:

  • Rust: Η γλώσσα προγραμματισμού για την κατασκευή προγραμμάτων Solana.
  • Solana CLI: Εργαλείο γραμμής εντολών για ανάπτυξη Solana.

Ξεκινώντας

Το παρακάτω παράδειγμα καλύπτει τα βασικά βήματα για τη δημιουργία του πρώτου σας προγράμματος Solana γραμμένο σε Rust. Θα δημιουργήσουμε ένα ελάχιστο πρόγραμμα που εκτυπώνει "Hello, world!" στο αρχείο καταγραφής του προγράμματος.

Δημιουργία νέου προγράμματος

Πρώτα, δημιουργήστε ένα νέο project Rust χρησιμοποιώντας την τυπική εντολή cargo init με τη σημαία --lib.

Terminal
cargo init hello_world --lib

Πλοηγηθείτε στον κατάλογο του project. Θα πρέπει να δείτε τα προεπιλεγμένα αρχεία src/lib.rs και Cargo.toml

Terminal
cd hello_world

Στη συνέχεια, προσθέστε την εξάρτηση solana-program. Αυτή είναι η ελάχιστη εξάρτηση που απαιτείται για την κατασκευή ενός προγράμματος Solana.

Terminal
cargo add solana-program@1.18.26

Στη συνέχεια, προσθέστε το ακόλουθο απόσπασμα στο Cargo.toml. Αν δεν συμπεριλάβετε αυτή τη ρύθμιση, ο κατάλογος target/deploy δεν θα δημιουργηθεί όταν κάνετε build το πρόγραμμα.

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

Το αρχείο Cargo.toml θα πρέπει να μοιάζει με το ακόλουθο:

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

Στη συνέχεια, αντικαταστήστε τα περιεχόμενα του src/lib.rs με τον ακόλουθο κώδικα. Αυτό είναι ένα ελάχιστο πρόγραμμα Solana που εκτυπώνει "Hello, world!" στο αρχείο καταγραφής του προγράμματος όταν γίνεται επίκληση του προγράμματος.

Η μακροεντολή msg! χρησιμοποιείται στα προγράμματα Solana για την εκτύπωση ενός μηνύματος στο αρχείο καταγραφής του προγράμματος.

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

Δημιουργία του προγράμματος

Στη συνέχεια, δημιουργήστε το πρόγραμμα χρησιμοποιώντας την εντολή cargo build-sbf.

Terminal
cargo build-sbf

Αυτή η εντολή δημιουργεί έναν κατάλογο target/deploy που περιέχει δύο σημαντικά αρχεία:

  1. Ένα αρχείο .so (π.χ., hello_world.so): Αυτό είναι το μεταγλωττισμένο πρόγραμμα Solana που θα αναπτυχθεί στο δίκτυο ως "έξυπνο συμβόλαιο".
  2. Ένα αρχείο keypair (π.χ., hello_world-keypair.json): Το δημόσιο κλειδί αυτού του keypair χρησιμοποιείται ως αναγνωριστικό προγράμματος κατά την ανάπτυξη του προγράμματος.

Για να δείτε το αναγνωριστικό του προγράμματος, εκτελέστε την ακόλουθη εντολή στο τερματικό σας. Αυτή η εντολή εκτυπώνει το δημόσιο κλειδί του keypair στη συγκεκριμένη διαδρομή αρχείου:

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

Παράδειγμα εξόδου:

4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz

Δοκιμή του προγράμματος

Στη συνέχεια, δοκιμάστε το πρόγραμμα χρησιμοποιώντας το crate solana-program-test. Προσθέστε τις ακόλουθες εξαρτήσεις στο Cargo.toml.

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

Προσθέστε την ακόλουθη δοκιμή στο src/lib.rs, κάτω από τον κώδικα του προγράμματος. Αυτή είναι μια μονάδα δοκιμής που καλεί το πρόγραμμα hello world.

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());
}
}

Εκτελέστε τη δοκιμή χρησιμοποιώντας την εντολή cargo test-sbf. Το αρχείο καταγραφής του προγράμματος θα εμφανίσει "Hello, world!".

Terminal
cargo test-sbf

Παράδειγμα εξόδου:

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

Ανάπτυξη του προγράμματος

Στη συνέχεια, αναπτύξτε το πρόγραμμα. Κατά την τοπική ανάπτυξη, μπορούμε να χρησιμοποιήσουμε το solana-test-validator.

Πρώτα, ρυθμίστε το Solana CLI για να χρησιμοποιεί το τοπικό Solana cluster.

Terminal
solana config set -ul

Παράδειγμα εξόδου:

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

Ανοίξτε ένα νέο τερματικό και εκτελέστε την εντολή solana-test-validators για να ξεκινήσετε τον τοπικό validator.

Terminal
solana-test-validator

Ενώ ο test validator εκτελείται, τρέξτε την εντολή solana program deploy σε ξεχωριστό τερματικό για να αναπτύξετε το πρόγραμμα στον τοπικό validator.

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

Παράδειγμα εξόδου:

Program Id: 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz
Signature:
5osMiNMiDZGM7L1e2tPHxU8wdB8gwG8fDnXLg5G7SbhwFz4dHshYgAijk4wSQL5cXiu8z1MMou5kLadAQuHp7ybH

Μπορείτε να επιθεωρήσετε το αναγνωριστικό προγράμματος και την υπογραφή συναλλαγής στον Solana Explorer. Σημειώστε ότι το cluster στον Solana Explorer πρέπει επίσης να είναι localhost. Η επιλογή "Custom RPC URL" στον Solana Explorer έχει προεπιλογή το http://localhost:8899.

Κλήση του προγράμματος

Στη συνέχεια, θα δείξουμε πώς να καλέσετε το πρόγραμμα χρησιμοποιώντας ένα Rust client.

Πρώτα δημιουργήστε έναν κατάλογο examples και ένα αρχείο client.rs.

Terminal
mkdir -p examples
touch examples/client.rs

Προσθέστε τα παρακάτω στο Cargo.toml.

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

Προσθέστε την εξάρτηση solana-client.

Terminal
cargo add solana-client@1.18.26 --dev

Προσθέστε τον ακόλουθο κώδικα στο examples/client.rs. Αυτό είναι ένα script πελάτη σε Rust που χρηματοδοτεί ένα νέο keypair για την πληρωμή των τελών συναλλαγής και στη συνέχεια καλεί το πρόγραμμα hello world.

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),
}
}

Πριν εκτελέσετε το script, αντικαταστήστε το αναγνωριστικό προγράμματος στο παραπάνω απόσπασμα κώδικα με αυτό του δικού σας προγράμματος.

Μπορείτε να βρείτε το αναγνωριστικό του προγράμματός σας εκτελώντας την ακόλουθη εντολή.

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();
}
}

Εκτελέστε το script του πελάτη με την ακόλουθη εντολή.

Terminal
cargo run --example client

Παράδειγμα εξόδου:

Transaction Signature: 54TWxKi3Jsi3UTeZbhLGUFX6JQH7TspRJjRRFZ8NFnwG5BXM9udxiX77bAACjKAS9fGnVeEazrXL4SfKrW7xZFYV

Μπορείτε να επιθεωρήσετε την υπογραφή της συναλλαγής στον Solana Explorer (τοπικό cluster) για να δείτε το "Hello, world!" στο αρχείο καταγραφής του προγράμματος.

Ενημέρωση του προγράμματος

Τα προγράμματα Solana μπορούν να ενημερωθούν με επανατοποθέτηση στο ίδιο αναγνωριστικό προγράμματος. Ενημερώστε το πρόγραμμα στο src/lib.rs ώστε να εμφανίζει "Hello, Solana!" αντί για "Hello, world!".

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

Δοκιμάστε το ενημερωμένο πρόγραμμα εκτελώντας την εντολή cargo test-sbf.

Terminal
cargo test-sbf

Θα πρέπει να δείτε το "Hello, Solana!" στο αρχείο καταγραφής του προγράμματος.

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

Εκτελέστε την εντολή cargo build-sbf για να δημιουργήσετε ένα ενημερωμένο αρχείο .so.

Terminal
cargo build-sbf

Επανατοποθετήστε το πρόγραμμα χρησιμοποιώντας την εντολή solana program deploy.

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

Εκτελέστε ξανά τον κώδικα του πελάτη και επιθεωρήστε την υπογραφή της συναλλαγής στον Solana Explorer για να δείτε το "Hello, Solana!" στο αρχείο καταγραφής του προγράμματος.

Terminal
cargo run --example client

Κλείσιμο του προγράμματος

Μπορείτε να κλείσετε το πρόγραμμά σας στο Solana για να ανακτήσετε το SOL που έχει διατεθεί στον λογαριασμό. Το κλείσιμο ενός προγράμματος είναι μη αναστρέψιμο, οπότε θα πρέπει να γίνεται με προσοχή.

Για να κλείσετε ένα πρόγραμμα, χρησιμοποιήστε την εντολή solana program close <PROGRAM_ID>. Για παράδειγμα:

Terminal
solana program close 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz
--bypass-warning

Παράδειγμα εξόδου:

Closed Program Id 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz, 0.1350588 SOL
reclaimed

Σημειώστε ότι μόλις κλείσει ένα πρόγραμμα, το αναγνωριστικό του προγράμματος δεν μπορεί να επαναχρησιμοποιηθεί. Η προσπάθεια ανάπτυξης ενός προγράμματος με ένα αναγνωριστικό προγράμματος που έχει κλείσει προηγουμένως θα οδηγήσει σε σφάλμα.

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

Εάν χρειάζεται να αναπτύξετε ξανά ένα πρόγραμμα με τον ίδιο πηγαίο κώδικα μετά το κλείσιμο ενός προγράμματος, πρέπει να δημιουργήσετε ένα νέο αναγνωριστικό προγράμματος. Για να δημιουργήσετε ένα νέο keypair για το πρόγραμμα, εκτελέστε την ακόλουθη εντολή:

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

Εναλλακτικά, μπορείτε να διαγράψετε το υπάρχον αρχείο keypair (π.χ. ./target/deploy/hello_world-keypair.json) και να εκτελέσετε ξανά το cargo build-sbf, το οποίο θα δημιουργήσει ένα νέο αρχείο keypair.

Is this page helpful?