Ανάπτυξη προγραμμάτων σε 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
.
cargo init hello_world --lib
Πλοηγηθείτε στον κατάλογο του project. Θα πρέπει να δείτε τα προεπιλεγμένα
αρχεία src/lib.rs
και Cargo.toml
cd hello_world
Στη συνέχεια, προσθέστε την εξάρτηση solana-program
. Αυτή είναι η ελάχιστη
εξάρτηση που απαιτείται για την κατασκευή ενός προγράμματος Solana.
cargo add solana-program@1.18.26
Στη συνέχεια, προσθέστε το ακόλουθο απόσπασμα στο Cargo.toml
. Αν δεν
συμπεριλάβετε αυτή τη ρύθμιση, ο κατάλογος target/deploy
δεν θα δημιουργηθεί
όταν κάνετε build το πρόγραμμα.
[lib]crate-type = ["cdylib", "lib"]
Το αρχείο 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 για την εκτύπωση
ενός μηνύματος στο αρχείο καταγραφής του προγράμματος.
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
.
cargo build-sbf
Αυτή η εντολή δημιουργεί έναν κατάλογο target/deploy
που περιέχει δύο
σημαντικά αρχεία:
- Ένα αρχείο
.so
(π.χ.,hello_world.so
): Αυτό είναι το μεταγλωττισμένο πρόγραμμα Solana που θα αναπτυχθεί στο δίκτυο ως "έξυπνο συμβόλαιο". - Ένα αρχείο keypair (π.χ.,
hello_world-keypair.json
): Το δημόσιο κλειδί αυτού του keypair χρησιμοποιείται ως αναγνωριστικό προγράμματος κατά την ανάπτυξη του προγράμματος.
Για να δείτε το αναγνωριστικό του προγράμματος, εκτελέστε την ακόλουθη εντολή στο τερματικό σας. Αυτή η εντολή εκτυπώνει το δημόσιο κλειδί του keypair στη συγκεκριμένη διαδρομή αρχείου:
solana address -k ./target/deploy/hello_world-keypair.json
Παράδειγμα εξόδου:
4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz
Δοκιμή του προγράμματος
Στη συνέχεια, δοκιμάστε το πρόγραμμα χρησιμοποιώντας το crate
solana-program-test
. Προσθέστε τις ακόλουθες εξαρτήσεις στο Cargo.toml
.
cargo add solana-program-test@1.18.26 --devcargo add solana-sdk@1.18.26 --devcargo add tokio --dev
Προσθέστε την ακόλουθη δοκιμή στο src/lib.rs
, κάτω από τον κώδικα του
προγράμματος. Αυτή είναι μια μονάδα δοκιμής που καλεί το πρόγραμμα hello world.
#[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 instructionlet instruction = Instruction {program_id,accounts: vec![],data: vec![],};// Create transaction with instructionlet mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey()));// Sign transactiontransaction.sign(&[&payer], recent_blockhash);let transaction_result = banks_client.process_transaction(transaction).await;assert!(transaction_result.is_ok());}}
Εκτελέστε τη δοκιμή χρησιμοποιώντας την εντολή cargo test-sbf
. Το αρχείο
καταγραφής του προγράμματος θα εμφανίσει "Hello, world!".
cargo test-sbf
Παράδειγμα εξόδου:
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 successtest test::test_hello_world ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.13s
Ανάπτυξη του προγράμματος
Στη συνέχεια, αναπτύξτε το πρόγραμμα. Κατά την τοπική ανάπτυξη, μπορούμε να
χρησιμοποιήσουμε το solana-test-validator
.
Πρώτα, ρυθμίστε το Solana CLI για να χρησιμοποιεί το τοπικό Solana cluster.
solana config set -ul
Παράδειγμα εξόδου:
Config File: /.config/solana/cli/config.ymlRPC URL: http://localhost:8899WebSocket URL: ws://localhost:8900/ (computed)Keypair Path: /.config/solana/id.jsonCommitment: confirmed
Ανοίξτε ένα νέο τερματικό και εκτελέστε την εντολή solana-test-validators
για
να ξεκινήσετε τον τοπικό validator.
solana-test-validator
Ενώ ο test validator εκτελείται, τρέξτε την εντολή solana program deploy
σε
ξεχωριστό τερματικό για να αναπτύξετε το πρόγραμμα στον τοπικό validator.
solana program deploy ./target/deploy/hello_world.so
Παράδειγμα εξόδου:
Program Id: 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMzSignature:5osMiNMiDZGM7L1e2tPHxU8wdB8gwG8fDnXLg5G7SbhwFz4dHshYgAijk4wSQL5cXiu8z1MMou5kLadAQuHp7ybH
Μπορείτε να επιθεωρήσετε το αναγνωριστικό προγράμματος και την υπογραφή
συναλλαγής στον
Solana Explorer.
Σημειώστε ότι το cluster στον Solana Explorer πρέπει επίσης να είναι localhost.
Η επιλογή "Custom RPC URL" στον Solana Explorer έχει προεπιλογή το
http://localhost:8899
.
Κλήση του προγράμματος
Στη συνέχεια, θα δείξουμε πώς να καλέσετε το πρόγραμμα χρησιμοποιώντας ένα Rust client.
Πρώτα δημιουργήστε έναν κατάλογο examples
και ένα αρχείο client.rs
.
mkdir -p examplestouch examples/client.rs
Προσθέστε τα παρακάτω στο Cargo.toml
.
[[example]]name = "client"path = "examples/client.rs"
Προσθέστε την εξάρτηση solana-client
.
cargo add solana-client@1.18.26 --dev
Προσθέστε τον ακόλουθο κώδικα στο examples/client.rs
. Αυτό είναι ένα script
πελάτη σε Rust που χρηματοδοτεί ένα νέο keypair για την πληρωμή των τελών
συναλλαγής και στη συνέχεια καλεί το πρόγραμμα hello world.
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 devnetlet 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 payerlet payer = Keypair::new();// Request airdroplet airdrop_amount = 1_000_000_000; // 1 SOLlet signature = client.request_airdrop(&payer.pubkey(), airdrop_amount).expect("Failed to request airdrop");// Wait for airdrop confirmationloop {let confirmed = client.confirm_transaction(&signature).unwrap();if confirmed {break;}}// Create the instructionlet instruction = Instruction::new_with_borsh(program_id,&(), // Empty instruction datavec![], // No accounts needed);// Add the instruction to new transactionlet mut transaction = Transaction::new_with_payer(&[instruction], Some(&payer.pubkey()));transaction.sign(&[&payer], client.get_latest_blockhash().unwrap());// Send and confirm the transactionmatch client.send_and_confirm_transaction(&transaction) {Ok(signature) => println!("Transaction Signature: {}", signature),Err(err) => eprintln!("Error sending transaction: {}", err),}}
Πριν εκτελέσετε το script, αντικαταστήστε το αναγνωριστικό προγράμματος στο παραπάνω απόσπασμα κώδικα με αυτό του δικού σας προγράμματος.
Μπορείτε να βρείτε το αναγνωριστικό του προγράμματός σας εκτελώντας την ακόλουθη εντολή.
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 του πελάτη με την ακόλουθη εντολή.
cargo run --example client
Παράδειγμα εξόδου:
Transaction Signature: 54TWxKi3Jsi3UTeZbhLGUFX6JQH7TspRJjRRFZ8NFnwG5BXM9udxiX77bAACjKAS9fGnVeEazrXL4SfKrW7xZFYV
Μπορείτε να επιθεωρήσετε την υπογραφή της συναλλαγής στον Solana Explorer (τοπικό cluster) για να δείτε το "Hello, world!" στο αρχείο καταγραφής του προγράμματος.
Ενημέρωση του προγράμματος
Τα προγράμματα Solana μπορούν να ενημερωθούν με επανατοποθέτηση στο ίδιο
αναγνωριστικό προγράμματος. Ενημερώστε το πρόγραμμα στο src/lib.rs
ώστε να
εμφανίζει "Hello, Solana!" αντί για "Hello, world!".
pub fn process_instruction(_program_id: &Pubkey,_accounts: &[AccountInfo],_instruction_data: &[u8],) -> ProgramResult {- msg!("Hello, world!");+ msg!("Hello, Solana!");Ok(())}
Δοκιμάστε το ενημερωμένο πρόγραμμα εκτελώντας την εντολή cargo test-sbf
.
cargo test-sbf
Θα πρέπει να δείτε το "Hello, Solana!" στο αρχείο καταγραφής του προγράμματος.
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 successtest test::test_hello_world ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.14s
Εκτελέστε την εντολή cargo build-sbf
για να δημιουργήσετε ένα ενημερωμένο
αρχείο .so
.
cargo build-sbf
Επανατοποθετήστε το πρόγραμμα χρησιμοποιώντας την εντολή
solana program deploy
.
solana program deploy ./target/deploy/hello_world.so
Εκτελέστε ξανά τον κώδικα του πελάτη και επιθεωρήστε την υπογραφή της συναλλαγής στον Solana Explorer για να δείτε το "Hello, Solana!" στο αρχείο καταγραφής του προγράμματος.
cargo run --example client
Κλείσιμο του προγράμματος
Μπορείτε να κλείσετε το πρόγραμμά σας στο Solana για να ανακτήσετε το SOL που έχει διατεθεί στον λογαριασμό. Το κλείσιμο ενός προγράμματος είναι μη αναστρέψιμο, οπότε θα πρέπει να γίνεται με προσοχή.
Για να κλείσετε ένα πρόγραμμα, χρησιμοποιήστε την εντολή
solana program close <PROGRAM_ID>
. Για παράδειγμα:
solana program close 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz--bypass-warning
Παράδειγμα εξόδου:
Closed Program Id 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz, 0.1350588 SOLreclaimed
Σημειώστε ότι μόλις κλείσει ένα πρόγραμμα, το αναγνωριστικό του προγράμματος δεν μπορεί να επαναχρησιμοποιηθεί. Η προσπάθεια ανάπτυξης ενός προγράμματος με ένα αναγνωριστικό προγράμματος που έχει κλείσει προηγουμένως θα οδηγήσει σε σφάλμα.
Error: Program 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz has been closed, usea new Program Id
Εάν χρειάζεται να αναπτύξετε ξανά ένα πρόγραμμα με τον ίδιο πηγαίο κώδικα μετά το κλείσιμο ενός προγράμματος, πρέπει να δημιουργήσετε ένα νέο αναγνωριστικό προγράμματος. Για να δημιουργήσετε ένα νέο keypair για το πρόγραμμα, εκτελέστε την ακόλουθη εντολή:
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?