초당 65,000건의 트랜잭션을 처리하고 400밀리초 안에 최종성을 확보하는 블록체인 애플리케이션을 구축할 수 있다면 어떨까요? 솔라나(Solana)의 API는 이를 가능하게 합니다. JSON-RPC 인터페이스를 제공하여 검증자 인프라를 직접 관리할 필요 없이 계정을 쿼리하고, 트랜잭션을 제출하며, 실시간 업데이트를 구독할 수 있습니다.
기존 블록체인 개발에서는 속도와 탈중앙화 사이에서 선택해야 합니다. 이더리움의 15 TPS는 네트워크 정체 시 병목 현상을 일으킵니다. 레이어 2 솔루션은 복잡성을 증가시킵니다. 솔라나는 지분 증명(proof-of-stake)과 결합된 기록 증명(proof-of-history) 합의를 통해 이러한 절충을 제거하며, Web3 보장과 함께 Web2 수준의 성능을 제공합니다. 검열 저항을 유지하면서 즉각적인 느낌의 애플리케이션을 구축할 수 있습니다.
목차:
- 솔라나 아키텍처 이해하기
- 개발 환경 설정하기
- 핵심 RPC API 메서드
- Web3.js로 트랜잭션 구축하기
- 최고의 보안 사례
- 결론
솔라나 아키텍처 이해하기
솔라나는 솔라나 프로그램 라이브러리(SPL)와 고성능 런타임을 중심으로 하는 독특한 아키텍처를 사용합니다. 이러한 기본 사항들을 이해하면 효율적인 API 호출을 작성하는 데 도움이 됩니다.
기록 증명 (PoH)
PoH는 합의 전에 모든 트랜잭션에 대한 암호화된 타임스탬프를 생성합니다. 이는 노드들이 시간에 대해 합의할 필요를 없애 지연 시간을 극적으로 줄입니다. API를 통해 트랜잭션을 제출하면 즉시 타임스탬프가 찍히고 처리를 위해 리더의 대기열에 들어갑니다.
계정 및 프로그램
코드 스토리지를 포함하는 이더리움의 계정 기반 모델과 달리, 솔라나는 코드(프로그램)와 데이터(계정)를 분리합니다. 프로그램은 상태를 저장하지 않으며—실행 가능한 로직만 포함합니다. 계정은 데이터를 저장하고 어떤 프로그램이 소유하는지를 지정합니다. 이러한 아키텍처는 겹치지 않는 계정이 동시에 실행될 수 있으므로 병렬 트랜잭션 처리를 가능하게 합니다.
모든 계정은 Ed25519 공개 키에서 파생된 고유한 32바이트 주소를 가집니다. 계정은 온체인에 유지되기 위해 람포트(lamports, 1 SOL = 10^9 람포트)로 임대료를 지불합니다. 임대료 면제 계정—최소 2년치 임대료를 보유한 계정—은 영구적으로 소멸되지 않고 유지됩니다.
확정 수준 (Commitment Levels)
솔라나는 세 가지 확정 수준을 제공합니다:
- Processed (처리됨): 현재 리더에 의해 트랜잭션이 처리되었지만 아직 확정되지 않았습니다. 가장 빠른 응답, 가장 낮은 확실성.
- Confirmed (확정됨): 클러스터에 의해 트랜잭션이 확정되었습니다. 평균 약 5-10초 소요.
- Finalized (최종 확정됨): 트랜잭션이 루트에 기록되어 되돌릴 수 없습니다. 약 12-15초 소요.
API 호출에서 확정 수준을 지정하여 속도와 최종성 보장 사이의 균형을 맞출 수 있습니다.

개발 환경 설정하기
키 관리 및 배포를 위한 솔라나 CLI, 블록체인 접근을 위한 RPC 엔드포인트, 그리고 애플리케이션 통합을 위한 JavaScript SDK, 이렇게 세 가지 구성 요소가 필요합니다.
솔라나 CLI 설치
공식 CLI 도구를 설치합니다:
sh -c "$(curl -sSfL https://release.solana.com/stable/install)"
설치 확인:
solana --version
Devnet (테스트) 또는 Mainnet (운영) 환경을 구성합니다:
# 개발용
solana config set --url https://api.devnet.solana.com
# 운영용
solana config set --url https://api.mainnet-beta.solana.com
지갑 생성하기
트랜잭션 서명을 위한 새로운 키페어를 생성합니다:
solana-keygen new --outfile ~/.config/solana/id.json
CLI는 공개 주소와 12단어 시드 구문을 출력합니다. 시드 구문은 지갑을 복구하는 데 사용되므로 안전하게 보관하세요. JSON 파일에는 개인 키가 포함되어 있으므로 파일 권한(chmod 600)으로 보호해야 합니다.
잔액 확인:
solana balance
Devnet 지갑에 무료 SOL을 충전합니다:
solana airdrop 2
Devnet 에어드롭은 요청당 2 SOL을 제공하며, 10초당 한 번의 요청으로 제한됩니다. Mainnet에서는 거래소를 통해 SOL을 구매해야 합니다.
RPC 제공업체 선택하기
솔라나는 공개 RPC 엔드포인트를 제공하지만, 운영 환경의 애플리케이션에는 전용 인프라가 필요합니다. 옵션은 다음과 같습니다:
- Helius:
https://mainnet.helius-rpc.com/?api-key=YOUR_KEY - QuickNode:
https://solana-mainnet.g.alchemy.com/v2/YOUR_KEY - Chainstack: 엔터프라이즈급 전용 노드
무료 티어는 일반적으로 월 100,000건의 요청을 허용합니다. 유료 요금제는 더 높은 제한, 트랜잭션 랜딩을 위한 스테이킹 연결, 우선 수수료 API를 제공합니다.
Web3.js 설치하기
솔라나의 JavaScript SDK는 두 가지 주요 버전을 가지고 있습니다. 버전 2.0은 함수형 프로그래밍 패턴, 트리 셰이킹 가능성, 제로 종속성을 갖춘 완전한 재작성 버전입니다.
버전 2.0 설치:
npm install @solana/web3.js@2 @solana-program/system @solana-program/compute-budget
버전 1.x 호환성을 위해:
npm install @solana/web3.js
팁Apidog솔라나
핵심 솔라나 RPC API 메서드
솔라나의 JSON-RPC API는 쿼리를 위한 HTTP 엔드포인트와 구독을 위한 WebSocket 엔드포인트를 제공합니다. 모든 요청은 JSON-RPC 2.0 사양을 따릅니다.

계정 작업
계정 정보 및 잔액 가져오기:
curl https://api.devnet.solana.com \
-X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getAccountInfo",
"params": [
"vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36zEGQp",
{"encoding": "base58"}
]
}'
여러 계정을 효율적으로 가져오기:
curl https://api.devnet.solana.com \
-X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getMultipleAccounts",
"params": [
[
"vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36zEGQp",
"4fYNw3dojWGPgVMtUU7ziPwq1r2VMGrhCrKZC9EQTbkV"
],
{"encoding": "base64"}
]
}'
블록 및 트랜잭션 쿼리
트랜잭션 구축을 위한 최신 블록 해시 가져오기:
curl https://api.devnet.solana.com \
-X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getLatestBlockhash",
"params": [{"commitment": "confirmed"}]
}'
트랜잭션 상태 쿼리:
curl https://api.devnet.solana.com \
-X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getSignatureStatuses",
"params": [
[
"5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpEz7CmGVZxhEHppBrGK"
],
{"searchTransactionHistory": true}
]
}'
WebSocket 구독
실시간으로 계정 변경 사항 모니터링:
import { createSolanaRpcSubscriptions } from "@solana/web3.js";
const rpcSubscriptions = createSolanaRpcSubscriptions(
"wss://api.devnet.solana.com"
);
const abortController = new AbortController();
await rpcSubscriptions.accountNotifications(
"vines1vzrYbzLMRdu58ou5XTby4qAqVRLmqo36zEGQp",
{ commitment: "confirmed" },
(notification) => {
console.log("Account changed:", notification);
},
{ abortSignal: abortController.signal }
);
// 60초 후 리스닝 중지
setTimeout(() => abortController.abort(), 60000);
WebSocket 연결은 활성 상태를 유지하기 위해 30-60초마다 주기적인 핑(ping)이 필요합니다. 운영 애플리케이션의 경우 재연결 로직을 구현하세요.
전문가 팁Apidog솔라나
Web3.js로 트랜잭션 구축하기
솔라나 트랜잭션은 특정 프로그램을 대상으로 하는 하나 이상의 명령(instruction)으로 구성됩니다. 각 명령은 프로그램, 상호 작용하는 계정, 직렬화된 데이터를 지정합니다.
전송 트랜잭션 생성하기
버전 2.0 SDK를 사용하여 계정 간 SOL을 전송합니다:
import {
airdropFactory,
createKeyPairSignerFromBytes,
createSolanaRpc,
createSolanaRpcSubscriptions,
generateKeyPairSigner,
lamports,
sendAndConfirmTransactionFactory,
pipe,
createTransactionMessage,
setTransactionMessageFeePayer,
setTransactionMessageLifetimeUsingBlockhash,
appendTransactionMessageInstruction,
signTransactionMessageWithSigners,
getSignatureFromTransaction,
} from "@solana/web3.js";
import { getTransferSolInstruction } from "@solana-program/system";
const LAMPORTS_PER_SOL = BigInt(1_000_000_000);
// RPC 연결 설정
const rpc = createSolanaRpc("https://api.devnet.solana.com");
const rpcSubscriptions = createSolanaRpcSubscriptions("wss://api.devnet.solana.com");
const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({ rpc, rpcSubscriptions });
// 송신자와 수신자 생성
const sender = await generateKeyPairSigner();
const recipient = await generateKeyPairSigner();
// 에어드롭으로 송신자에게 자금 지원
await airdropFactory({ rpc, rpcSubscriptions })({
recipientAddress: sender.address,
lamports: lamports(2n * LAMPORTS_PER_SOL),
commitment: "confirmed",
});
// 최신 블록 해시 가져오기
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
// 파이프(pipe)를 사용하여 트랜잭션 구축
const transactionMessage = pipe(
createTransactionMessage({ version: 0 }),
(msg) => setTransactionMessageFeePayer(sender.address, msg),
(msg) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, msg),
(msg) => appendTransactionMessageInstruction(
getTransferSolInstruction({
amount: lamports(LAMPORTS_PER_SOL / BigInt(2)),
destination: recipient.address,
source: sender,
}),
msg
)
);
// 서명 및 전송
const signedTransaction = await signTransactionMessageWithSigners(transactionMessage);
console.log("Transaction signed");
await sendAndConfirmTransaction(signedTransaction, {
commitment: "confirmed",
maxRetries: 0n,
skipPreflight: true,
});
console.log("Confirmed:", getSignatureFromTransaction(signedTransaction));
pipe 함수는 각 단계가 트랜잭션 메시지를 변환하는 함수형 체인을 생성합니다. 이 패턴은 가변 상태를 제거하고 트랜잭션 구성을 선언적으로 만듭니다.
우선 수수료로 최적화하기
네트워크 정체 시, 우선 수수료는 트랜잭션 포함을 보장합니다. Helius API에서 권장 수수료를 가져옵니다:
import { getBase64EncodedWireTransaction } from "@solana/web3.js";
const base64Transaction = getBase64EncodedWireTransaction(signedTransaction);
const response = await fetch("https://mainnet.helius-rpc.com/?api-key=YOUR_KEY", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0",
id: "priority-fee-request",
method: "getPriorityFeeEstimate",
params: [{
transaction: base64Transaction,
options: { recommended: true }
}]
})
});
const { result } = await response.json();
const priorityFee = result.priorityFeeEstimate;
// 우선 수수료 명령 추가
import { getSetComputeUnitPriceInstruction } from "@solana-program/compute-budget";
const optimizedMessage = pipe(
transactionMessage,
(msg) => appendTransactionMessageInstruction(
getSetComputeUnitPriceInstruction({ microLamports: priorityFee }),
msg
)
);
우선 수수료는 컴퓨트 유닛당 마이크로 람포트(micro-lamports) 단위로 지정됩니다. 수수료가 높을수록 정체 시 트랜잭션 우선순위가 높아집니다.
오류 처리
솔라나는 일반적인 실패에 대해 특정 오류 코드를 반환합니다:
import { isSolanaError, SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE } from "@solana/web3.js";
try {
await sendAndConfirmTransaction(signedTransaction);
} catch (error) {
if (isSolanaError(error)) {
switch (error.contextErrorCode) {
case SOLANA_ERROR__JSON_RPC__SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE:
console.error("사전 점검 실패:", error.message);
break;
default:
console.error("솔라나 오류:", error);
}
}
}
일반적인 오류에는 자금 부족(0x1), 잘못된 블록 해시(만료됨), 사용 중인 계정(트랜잭션 충돌) 등이 있습니다.
최고의 보안 사례
솔라나의 높은 처리량은 독특한 보안 고려 사항을 가져옵니다. 애플리케이션과 사용자를 보호하기 위해 다음 조치들을 구현하세요.
키 관리
개인 키를 버전 제어 시스템에 커밋하지 마십시오. 환경 변수를 사용하세요:
# .env
SOLANA_PRIVATE_KEY="[1,2,3,...]"
애플리케이션에서 키를 안전하게 로드합니다:
import { createKeyPairSignerFromBytes } from "@solana/web3.js";
import { getBase58Encoder } from "@solana/codecs";
const secretKey = JSON.parse(process.env.SOLANA_PRIVATE_KEY);
const signer = await createKeyPairSignerFromBytes(
new Uint8Array(secretKey)
);
브라우저 애플리케이션의 경우, 개인 키를 직접 처리하는 대신 지갑 어댑터(팬텀, 솔플레어)를 통합하세요. 사용자는 지갑 확장을 통해 트랜잭션에 서명하여 키를 안전하게 유지합니다.
트랜잭션 시뮬레이션
오류를 조기에 감지하기 위해 제출 전에 항상 트랜잭션을 시뮬레이션하세요:
const simulationResult = await rpc.simulateTransaction(signedTransaction).send();
if (simulationResult.value.err) {
console.error("시뮬레이션 실패:", simulationResult.value.err);
// 수수료 낭비 없이 오류 처리
}
시뮬레이션은 변경 사항을 커밋하지 않고 현재 상태에 대해 트랜잭션을 실행합니다. 이는 논리 오류, 불충분한 계정, 컴퓨트 예산 위반 등을 밝혀냅니다.
재실행 방지 (Replaying Protection)
솔라나 트랜잭션에는 약 90초 후에 만료되는 최신 블록 해시가 포함됩니다. 이는 동일한 트랜잭션을 여러 번 제출하는 재실행 공격을 방지합니다. 멱등(idempotent) 작업의 경우, 트랜잭션당 고유한 명령 데이터 또는 계정을 생성하세요.
속도 제한 (Rate Limiting)
공개 RPC 엔드포인트는 엄격한 속도 제한(일반적으로 10초당 100회 요청)을 구현합니다. 지수 백오프(exponential backoff)를 구현하세요:
async function withRetry(fn, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await fn();
} catch (error) {
if (error.status === 429) {
await new Promise(r => setTimeout(r, 1000 * Math.pow(2, i)));
continue;
}
throw error;
}
}
}
운영 환경의 경우, 더 높은 제한을 제공하는 전용 RPC 노드 또는 유료 제공업체 티어를 사용하세요.
프로그램 검증
타사 프로그램과 상호 작용하기 전에 SolanaFM 또는 Solscan과 같은 탐색기에서 해당 소스 코드를 확인하세요. 배포된 바이트코드가 오픈 소스 리포지토리와 일치함을 나타내는 확인 배지(verified badges)를 찾아보세요. 확인되지 않은 프로그램은 사용자 자금을 소진시키는 악성 로직을 포함할 수 있습니다.
결론
솔라나의 API는 현대 애플리케이션이 요구하는 성능—1초 미만의 최종성, 높은 처리량, 예측 가능한 수수료—를 제공합니다. JSON-RPC를 통해 계정 상태를 쿼리하고, WebSocket을 통해 실시간 업데이트를 구독하며, 함수형 Web3.js 2.0 SDK를 사용하여 트랜잭션을 구성할 수 있습니다. 계정 기반 아키텍처는 병렬 실행을 가능하게 하고, 확정 수준(commitment levels)을 통해 보안-속도 절충점을 선택할 수 있습니다.
재정적 위험 없이 실험하려면 Devnet부터 시작하세요. Mainnet 정체 시에는 우선 수수료를 사용하십시오. 사용자 대면 애플리케이션을 배포하기 전에 시뮬레이션 및 적절한 키 관리를 구현하세요. 솔라나 생태계는 도구를 제공하며, 애플리케이션 로직이 가치를 결정합니다.
Apidog로 오늘 바로 시작하세요—솔라나 API 엔드포인트를 몇 초 만에 가져와 설정 없이 테스트를 시작할 수 있습니다.
