Solana 프로그램은 주로 Rust 프로그래밍 언어를 사용하여 개발됩니다. 이 페이지는 Anchor 프레임워크를 사용하지 않고 Rust로 Solana 프로그램을 작성하는 데 중점을 두며, 이 접근 방식은 종종 "네이티브 Rust" 프로그램 작성이라고 불립니다.
네이티브 Rust 개발은 개발자에게 Solana 프로그램에 대한 직접적인 제어를 제공합니다. 그러나 이 접근 방식은 Anchor 프레임워크를 사용하는 것에 비해 더 많은 수동 설정과 상용구 코드가 필요합니다. 이 방법은 다음과 같은 개발자에게 권장됩니다:
- 프로그램 로직과 최적화에 대한 세밀한 제어를 원하는 경우
- 상위 수준 프레임워크로 이동하기 전에 기본 개념을 배우고 싶은 경우
초보자의 경우, Anchor 프레임워크로 시작하는 것을 권장합니다. 자세한 내용은 Anchor 섹션을 참조하세요.
사전 요구 사항
자세한 설치 지침은 설치 페이지를 방문하세요.
시작하기 전에 다음 항목이 설치되어 있는지 확인하세요:
- Rust: Solana 프로그램을 구축하기 위한 프로그래밍 언어.
- Solana CLI: Solana 개발을 위한 명령줄 도구.
시작하기
아래 예제는 Rust로 작성된 첫 번째 Solana 프로그램을 만드는 기본 단계를 다룹니다. 프로그램 로그에 "Hello, world!"를 출력하는 최소한의 프로그램을 만들 것입니다.
새 프로그램 만들기
먼저 --lib 플래그와 함께 표준 cargo new 명령을 사용하여 새 Rust 프로젝트를
생성하세요.
$cargo new hello_world --lib
프로젝트 디렉터리로 이동하세요. 기본 src/lib.rs 및 Cargo.toml 파일이
표시됩니다.
$cd hello_world
Cargo.toml의 edition 필드를 2021로 업데이트하세요. 그렇지 않으면
프로그램을 빌드할 때 오류가 발생할 수 있습니다.
solana-program 의존성 추가하기
다음으로 solana-program 의존성을 추가하세요. 이것은 Solana 프로그램을 빌드하는
데 필요한 최소 의존성입니다.
$cargo add solana-program@2.2.0
crate-type 추가하기
다음으로 Cargo.toml에 다음 코드를 추가하세요.
[lib]crate-type = ["cdylib", "lib"]
이 설정을 포함하지 않으면 프로그램을 빌드할 때 target/deploy 디렉터리가
생성되지 않습니다.
Cargo.toml 파일은 다음과 같아야 합니다.
[package]name = "hello_world"version = "0.1.0"edition = "2021"[lib]crate-type = ["cdylib", "lib"][dependencies]solana-program = "2.2.0"
프로그램 코드 추가하기
다음으로 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
테스트 의존성 추가하기
다음으로 litesvm 크레이트를 사용하여 프로그램을 테스트합니다. Cargo.toml에
다음 의존성을 추가합니다.
$cargo add litesvm@0.6.1 --dev$cargo add solana-sdk@2.2.0 --dev
프로그램 테스트하기
프로그램 코드 아래 src/lib.rs에 다음 테스트를 추가합니다. 이것은 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:#?}");}}
cargo test 명령을 사용하여 테스트를 실행합니다. 프로그램 로그에 "Hello,
world!"가 표시됩니다.
$cargo test -- --no-capture
출력 예시:
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
프로그램 배포하기
다음으로 프로그램을 배포합니다. 로컬에서 개발할 때는 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 examples && touch examples/client.rs
Cargo.toml에 다음을 추가합니다.
[[example]]name = "client"path = "examples/client.rs"
solana-client 및 tokio 종속성을 추가합니다.
$cargo add solana-client@2.2.0 --dev$cargo add tokio --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://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),}}
프로그램 ID 교체하기
클라이언트 코드를 실행하기 전에, 코드 스니펫의 프로그램 ID를 여러분의 프로그램 ID로 교체하세요.
다음 명령어를 실행하여 프로그램 ID를 확인할 수 있습니다.
$solana address -k ./target/deploy/hello_world-keypair.json
프로그램 호출하기
다음 명령어로 클라이언트 스크립트를 실행합니다.
$cargo run --example client
출력 예시:
Transaction Signature: 54TWxKi3Jsi3UTeZbhLGUFX6JQH7TspRJjRRFZ8NFnwG5BXM9udxiX77bAACjKAS9fGnVeEazrXL4SfKrW7xZFYV
Solana 익스플로러 (로컬 클러스터)에서 트랜잭션 서명을 검사하여 프로그램 로그에서 "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 build-sbf 명령을 실행하여 업데이트된 .so 파일을 생성합니다.
$cargo build-sbf
cargo test 명령을 실행하여 업데이트된 프로그램을 테스트합니다.
$cargo test -- --no-capture
프로그램 로그에서 "Hello, Solana!"를 확인할 수 있습니다.
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
프로그램 재배포하기
동일한 solana program deploy 명령을 사용하여 프로그램을 재배포합니다.
$solana program deploy ./target/deploy/hello_world.so
클라이언트 코드를 다시 실행하고 Solana 익스플로러에서 트랜잭션 서명을 검사하여 프로그램 로그에서 "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?