Rust로 프로그램 개발하기
Solana 프로그램은 주로 Rust 프로그래밍 언어를 사용하여 개발됩니다. 이 페이지는 Anchor 프레임워크를 사용하지 않고 Rust로 Solana 프로그램을 작성하는 데 중점을 두며, 이 접근 방식은 종종 "네이티브 Rust" 프로그램 작성이라고 불립니다.
네이티브 Rust 개발은 개발자에게 Solana 프로그램에 대한 직접적인 제어 권한을 제공합니다. 그러나 이 접근 방식은 Anchor 프레임워크를 사용하는 것에 비해 더 많은 수동 설정과 상용구 코드가 필요합니다. 이 방법은 다음과 같은 개발자에게 권장됩니다:
- 프로그램 로직과 최적화에 대한 세밀한 제어를 원하는 개발자
- 상위 수준 프레임워크로 이동하기 전에 기본 개념을 배우고 싶은 개발자
초보자의 경우, Anchor 프레임워크로 시작하는 것을 권장합니다. 자세한 내용은 Anchor 섹션을 참조하세요.
사전 요구 사항
자세한 설치 지침은 설치 페이지를 방문하세요.
시작하기 전에 다음 항목이 설치되어 있는지 확인하세요:
- Rust: Solana 프로그램을 구축하기 위한 프로그래밍 언어.
- Solana CLI: Solana 개발을 위한 명령줄 도구.
시작하기
아래 예제는 Rust로 작성된 첫 번째 Solana 프로그램을 만드는 기본 단계를 다룹니다. 프로그램 로그에 "Hello, world!"를 출력하는 최소한의 프로그램을 만들 것입니다.
새 프로그램 만들기
먼저, 표준 cargo init
명령어와 --lib
플래그를 사용하여 새 Rust 프로젝트를
만듭니다.
cargo init hello_world --lib
프로젝트 디렉토리로 이동합니다. 기본 src/lib.rs
및 Cargo.toml
파일이 보일
것입니다.
cd hello_world
다음으로, solana-program
의존성을 추가합니다. 이것은 Solana 프로그램을
빌드하는 데 필요한 최소한의 의존성입니다.
cargo add solana-program@1.18.26
다음으로, 아래 코드 조각을 Cargo.toml
에 추가하세요. 이 설정을 포함하지 않으면
프로그램을 빌드할 때 target/deploy
디렉토리가 생성되지 않습니다.
[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
의 내용을 다음 코드로 교체하세요. 이것은 프로그램이 호출될
때 프로그램 로그에 "Hello, world!"를 출력하는 최소한의 Solana 프로그램입니다.
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의 공개 키는 프로그램을 배포할 때 프로그램 ID로 사용됩니다.
프로그램 ID를 확인하려면 터미널에서 다음 명령을 실행하세요. 이 명령은 지정된 파일 경로에 있는 keypair의 공개 키를 출력합니다:
solana address -k ./target/deploy/hello_world-keypair.json
출력 예시:
4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz
프로그램 테스트하기
다음으로, 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 클러스터를 사용하도록 구성합니다.
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
테스트 validator가 실행되는 동안, 별도의 터미널에서 solana program deploy
명령어를 실행하여 프로그램을 로컬 validator에 배포합니다.
solana program deploy ./target/deploy/hello_world.so
출력 예시:
Program Id: 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMzSignature:5osMiNMiDZGM7L1e2tPHxU8wdB8gwG8fDnXLg5G7SbhwFz4dHshYgAijk4wSQL5cXiu8z1MMou5kLadAQuHp7ybH
Solana Explorer에서
프로그램 ID와 트랜잭션 서명을 확인할 수 있습니다. Solana Explorer의 클러스터도
localhost로 설정되어 있어야 합니다. Solana Explorer의 "Custom RPC URL" 옵션은
기본적으로 http://localhost:8899
로 설정됩니다.
프로그램 호출하기
다음으로, Rust 클라이언트를 사용하여 프로그램을 호출하는 방법을 보여드리겠습니다.
먼저 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
에 추가하세요. 이것은 트랜잭션 수수료를 지불하기
위해 새로운 keypair에 자금을 제공하고 hello world 프로그램을 호출하는 Rust
클라이언트 스크립트입니다.
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),}}
스크립트를 실행하기 전에, 위 코드 스니펫의 프로그램 ID를 여러분의 프로그램 ID로 교체하세요.
다음 명령어를 실행하여 프로그램 ID를 확인할 수 있습니다.
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();}}
다음 명령어로 클라이언트 스크립트를 실행하세요.
cargo run --example client
출력 예시:
Transaction Signature: 54TWxKi3Jsi3UTeZbhLGUFX6JQH7TspRJjRRFZ8NFnwG5BXM9udxiX77bAACjKAS9fGnVeEazrXL4SfKrW7xZFYV
Solana Explorer(로컬 클러스터)에서 트랜잭션 서명을 검사하여 프로그램 로그에서 "Hello, world!"를 확인할 수 있습니다.
프로그램 업데이트하기
Solana 프로그램은 동일한 프로그램 ID에 재배포하여 업데이트할 수 있습니다.
src/lib.rs
의 프로그램을 "Hello, world!" 대신 "Hello, Solana!"를 출력하도록
업데이트하세요.
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
프로그램이 종료되면 해당 프로그램 ID는 재사용할 수 없습니다. 이전에 종료된 프로그램 ID로 프로그램을 배포하려고 하면 오류가 발생합니다.
Error: Program 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz has been closed, usea new Program Id
프로그램을 종료한 후 동일한 소스 코드로 프로그램을 다시 배포해야 하는 경우, 새로운 프로그램 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?