개요
Solana 블록체인은 데이터를 순차적인 추가 전용 원장에 저장합니다. 이는 데이터 무결성과 트랜잭션 처리량 측면에서는 뛰어나지만 상당한 대가가 따릅니다. 과거 데이터를 쿼리하는 작업이 매우 비효율적이고 지나치게 느려집니다. 복잡한 작업에는 여러 소스의 데이터를 필터링, 집계 또는 조인하는 과정이 포함되는 경우가 많습니다. 이러한 경우 대부분의 실제 애플리케이션에서는 Solana를 직접 쿼리하는 것이 비현실적입니다. 이 문제를 해결하기 위해 대부분의 기업은 Solana 과거 데이터의 비공개 인덱스를 구축합니다. 이 가이드에서는 전체 수명 주기를 다룹니다.getTransactionsForAddress 및 기타 아카이브 RPC 메서드를 사용한 과거 데이터 백필, 데이터베이스 선택, 실시간 스트리밍을 통한 인덱스 최신 상태 유지 방법을 설명합니다.
사용해야 하는 경우
다음과 같은 경우 인덱스를 구축하세요.- 제품에 직접 RPC 호출로는 너무 느린 고속 필터링 쿼리가 필요한 경우(예: 지갑의 토큰 계정과 잔액 또는 거래 페어의 전체 내역)
- 온체인 데이터를 필터링, 집계 또는 조인하거나 오프체인 데이터(CEX 가격, KYC, 레이블)와 결합해야 하는 경우
- 사전 처리되어 쿼리할 수 있는 데이터가 필요한 PnL, 보유자 분석 또는 NFT 판매 내역 등을 계산하는 경우
- 많은 사용자에게 서비스를 제공하며 체인에 대한 요청별 지연 시간을 감당할 수 없는 경우
Solana 데이터 인덱싱이란 무엇인가요?
인덱싱은 Solana 블록체인에서 데이터를 쿼리하여 백엔드 데이터베이스(예: PostgreSQL, ClickHouse)에 저장하는 과정입니다. 이렇게 저장된 데이터는 Solana RPC 호출을 사용해 블록체인을 직접 쿼리하지 않고도 고객 요청에 신속하게 응답하는 데 사용할 수 있습니다. 인덱서는 일반적으로 다음 네 가지 작업을 수행합니다.- 과거 데이터 백필: 아카이브 RPC 메서드를 사용해 모든 과거 데이터를 쿼리합니다.
- 새 데이터 스트리밍: 네트워크에서 확인된 새 블록을 처리합니다.
- 데이터 파싱 및 변환: 확인된 블록에서 관련 데이터(예: 트랜잭션, 상태 변경 등)를 추출합니다.
- 데이터베이스에 데이터 구성: 새 데이터로 인덱스를 업데이트합니다.
대부분의 기업이 Solana 인덱스를 구축하는 이유는 무엇인가요?
기업은 네이티브 RPC가 제공하지 않는 목적별 블록체인 데이터(예: NFT 판매 내역)에 빠르게 실시간으로 액세스하는 것이 비즈니스에 중요하기 때문에 Solana 인덱스를 구축합니다. 또한 기업은 사용자 지정 인덱스를 활용하여 오프체인 데이터(예: 중앙화 거래소 가격, KYC 정보 등)를 온체인 데이터와 결합합니다.지갑 예시
예를 들어 Solana 지갑에서 사용자의 토큰 계정과 잔액을 빠르게 반환해야 하는 경우,getTokenAccountsByOwner 및 getTokenAccountBalance를 사용하여 Solana를 직접 쿼리하면 너무 느려 제품을 사용할 수 없게 될 수 있습니다. 대신 지갑 서비스는 일반적으로 고객 주소, 토큰 및 계정 잔액에 대한 자체 인덱스를 유지합니다.
거래 예시
마찬가지로 암호화폐 거래 회사는 거래 알고리즘을 백테스트하기 위해 특정 거래 페어(예: SOL-USDC) 또는 특정 시장에서 발생하는 모든 거래 활동을 기록하려 할 수 있습니다. 이 데이터를 얻기 위해 블록체인을 직접 쿼리하면 실용적인 거래 분석에 사용하기에는 지나치게 느립니다. 대신 퀀트 트레이더는 SOL-USDC 시장의 인덱스를 구축하고 LaserStream 같은 실시간 스트리밍 제품을 사용하여 최신 거래 정보로 업데이트할 수 있습니다.필터링 예시
사용자가 프런트엔드 애플리케이션에서 특정 기준(예: 토큰 유형, 전송 금액, 날짜 또는 지갑 주소)에 따라 트랜잭션을 필터링하려는 상황을 가정해 보세요. 인덱서가 없으면 앱에서 수십만 개 블록에 걸친 수백만 건의 트랜잭션을 스캔하며 각각을 필터 기준과 대조해야 합니다. 이 과정은 최신 제품의 사용자 경험에 사용하기에는 너무 느립니다.PnL 예시
트레이더의 손익(PnL)을 계산하려면 다음 작업이 필요합니다.- 지정된 기간에 해당 지갑과 연결된 모든 트랜잭션 찾기
- 스왑 트랜잭션을 선별하고 매수 또는 매도로 레이블 지정하기
- 각 스왑에서 사용자가 지불한 수수료 계산하기
- 각 거래 시점의 각 토큰 과거 가격 데이터 가져오기
- 각 트랜잭션의 PnL을 집계하여 트레이더의 총 PnL 계산하기
1단계: 과거 데이터 가져오기
Solana 인덱스를 구축하는 첫 단계는 필요한 모든 과거 데이터를 가져오는 것입니다. 주요 방법은 다음 세 가지입니다.방법 1: getTransactionsForAddress(권장)
getTransactionsForAddress RPC 메서드를 사용하면 블록체인 데이터의 임의 구간에 대한 전체 트랜잭션 세부 정보를 가져올 수 있습니다. 강력한 필터링 기능 덕분에 인덱스에 필요하지 않은 데이터를 검색하는 데 시간을 낭비하지 않으며, 역방향 검색 기능을 사용해 트랜잭션을 시간순으로 가져올 수 있습니다.
이 메서드를 사용하는 단계
- 데이터가 필요한 기간을 결정하고 그에 맞게 필터 설정하기
- 모든 트랜잭션 세부 정보를 가져오도록
transactionDetails을full으로 설정하기 - 필요한 경우 연결된 토큰 계정 트랜잭션이 포함되도록
tokenAccounts필터 구성하기 paginationToken을 사용하여 결과를 페이지 단위로 가져오기- 각 반복에서 필요한 데이터를 추출하여 데이터베이스에 저장하기
getTransactionsForAddress 사용의 이점
gTFA 엔드포인트의 주요 장점은 속도와 단순성입니다. 슬롯 및 시간 기반 필터, 토큰 계정 지원, 역방향 검색, 페이지네이션을 사용하면 복잡한 반복 또는 재시도 로직 없이 한 번의 호출만으로 Solana 기록의 어느 시점에서든 원하는 데이터를 가져올 수 있습니다.getSignaturesForAddress와 달리 주소가 소유한 연결 토큰 계정 관련 트랜잭션도 포함할 수 있습니다.
인덱스가 토큰 및 네이티브 SOL 이동(결제, 원장, 잔액 조정)을 대상으로 하는 경우 getTransfersByAddress는 전체 트랜잭션 대신 파싱된 조정 준비 완료 전송 행을 반환하므로 파싱 단계를 줄일 수 있습니다.
방법 2: getSignaturesForAddress 및 getTransaction
gTFA가 출시되기 전에는getSignaturesForAddress를 사용하여 서명을 최신 항목부터 가장 오래된 항목까지 재귀적으로 순회한 다음 getTransaction을 호출하여 전체 트랜잭션 세부 정보를 추출하는 것이 과거 데이터 쿼리의 표준 접근 방식이었습니다.
이 메서드를 사용하는 단계
이 메서드를 사용하는 기본 단계는 다음과 같습니다.getSignaturesForAddress호출하기- 이 호출에서 마지막으로 수신한 트랜잭션의 서명 저장하기
- 다음
getSignaturesForAddress호출에서는before매개변수를 이 서명으로 설정하기 - 필요한 만큼 루프에서 이 과정 반복하기
- 이 방식으로 검색한 각 트랜잭션 서명에 대해
getTransaction을 호출하여 전체 트랜잭션 세부 정보 가져오기 - 관련 데이터를 데이터베이스에 삽입하기
이 메서드의 단점
안타깝게도 이 메서드를 사용하려면 다음 작업이 필요합니다.- 최신 트랜잭션부터 시작하여 과거 방향으로 작업하기
- 각 트랜잭션마다 RPC 호출 한 번 더 수행하기
- 동시 처리를 위한 스레드 안전 큐 구축하기
- 데이터 누락과 속도 제한을 방지하기 위한 재시도 및 백오프 로직 구축하기
- 주소가 소유한 연결 토큰 계정 관련 트랜잭션은 포함되지 않음
getTransactionsForAddress를 사용하세요.
방법 3: getBlock 사용
getBlock 메서드는 대상 블록에 있는 트랜잭션 중 높은 비율이 분석과 관련된 경우에 가장 효과적입니다. 예를 들어 DFlow의 Aggregator, Pump.fun 프로그램 또는 Solana의 Token 프로그램처럼 자주 사용되는 Solana 프로그램의 트랜잭션을 인덱싱하는 경우가 해당합니다.
이 메서드를 사용하는 단계
getBlock을 사용하여 과거 데이터를 쿼리하는 기본 과정은 다음과 같습니다.
- 쿼리할 기간 결정하기
- 이 기간을 슬롯 번호로 변환하기
- 해당 블록을 순차적으로 가져오기(정방향 또는 역방향)
- 각 블록에서 인덱스와 관련된 트랜잭션 필터링하기
- 트랜잭션의 관련 정보를 인덱스에 저장하기
2단계: Solana 데이터를 데이터베이스와 동기화하기
과거 데이터를 가져온 후에는 데이터를 변환하여 데이터베이스에 효율적으로 저장해야 합니다. 스토리지 선택은 구체적인 사용 사례에 맞춰야 합니다. 모든 상황에 적합한 단일 솔루션은 없습니다. 적합한 데이터베이스는 데이터세트 크기, 지연 시간 요구 사항, 쿼리 패턴 및 팀의 전문성에 따라 달라집니다.옵션 1: SQL 데이터베이스
대부분의 사용 사례에서는 PostgreSQL 같은 관계형 데이터베이스에 Solana 데이터를 저장하는 것이 좋습니다. SQL은 유연하고 널리 사용되며 배우기 쉽습니다. 최신 관계형 데이터베이스는 1억 개 이상의 행까지 확장하면서도 ACID 준수, 복잡한 조인 및 강력한 보조 인덱스의 이점을 제공할 수 있습니다. 프로토타이핑, 로컬 개발 또는 단일 파일 데이터베이스로 구성을 전혀 하지 않으려면 SQLite를 사용하세요. 데이터세트가 수 GB 미만으로 유지되는 경우에 적합합니다. 데이터 복제, 여러 클라이언트의 동시 액세스 또는 전체 텍스트 검색과 JSON 연산자 같은 고급 기능이 필요한 프로덕션 애플리케이션에는 PostgreSQL을 사용하세요. 대부분의 프로덕션급 Solana 인덱서에는 PostgreSQL을 권장합니다.구현 예시:
예시로 PostgreSQL 데이터베이스에 토큰 전송을 저장하는 방법을 보여드리겠습니다. 먼저 테이블을 생성하세요.옵션 2: 컬럼형 데이터베이스
컬럼형 데이터베이스는 분석 쿼리, 집계 및 대용량 시계열 데이터에 최적화되어 있습니다. 수십억 건의 트랜잭션을 인덱싱해야 한다면 ClickHouse나 Cassandra 같은 컬럼형 데이터베이스가 가장 적합합니다. 대규모 데이터세트에서 실시간 분석 쿼리가 필요하다면 ClickHouse를 사용하세요. 빠른 읽기, 집계 및 시계열 분석에 최적화되어 있습니다. 매우 높은 쓰기 처리량, 간편한 수평 확장 및 높은 내결함성이 필요하다면 Cassandra를 사용하세요. 따라서 방대한 양의 Solana 데이터를 지속적으로 수집하는 데 적합합니다.구현 예시:
ClickHouse 데이터베이스에 토큰 전송을 저장하는 방법을 보여드리겠습니다. 이를 위해 MergeTree 테이블 엔진을 사용하는 테이블을 생성하세요. 높은 수집 속도를 위해 설계되었으므로 인덱싱에 적합합니다. 다음 명령을 사용하세요.(token_mint, date)이 기본 키와 정렬 키로 모두 설정됩니다. ClickHouse는 정렬 키에 따라 디스크의 데이터를 정렬합니다. 이는 단일 토큰 민트를 쿼리하고 날짜 범위로 응답 범위를 좁히는 데 최적입니다.
쿼리 예시는 다음과 같습니다.
FixedString(N) 데이터 형식으로 저장됩니다. ClickHouse는 데이터를 자동으로 압축하여 스토리지 비용을 10~20배 절감하고 쿼리 성능을 개선합니다.
쿼리 성능을 최적화하려면 구체화된 뷰를 사용하여 일반적인 집계를 미리 계산하세요.
예를 들어 대시보드의 거래량 관련 차트에 사용할 토큰의 일일 전송량을 미리 계산할 수 있습니다.
옵션 3: 데이터 레이크
데이터 레이크는 장기 보관 및 분석 쿼리를 위해 방대한 양의 원시 및 처리된 블록체인 데이터를 저장하는 데 적합합니다. 간단한 구현에서는 Parquet 데이터 형식과 Amazon Athena를 사용합니다. Parquet는 효율적인 데이터 저장 및 검색을 위해 설계된 열 지향 데이터 파일 형식입니다. Amazon Athena는 인프라를 설정하거나 별도의 데이터베이스에 데이터를 로드하지 않고도 표준 SQL을 사용하여 Amazon S3에 저장된 데이터를 분석할 수 있는 대화형 쿼리 서비스입니다.구현 예시:
토큰 전송의 아카이브를 만들고 쿼리하려고 합니다. 먼저 S3에 저장해야 합니다.solana_index이라는 버킷을 생성하고 다음 키 구조를 사용하여 토큰 전송 데이터를 시간별로 파티셔닝하세요.
인덱싱 프레임워크 사용
Carbon 및 유사한 프레임워크를 사용하면 상용구 코드를 작성하지 않고 며칠이 아닌 몇 시간 만에 인덱서를 설정할 수 있습니다.주요 기능:
- 인기 프로그램(Token 프로그램, DeFi 프로토콜, Metaplex)을 위한 사전 구축된 디코더
- 구성 가능한 데이터 소스(RPC, LaserStream, Enhanced WebSockets)
- 백필과 실시간 스트리밍 모두 기본 지원
- 여러 스토리지 백엔드로 출력(Postgres 기본 제공)
- 완전한 사용자 지정 지원: 자체 데이터 소스, 디코더 및 데이터 싱크를 설정할 수 있음
3단계: 인덱스를 최신 상태로 유지하기
과거 데이터를 백필한 후에는 새 블록체인 활동으로 인덱스를 최신 상태로 유지할 실시간 스트리밍 솔루션이 필요합니다. 그렇지 않으면 인덱스가 오래된 상태가 됩니다.방법 1: LaserStream(권장)
모든 프로덕션 인덱싱 사용 사례의 기본 선택으로 LaserStream gRPC를 권장합니다. 안정적이고 지연 시간이 매우 짧으며 내결함성을 갖춘 데이터 스트리밍을 위해 특별히 설계되었습니다. LaserStream 사용의 몇 가지 이점은 다음과 같습니다.- 48시간 과거 재생: 인덱서의 연결이 끊기면 LaserStream이 중단된 지점부터 누락된 모든 트랜잭션을 자동으로 재생합니다.
- 자동 재연결: LaserStream SDK(Rust, Go, JS/TS)가 네트워크 중단을 원활하게 처리합니다.
- 노드 장애 조치: LaserStream 연결은 여러 노드의 데이터를 동시에 집계하여 가동 시간을 극대화합니다.
인덱싱에 LaserStream을 사용하는 방법
subscribe 메서드를 사용하여 블록체인 이벤트를 구독하세요.
권장 사항은 다음과 같습니다.
- 필터 범위를 최대한 좁히세요: 대역폭 사용량과 필요한 처리 작업을 최소화하도록 실제로 인덱싱해야 하는 데이터만 구독하세요.
confirmed커밋먼트 수준을 사용하세요: 이 수준은 지연 시간과 최종성 사이에서 균형을 제공합니다.processed수준은 안정성이 지나치게 낮을 수 있으며,finalized은 ~13초의 지연 시간을 추가합니다.- 실패한 트랜잭션을 구체적으로 추적해야 하는 경우가 아니라면
failed: false을 설정하세요. - 인덱싱과 관련이 없으므로 투표 트랜잭션을 제외하세요(
vote: false).
방법 2: LaserStream WebSocket 사용
LaserStream WebSocket은 Helius 전용transactionSubscribe 확장 기능이 포함된 LaserStream의 WebSocket 버전입니다. LaserStream gRPC와 동일한 백엔드에서 실행되며, gRPC가 필요하지 않을 때 비용 효율적인 실시간 스트리밍 대안입니다.
다음과 같은 경우 LaserStream WebSocket을 사용하세요.
- 애플리케이션에서 간헐적인 데이터 누락을 허용할 수 있는 경우
- 실시간 업데이트가 중요하지만 미션 크리티컬하지는 않은 경우
- 누락된 데이터를 감지하고 백필할 기존 인프라가 있는 경우
- 예산 제약이 크고 스트리밍 비용을 최소화해야 하는 경우
- LaserStream을 본격적으로 도입하기 전에 프로토타입을 만들거나 테스트하는 경우
- 속도: LaserStream WebSocket은 LaserStream gRPC와 동일한 백엔드에서 실행되지만 WebSocket 프로토콜에는 JSON 프레이밍과 메시지별 오버헤드가 추가됩니다. 동일한 데이터에서 가능한 한 가장 짧은 지연 시간을 얻으려면 LaserStream gRPC를 사용하세요.
- 안정성: 과거 데이터 재생이 보장되지 않습니다. WebSocket 연결이 끊어지면 RPC 메서드를 사용하여 누락 구간을 직접 감지하고 백필해야 합니다.
- 복잡성: 데이터 완전성을 보장하려면 추가 모니터링 인프라가 필요합니다.
인덱싱에 WebSocket을 사용하는 방법
모든 토큰 전송을 저장하는 인덱스를 업데이트하려면 다음과 같이transactionSubscribe를 구독합니다.
시작하기
견고한 Solana 인덱스를 구축하고 데이터를 백필하려면 다음 세 가지 핵심 과제를 해결해야 합니다.- 과거 데이터를 효율적으로 가져오기
- 빠른 검색을 위해 데이터 변환 및 저장하기
- 인덱싱된 Solana 데이터를 실시간으로 최신 상태로 유지하기
getTransactionsForAddress 같은 아카이브 호출, LaserStream 같은 업계 최고 수준의 데이터 스트리밍 솔루션 덕분에 이제 Solana 인덱스를 그 어느 때보다 쉽고 실용적으로 구축할 수 있습니다.
보완 옵션
자체 인덱스를 운영하면 모든 기능을 직접 제어할 수 있지만 항상 필요한 것은 아닙니다. 일반적인 요구 사항의 경우 관리형 Helius API가 사용자 지정 인덱스를 대체하거나 보완할 수 있습니다.- DAS API — 자산 데이터를 직접 인덱싱하지 않고 NFT, 대체 가능 토큰 및 압축 자산(메타데이터, 소유권, 잔액, 소유자/컬렉션/생성자별)을 쿼리합니다.
- Wallet API — USD 가치와 더 간단한 응답 구조를 제공하는 지갑 잔액, 내역, 전송 및 ID용 고수준 REST 엔드포인트입니다.
다음 단계
- API 액세스를 위해 무료 Helius 계정에 가입하세요.
- 백필에 관한 getTransactionsForAddress 가이드를 읽어보세요.
- 실시간 스트리밍에 관한 LaserStream 개요를 살펴보세요.
- 모든 아카이브 메서드에 관한 과거 데이터 개요를 검토하세요.