Tài liệu SolanaPhát triển chương trình

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 "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 lệnh tiêu chuẩn cargo init với cờ --lib.

Terminal
cargo init 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.rsCargo.toml

Terminal
cd hello_world

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.

Terminal
cargo add solana-program@1.18.26

Tiếp theo, thêm đoạn mã sau vào Cargo.toml. 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 khi bạn build chương trình.

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

File Cargo.toml của bạn nên trông như sau:

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

Tiếp theo, thay thế nội dung của src/lib.rs bằng mã sau. Đây là một 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.

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

Build chương trình

Tiếp theo, build chương trình bằng lệnh cargo build-sbf.

Terminal
cargo build-sbf

Lệnh này tạo ra một thư mục target/deploy chứa hai file quan trọng:

  1. Một file .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 "smart contract".
  2. Một file keypair (ví dụ: hello_world-keypair.json): Public key của keypair này được sử dụng làm program ID khi triển khai chương trình.

Để xem program ID, chạy lệnh sau trong terminal của bạn. Lệnh này in ra public key của keypair tại đường dẫn file được chỉ định:

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

Ví dụ kết quả:

4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz

Kiểm tra chương trình

Tiếp theo, kiểm tra chương trình bằng cách sử dụng crate solana-program-test. Thêm các dependencies sau vào Cargo.toml.

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

Thêm bài kiểm tra sau vào src/lib.rs, bên dưới mã chương trình. Đây là một module kiểm tra gọi chương trình 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());
}
}

Chạy bài kiểm tra bằng lệnh cargo test-sbf. Nhật ký chương trình sẽ hiển thị "Hello, world!".

Terminal
cargo test-sbf

Kết quả đầu ra mẫu:

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

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ộ.

Terminal
solana config set -ul

Kết quả đầu ra mẫu:

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

Mở một terminal mới và chạy lệnh solana-test-validators để khởi động validator cục bộ.

Terminal
solana-test-validator

Trong khi validator thử nghiệm đ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ộ.

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

Kết quả đầu ra mẫu:

Program Id: 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz
Signature:
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 cụm 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.

Gọi chương trình

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 một thư mục examples và một tệp client.rs.

Terminal
mkdir -p examples
touch examples/client.rs

Thêm nội dung sau vào Cargo.toml.

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

Thêm dependency solana-client.

Terminal
cargo add solana-client@1.18.26 --dev

Thêm đoạn mã sau vào examples/client.rs. Đây là một tập lệnh khách hàng 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.

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

Trước khi chạy tập lệnh, hãy thay thế ID chương trình trong đoạn mã trên bằng 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.

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

Chạy tập lệnh khách hàng với lệnh sau.

Terminal
cargo run --example client

Ví dụ về kết quả:

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!".

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

Kiểm tra chương trình đã cập nhật bằng cách chạy lệnh cargo test-sbf.

Terminal
cargo test-sbf

Bạn sẽ thấy "Hello, Solana!" trong nhật ký chương trình.

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

Chạy lệnh cargo build-sbf để tạo một tệp .so đã cập nhật.

Terminal
cargo build-sbf

Triển khai lại chương trình bằng lệnh solana program deploy.

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

Chạy mã khách hàng một 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.

Terminal
cargo run --example client

Đóng chương trình

Bạn có thể đóng chương trình Solana của mình để lấy lại SOL đã được phân bổ cho tài khoản. Việc đóng chương trình là không thể hoàn tá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ụ:

Terminal
solana program close 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz
--bypass-warning

Kết quả ví dụ:

Closed Program Id 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz, 0.1350588 SOL
reclaimed

Lưu ý rằng một khi chương trình đã đóng, ID chương trình của nó 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, use
a new Program Id

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 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:

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

Hoặc, 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 một tệp keypair mới.

Is this page helpful?

Mục lục

Chỉnh sửa trang