콘텐츠로 이동

P0 검증 기록

작성일: 2026-07-27

대상 네트워크: XMTP dev, GIWA Sepolia (chain ID 91342)

이 문서는 실제 네트워크에서 확인한 결과만 기록합니다. 개인키, 전체 세션 토큰, 서명 원문, 메시지 원문은 기록하지 않습니다.

1. 테스트 주소

라벨 주소
A 0xEf792c4973Cc8ef6aF433B3bd9f4461B701301f6
B 0x532dA989489eaB825d484EAd09f117018da47778
C 0x2F9713FB44eE7A15EF393eA694959324Be7a6479

2. Dojang 인증 상태

attesterId는 TESTNET_FAUCET을 사용합니다. UPBIT_KOREA 기준으로는 세 주소 모두 미검증이며, 이는 fork 테스트에 고정돼 있습니다.

발급 전 (기준 블록 31763461)

주소 isVerified
A true
B false
C false

이 블록은 contracts/test/ConversationEvidenceRegistry.fork.t.sol의 BASELINE_BLOCK으로 고정돼 있어, 이후 온체인 상태가 바뀌어도 혼합 상태 검증 근거가 남습니다.

B 인증 발급

GIWAFaucetExtension.payAndIssueEAS()를 0.001 ETH 수수료로 호출했습니다. attestation은 발급 30일 후 만료됩니다.

contract:        0x63CCe2b569A7bC35895ee24306c1512fefc06121
transactionHash: 0x245e27442da2987a3918b01e3fb48cfbdbff90f83e155bc6c5715662aa165494
blockNumber:     31763610
status:          success

발급 후 (블록 31763622 실측)

주소 isVerified
A true
B true
C false

C는 의도적으로 미검증으로 유지해 증빙 차단 경로를 검증합니다.

3. 증빙 컨트랙트 배포

contract:        ConversationEvidenceRegistry
address:         0x675dB91aCEC52DCb44e6d20FB1F1299FFafBb51B
transactionHash: 0x8f018ccbb711133dcc52958d50f472bf0c32bde970fec943d39e637d7db01da0
blockNumber:     31763659
compiler:        v0.8.35+commit.47b9dedd

Blockscout 소스 검증 상태는 is_verified: true로 확인했습니다. 배포 후 dojangScroll, attesterId, domainSeparator를 다시 조회해 생성자 인자와 일치하는 것을 확인했습니다.

4. 실제 온체인 증빙 트랜잭션

frontend/src/infrastructure/chain/ViemEvidenceContractAdapter.integration.test.ts 를 실제 GIWA Sepolia에 대해 실행했습니다. 4개 테스트 모두 통과했습니다.

검증 결과
A와 B 전원 서명 증빙 기록 성공
기록한 증빙을 체인에서 다시 조회 성공, contentHash와 참여자 일치
미검증 C가 포함된 증빙 ParticipantNotVerified로 거부
같은 evidence ID 재사용 EvidenceAlreadyRecorded로 거부

성공한 recordEvidence 트랜잭션은 다음과 같습니다.

transactionHash: 0xef01ef70199a1ec835fb9441b4859b7251c9ad7b7fffede7af6a8255f75a94fc
transactionHash: 0xc6d0f502a5c983d9225369250ad429dfc5ae80b4083a11be8f4718945feeecc2
transactionHash: 0x5ac2e5dd6ccaf2fd9a7d890334963bca770ed863ace11a466d242ea3afe1c2cc

4.1 유스케이스 전 구간 검증

frontend/src/application/evidence/EvidenceEndToEnd.integration.test.ts를 실제 백엔드와 실제 GIWA Sepolia에 대해 실행했습니다. 어댑터 단위가 아니라 제안부터 온체인 기록까지의 유스케이스 사슬을 한 번에 지납니다.

단계 결과
A가 SIWE로 로그인하고 증빙을 제안 PROPOSED
제어 메시지에 원문이 들어가지 않음 확인
A 서명 SIGNING
B 서명 READY
A가 온체인 제출 CONFIRMED
미검증 C를 포함한 제안 EVIDENCE_PARTICIPANTS_NOT_VERIFIED로 차단, API 요청과 제어 메시지 모두 생성 안 됨

성공한 전 구간 트랜잭션은 다음과 같습니다.

transactionHash: 0x677de178e5d99fdb38429206a2d8f50ba2a248e6c990b72df8e2ae3b6ae436ed
blockNumber:     31766627

이것이 설계 문서 11.2절의 "참여자 전원이 검증된 대화의 EIP-712 다중 서명과 GIWA Sepolia 증빙이 성공한다" 항목의 근거입니다.

5. 해시 규칙 일치

프론트엔드 hashParticipants와 배포된 컨트랙트의 hashParticipants가 같은 값을 반환하는 것을 실측으로 확인했습니다. 두 값 모두 0x4f68b5db8071fee0ae36ede40c0b63d7e402332397de1f8ad260e1f5082c286e였습니다.

6. 실제 XMTP dev 메시징

frontend/e2e/messaging-three-users.spec.ts를 실제 브라우저와 XMTP dev 네트워크에서 실행했습니다. 통과했다 (28.6초).

검증 항목 결과
A, B, C가 각각 XMTP Inbox 생성 또는 복구 성공
A와 B 1:1 왕복 성공
B와 C 1:1 왕복 성공
A가 A, B, C 그룹 생성 성공
세 사용자가 각각 그룹에 전송, 나머지 둘이 스트림으로 수신 성공
혼합 인증 상태(A·B 인증, C 미인증)에서 메시징 유지 성공

메시지 ID와 conversation ID는 실행마다 달라지므로 값 자체는 기록하지 않습니다. 테스트는 송신자가 받은 XMTP 메시지 ID와 수신자가 스트림으로 받은 ID가 같은지 비교해 통과 여부를 판정합니다.

7. 실제 앱 화면 흐름

frontend/e2e/app-wallet-login.spec.ts와 app-three-users.spec.ts를 실제 백엔드와 XMTP dev에 대해 실행했습니다. 테스트 전용 EIP-1193 provider를 주입하고 개인키는 Node 프로세스에만 두었습니다.

지갑 A 로그인 후 PostgreSQL sessions 테이블에 해당 주소의 세션 행이 생성된 것을 직접 확인했습니다.

app-three-users.spec.ts는 3개 시나리오 모두 통과했다 (57.4초).

시나리오 결과
A, B, C가 앱 화면으로 로그인하고 A-B, B-C 1:1 메시지를 주고받음 통과
미인증 C와의 대화가 요청함으로 분류되고 증빙 버튼이 비활성 통과
미인증 C와도 메시지 송수신은 계속 가능 통과
인증된 A-B 대화에서는 증빙 진입점이 활성 통과

지갑 하나가 XMTP 클라이언트를 만드는 데 40초 안팎이 걸립니다. 지갑을 여러 개 순차로 로그인하는 스펙은 타임아웃을 넉넉히 잡아야 합니다.

8. 자동 테스트 통과 수

대상 통과
frontend 단위·통합 178
backend 단위·PostgreSQL 통합 132
contracts 단위·퍼즈·fork 41

8.1 확인된 운영 제약: XMTP installation 한도

검증 도중 세 테스트 지갑 모두 XMTP Client.create가 응답하지 않는 상태가 됐습니다. 원인을 다음 순서로 좁혔습니다.

  1. 08:57에 통과했던 messaging-three-users.spec.ts가 코드 변경 없이 실패했습니다. 따라서 앱 코드 회귀가 아닙니다.
  2. 새로 생성한 무작위 지갑은 같은 시점에 로그인부터 수신함까지 정상 도달했습니다. 따라서 XMTP dev 네트워크 장애도 아닙니다.
  3. 지갑 A로 installation 조회를 시도하자 다음 오류가 나왔습니다.
Cannot register a new installation because the InboxID ... has already
registered 10/10 installations. Please revoke existing installations first.

XMTP는 inbox 하나당 installation을 10개로 제한합니다. Playwright가 매번 빈 브라우저 프로필로 컨텍스트를 열면 로그인마다 새 installation이 등록되므로, 반복 실행이 슬롯을 소진합니다. 실제 사용자는 브라우저 저장소를 유지하므로 이 상황이 생기지 않습니다.

대응은 두 가집니다.

  • e2e/support/persistentContext.ts가 지갑별 프로필 디렉터리를 고정해 재실행 시 기존 installation을 재사용합니다.
  • 이미 한도에 닿은 지갑은 e2e/revoke-installations.spec.ts로 복구합니다.
UMUL_REVOKE_WALLETS=A,B,C npx playwright test e2e/revoke-installations.spec.ts

9. 남은 제약

  • 파우셋 attestation은 발급 30일 후 만료됩니다. A는 2026-08-10, B는 2026-08-25 전후로 만료되며 그 이후에는 증빙 성공 경로를 다시 검증하려면 재발급이 필요합니다.
  • 증빙의 법적 효력은 이 단계의 판단 범위가 아닙니다.
  • P0는 EOA 서명만 지원합니다. EIP-1271 스마트 계정은 P1 항목입니다.
  • 안드로이드 앱은 구현하지 않았습니다. 사유는 mobile/README.md에 적었습니다.