주소의 거래 상대는 어떻게 가져옵니까: /graph 또는 /walk?
주소 · 노드와 엣지로 된 에고 하위 그래프, 또는 홉 단위 탐색 — 한 번에 토큰 하나, 주소 500개의 탐색 경계, 그리고 응답이 밝히는 기간 범위
- API 가이드
- 10분
- 중급
- 개발자
- GET …/graph
- GET …/walk
/v1/addresses/{address}/graph?chain=&token=&hops=는 주소 주변의 정산 그래프를 nodes[]와 edges[](엣지별 거래량, 노드별 라벨, motifs[])로 반환합니다. 최신 스냅샷이 저장되어 있으면 그것으로 만들고, 무거운 그래프가 아직 없으면 202 building으로 답합니다. /v1/addresses/{address}/walk?chain=&token=&hops=는 같은 이웃을 홉 단위로 반환하며, 요청마다 새로 만들고 stop_at_attributed와 stop_on_sanctioned 스위치를 가집니다. 두 라우트 모두 token을 전달하십시오. 그래프는 스테이블코인별로 만들어집니다. 무언가가 없다는 것에서 결론을 내리기 전에 window_from을 읽으십시오.
그래프
curl -s 'https://stablescan.achivx.com/v1/addresses/0x28C6c06298d514Db089934071355E5743bf21d60/graph?chain=1&token=USDT&hops=1'2026-10-24 바이낸스(Binance) 핫월렛의 USDT 이웃입니다. 노드 484개와 엣지 484개이며, 앞부분만 잘라 보여 줍니다.
{
"address": "0x28c6c06298d514db089934071355e5743bf21d60",
"chain_id": 1,
"token": "USDT",
"decimals": 6,
"window": "all",
"window_from": "2026-10-03",
"edge_source": "daily",
"max_hops": 1,
"frontier_cap": 500,
"start_key": "addr:28c6c06298d514db089934071355e5743bf21d60",
"nodes": [
{"key": "addr:28c6…1d60", "address": "0x28c6…1d60", "hop": 0, "volume": 0, "volume_usd6": 0, "score": 1, "attributed": false, "sanctioned": false,
"name": "Binance", "category": "exchange_hot", "is_service": true},
{"key": "addr:5754…b949", "address": "0x5754…b949", "hop": 1, "direction": "out", "volume": 500000000000000, "volume_usd6": 500000000000000, "score": 0.0431,
"attributed": false, "sanctioned": false, "name": "Tether: Treasury", "category": "issuer", "is_service": true}
],
"edges": [
{"from": "addr:28c6…1d60", "to": "addr:5754…b949", "volume": 500000000000000, "volume_usd6": 500000000000000, "tx_count": 1}
],
"motifs": [],
"extraction": {"hops": 1, "nodes_explored": 484, "frontier_truncated": true, "stop_at_attributed": true, "edges_omitted": false},
"built_at": "2026-10-24T08:22:06Z",
"snapshot_served": true,
"snapshot_age_seconds": 8696
}nodes[] — key와 address, 노드에 도달한 hop, direction(in: 대상에게 지급함, out: 대상이 지급함), 토큰 최소 단위의 volume과 volume_usd6, score(대상의 흐름 중 노드의 몫, 대상 자신은 1), attributed와 sanctioned, 그리고 라벨이 있으면 라벨이 들어 있습니다. edges[] — from, to, 거래량, tx_count. motifs[] — 자금 세탁 형태 적중으로, 섀도 신호이며 여기서는 비어 있습니다. extraction — 그림이 어떻게 잘렸는지를 나타냅니다. frontier_truncated: true는 홉 1이 frontier_cap(기본값이자 최댓값 500)보다 넓어서 가장 큰 거래 상대들만 남겼다는 뜻입니다.
edge_source, window, window_from — 그래프를 무엇으로 만들었는지를 나타냅니다. lifetime은 지금까지 인덱싱된 모든 날의 전체 기간 합계입니다(조용한 주소인 제재 대상 예시는 노드 하나, 엣지 없이 edge_source: "lifetime"으로 답했습니다). daily는 일 단위이며, 이때 window_from이 시작 지점을 알려 줍니다. 요청은 window=all이었지만 여기서는 2026-10-03입니다. 연결 수 기준을 넘는 메가 허브는 항상 daily입니다. lifetime_deferred: true는 전체 이력이 백그라운드에서 만들어지는 중인, 기간 all에 대한 일 단위 응답을 표시합니다.
snapshot_served, snapshot_age_seconds, built_at — 이 그림은 저장된 것이며 2.4시간 지난 것입니다. 그래프가 저장되어 있지 않고 기한 안에 만들어지지 않는 무거운 주소는 {"status": "building", "retry_after_seconds": 5, …}와 Retry-After: 5로 202를 답합니다. 그래프도 아니고 오류도 아닙니다. 기다린 뒤 같은 요청을 반복하십시오. 노드를 읽기 전에 상태를 확인하십시오. X-Degraded 헤더와 함께 오는 degraded_reason은 응답의 일부가 빠졌다는 뜻이며, 그 응답은 no-store입니다.
hops는 0–4(기본값 1)이고, window는 1h, 24h, 7d, 30d, 90d, 1y, all 중 하나이며, frontier는 너비의 상한을 정합니다(0이거나 파싱할 수 없으면 500 유지). token이 없으면 네트워크의 기본 스테이블코인이 쓰이므로 전달하십시오.
탐색
curl -s 'https://stablescan.achivx.com/v1/addresses/0x28C6c06298d514Db089934071355E5743bf21d60/walk?chain=1&token=USDC&hops=1&frontier_cap=20'{
"address": "0x28c6c06298d514db089934071355e5743bf21d60",
"chain_id": 1,
"token": "USDC",
"decimals": 6,
"token_source": "explicit",
"window": "all",
"window_from": "2026-10-03",
"max_hops": 1,
"frontier_cap": 20,
"stop_at_attributed": true,
"stop_on_sanctioned": false,
"start_key": "addr:28c6c06298d514db089934071355e5743bf21d60",
"self_sanctioned": false,
"hops": [
{"hop": 1, "nodes": [
{"key": "addr:6a36…d9aa", "address": "0x6a36…d9aa", "direction": "in", "volume": 99200000, "volume_usd6": 99200000, "score": 0.6005, "attributed": false, "service": false, "sanctioned": false},
{"key": "addr:b03f…2337", "address": "0xb03f…2337", "direction": "in", "volume": 66000000, "volume_usd6": 66000000, "score": 0.3995, "attributed": false, "service": false, "sanctioned": false}
]}
],
"nodes_explored": 2,
"frontier_truncated": false
}탐색은 노드를 hops[]별로 묶고 스위치 값을 그대로 돌려줍니다. stop_at_attributed(기본값 true: 라벨이 붙은 서비스는 경계이며, 확인은 하지만 통과해 탐색하지 않음), stop_on_sanctioned(기본값 false), frontier_cap 1–500, hops 0–4(기본값 2)입니다. token_source는 토큰이 여러분이 지정한 것(explicit)인지 네트워크 기본값인지 알려 줍니다. self_sanctioned는 대상 자신이 목록에 올라 있는지입니다. 요청마다 새로 만들어지므로 마지막 집계 처리 시점의 일 단위 데이터를 반영합니다. 솔라나(Solana)에서는 채움이 끝나면 다음 처리(약 10분) 후 walk에 나타나고, graph에는 그 이후 그래프가 새로 만들어져야 나타납니다.
첫 요청의 세 가지 헬퍼로 같은 호출을 하면 다음과 같습니다.
Python
import time
g = scan(f"/v1/addresses/{addr}/graph", chain=1, token="USDT", hops=1)
if g.get("status") == "building": # a 202 — urllib does not raise on it
time.sleep(g["retry_after_seconds"]); g = scan(f"/v1/addresses/{addr}/graph", chain=1, token="USDT", hops=1)
print(g.get("window_from"), g["extraction"]["nodes_explored"], "nodes;", len(g["edges"]), "edges")
top = sorted((n for n in g["nodes"] if n["hop"] == 1), key=lambda n: -n["volume_usd6"])[:5]
for n in top:
print(" ", n["direction"], n.get("name") or n["address"], n["volume_usd6"] / 1e6)Go
var g struct {
Status string `json:"status"` // "building" on a 202
WindowFrom string `json:"window_from"`
Nodes []struct {
Address string `json:"address"`
Hop int `json:"hop"`
Direction string `json:"direction"`
VolumeUSD float64 `json:"volume_usd6"`
Name string `json:"name"`
} `json:"nodes"`
Edges []struct {
From, To string
TxCount int `json:"tx_count"`
} `json:"edges"`
}
err := get("/v1/addresses/"+addr+"/graph", url.Values{"chain": {"1"}, "token": {"USDT"}, "hops": {"1"}}, &g)
if err != nil {
return err
}
if g.Status == "building" {
time.Sleep(5 * time.Second) // then repeat the same request
}TypeScript
type Node = { address: string; hop: number; direction?: "in" | "out"; volume_usd6: number; name?: string; sanctioned: boolean };
type Graph = { status?: "building"; retry_after_seconds?: number; window_from?: string; nodes: Node[]; edges: { from: string; to: string; tx_count: number }[] };
let g = await scan<Graph>(`/v1/addresses/${addr}/graph`, { chain: 1, token: "USDT", hops: 1 });
if (g.status === "building") {
await new Promise((r) => setTimeout(r, (g.retry_after_seconds ?? 5) * 1000));
g = await scan<Graph>(`/v1/addresses/${addr}/graph`, { chain: 1, token: "USDT", hops: 1 });
}Python의 urllib는 202를 성공으로 처리하므로, 만들어지는 중인 그래프와 실제 그래프를 구분해 주는 것은 위의 status 확인입니다. Go와 TypeScript 헬퍼도 202가 400 미만이므로 같은 방식으로 동작합니다.
무엇을 호출할 것인가
- 그림 — 노드, 엣지, 거래량, 가장 활발한 거래 상대:
/graph. 저장된 것이므로 반복 호출이 저렴하며, 몇 시간 지난 것일 수 있습니다(snapshot_age_seconds, 최대 6시간, 빌드 실패 시 대체용은 72시간). - 경로에 대한 질문 — 홉 2에 누가 있는가, 탐색이 서비스에서 멈췄는가, 경로상에 제재 대상이 있는가:
/walk. 목록에 오른 첫 노드에서 멈추려면stop_on_sanctioned=true를 씁니다. 요청마다 만들어지며frontier_cap으로 제한됩니다. - 거래 상대가 의미하는 바에 대한 판정: 둘 다 아닙니다.
/exposure가 오염 출발점까지 역방향으로 탐색하고 분류를 답합니다. 여기의 두 라우트는 그림만 그립니다.
이런 것이 보이면 …
window=all요청에"window_from": "2026-10-03"— 일 단위 데이터는 고정된 기간 범위만큼 보관됩니다(/v1/methodology에서는 이를edge_grain_horizon이라고 부릅니다). 응답은 그 구간만 다룹니다. 그 안에 없는 거래 상대를 그 날짜 이전에도 없었던 것으로 취급하지 마십시오."frontier_truncated": true— 홉이 상한보다 넓었습니다. 가장 큰 거래 상대만 남았고 나머지는 그림에 없습니다.window를 좁히거나 특정token으로/walk를 요청하십시오.token "USDC" is not indexed on chain 728126428과 함께400 bad_request— 해당 스테이블코인이 이 네트워크의 레지스트리에 없습니다. 무엇이 있는지는/v1/tokens?chain=이 나열합니다.- 솔라나 — 대상의
coverage_status가 함께 옵니다.pending은 그림이 더 커질 수 있다는 뜻입니다.
Stablecoin scanner ACHIVX에서
- JSON 형태의 그래프: /graph?chain=1&token=USDT&hops=1; 탐색: /walk?chain=1&token=USDC&hops=1&frontier_cap=20.
- 같은 그래프를 그린 것 — 흐름 보기와 트리 보기, drawing 32 of 479+: /ethereum/address/0x28C6…1d60.
출처
- REST 인터페이스의 OpenAPI 3.1 명세(API 1.4.0)
- 에이전트 매뉴얼 — agents.md(버전 2026-10-05)
- GET /v1/methodology (stablscan-methodology-v0.5.0)
더 알아보기
관련 질문
- 주소의 제재 대상 자금이나 해킹 자금 노출은 어떻게 측정합니까?
- 주소의 스테이블코인 잔액과 거래량은 어떻게 읽습니까?
- 한 스테이블코인의 가장 큰 주소와 가장 바쁜 경로를 얻으려면 어떻게 합니까?
주소 · GET …/graph · GET …/walk · 2026-10-24 작성, openapi.json, agents.md 및 당일 실제 호출 기준. 응답 형태는 인용이며, 수치는 날짜 기준이고 인덱스에 따라 달라집니다.
이 페이지는 ACHIVX Academy 영어 원문을 한국어로 옮긴 것입니다. 번역과 원문이 다르면 영어 원문이 기준입니다.