Back to Blog

Solana 생태계 보안 (1) — 안녕하세요 Solana

March 9, 2022
4 min read

1. 소개

Solana는 고성능의 무허가형(permissionless) Layer 1 블록체인 시스템으로, 다양한 언어(예: Rust, C++, C)로 프로그램(스마트 컨트랙트)을 개발할 수 있도록 지원합니다. Tower BFT(비잔틴 장애 허용)의 도움으로 초당 수천 건의 트랜잭션을 처리할 수 있는 블록 타임을 실현합니다. Solana의 핵심 혁신 중 하나는 PoH(Proof of History)로, 이는 네트워크에서 합의 이전에 작동하는 전역적으로 이용 가능한 무허가형 시간 소스입니다. PoH에 대해서는 추후 더 자세히 다룰 예정입니다.

2. 우리의 미션

BlockSec은 "DApp 생태계 보안"을 미션으로 삼는 블록체인 보안 회사입니다. 따라서 저희는 컨트랙트 감사 서비스뿐만 아니라, 전체 커뮤니티를 위한 안전한 스마트 컨트랙트 작성 방법에 대한 제안도 제공합니다. Solana의 인기, 고성능, 뛰어난 설계를 고려하여, 이 시리즈는 Solana에서 Rust로 작성된 스마트 컨트랙트의 보안에 초점을 맞출 것입니다.

3. Hello Solana

보안 관점에서 Solana 스마트 컨트랙트를 논의하기 전에, 먼저 Solana 스마트 컨트랙트를 작성하고, 컴파일하고, 배포하는 방법을 알아야 합니다. 여기서는 Hello World를 예시로 사용합니다.

3.1 코드 리뷰

Solana에서 스마트 컨트랙트는 프로그램(program)이라고 불립니다. Hello World 프로그램은 카운터를 유지하는 것을 목표로 하며, 클라이언트가 대상 계정(프로그램 소유)을 호출한 횟수를 기록하고 이 숫자를 출력합니다.

이제 전체 컨트랙트를 살펴보겠습니다.

1번째 줄부터 9번째 줄까지는 use 키워드를 사용하여 많은 라이브러리를 명시적으로 스코프에 가져옵니다.

12번째 줄에서 [derive(BorshSerialize, BorshDeserialize, Debug)]는 13번째 줄부터 16번째 줄까지 정의된 구조체 GreetingAccount에 전달된 매개변수를 직렬화 및 역직렬화하는 데 사용됩니다. 이 구조체는 u32 타입의 counter라는 공개 멤버를 포함합니다. 이후 주석에 명시된 대로, 19번째 줄은 프로그램의 진입점(entrypoint)인 process_instruction 함수를 내보냅니다.

process_instruction 함수는 세 개의 매개변수(즉, program_id, accounts, _instruction_data)를 받습니다. program_id는 배포된 프로그램의 공개 키(즉, 주소)이며, accounts는 인사할 계정을 포함합니다. _instruction_data는 비어 있으며 사용되지 않습니다.

Solana의 프로그램과 계정에 대해 더 알고 싶으시면 Solana 문서를 참조하세요.

27번째 줄에서 인사 메시지가 출력됩니다. 30번째 줄부터 33번째 줄까지 계정들이 반복(iterate)되며, 인사할 특정 계정이 추출됩니다. 이후 계정의 소유자가 확인되며, 프로그램이 계정에 쓸 수 있도록 program_id와 동일해야 합니다. 마지막으로 greeting_accounttry_from_slice로 추출되고, 카운터가 1 증가합니다.

3.2 프로그램 컴파일

프로그램을 컴파일하려면 다음 명령으로 Solana CLI를 설치해야 합니다.

sh -c "$(curl -sSfL https://release.solana.com/v1.9.9/install)"

Solana CLI가 성공적으로 설치되었는지 확인하려면 다음 명령으로 버전을 확인할 수 있습니다.

solana --version

RustNodeJS도 필요합니다.

프로그램을 컴파일하려면 다음 명령을 사용할 수 있습니다.

cargo build-bpf --manifest-path=./src/program-rust/Cargo.toml --bpf-out-dir=dist/program

컴파일된 프로그램은 --bpf-out-dir에 지정된 디렉토리 아래에 helloworld.so라는 이름으로 생성됩니다.

3.3 컨트랙트 배포

Solana에 컴파일된 프로그램을 배포하려면 먼저 클러스터를 선택해야 합니다. Solana에는 mainnet, testnet, devnet, localnet의 네 가지 클러스터가 있습니다. 이 게시물에서는 데모 목적으로 devnet에만 컴파일된 프로그램을 배포합니다.

다음 명령을 사용하여 클러스터를 지정합니다.

solana config set --url https://api.devnet.solana.com

이후 배포를 위한 지갑을 생성해야 합니다. solana-keygen new --force를 사용하면 지갑을 생성할 수 있습니다. 더 많은 정보는 Solana 문서를 확인하세요.

새로 생성된 계정에는 트랜잭션 수수료를 지불할 잔액이 없으므로, 다음 명령으로 1 SOL을 에어드랍합니다.

solana airdrop 1 <YourPublicKey> --url https://api.devnet.solana.com

이제 컨트랙트를 배포할 준비가 되었습니다.

solana program deploy dist/program/helloworld.so

사용자는 Devnet Explorer에서 프로그램과 트랜잭션을 확인할 수 있습니다. 이 데모에서는 이 링크에서 배포된 프로그램을 찾을 수 있습니다.

3.4 트랜잭션 전송

Solana에서는 트랜잭션을 전송하기 위해 클라이언트라고 불리는 스크립트를 작성하는 것이 권장됩니다. 다행히 Solana는 샘플 코드를 제공합니다. 클라이언트를 실행하려면 먼저 클라이언트 의존성을 설치해야 합니다.

npm install 

설치가 완료된 후, 다음 명령으로 main.ts 파일의 main 함수를 실행합니다.

npm run start 

main 함수에서 클라이언트는 먼저 establishConnection() 함수로 지정된 클러스터(즉, Devnet)에 연결을 설정하고, establishPayer 함수로 트랜잭션 수수료를 지불하는 페이어를 확인하며, checkProgram 함수로 프로그램과 인사할 계정의 존재를 검증합니다. 필요한 계정이 존재하지 않는 경우 트랜잭션을 전송하여 생성됩니다. 이 데모에서 계정은 이 트랜잭션에서 생성되었습니다.

모든 준비가 완료되면 sayHello 함수가 호출되어 대상 계정에 인사합니다. 트랜잭션은 하나의 명령어로 구성됩니다. 이 명령어는 하나의 계정을 포함하는 keys를 받습니다. 계정의 공개 키(즉, greetedPubkey)는 인사할 대상 계정입니다. 이 계정은 저장소 용도로 사용되며 서명자가 아닙니다. 이 경우 isSigner 속성은 false이고 isWritabletrue입니다. programIdgreetedPubkey의 소유자이자 배포된 컨트랙트의 주소입니다. data는 비어 있으며 이 트랜잭션에서 사용되지 않습니다. 208번째 줄에서 sendAndConfirmTransaction 함수가 호출되고, 트랜잭션이 클러스터에 전송됩니다.

자세한 트랜잭션은 **여기**에서 확인할 수 있습니다.

4. 결론

이 글에서는 Solana의 배경을 간략히 소개하고 샘플 프로젝트(즉, Hello World)를 살펴보았습니다. Solana에 프로그램을 배포하는 방법과 클라이언트를 사용하여 온체인 프로그램과 상호작용하는 방법을 배웠습니다. 블로그를 계속 팔로우해 주세요. 이 시리즈의 더 많은 글을 꾸준히 게시할 예정입니다.

이 시리즈의 다른 글 읽기:

Sign up for the latest updates
~$410만 손실: Taiko, SecondFi 익스플로잇 | BlockSec 위클리
Security Insights

~$410만 손실: Taiko, SecondFi 익스플로잇 | BlockSec 위클리

이 주간 블록체인 보안 리포트는 2026년 6월 22~28일 발생한 주요 사건 2건을 다루며, 이더리움과 카르다노에서 약 410만 달러의 피해가 확인됐습니다. Taiko 브릿지 공격은 노출된 SGX 서명 키와 디버그 엔클레이브를 거부하지 못한 증명 정책 결함을 이용해 악성 증명자를 등록하고 L2 상태 증명을 위조했습니다. SecondFi 지갑은 Ed25519 논스 도출 시 비밀 입력이 제거되는 결함으로 공개 트랜잭션 데이터만으로 개인 키 복구가 가능했습니다.

~$18M 손실: jaredFromSubway, Aztec 등 | BlockSec 위클리
Security Insights

~$18M 손실: jaredFromSubway, Aztec 등 | BlockSec 위클리

이 주간 블록체인 보안 보고서는 2026년 6월 15일~21일을 다루며, 이더리움과 BNB 체인에서 3건의 주요 사고가 발생해 약 $18.3M의 손실이 발생했습니다. jaredFromSubway 사건은 MEV 봇이 차익거래를 위해 신뢰할 수 없는 제3자 컨트랙트에 자산을 승인한 역방향 승인 공격으로, 가짜 래퍼 토큰과 스왑 풀을 이용해 약 $15M 손실이 발생했습니다. Aztec은 이스케이프 해치 ZK 회로의 제약 누락으로 공격자가 가짜 머클 트리로 온체인 검증을 통과했습니다.

~$598만 달러 손실: Aztec, Raydium 등 | BlockSec 위클리
Security Insights

~$598만 달러 손실: Aztec, Raydium 등 | BlockSec 위클리

이 주간 블록체인 보안 리포트는 2026년 6월 8일~14일을 다루며, 이더리움과 솔라나에서 발생한 4건의 주요 사고를 분석하고 총 손실액은 약 598만 달러입니다. Aztec Connect의 입력 검증 누락으로 롤업 증명 경로와 L1 정산 불일치가 발생했고, Raydium의 레거시 AMM v3 검증 누락으로 LP 토큰 상환 계산이 조작되어 4개 풀이 탈취됐습니다. 두 취약점 모두 수년간 노출된 상태였습니다. 입력 검증 부재, 정수 오버플로우, 거버넌스 탈취 등의 공격 유형을 다룹니다.