증빙 컨트랙트¶
ConversationEvidenceRegistry는 참여자 전원이 동의한 대화의 해시만 기록합니다.
대화 원문과 개별 메시지 원문은 저장하지 않습니다.
동작 원리와 실제 트랜잭션 예시는 증빙 컨트랙트 가이드에 있습니다.
배포¶
| 항목 | 값 |
|---|---|
| 네트워크 | GIWA Sepolia (chain ID 91342) |
| 주소 | 0x675dB91aCEC52DCb44e6d20FB1F1299FFafBb51B |
| DojangScroll | 0xd5077b67dcb56caC8b270C7788FC3E6ee03F17B9 |
| attesterId | TESTNET_FAUCET |
| 배포 블록 | 31763659 |
전체 산출물은 contracts/deployments/giwa-sepolia.json에 있습니다.
기록 대상¶
struct Evidence {
bytes32 conversationHash;
bytes32 contentHash;
bytes32 participantsHash;
uint32 messageCount;
uint64 startedAt;
uint64 endedAt;
bytes32 nonce;
uint64 deadline;
}
evidenceId = keccak256(abi.encode(typedDataDigest, nonce))이며 재사용을
막습니다.
검증 순서¶
recordEvidence는 다음을 순서대로 확인합니다.
- 참여자가 2명 이상이고 서명 개수가 참여자 수와 같다
- 해시가 0이 아니고 시간 범위가 뒤집히지 않았으며
deadline이 지나지 않았다 - 참여자 주소가 오름차순이고 중복이 없다
participantsHash가keccak256(abi.encode(participants))와 일치한다evidenceId가 아직 쓰이지 않았다- 각 참여자에 대해
DojangScroll.isVerified가 true다 - 각 서명이 같은 typed data digest에서 해당 참여자 주소를 복구한다
EIP-712 도메인¶
| 항목 | 값 |
|---|---|
| name | GasokConversationEvidence |
| version | 1 |
| chainId | 91342 |
| verifyingContract | 배포 주소 |
도메인에 chain ID와 컨트랙트 주소가 들어가므로 다른 체인이나 다른 배포본으로 서명을 재사용할 수 없습니다. 재배포하면 기존에 모은 서명은 무효가 됩니다.
deadline을 포함해 모든 필드는 백엔드가 돌려준 요청 값에서 파생합니다. 서명자가
각자 다른 deadline을 고르면 digest가 갈려 컨트랙트가 서명을 전부 거부하므로,
공통값인 요청의 expiresAt을 그대로 씁니다.
프론트엔드와의 해시 일치¶
frontend/src/domain/evidence/hashEvidenceManifest.ts의 hashParticipants는
컨트랙트의 hashParticipants와 같은 keccak256(abi.encode(address[]))
인코딩을 씁니다. 배포본과 실제 값이 일치하는 것을 확인했습니다.
한계¶
- P0는 EOA 서명만 지원합니다. EIP-1271 스마트 계정은 P1로 미룹니다.
- 컨트랙트는 XMTP 그룹 참여자 집합을 독립적으로 확인할 수 없습니다. 참여자 전원이
같은
participantsHash에 서명하는 방식으로 선언된 집합에 동의합니다. - 서명 이후 Dojang 인증이 철회되거나 만료되면 제출이 거부됩니다. 테스트넷 파우셋 attestation은 발급 30일 후 만료됩니다.
- 법적 효력은 이 단계의 범위가 아닙니다.