Skip to content

Evidence Contract

ConversationEvidenceRegistry records only the hash of a conversation that every participant agreed to. It stores neither the conversation nor any individual message plaintext.

How it works, with a real transaction walkthrough, is in the Evidence Contract Guide.

Deployment

Item Value
Network GIWA Sepolia (chain ID 91342)
Address 0x675dB91aCEC52DCb44e6d20FB1F1299FFafBb51B
DojangScroll 0xd5077b67dcb56caC8b270C7788FC3E6ee03F17B9
attesterId TESTNET_FAUCET
Deployment block 31763659

The full artifact is in contracts/deployments/giwa-sepolia.json.

What gets recorded

struct Evidence {
    bytes32 conversationHash;
    bytes32 contentHash;
    bytes32 participantsHash;
    uint32 messageCount;
    uint64 startedAt;
    uint64 endedAt;
    bytes32 nonce;
    uint64 deadline;
}

evidenceId = keccak256(abi.encode(typedDataDigest, nonce)), which prevents reuse.

Verification order

recordEvidence checks the following in order.

  1. There are at least two participants and the signature count equals the participant count
  2. Hashes are non-zero, the time range is not inverted, and deadline has not passed
  3. Participant addresses are in ascending order with no duplicates
  4. participantsHash matches keccak256(abi.encode(participants))
  5. evidenceId has not been used yet
  6. DojangScroll.isVerified is true for every participant
  7. Each signature recovers the corresponding participant address from the same typed data digest

EIP-712 domain

Item Value
name GasokConversationEvidence
version 1
chainId 91342
verifyingContract Deployment address

Because the domain includes the chain ID and the contract address, signatures cannot be replayed on another chain or another deployment. Redeploying invalidates any signatures already collected.

Every field, deadline included, derives from the request values the backend returned. If signers each picked their own deadline, the digests would diverge and the contract would reject every signature, so the request's shared expiresAt is used as is.

Hash parity with the frontend

hashParticipants in frontend/src/domain/evidence/hashEvidenceManifest.ts uses the same keccak256(abi.encode(address[])) encoding as the contract's hashParticipants. Parity between the deployment and the actual values has been confirmed.

Limits

  • P0 supports EOA signatures only. EIP-1271 smart accounts are deferred to P1.
  • The contract cannot independently confirm the XMTP group's participant set. Everyone signing the same participantsHash is how they agree to the declared set.
  • If Dojang verification is revoked or expires after signing, submission is rejected. Testnet faucet attestations expire 30 days after issuance.
  • Legal weight is out of scope at this stage.