본문으로 건너뛰기
0%

과거 Solana 토큰 잔액 조회 기능 소개

작성자: Alchemy

마지막 업데이트: 2026년 7월 21일3분 읽기
getTokenAccountsByOwnerAtSlot — 과거 Solana 토큰 잔액

Solana 지갑에게 오늘 무엇을 보유하고 있는지 물으면 어떤 노드든 한 번의 호출로 답할 수 있습니다. 하지만 작년 봄에 무엇을 보유하고 있었는지, 또는 탈취당하기 직전 정확한 순간에 무엇을 보유하고 있었는지 물으면 그 쉬운 방법이 사라집니다. 노드는 현재 잔액만 제공합니다. 누가 언제 무엇을 보유했는지에 대한 기록을 유지하지 않습니다. 그래서 "이 지갑이 그때 무엇을 보유하고 있었는가"에 대한 정직한 답은 지금까지 "직접 재구성하라"였습니다.

오늘 그 상황을 바꿉니다. getTokenAccountsByOwnerAtSlot은 과거 어느 시점에 지갑이 보유했던 모든 것을 정확한 잔액과 함께 단 한 번의 호출로 반환합니다.

과거를 재구성하는 문제

표준 getTokenAccountsByOwner은 단 하나의 질문에만 답합니다: 이 지갑이 지금 무엇을 보유하고 있는가. 대부분의 실시간 앱 흐름에는 이것으로 충분하지만, 답할 수 없는 질문들이 한 부류 남아 있습니다.

과거 잔액을 직접 재구성하려면 계정의 이력을 처음부터 재생해야 합니다. getSignaturesForAddress로 지갑의 전체 서명 이력을 가져오고, getTransaction로 모든 트랜잭션을 조회한 다음, 목표 지점까지 슬롯 단위로 잔액을 다시 계산해야 합니다. 활발히 사용된 지갑이라면 수천 번의 호출과 많은 파싱이 필요하고, 계산이 틀릴 여지도 많습니다. 아카이벌 노드는 과거 상태를 읽는 데 도움이 되지만, "슬롯 X에서 이 소유자의 토큰 계정 목록을 달라"는 질문에 직접 답하지는 않습니다.

작동 방식

이 메서드는 getTokenAccountsByOwner에서 이미 익숙한 문법을 그대로 유지하면서 한 가지를 추가합니다: slot입니다. 슬롯은 Solana의 시계로, 대략 하나의 블록에 해당하므로, 슬롯을 전달한다는 것은 "이 지갑이 그 역사적 시점에 정확히 어떤 상태였는지 알려달라"는 뜻입니다.

이 메서드를 호출하면 지갑의 토큰 계정, 즉 지갑이 보유한 각 토큰을 담고 있는 개별 레코드를 반환받습니다. Solana에서는 지갑이 잔액을 직접 보유하지 않으므로, 이 계정들을 나열하는 것이 곧 보유 내역을 읽는 방법입니다. 각 계정에는 잔액과 lamports가 함께 제공되는데, lamports는 모든 계정이 온체인에 존재하기 위해 지니고 있는 소량의 SOL(코인의 일부 단위로, 1 SOL은 10억 lamports)입니다. 이 메서드는 Solana의 두 토큰 표준을 모두 다룹니다: 사실상 USDC 같은 잘 알려진 모든 토큰의 기반이 되는 원조 표준인 SPL Token, 그리고 전송 수수료와 기밀 잔액 같은 추가 기능을 갖춘 더 새로운 버전인 Token-2022입니다. 이 두 표준은 서로 다른 프로그램 ID 아래에 있으므로, 단일 programId 필터는 해당 프로그램의 계정만 반환합니다.

이 호출 뒤에는 지속적으로 구축되는 이력 인덱스, 즉 누가 어떤 계정을 얼마나, 어느 슬롯 사이에 보유했는지를 시간에 따라 버전별로 기록한 데이터가 자리하고 있으며, 새 블록이 생성될 때마다 최신 상태로 유지됩니다. 쿼리 범위는 두 가지 방식으로 지정할 수 있습니다. mint 기준으로, 과거 특정 슬롯에서 단일 토큰의 잔액을 읽을 수 있습니다. 또는 program 기준으로, 해당 슬롯에서 그 프로그램 아래 소유된 모든 토큰 계정을 나열할 수 있습니다. 두 표준을 아우르는 전체 포트폴리오를 조회하려면, SPL Token 프로그램 ID로 한 번, Token-2022 프로그램 ID로 한 번 호출한 다음 결과를 합치면 됩니다. 아래 예제는 SPL Token으로만 범위를 한정합니다.

javascript
Copied
const res = await fetch("https://solana-mainnet.g.alchemy.com/v2/{ALCHEMY_API_KEY}", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "getTokenAccountsByOwnerAtSlot", params: [ "89zoESAF7JqYQz5uhf5eYwg3QsKXQy5QFs4WZQ4hMPnb", { programId: "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" }, { encoding: "jsonParsed", slot: 80000000 } ] }) }); console.log(await res.json());

pageKey이 요청한 슬롯을 고정하므로 페이징은 일관되게 유지됩니다. 페이징하는 동안 체인의 최신 지점은 계속 진행될 수 있지만, 결과는 여전히 동일한 시점을 나타내며, 페이지당 최대 10,000개의 계정을 처리합니다.

왜 중요한가

특정 시점의 보유 내역이 일급 쿼리가 됩니다. 직접 구축하고 유지보수해야 했던 인덱싱 파이프라인이 하나의 RPC 호출로 축소되어, 팀이 배관 작업 대신 제품에 집중할 수 있게 됩니다.

이로써 그동안 고통스러웠던 작업들이 가능해집니다:

  • 과거 임의 시점의 포트폴리오 및 손익(PnL) 스냅샷
  • 특정 슬롯이나 날짜에 연동된 취득원가 및 세무 보고
  • 지갑이 탈취당하기 직전 블록에서 무엇을 보유하고 있었는지 보여주는 등의 분쟁, 포렌식, 인시던트 대응 작업
  • 재생 없이 정확한 과거 상태가 필요한 분석 및 인덱싱 파이프라인

테스트 과정에서 온체인 실측 데이터와 결과를 대조하여 검증했습니다. 샘플링한 과거 쿼리들은 슬롯 80,000,000에서의 KIN 잔액과 같은 깊은 과거 기록을 포함해, 체인 잔액 및 lamports와 정확히 일치했습니다.

시작하기

이 메서드는 표준 Solana mainnet 엔드포인트에서 사용할 수 있으므로, 이미 Alchemy를 통해 Solana RPC를 보내고 있다면 기존 API 키로 바로 호출할 수 있습니다. https://solana-mainnet.g.alchemy.com/v2/{ALCHEMY_API_KEY}을 대상으로 지정하고 slot를 추가한 다음, 보유 내역을 읽어오면 됩니다.

키를 설정하고 첫 요청을 보내는 방법은 Solana API 퀵스타트를 참고하세요.

FAQ

getTokenAccountsByOwnerAtSlot은 무엇을 하나요?

지정한 과거 슬롯 시점의 Solana 지갑 토큰 계정을 잔액 및 lamports와 함께 반환합니다. getTokenAccountsByOwner과 동일한 형태에 slot 파라미터가 추가된 형태입니다.

SPL Token과 Token-2022는 무엇인가요?

Solana의 두 토큰 표준입니다. SPL Token은 네트워크상 사실상 모든 잘 알려진 토큰을 아우르는 원조 표준입니다. Token-2022는 전송 수수료와 기밀 잔액 같은 선택적 기능을 추가한 더 새로운 버전입니다. 이 메서드는 두 가지를 모두 지원합니다.

getTokenAccountsByOwner와 무엇이 다른가요?

getTokenAccountsByOwner는 현재 보유 내역만 반환합니다. getTokenAccountsByOwnerAtSlot은 실시간 노드 상태가 아닌 이력 인덱스를 읽어, 과거 어느 슬롯에서든 같은 질문에 답합니다.

아카이벌 노드나 별도의 인덱서가 필요한가요?

아니요. 이 메서드는 미리 구축된 이력 인덱스를 읽으므로, 아카이벌 인프라를 운영하거나 트랜잭션 이력을 직접 재생할 필요가 없습니다.

단일 토큰이 아닌 지갑의 전체 포트폴리오를 조회할 수 있나요?

가능하지만, 지갑이 두 표준을 모두 보유하고 있다면 한 번의 programId 호출로는 안 됩니다. 단일 토큰은 mint로, 특정 슬롯에서 해당 프로그램 아래의 모든 계정은 programId으로 범위를 지정하세요. SPL Token과 Token-2022는 서로 다른 프로그램 ID를 사용하므로, 전체 포트폴리오를 조회하려면 두 곳을 모두 쿼리한 후 응답을 병합해야 합니다.

체인이 진행되는 동안 페이지네이션은 어떻게 정확성을 유지하나요?

pageKey이 쿼리 슬롯을 고정하므로, 새 블록이 도착하더라도 페이지 간 결과가 일관되게 유지되며, 페이지당 최대 10,000개의 계정을 처리합니다.

Alchemy 뉴스레터

출시 소식을 가장 먼저 받아보세요

뉴스레터 구독하기

Alchemy의 최신 제품 업데이트와 리소스 받기

A
O
D
+
구독자 80,000명 이상

이메일 주소를 입력하면 마케팅 커뮤니케이션 및 제품 업데이트 수신에 동의하게 됩니다. Alchemy는 저희 개인정보 처리방침에 따라 수집한 정보를 처리합니다. 언제든지 구독을 취소할 수 있습니다.