# 해시로 거래를 찾으려면 어떻게 합니까: /v1/verify 또는 /v1/transfers?tx=?

전송과 거래 · 해시 하나를 모든 네트워크에서 한 번에 검색하거나, 네트워크 하나를 지정하기 — 그리고 빈 응답이 의미할 수 있는 것과 없는 것

*API 가이드 · 7분 · 중급 · 개발자 · GET /v1/verify · GET /v1/transfers?tx=*

`GET /v1/verify?tx=<hash>`는 해시만 받아, 거래 ID 형식이 맞는 모든 인덱싱된 네트워크(EVM 네트워크와 트론(Tron)은 16진수, 솔라나(Solana)는 base58)에서 스테이블코인 전송 *및* 발행사 기록을 검색합니다. 찾으면 `chain_id`, `transfers[]`, `freeze`와 함께 `found: true`를, 모든 네트워크가 찾지 못했다고 답하면 `false`를, 적어도 하나가 답하지 않으면 `null`을 답합니다. `GET /v1/transfers?tx=&chain=`은 네트워크 하나에서 찾아 행을 반환합니다. 둘 다 최근 보관 구간(hot window)보다 오래되었거나 네트워크의 인덱싱된 헤드보다 새로운 거래는 볼 수 없습니다.

## 해시 하나, 모든 네트워크

```
curl -s 'https://stablescan.achivx.com/v1/verify?tx=0x2b3252e52889309dcf91d8b24034d28a01d247e6229189e05e16409a1eb12ac3'
```

```
{
  "tx": "0x2b3252e52889309dcf91d8b24034d28a01d247e6229189e05e16409a1eb12ac3",
  "found": true,
  "complete": true,
  "chain_id": 1,
  "chain_slug": "ethereum",
  "transfers": [
    {"tx_hash": "0x2b32…2ac3", "log_index": 483, "block_number": 26261992, "block_time": "2026-10-24T10:45:23Z",
     "payer": "0x4299…6ccb", "recipient": "0x6872…f7de", "recipient_name": "Unidentified custodial service 0x6872b663",
     "amount": {"amount": "1047600000", "decimals": 6, "token": "USDC"}, "token": "0xa0b8…eb48", "finality": "pending", "usd_amount": 1047.6}
  ],
  "transfers_total": 1,
  "freeze": {"chain_id": 1, "chain_slug": "ethereum", "tx_hash": "0x2b32…2ac3", "items": []},
  "hot_window_start": "2026-10-22T00:00:00Z",
  "chains": [
    {"chain_id": 1,  "chain_slug": "ethereum", "status": "found",     "sync": {"last_indexed_block": 26261996, "head_block": 26262012, "finalized_block": 26261919, "lag_blocks": 16, "freshness_seconds": 209, "as_of": "2026-10-24T10:49:40Z"}},
    {"chain_id": 10, "chain_slug": "optimism", "status": "not_found", "sync": {"last_indexed_block": 158620078, "head_block": 158620095, "lag_blocks": 17, "freshness_seconds": 47, "…": "…"}},
    {"…": "the other four hex networks"}
  ],
  "as_of": "2026-10-24T10:49:40Z",
  "note": "found=false means: no stablecoin transfer and no issuer act under this hash in any searched network's hot window, as of each network's sync status. A transaction newer than a network's indexed head is not seen yet …"
}
```

전날 주소를 동결한 기록은 같은 형태에 `transfers: []`와 `freeze.items[]` 안의 기록으로 답합니다. 호출 한 번으로 결제와 [발행사 기록](https://achivx.kr/academy/guides/issuer-freezes/)을 구분할 수 있습니다. 아무도 본 적 없는 해시는 모든 `chains[].status: "not_found"`와 함께 `found: false, complete: true, chain_id: null`을 답합니다.

[첫 요청](https://achivx.kr/academy/api/first-request/)의 세 가지 헬퍼로 같은 호출을 하면 다음과 같습니다.

**Python**

```
v = scan("/v1/verify", tx=tx_hash)
if v["found"] is None:
    print("retry: a network did not answer", [c["chain_slug"] for c in v["chains"] if c["status"] == "unknown"])
elif v["found"]:
    print("on", v["chain_slug"], "-", len(v["transfers"]), "transfer(s),", len(v["freeze"]["items"]), "issuer act(s)")
else:
    print("not in any hot window as of", v["as_of"], "- older than", v["hot_window_start"], "or never happened")
```

**Go**

```
var v struct {
	Found     *bool  `json:"found"` // nil = at least one network did not answer
	Complete  bool   `json:"complete"`
	ChainSlug string `json:"chain_slug"`
	Transfers []json.RawMessage `json:"transfers"`
	Chains    []struct {
		ChainSlug string `json:"chain_slug"`
		Status    string `json:"status"` // found | not_found | unknown
	} `json:"chains"`
}
if err := get("/v1/verify", url.Values{"tx": {txHash}}, &v); err != nil {
	return err
}
switch {
case v.Found == nil:
	// retry later: not a negative
case *v.Found:
	fmt.Println("found on", v.ChainSlug)
default:
	fmt.Println("not found in any hot window")
}
```

**TypeScript**

```
type Verify = {
  found: boolean | null; complete: boolean; chain_id: number | null; chain_slug?: string;
  transfers: Transfer[]; transfers_total: number | null; freeze: { items: unknown[] } | null;
  chains: { chain_id: number; chain_slug: string; status: "found" | "not_found" | "unknown"; sync: { freshness_seconds: number | null } }[];
  hot_window_start: string; as_of: string;
};
const v = await scan<Verify>("/v1/verify", { tx: txHash });
if (v.found === null) retryLater();
else if (v.found) console.log("on", v.chain_slug, v.transfers.length, "transfer(s)");
```

## `found`의 세 가지 값

- **`true`** — 적중입니다. `chain_id`, `chain_slug`, `transfers[]`(`transfers_total` 포함), `freeze`가 이를 설명합니다. 각 행의 `finality`는 네트워크가 그것을 확정했는지 알려 줍니다.
- **`false`** — 검색한 모든 네트워크의 최근 보관 구간에 대해 *각 네트워크의 `chains[].sync` 기준으로* 부정 결과입니다. 이 해시로 된 전송도 기록도 없습니다. 이것이 의미할 수 없는 두 가지가 있습니다. `hot_window_start`보다 오래된 거래(보관 처리되어 검색되지 않음)와 네트워크의 `last_indexed_block`보다 새로운 거래(아직 보지 못함 — 얼마나 뒤처졌는지는 `freshness_seconds`가 알려 줌)입니다. 방금 보낸 전송이라면 최신성 간격 하나만큼 기다렸다가 다시 요청하십시오.
- **`null`** — 적어도 하나의 네트워크가 답하지 않았습니다(`chains[].status: "unknown"`). `complete: false`입니다. 재시도하십시오. 부정 결과가 아닙니다. 응답은 `no-store`입니다.

거래 ID가 전혀 아닌 해시는 `400 invalid_tx`입니다(*32-byte hex (0x-prefixed or bare) on the EVM networks and Tron, a 64-byte base58 signature on Solana*). `chain`을 전달하면 `400 unknown_param` — *every indexed network is searched; to look on one network use /v1/transfers?tx=&chain=* — 입니다.

## 네트워크 하나, 행들

```
curl -s 'https://stablescan.achivx.com/v1/transfers?chain=1&tx=0x2b3252e52889309dcf91d8b24034d28a01d247e6229189e05e16409a1eb12ac3'
```

해당 해시에 대한 [피드](https://achivx.kr/academy/courses/following-the-stablecoins/following-the-stablecoins-01-settlement-tables/) 페이지를 답합니다. `items[]`, `total: 1`, `chain_id: 1`, `chain_source: "explicit"`입니다. 네트워크를 알 때 더 저렴하며, 한 체인을 도는 루프 안에서는 이것이 올바른 호출입니다. `chain`이 없으면 베이스(Base)에서만 찾고 `chain_source: "default"`로 그렇다고 밝힙니다. `default`와 함께 온 빈 응답은 다른 네트워크의 해시에 대해 아무것도 말하지 않습니다. 이 라우트의 빈 응답에도 `found: false`와 같은 사각지대가 있습니다. 보관 처리되었거나 아직 인덱싱되지 않은 경우입니다.

[발행사 기록](https://achivx.kr/academy/guides/issuer-freezes/)에는 별도의 조회 `GET /v1/freezes?tx=&chain=` — [기록 원장](https://achivx.kr/academy/api/freeze-acts-ledger/) — 이 있으며, `/v1/verify`는 두 조회를 한 번에 실행합니다.

## 캐시

완전한 `/v1/verify` 응답은 15초 동안 유지되고, 불완전한 응답은 `no-store`입니다. `/v1/transfers?tx=`는 [피드](https://achivx.kr/academy/courses/following-the-stablecoins/following-the-stablecoins-01-settlement-tables/)와 같은 15초입니다.

## Stablecoin scanner ACHIVX에서

- 찾은 결제: [/v1/verify?tx=0x2b32…2ac3](https://stablescan.achivx.com/v1/verify?tx=0x2b3252e52889309dcf91d8b24034d28a01d247e6229189e05e16409a1eb12ac3); 찾은 [발행사 기록](https://achivx.kr/academy/guides/issuer-freezes/): [/v1/verify?tx=0x00c3…1410](https://stablescan.achivx.com/v1/verify?tx=0x00c3cea47aac0a3c4fccbac87eb38b628d17ce0c2c3d13d57dfeabebe1f61410).
- 같은 거래의 페이지 — 해시, 상태, 블록, 보낸 주소, 받는 주소, 전송된 토큰: [/ethereum/tx/0x2b32…2ac3](https://stablescan.achivx.com/ethereum/tx/0x2b3252e52889309dcf91d8b24034d28a01d247e6229189e05e16409a1eb12ac3).

## 출처

- [REST 인터페이스의 OpenAPI 3.1 명세(API 1.4.0)](https://stablescan.achivx.com/openapi.json)
- [에이전트 매뉴얼 — agents.md(버전 2026-10-05)](https://stablescan.achivx.com/agents.md)
- [GET /v1/verify?tx=… (2026-10-24 조회)](https://stablescan.achivx.com/v1/verify?tx=0x2b3252e52889309dcf91d8b24034d28a01d247e6229189e05e16409a1eb12ac3)

## 더 알아보기

- [가이드: 거래 페이지](https://achivx.kr/academy/guides/transaction-page/)
- [USDT가 도착하지 않았습니다 — 어디에 있습니까?](https://achivx.kr/academy/how-it-works/my-usdt-has-not-arrived/)

## 관련 질문

- [정산 피드는 어떻게 읽고, 주소·토큰·블록으로 어떻게 필터링합니까?](https://achivx.kr/academy/api/settlement-feed/)
- [지금 네트워크의 데이터는 얼마나 최신입니까?](https://achivx.kr/academy/api/sync-status/)
- [레시피: 결제가 도착했고 동결되지 않았는지 확인하기](https://achivx.kr/academy/api/recipe-confirm-a-payment/)

전송과 거래 · GET /v1/verify · GET /v1/transfers?tx= · 2026-10-24 작성, openapi.json, agents.md 및 당일 실제 호출 기준. 응답 형태는 인용이며, 수치는 날짜 기준이고 인덱스에 따라 달라집니다.

---

출처: https://achivx.kr/academy/api/find-a-transaction/ · 영어 원문: https://achivx.com/academy/api/find-a-transaction.html
