# 페이로드에서 정직성 계약 읽기

계약과 루프

*레슨 3/5 · 12분 · 고급 · 개발자*

## 이번 레슨에서는

레슨을 마치면 다음을 할 수 있습니다.

- 위험 응답에서 incomplete_reasons, chain_source, chains_with_data, freshness_seconds, address_respelled 찾기
- coverage와 freeze_log_backfilled가 있는 freeze[], 그리고 나머지 세 목록 읽기
- no-store 응답과 배치 null 구분하기

## 빠진 것 없는 판정

아카데미의 제재 대상 예시인 이더리움(Ethereum)의 0x098B71…3E2f96은 2026-10-13에 `GET /v1/addresses/{address}/risk?chain=1`에 다음과 같이 응답했습니다. `tier: "severe"`, 세 개의 `flags`(`sanctioned`, `frozen`, `exposed`)가 모두 true, `incomplete_reasons: []`, 그리고 `evidence` 행 다섯 개입니다. *on the OFAC SDN list*(OFAC SDN 목록에 있음, severe), *frozen/seized by the PYUSD issuer*(PYUSD 발행사가 동결/소각), *by the USDC issuer*(USDC 발행사가), *by the USDT issuer*(USDT 발행사가)(각각 high), *received funds within reach of an OFAC-sanctioned address*(OFAC 제재 대상 주소에서 도달 가능한 범위의 자금을 받음, severe). 판정 옆에는 `chain_source: "explicit"`(`chain`을 넘겼음), `issuer_acts`가 있는 네트워크 네 개를 밝히는 `chains_with_data`, `freshness_seconds` 212, `data_vintage` 2026-09-10T00:00:11Z, `sanctions_list_as_of` 2026-10-13T04:00:02Z, `computed_at`, `requested_address`, `address_respelled: false`가 있습니다.

다음 순서로 읽으십시오. **`chain_source`** — `default`(베이스(Base)) 또는 `address_form`은 `chain`을 넘기지 않았다는 뜻입니다. **`incomplete_reasons`** — `[]`는 모든 입력이 평가되었다는 뜻이고, 그 밖의 값은 무엇이 평가되지 않았는지 밝힙니다. 등급이 `unknown`이면 항상 하나 이상이 나열되며, *사유는 사실이나 라벨이 정한 등급을 결코 낮추지 않습니다*. **`evidence`** — 행에 자체 `tier`가 있으면 그것을 읽습니다(`signal: "service"` 행에는 없을 수 있습니다). `tier: "unknown"`인 `signal: "coverage"` 행은 판단 결과가 아니라 공백을 밝힙니다. **`freshness_seconds`** — 자신의 허용 기준과 비교합니다. **`chains_with_data`** — `issuer_acts`와 함께 나열된 각 네트워크에 대해 그 `chain`으로 `get-address-compliance`를 호출합니다. 중요한 다른 네트워크가 있다면 `chain`을 지정해 필요한 읽기를 반복합니다.

## 그 뒤의 사실

컴플라이언스 응답 `GET /v1/addresses/{address}?chain=1`에는 `sanctioned: true`와 `freeze[]` 행 네 개가 있었습니다. 2024-01-03부터 PYUSD `frozen`, 2022-04-14부터 USDC `frozen`, 2023-12-09부터 USDT `frozen`, USD1 `clear`이며, 모든 행에 `coverage: true`와 `freeze_log_backfilled: true`가 있습니다. 행이 없다는 것(그 쌍의 인덱싱된 로그에 [동결](https://achivx.kr/academy/how-it-works/how-does-a-freeze-happen/) 조치가 없음)은 `freeze_log_backfilled`가 있을 때만 `clear`라는 답이 됩니다. `coverage`는 이 네트워크에서 발행사의 조치가 애초에 인덱싱된 로그에 들어 있다는 뜻입니다. 설명서는 이렇게 말합니다. *그 진술이 있어야만 행의 부재가 `clear`로 답할 수 있습니다. 그 진술이 없는 쌍에서는 행의 부재가 `unknown`으로 답하며, 결코 `clear`가 아닙니다*. `not_freezable[]`은 DAI, USDS, USDe를 `reason: no_freeze_function`과 함께 나열했고, `frozen_elsewhere[]`는 같은 바이트가 동결된 네 행(아비트럼 원(Arbitrum One)의 PYUSD, 베이스·옵티미즘(Optimism)·아비트럼 원의 USDC)을 나열했으며, `freeze_proposals: []`였습니다. 설명서는 이 응답의 목록 중 세 가지가 비어 있을 때 경고합니다. `freeze: []`, `frozen_elsewhere: []`, `freeze_proposals: []` 중 어느 것도 깨끗하다는 증명이 아닙니다. 여기서는 `freeze_proposals`만 비어 있으며, 이것은 *게시된 제안 없음이지, 결코 “대기 중인 것 없음”이 아닙니다*.

## `no-store`, 그리고 배치 null

일부를 잃은 답(라벨 없는 판정, 읽기가 끝나지 않아 `null`인 `freshness_seconds`, `"total": null`인 피드 페이지, `degraded_reason`이 있는 `/graph`)은 REST에서 `Cache-Control: no-store`로 제공됩니다. A2A 응답에는 캐시 헤더가 없고, [MCP](https://stablescan.achivx.com/mcp) 응답은 완전한 판정에도 `no-cache, no-transform`으로 표시되므로(2026-10-20), 이 접근 경로에서는 본문을 읽으십시오. 모든 접근 경로에서 같은 필드입니다. `incomplete_reasons`의 `labels_unread`, `null`인 `chains_with_data`, 읽기가 끝나지 않아 `null`인 `freshness_seconds`(스키마상 체인에 아직 인덱싱된 전송이 없을 때도 `null`), 그리고 REST에서 `?from=`이 붙은 `risk`에는 `new_counterparty_unread`도 있습니다. 피드 진입 페이지에서는 REST든 스킬이든(스킬 응답에도 `total`이 있음, 2026-10-20) `total_unavailable_reason`도 있습니다. REST에서는 `/graph`의 `degraded_reason`이 있습니다. 어느 경우든 다시 요청하십시오. 다음 답은 완전할 수 있습니다. 솔라나(Solana)의 위험 또는 노출 판정도 호출마다 계산되므로 `no-store`이지만, 이것은 일부를 잃은 것이 아닙니다. `/v1/stats/home`이나 `/v1/stats/overview`의 `null` 유기적 수치는 배치의 상태이며 `organic_unavailable_reason`에 밝혀져 있고, `organic_excluded_chains`는 수치에서 제외된 각 네트워크를 `{chain_id, reason}`으로 나열합니다(overview에서는 둘 다 최상위, home에서는 둘 다 `headline` 아래). 다시 요청해도 채워지지 않습니다. 두 가지 null, 두 가지 의미이며, 둘 다 명시되어 있습니다.

## 핵심 정리

- incomplete_reasons []는 완전히 평가되었다는 뜻이고, 그 밖의 값은 공백을 밝힙니다. unknown은 결코 깨끗함이 아닙니다
- evidence 행에 자체 tier가 있으면 그것을 읽으십시오. tier가 unknown인 coverage 행은 판단 결과가 아니라 공백을 밝힙니다
- 행의 부재가 clear로 답할 수 있게 하는 것은 freeze_log_backfilled입니다. 그것이 없으면 clear는 관측된 동결 해제일 뿐입니다. coverage는 이 네트워크에서 발행사의 조치가 애초에 인덱싱된 로그에 있다는 뜻입니다
- 빈 동결 목록은 깨끗하다는 증명이 아닙니다. frozen_elsewhere는 등급이 점수로 매기지 않는 신호입니다
- EVM이나 트론(Tron) 판정의 no-store는 다시 요청하라는 뜻이고, 배치 null은 가져올 수치가 없다는 뜻입니다

## Stablecoin scanner ACHIVX에서 직접 해 보기

1. [제재 대상 예시의 위험 판정](https://stablescan.achivx.com/v1/addresses/0x098B716B8Aaf21512996dC57EB0615e2383E2f96/risk?chain=1)을 열고 `tier`, `incomplete_reasons`, `chain_source`, 그리고 각 `evidence` 행의 `tier`(있는 경우)를 읽습니다.
2. [그 컴플라이언스 응답](https://stablescan.achivx.com/v1/addresses/0x098B716B8Aaf21512996dC57EB0615e2383E2f96?chain=1)을 엽니다. `freeze[]` 행의 수를 세고, 각 `status`를 읽고, `clear`인 행의 `freeze_log_backfilled`를 확인합니다.
3. 같은 응답에서 `frozen_elsewhere[]`와 `chains_with_data`를 읽습니다. 그다음 `chain=42161`로 컴플라이언스 읽기를 다시 요청하고 비교합니다.
4. [overview](https://stablescan.achivx.com/v1/stats/overview)를 열고 `organic_excluded_chains`와, 있다면 `hot_window_start`를 찾습니다.

## 레슨 돌아보기

- 이 필드 중 데이터 모델에 열이 있는 것은 무엇이고, 조용히 버려질 것은 무엇입니까?
- 사유에 `time_budget`이 있는 등급 `unknown`을 보고서에서 어떻게 표현하겠습니까?

## 다음 내용

이 필드들을 이 순서로 읽는 것이 곧 스크리닝 루프입니다. 다음은 설명서의 스크리닝 루프를 처음부터 끝까지 실행하는 것입니다.

## 더 알아보기

- [정직성 계약이란 무엇입니까?](https://achivx.kr/academy/for-agents/what-is-the-honesty-contract/)
- [get-address-risk는 무엇을 반환하며, 언제 호출합니까?](https://achivx.kr/academy/for-agents/get-address-risk/)
- [get-address-compliance는 무엇을 반환합니까?](https://achivx.kr/academy/for-agents/get-address-compliance/)

레슨 3/5 · 에이전트를 위한 Stablecoin scanner ACHIVX · 위에 링크된 사용자 가이드를 바탕으로 합니다.

---

출처: https://achivx.kr/academy/courses/the-scanner-for-agents/the-scanner-for-agents-03-reading-the-honesty-contract/ · 영어 원문: https://achivx.com/academy/courses/the-scanner-for-agents/the-scanner-for-agents-03-reading-the-honesty-contract.html
