Solana documentatieProgramma's ontwikkelen

Programma's ontwikkelen in Rust

Solana-programma's worden voornamelijk ontwikkeld met de programmeertaal Rust. Deze pagina richt zich op het schrijven van Solana-programma's in Rust zonder gebruik te maken van het Anchor framework, een aanpak die vaak wordt aangeduid als het schrijven van "native Rust"-programma's.

Native Rust-ontwikkeling geeft ontwikkelaars directe controle over hun Solana-programma's. Deze aanpak vereist echter meer handmatige configuratie en standaardcode in vergelijking met het gebruik van het Anchor-framework. Deze methode wordt aanbevolen voor ontwikkelaars die:

  • Gedetailleerde controle zoeken over programmalogica en optimalisaties
  • De onderliggende concepten willen leren voordat ze overstappen naar frameworks van hoger niveau

Voor beginners raden we aan om te starten met het Anchor-framework. Zie de Anchor sectie voor meer informatie.

Vereisten

Voor gedetailleerde installatie-instructies, bezoek de installatiepagina.

Voordat je begint, zorg ervoor dat je het volgende hebt geïnstalleerd:

  • Rust: De programmeertaal voor het bouwen van Solana-programma's.
  • Solana CLI: Command-line tool voor Solana-ontwikkeling.

Aan de slag

Het onderstaande voorbeeld behandelt de basisstappen om je eerste Solana-programma geschreven in Rust te maken. We zullen een minimaal programma maken dat "Hello, world!" afdrukt in het programmalogboek.

Een nieuw programma maken

Maak eerst een nieuw Rust-project aan met het standaard cargo init commando met de --lib vlag.

Terminal
cargo init hello_world --lib

Navigeer naar de projectmap. Je zou de standaard src/lib.rs en Cargo.toml bestanden moeten zien

Terminal
cd hello_world

Voeg vervolgens de solana-program dependency toe. Dit is de minimale dependency die vereist is om een Solana-programma te bouwen.

Terminal
cargo add solana-program@1.18.26

Voeg vervolgens het volgende fragment toe aan Cargo.toml. Als je deze configuratie niet opneemt, wordt de target/deploy map niet gegenereerd wanneer je het programma bouwt.

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

Je Cargo.toml bestand zou er als volgt uit moeten zien:

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

Vervang vervolgens de inhoud van src/lib.rs met de volgende code. Dit is een minimaal Solana-programma dat "Hello, world!" naar het programmalogboek print wanneer het programma wordt aangeroepen.

De msg! macro wordt in Solana-programma's gebruikt om een bericht naar het programmalogboek te printen.

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

Het programma bouwen

Bouw vervolgens het programma met het cargo build-sbf commando.

Terminal
cargo build-sbf

Dit commando genereert een target/deploy map met twee belangrijke bestanden:

  1. Een .so bestand (bijv. hello_world.so): Dit is het gecompileerde Solana-programma dat naar het netwerk wordt gedeployed als een "smart contract".
  2. Een keypair bestand (bijv. hello_world-keypair.json): De publieke sleutel van deze keypair wordt gebruikt als programma-ID bij het deployen van het programma.

Om de programma-ID te bekijken, voer je het volgende commando uit in je terminal. Dit commando print de publieke sleutel van de keypair op het opgegeven bestandspad:

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

Voorbeelduitvoer:

4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz

Het programma testen

Test vervolgens het programma met de solana-program-test crate. Voeg de volgende afhankelijkheden toe aan Cargo.toml.

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

Voeg de volgende test toe aan src/lib.rs, onder de programmacode. Dit is een test module die het hello world programma aanroept.

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

Voer de test uit met het cargo test-sbf commando. Het programmalogboek zal "Hello, world!" weergeven.

Terminal
cargo test-sbf

Voorbeelduitvoer:

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

Het programma implementeren

Implementeer vervolgens het programma. Bij lokale ontwikkeling kunnen we de solana-test-validator gebruiken.

Configureer eerst de Solana CLI om de lokale Solana-cluster te gebruiken.

Terminal
solana config set -ul

Voorbeelduitvoer:

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

Open een nieuwe terminal en voer het commando solana-test-validators uit om de lokale validator te starten.

Terminal
solana-test-validator

Terwijl de testvalidator draait, voer het commando solana program deploy uit in een aparte terminal om het programma op de lokale validator te implementeren.

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

Voorbeelduitvoer:

Program Id: 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz
Signature:
5osMiNMiDZGM7L1e2tPHxU8wdB8gwG8fDnXLg5G7SbhwFz4dHshYgAijk4wSQL5cXiu8z1MMou5kLadAQuHp7ybH

Je kunt de programma-ID en transactiehandtekening bekijken op Solana Explorer. Let op dat de cluster op Solana Explorer ook localhost moet zijn. De optie "Custom RPC URL" op Solana Explorer staat standaard ingesteld op http://localhost:8899.

Het programma aanroepen

Vervolgens laten we zien hoe je het programma kunt aanroepen met een Rust-client.

Maak eerst een examples map en een client.rs bestand.

Terminal
mkdir -p examples
touch examples/client.rs

Voeg het volgende toe aan Cargo.toml.

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

Voeg de solana-client dependency toe.

Terminal
cargo add solana-client@1.18.26 --dev

Voeg de volgende code toe aan examples/client.rs. Dit is een Rust-clientscript dat een nieuw keypair financiert om transactiekosten te betalen en vervolgens het hello world-programma aanroept.

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

Voordat je het script uitvoert, vervang de programma-ID in het bovenstaande codefragment door de ID van jouw programma.

Je kunt je programma-ID krijgen door het volgende commando uit te voeren.

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

Voer het clientscript uit met het volgende commando.

Terminal
cargo run --example client

Voorbeelduitvoer:

Transaction Signature: 54TWxKi3Jsi3UTeZbhLGUFX6JQH7TspRJjRRFZ8NFnwG5BXM9udxiX77bAACjKAS9fGnVeEazrXL4SfKrW7xZFYV

Je kunt de transactiehandtekening inspecteren op Solana Explorer (lokale cluster) om "Hello, world!" in het programmalogboek te zien.

Het programma bijwerken

Solana-programma's kunnen worden bijgewerkt door opnieuw te deployen naar dezelfde programma-ID. Werk het programma in src/lib.rs bij om "Hello, Solana!" te printen in plaats van "Hello, world!".

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

Test het bijgewerkte programma door het cargo test-sbf commando uit te voeren.

Terminal
cargo test-sbf

Je zou "Hello, Solana!" in het programmalogboek moeten zien.

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

Voer het cargo build-sbf commando uit om een bijgewerkt .so bestand te genereren.

Terminal
cargo build-sbf

Deploy het programma opnieuw met het solana program deploy commando.

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

Voer de clientcode opnieuw uit en inspecteer de transactiehandtekening op Solana Explorer om "Hello, Solana!" in het programmalogboek te zien.

Terminal
cargo run --example client

Het programma sluiten

Je kunt je Solana-programma sluiten om de SOL die aan het account is toegewezen terug te vorderen. Het sluiten van een programma is onomkeerbaar, dus dit moet met voorzichtigheid worden gedaan.

Om een programma te sluiten, gebruik je het solana program close <PROGRAM_ID> commando. Bijvoorbeeld:

Terminal
solana program close 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz
--bypass-warning

Voorbeelduitvoer:

Closed Program Id 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz, 0.1350588 SOL
reclaimed

Let op dat zodra een programma is gesloten, de programma-ID niet opnieuw kan worden gebruikt. Een poging om een programma te implementeren met een eerder gesloten programma-ID zal resulteren in een fout.

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

Als je een programma met dezelfde broncode opnieuw wilt implementeren na het sluiten van een programma, moet je een nieuwe programma-ID genereren. Om een nieuw keypair voor het programma te genereren, voer je het volgende commando uit:

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

Als alternatief kun je het bestaande keypair-bestand verwijderen (bijv. ./target/deploy/hello_world-keypair.json) en cargo build-sbf opnieuw uitvoeren, waardoor een nieuw keypair-bestand wordt gegenereerd.

Is this page helpful?

Inhoudsopgave

Pagina Bewerken