Phát triển chương trình bằng Rust
Các chương trình Solana chủ yếu được phát triển bằng ngôn ngữ lập trình Rust. Trang này tập trung vào việc viết các chương trình Solana bằng Rust mà không sử dụng framework Anchor, một phương pháp thường được gọi là viết chương trình "Rust nguyên bản".
Phát triển Rust nguyên bản cung cấp cho các nhà phát triển quyền kiểm soát trực tiếp đối với chương trình Solana của họ. Tuy nhiên, phương pháp này đòi hỏi nhiều thiết lập thủ công và mã boilerplate hơn so với việc sử dụng framework Anchor. Phương pháp này được khuyến nghị cho các nhà phát triển:
- Tìm kiếm kiểm soát chi tiết đối với logic chương trình và tối ưu hóa
- Muốn tìm hiểu các khái niệm cơ bản trước khi chuyển sang các framework cấp cao hơn
Đối với người mới bắt đầu, chúng tôi khuyên bạn nên bắt đầu với framework Anchor. Xem phần Anchor để biết thêm thông tin.
Điều kiện tiên quyết
Để biết hướng dẫn cài đặt chi tiết, hãy truy cập trang cài đặt.
Trước khi bắt đầu, hãy đảm bảo bạn đã cài đặt những thứ sau:
- Rust: Ngôn ngữ lập trình để xây dựng các chương trình Solana.
- Solana CLI: Công cụ dòng lệnh cho phát triển Solana.
Bắt đầu
Ví dụ dưới đây bao gồm các bước cơ bản để tạo chương trình Solana đầu tiên của bạn viết bằng Rust. Chúng ta sẽ tạo một chương trình tối thiểu in ra "Hello, world!" vào nhật ký chương trình.
Tạo một chương trình mới
Đầu tiên, tạo một dự án Rust mới bằng cách sử dụng lệnh tiêu chuẩn cargo new
với cờ --lib
.
$cargo new hello_world --lib
Di chuyển đến thư mục dự án. Bạn sẽ thấy các tệp mặc định src/lib.rs
và
Cargo.toml
$cd hello_world
Cập nhật trường edition
trong Cargo.toml
thành 2021
. Nếu không, bạn có
thể gặp lỗi khi xây dựng chương trình.
Thêm dependency solana-program
Tiếp theo, thêm dependency solana-program
. Đây là dependency tối thiểu cần
thiết để xây dựng một chương trình Solana.
$cargo add solana-program@2.2.0
Thêm crate-type
Tiếp theo, thêm đoạn mã sau vào Cargo.toml
.
[lib]crate-type = ["cdylib", "lib"]
Nếu bạn không bao gồm cấu hình này, thư mục target/deploy
sẽ không được tạo
ra khi bạn xây dựng chương trình.
Tệp Cargo.toml
của bạn nên trông giống như sau:
[package]name = "hello_world"version = "0.1.0"edition = "2021"[lib]crate-type = ["cdylib", "lib"][dependencies]solana-program = "2.2.0"
Thêm mã chương trình
Tiếp theo, thay thế nội dung của src/lib.rs
bằng đoạn mã sau. Đây là chương
trình Solana tối giản in ra "Hello, world!" vào nhật ký chương trình khi chương
trình được gọi.
Macro msg!
được sử dụng trong các chương trình Solana để in một thông báo vào
nhật ký chương trình.
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(())}
Xây dựng chương trình
Tiếp theo, xây dựng chương trình bằng lệnh cargo build-sbf
.
$cargo build-sbf
Lệnh này tạo ra một thư mục target/deploy
chứa hai tệp quan trọng:
- Một tệp
.so
(ví dụ:hello_world.so
): Đây là chương trình Solana đã được biên dịch sẽ được triển khai lên mạng như một "hợp đồng thông minh". - Một tệp keypair (ví dụ:
hello_world-keypair.json
): Khóa công khai của keypair này được sử dụng làm ID chương trình khi triển khai chương trình.
Để xem ID chương trình, chạy lệnh sau trong terminal của bạn. Lệnh này in ra khóa công khai của keypair tại đường dẫn tệp được chỉ định:
$solana address -k ./target/deploy/hello_world-keypair.json
Kết quả ví dụ:
4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz
Thêm các phụ thuộc kiểm thử
Tiếp theo, kiểm thử chương trình bằng cách sử dụng crate litesvm
. Thêm các phụ
thuộc sau vào Cargo.toml
.
$cargo add litesvm --dev$cargo add solana-sdk@2.2.0 --dev
Kiểm thử chương trình
Thêm bài kiểm thử sau vào src/lib.rs
, bên dưới mã chương trình. Đây là một
module kiểm thử gọi chương trình hello world.
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 instancelet mut svm = LiteSVM::new();// Create a keypair for the transaction payerlet payer = Keypair::new();// Airdrop some lamports to the payersvm.airdrop(&payer.pubkey(), 1_000_000_000).unwrap();// Load our programlet 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 datalet instruction = Instruction {program_id,accounts: vec![],data: vec![],};// Create transactionlet message = Message::new(&[instruction], Some(&payer.pubkey()));let transaction = Transaction::new(&[&payer], message, svm.latest_blockhash());// Send transaction and verify it succeedslet result = svm.send_transaction(transaction);assert!(result.is_ok(), "Transaction should succeed");let logs = result.unwrap().logs;println!("Logs: {logs:#?}");}}
Chạy bài kiểm thử bằng lệnh cargo test
. Nhật ký chương trình sẽ hiển thị
"Hello, world!".
$cargo test -- --no-capture
Kết quả ví dụ:
running 1 testLogs: ["Program 9528phXNvdWp5kkR4rgpoeZvR8ZWT5THVywK95YRprkk invoke [1]","Program log: Hello, world!","Program 9528phXNvdWp5kkR4rgpoeZvR8ZWT5THVywK95YRprkk consumed 211 of 200000 compute units","Program 9528phXNvdWp5kkR4rgpoeZvR8ZWT5THVywK95YRprkk success",]test test::test_hello_world ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.05s
Triển khai chương trình
Tiếp theo, triển khai chương trình. Khi phát triển cục bộ, chúng ta có thể sử
dụng solana-test-validator
.
Đầu tiên, cấu hình Solana CLI để sử dụng cụm Solana cục bộ.
$solana config set -ul
Kết quả ví dụ:
Config File: /.config/solana/cli/config.ymlRPC URL: http://localhost:8899WebSocket URL: ws://localhost:8900/ (computed)Keypair Path: /.config/solana/id.jsonCommitment: confirmed
Mở một terminal mới và chạy lệnh solana-test-validators
để khởi động validator
cục bộ.
$solana-test-validator
Trong khi validator kiểm thử đang chạy, chạy lệnh solana program deploy
trong
một terminal riêng biệt để triển khai chương trình lên validator cục bộ.
$solana program deploy ./target/deploy/hello_world.so
Kết quả ví dụ:
Program Id: 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMzSignature:5osMiNMiDZGM7L1e2tPHxU8wdB8gwG8fDnXLg5G7SbhwFz4dHshYgAijk4wSQL5cXiu8z1MMou5kLadAQuHp7ybH
Bạn có thể kiểm tra ID chương trình và chữ ký giao dịch trên Solana Explorer.
Lưu ý rằng cluster trên Solana Explorer cũng phải là localhost. Tùy chọn
"Custom RPC URL" trên Solana Explorer mặc định là http://localhost:8899
.
Tạo client ví dụ
Tiếp theo, chúng ta sẽ minh họa cách gọi chương trình bằng client Rust.
Đầu tiên tạo thư mục examples
và tệp client.rs
.
$mkdir -p examples && touch examples/client.rs
Thêm nội dung sau vào Cargo.toml
.
[[example]]name = "client"path = "examples/client.rs"
Thêm các dependency solana-client
và tokio
.
$cargo add solana-client@2.2.0 --dev$cargo add tokio --dev
Thêm client
Thêm mã sau vào examples/client.rs
. Đây là script client Rust nạp tiền vào một
keypair mới để thanh toán phí giao dịch và sau đó gọi chương trình 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://localhost: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),}}
Thay thế ID chương trình
Trước khi chạy mã client, hãy thay thế ID chương trình trong đoạn mã với ID của chương trình của bạn.
Bạn có thể lấy ID chương trình của mình bằng cách chạy lệnh sau.
$solana address -k ./target/deploy/hello_world-keypair.json
Gọi chương trình
Chạy script client với lệnh sau.
$cargo run --example client
Kết quả ví dụ:
Transaction Signature: 54TWxKi3Jsi3UTeZbhLGUFX6JQH7TspRJjRRFZ8NFnwG5BXM9udxiX77bAACjKAS9fGnVeEazrXL4SfKrW7xZFYV
Bạn có thể kiểm tra chữ ký giao dịch trên Solana Explorer (cụm cục bộ) để xem "Hello, world!" trong nhật ký chương trình.
Cập nhật chương trình
Các chương trình Solana có thể được cập nhật bằng cách triển khai lại với cùng
một ID chương trình. Cập nhật chương trình trong src/lib.rs
để in "Hello,
Solana!" thay vì "Hello, world!".
pub fn process_instruction(_program_id: &Pubkey,_accounts: &[AccountInfo],_instruction_data: &[u8],) -> ProgramResult {-msg!("Hello, world!");+msg!("Hello, Solana!");Ok(())}
Chạy lệnh cargo build-sbf
để tạo tệp .so
đã cập nhật.
$cargo build-sbf
Kiểm tra chương trình đã cập nhật bằng cách chạy lệnh cargo test
.
$cargo test -- --no-capture
Bạn sẽ thấy "Hello, Solana!" trong nhật ký chương trình.
running 1 testLogs: ["Program 5y8bHrnwfq2dLDgLn3WoTHb9dDuyorj9gyapW6aeyrpV invoke [1]","Program log: Hello, Solana!","Program 5y8bHrnwfq2dLDgLn3WoTHb9dDuyorj9gyapW6aeyrpV consumed 211 of 200000 compute units","Program 5y8bHrnwfq2dLDgLn3WoTHb9dDuyorj9gyapW6aeyrpV success",]test test::test_hello_world ... oktest result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.08s
Triển khai lại chương trình
Triển khai lại chương trình bằng cùng lệnh solana program deploy
.
$solana program deploy ./target/deploy/hello_world.so
Chạy mã khách hàng lần nữa và kiểm tra chữ ký giao dịch trên Solana Explorer để xem "Hello, Solana!" trong nhật ký chương trình.
$cargo run --example client
Đóng chương trình
Bạn có thể đóng chương trình Solana để lấy lại SOL đã phân bổ cho tài khoản. Việc đóng chương trình là không thể đảo ngược, vì vậy nên thực hiện một cách thận trọng.
Để đóng một chương trình, sử dụng lệnh solana program close <PROGRAM_ID>
. Ví
dụ:
$solana program close 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz --bypass-warning
Kết quả ví dụ:
Closed Program Id 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz, 0.1350588 SOLreclaimed
Lưu ý rằng khi một chương trình đã đóng, ID của chương trình đó không thể được sử dụng lại. Việc cố gắng triển khai một chương trình với ID chương trình đã đóng trước đó sẽ dẫn đến lỗi.
Error: Program 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz has been closed, usea new Program Id
Triển khai lại một chương trình đã đóng
Nếu bạn cần triển khai lại một chương trình với cùng mã nguồn sau khi đóng một chương trình, bạn phải tạo một ID chương trình mới. Để tạo một keypair mới cho chương trình, chạy lệnh sau:
$solana-keygen new -o ./target/deploy/hello_world-keypair.json --force
Ngoài ra, bạn có thể xóa tệp keypair hiện có (ví dụ:
./target/deploy/hello_world-keypair.json
) và chạy cargo build-sbf
một lần
nữa, điều này sẽ tạo ra một tệp keypair mới.
Is this page helpful?