솔라나 문서프로그램 개발하기

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 프로젝트를 만듭니다.

Terminal
cargo init hello_world --lib

프로젝트 디렉토리로 이동합니다. 기본 src/lib.rsCargo.toml 파일이 보일 것입니다.

Terminal
cd hello_world

다음으로, solana-program 의존성을 추가합니다. 이것은 Solana 프로그램을 빌드하는 데 필요한 최소한의 의존성입니다.

Terminal
cargo add solana-program@1.18.26

다음으로, 아래 코드 조각을 Cargo.toml에 추가하세요. 이 설정을 포함하지 않으면 프로그램을 빌드할 때 target/deploy 디렉토리가 생성되지 않습니다.

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

Cargo.toml 파일은 다음과 같이 보여야 합니다:

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 프로그램에서 메시지를 프로그램 로그에 출력하는 데 사용됩니다.

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

프로그램 빌드하기

다음으로, cargo build-sbf 명령을 사용하여 프로그램을 빌드하세요.

Terminal
cargo build-sbf

이 명령은 두 가지 중요한 파일이 포함된 target/deploy 디렉토리를 생성합니다:

  1. .so 파일(예: hello_world.so): 이것은 "스마트 컨트랙트"로서 네트워크에 배포될 컴파일된 Solana 프로그램입니다.
  2. keypair 파일(예: hello_world-keypair.json): 이 keypair의 공개 키는 프로그램을 배포할 때 프로그램 ID로 사용됩니다.

프로그램 ID를 확인하려면 터미널에서 다음 명령을 실행하세요. 이 명령은 지정된 파일 경로에 있는 keypair의 공개 키를 출력합니다:

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

출력 예시:

4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz

프로그램 테스트하기

다음으로, solana-program-test 크레이트를 사용하여 프로그램을 테스트하세요. 다음 의존성을 Cargo.toml에 추가하세요.

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

다음 테스트를 프로그램 코드 아래의 src/lib.rs에 추가하세요. 이것은 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());
}
}

cargo test-sbf 명령을 사용하여 테스트를 실행하세요. 프로그램 로그에 "Hello, world!"가 표시됩니다.

Terminal
cargo test-sbf

출력 예시:

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

프로그램 배포하기

다음으로, 프로그램을 배포합니다. 로컬에서 개발할 때는 solana-test-validator를 사용할 수 있습니다.

먼저, Solana CLI를 로컬 Solana 클러스터를 사용하도록 구성합니다.

Terminal
solana config set -ul

출력 예시:

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

새 터미널을 열고 solana-test-validators 명령어를 실행하여 로컬 validator를 시작합니다.

Terminal
solana-test-validator

테스트 validator가 실행되는 동안, 별도의 터미널에서 solana program deploy 명령어를 실행하여 프로그램을 로컬 validator에 배포합니다.

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

출력 예시:

Program Id: 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz
Signature:
5osMiNMiDZGM7L1e2tPHxU8wdB8gwG8fDnXLg5G7SbhwFz4dHshYgAijk4wSQL5cXiu8z1MMou5kLadAQuHp7ybH

Solana Explorer에서 프로그램 ID와 트랜잭션 서명을 확인할 수 있습니다. Solana Explorer의 클러스터도 localhost로 설정되어 있어야 합니다. Solana Explorer의 "Custom RPC URL" 옵션은 기본적으로 http://localhost:8899로 설정됩니다.

프로그램 호출하기

다음으로, Rust 클라이언트를 사용하여 프로그램을 호출하는 방법을 보여드리겠습니다.

먼저 examples 디렉토리와 client.rs 파일을 생성합니다.

Terminal
mkdir -p examples
touch examples/client.rs

다음 내용을 Cargo.toml에 추가합니다.

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

solana-client 의존성을 추가합니다.

Terminal
cargo add solana-client@1.18.26 --dev

다음 코드를 examples/client.rs에 추가하세요. 이것은 트랜잭션 수수료를 지불하기 위해 새로운 keypair에 자금을 제공하고 hello world 프로그램을 호출하는 Rust 클라이언트 스크립트입니다.

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

스크립트를 실행하기 전에, 위 코드 스니펫의 프로그램 ID를 여러분의 프로그램 ID로 교체하세요.

다음 명령어를 실행하여 프로그램 ID를 확인할 수 있습니다.

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

다음 명령어로 클라이언트 스크립트를 실행하세요.

Terminal
cargo run --example client

출력 예시:

Transaction Signature: 54TWxKi3Jsi3UTeZbhLGUFX6JQH7TspRJjRRFZ8NFnwG5BXM9udxiX77bAACjKAS9fGnVeEazrXL4SfKrW7xZFYV

Solana Explorer(로컬 클러스터)에서 트랜잭션 서명을 검사하여 프로그램 로그에서 "Hello, world!"를 확인할 수 있습니다.

프로그램 업데이트하기

Solana 프로그램은 동일한 프로그램 ID에 재배포하여 업데이트할 수 있습니다. src/lib.rs의 프로그램을 "Hello, world!" 대신 "Hello, Solana!"를 출력하도록 업데이트하세요.

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

cargo test-sbf 명령어를 실행하여 업데이트된 프로그램을 테스트하세요.

Terminal
cargo test-sbf

프로그램 로그에서 "Hello, Solana!"를 확인할 수 있어야 합니다.

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

cargo build-sbf 명령어를 실행하여 업데이트된 .so 파일을 생성하세요.

Terminal
cargo build-sbf

solana program deploy 명령어를 사용하여 프로그램을 재배포하세요.

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

클라이언트 코드를 다시 실행하고 Solana Explorer에서 트랜잭션 서명을 검사하여 프로그램 로그에서 "Hello, Solana!"를 확인하세요.

Terminal
cargo run --example client

프로그램 종료하기

Solana 프로그램을 종료하여 계정에 할당된 SOL을 회수할 수 있습니다. 프로그램 종료는 되돌릴 수 없으므로 주의해서 진행해야 합니다.

프로그램을 종료하려면 solana program close <PROGRAM_ID> 명령어를 사용하세요. 예시:

Terminal
solana program close 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz
--bypass-warning

출력 예시:

Closed Program Id 4Ujf5fXfLx2PAwRqcECCLtgDxHKPznoJpa43jUBxFfMz, 0.1350588 SOL
reclaimed

프로그램이 종료되면 해당 프로그램 ID는 재사용할 수 없습니다. 이전에 종료된 프로그램 ID로 프로그램을 배포하려고 하면 오류가 발생합니다.

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

프로그램을 종료한 후 동일한 소스 코드로 프로그램을 다시 배포해야 하는 경우, 새로운 프로그램 ID를 생성해야 합니다. 프로그램용 새 keypair를 생성하려면 다음 명령어를 실행하세요:

Terminal
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?

목차

페이지 편집