For developers
For developers
Everything an integrator or auditor needs to verify Sentinel's claims independently — the on-chain contract interface, the verify-root-locally algorithm, the export format, and the configured testnet addresses.
EvidenceRegistry interface
A minimal append-only contract. Permissionless: anyone may call it, but records are isolated per msg.sender.
anchor(bytes32 batchId, bytes32 root) — writes anchors[msg.sender][batchId]. Reverts on ZeroRoot, ZeroBatchId, or AlreadyAnchored.verify(address customer, bytes32 leaf, bytes32[] proof, bytes32 batchId) → bool — permissionless sorted-pair Merkle inclusion check against the customer's anchored root. Returns false if no anchor exists.getAnchor(address customer, bytes32 batchId) → Anchor — full read of an anchor record (root, timestamp, blockNumber).EvidenceAnchored(address indexed customer, bytes32 indexed batchId, bytes32 root, uint64 timestamp, uint64 blockNumber)Verify a root locally
The trust-minimizing step. Before a Safe owner signs an anchor proposal, they recompute the Merkle root entirely client-side from their own audit-log export and compare it against the proposed root. A mismatch is surfaced before any signing affordance is enabled. The algorithm:
- For each entry, recompute the leaf:
keccak256(canonical_json({...payload, _prev_hash, _customer})). Canonical JSON = sorted keys, no whitespace, UTF-8. - Re-walk the chain: each entry's
prev_hashmust equal the previous entry's recomputedentry_hash; the first entry chains tobytes32(0). - Merkle-root the leaves with commutative sorted-pair keccak256. This matches OpenZeppelin's
MerkleProof.verifyCalldata, so a proof that verifies locally also verifies on-chain viaEvidenceRegistry.verify.
The browser implementation and the policy-service generator share the exact same canonical-JSON + sorted-pair algorithm, so a clean local round-trip is also a self-test of the implementation.
Audit-log export
The primary disclosure artifact is an exportable hash-chained audit log as NDJSON (one canonical entry per line, with its prev_hash and entry_hash). Any third party holding the export can re-walk the chain, recompute leaves, and recompute the root of any batch window — without trusting Sentinel. The on-chain anchor strengthens third-party verifiability; it does not replace the export.
Configured testnet addresses
0x6447ae565a90Daa0BD0B36C03EEB7717Cd2BFd430xd0E2BDa7DB57630817B8Efd75e351356d2ddabC6