-
Notifications
You must be signed in to change notification settings - Fork 0
Protocol Architecture
- Introduction
- Project Structure
- Core Components
- Architecture Overview
- Detailed Component Analysis
- Dependency Analysis
- Performance Considerations
- Troubleshooting Guide
- Conclusion
- Appendices
This document describes the architecture of the Countersig Network protocol, a three-layer system that anchors AI agent identities on-chain, enables off-chain Ed25519 PKI authentication, and secures agent reputation through a staked cryptoeconomic model. The protocol consists of:
- Off-chain verification layer: Ed25519-based challenge-response authentication and W3C DID document generation.
- Decentralized identity layer: On-chain anchoring of W3C did:countersig identifiers and agent status.
- On-chain state layer: UUPS upgradeable contracts for identity, reputation, staking, and governance.
The system emphasizes trustless determinism (didHash derivation), verifiable identity (W3C DID), and economic accountability (slashing with staged governance).
The repository organizes protocol logic into smart contracts, a TypeScript SDK, deployment scripts, tests, and documentation.
graph TB
subgraph "Contracts"
ID["CountersigIdentity.sol"]
REP["CountersigReputation.sol"]
ST["CountersigStaking.sol"]
TOK["CSIGToken.sol"]
end
subgraph "Deployment"
DEP["Deploy.s.sol"]
end
subgraph "SDK"
IDX["index.ts"]
AGT["agent.ts"]
VRF["verifier.ts"]
DID["did.ts"]
CHG["challenge.ts"]
KEY["keys.ts"]
end
subgraph "Tests"
TID["CountersigIdentity.t.sol"]
TRP["CountersigReputation.t.sol"]
end
subgraph "Docs"
RM["reputation-model.md"]
RD["README.md"]
end
DEP --> ID
DEP --> REP
DEP --> ST
DEP --> TOK
IDX --> AGT
IDX --> VRF
IDX --> DID
IDX --> CHG
IDX --> KEY
TID --> ID
TRP --> REP
VRF --> ID
VRF --> REP
VRF --> ST
RM --> REP
RD --> ID
RD --> REP
RD --> ST
Diagram sources
- script/Deploy.s.sol:31-106
- packages/sdk/src/index.ts:1-36
- packages/sdk/src/agent.ts:1-80
- packages/sdk/src/verifier.ts:1-160
- packages/sdk/src/did.ts:1-29
- packages/sdk/src/challenge.ts:1-80
- packages/sdk/src/keys.ts:1-91
- test/CountersigIdentity.t.sol:8-244
- test/CountersigReputation.t.sol:8-198
- docs/reputation-model.md:1-156
- README.md:20-51
Section sources
- README.md:20-51
- script/Deploy.s.sol:31-106
- packages/sdk/src/index.ts:1-36
- CountersigIdentity: On-chain DID anchoring, Ed25519 public key storage, agent status lifecycle, and role-gated operations.
- CountersigReputation: Oracle-written 6-factor reputation store with strict per-factor caps and threshold checks.
- CountersigStaking: $CSIG bond management, slash initiation/dispute/execution with a configurable challenge window, and cross-contract coordination with Identity and Reputation.
- CSIGToken: Testnet mintable ERC20 token for onboarding and faucet use.
- SDK: Off-chain cryptography, DID parsing/formatting, challenge generation/signing/verification, and on-chain verification utilities.
Key integration patterns:
- Off-chain: Agent nodes generate Ed25519 keypairs, issue challenges, and sign payloads. They also construct W3C DID documents for interoperability.
- On-chain: Operators register agents with didHash-derived keys; Reputation is updated by oracles; Staking manages stake and slash lifecycle.
Section sources
- src/CountersigIdentity.sol:18-227
- src/CountersigReputation.sol:24-181
- src/CountersigStaking.sol:28-331
- src/CSIGToken.sol:12-27
- packages/sdk/src/agent.ts:7-80
- packages/sdk/src/verifier.ts:15-160
- packages/sdk/src/did.ts:8-29
- packages/sdk/src/challenge.ts:11-80
- packages/sdk/src/keys.ts:62-91
The protocol employs a layered architecture:
- Off-chain verification layer: Uses Ed25519 for challenge-response authentication and builds W3C DID documents for interoperability.
- Decentralized identity layer: Anchors did:countersig identifiers on-chain and exposes agent status and public keys.
- On-chain state layer: UUPS upgradeable contracts for identity, reputation, and staking with role-based access control and governance.
graph TB
subgraph "Off-chain"
A["Agent A<br/>Ed25519 keys"]
B["Agent B<br/>Ed25519 keys"]
VR["Verifier<br/>SDK"]
DIDR["DID Resolver<br/>did:countersig"]
end
subgraph "On-chain"
ID["CountersigIdentity"]
REP["CountersigReputation"]
ST["CountersigStaking"]
TOK["CSIGToken"]
end
subgraph "Governance"
ADM["DEFAULT_ADMIN_ROLE"]
UPG["UPGRADER_ROLE"]
ORA["ORACLE_ROLE"]
STK["STAKING_CORE_ROLE"]
CM["SLASHING_COMMITTEE_ROLE"]
end
A -- "challenge-response" --> B
B -- "resolve DID" --> DIDR
DIDR -- "reads pubkey/status" --> ID
VR -- "on-chain lookups" --> ID
VR -- "on-chain lookups" --> REP
VR -- "on-chain lookups" --> ST
ST -- "updateStatus(Slashed)" --> ID
ST -- "zeroReputation()" --> REP
TOK --- ST
ADM --- ID
ADM --- REP
ADM --- ST
UPG --- ID
UPG --- REP
UPG --- ST
ORA --- REP
STK --- ID
STK --- REP
CM --- ST
Diagram sources
- README.md:22-51
- src/CountersigIdentity.sol:18-227
- src/CountersigReputation.sol:24-181
- src/CountersigStaking.sol:28-331
- src/CSIGToken.sol:12-27
- packages/sdk/src/verifier.ts:15-160
- Ed25519 PKI authentication:
- Agents generate keypairs and derive a did:countersig identifier.
- Challenges are issued with a payload containing the prover’s DID, nonce, and timestamp.
- Signatures are base58-encoded Ed25519 signatures over the UTF-8 payload.
- W3C DID compliance:
- The SDK constructs a compliant DID document with Ed25519VerificationKey2020 and appropriate contexts.
- The controller field references the operator’s EIP-155 DID.
sequenceDiagram
participant A as "Agent A"
participant B as "Agent B"
participant VR as "Verifier (SDK)"
participant ID as "CountersigIdentity"
participant REP as "CountersigReputation"
A->>B : "challenge payload"
B->>A : "{ did, signature }"
A->>VR : "verifySignature(did, payload, signature)"
VR->>ID : "getIdentity(didHash)"
ID-->>VR : "ed25519PubKey, status"
VR->>VR : "verify Ed25519 signature"
VR->>REP : "meetsThreshold(didHash, threshold)"
REP-->>VR : "true/false"
VR-->>A : "verification result"
Diagram sources
- packages/sdk/src/challenge.ts:11-35
- packages/sdk/src/verifier.ts:101-132
- src/CountersigIdentity.sol:195-206
- src/CountersigReputation.sol:171-173
Section sources
- packages/sdk/src/agent.ts:7-80
- packages/sdk/src/challenge.ts:11-80
- packages/sdk/src/keys.ts:62-91
- packages/sdk/src/verifier.ts:101-132
- packages/sdk/src/did.ts:8-29
- DID anchoring:
- didHash is computed on-chain as keccak256("did:countersig:" || chainId || ":" || agentAddress).
- Any party can reproduce didHash without querying storage.
- Identity management:
- Operators register agents with Ed25519 public keys.
- Status lifecycle: Active → Suspended → Slashed (terminal).
- Key rotation allowed for suspended agents; slashed agents are immutable.
flowchart TD
Start(["Register Agent"]) --> CheckInputs["Validate agentAddress<br/>and ed25519PubKey"]
CheckInputs --> ComputeDid["Compute didHash on-chain"]
ComputeDid --> Exists{"Already registered?"}
Exists --> |Yes| Revert["Revert AlreadyRegistered"]
Exists --> |No| Store["Store operator, agentAddress,<br/>ed25519PubKey, Active status"]
Store --> Emit["Emit AgentRegistered"]
Emit --> End(["Done"])
Diagram sources
- src/CountersigIdentity.sol:120-141
Section sources
- src/CountersigIdentity.sol:18-227
- test/CountersigIdentity.t.sol:47-103
- CountersigReputation:
- Oracle role holders write 6-factor scores; per-factor caps enforced.
- Threshold checks and total score exposed for on-chain gating.
- CountersigStaking:
- Manages $CSIG bonds, slash lifecycle with a challenge window, and cross-contract coordination.
- Slashing distributes funds and terminates agent identity.
sequenceDiagram
participant CM as "Committee"
participant ST as "CountersigStaking"
participant ID as "CountersigIdentity"
participant REP as "CountersigReputation"
CM->>ST : "initiateSlash(didHash, victim, evidenceHash)"
ST->>ID : "updateStatus(didHash, Suspended)"
Note over ST : "challengePeriod begins"
alt Operator disputes within window
OP->>ST : "disputeSlash(didHash)"
ST->>ID : "updateStatus(didHash, Active)"
else Window passes undisputed
ANY->>ST : "executeSlash(didHash)"
ST->>ID : "updateStatus(didHash, Slashed)"
ST->>REP : "zeroReputation(didHash)"
end
Diagram sources
- src/CountersigStaking.sol:205-293
- src/CountersigIdentity.sol:164-179
- src/CountersigReputation.sol:135-146
Section sources
- src/CountersigReputation.sol:24-181
- src/CountersigStaking.sol:28-331
- docs/reputation-model.md:104-114
- UUPS upgradeable contracts:
- All core contracts inherit from OpenZeppelin’s UUPSUpgradeable and use AccessControlUpgradeable.
- Upgrades authorized by UPGRADER_ROLE, typically a governance timelock.
- Role-based access control:
- DEFAULT_ADMIN_ROLE grants role management.
- STAKING_CORE_ROLE allows identity and reputation updates from staking.
- ORACLE_ROLE authorizes reputation updates.
- SLASHING_COMMITTEE_ROLE initiates slashes (testnet multisig).
- Deployment orchestration:
- Deploy script initializes implementations behind ERC1967 proxies, wires roles, and writes deployment artifacts.
classDiagram
class CountersigIdentity {
+initialize(admin, stakingCore)
+registerAgent(agentAddress, ed25519PubKey)
+rotatePublicKey(didHash, newEd25519PubKey)
+updateStatus(didHash, status)
+computeDidHash(agentAddress)
+_authorizeUpgrade()
}
class CountersigReputation {
+initialize(admin, oracle, stakingCore)
+updateReputation(didHash, data)
+zeroReputation(didHash)
+_authorizeUpgrade()
}
class CountersigStaking {
+initialize(admin, identity, reputation, csig, minStake, period)
+depositStake(didHash, amount)
+withdrawStake(didHash, amount)
+initiateSlash(didHash, victim, evidenceHash)
+disputeSlash(didHash)
+executeSlash(didHash)
+_authorizeUpgrade()
}
CountersigStaking --> CountersigIdentity : "calls updateStatus()"
CountersigStaking --> CountersigReputation : "calls zeroReputation()"
Diagram sources
- src/CountersigIdentity.sol:92-101
- src/CountersigReputation.sol:86-94
- src/CountersigStaking.sol:121-142
- src/CountersigStaking.sol:284-285
Section sources
- src/CountersigIdentity.sol:225
- src/CountersigReputation.sol:179
- src/CountersigStaking.sol:329
- script/Deploy.s.sol:77-81
- Identity, Reputation, and Staking integration:
- Staking coordinates with Identity (status) and Reputation (zeroing) during slash execution.
- Reputation is updated by oracles and consumed by agents for trust decisions.
graph TB
ID["CountersigIdentity"]
REP["CountersigReputation"]
ST["CountersigStaking"]
ORA["Oracle Network"]
ORA --> REP
ST --> ID
ST --> REP
Diagram sources
- README.md:22-51
- src/CountersigStaking.sol:284-285
- Cross-contract dependencies:
- CountersigStaking depends on CountersigIdentity and CountersigReputation for state transitions and score resets.
- CountersigReputation depends on oracles for score updates.
- SDK dependencies:
- Verifier composes Identity, Reputation, and Staking lookups.
- Agent and Challenge utilities depend on cryptographic primitives and key encoding.
graph LR
AGT["SDK Agent"] --> CHG["Challenge Utils"]
AGT --> KEY["Keys Utils"]
VR["SDK Verifier"] --> ID["CountersigIdentity"]
VR --> REP["CountersigReputation"]
VR --> ST["CountersigStaking"]
ST --> ID
ST --> REP
Diagram sources
- packages/sdk/src/agent.ts:7-80
- packages/sdk/src/challenge.ts:11-35
- packages/sdk/src/keys.ts:62-91
- packages/sdk/src/verifier.ts:26-36
- src/CountersigStaking.sol:137-139
Section sources
- packages/sdk/src/verifier.ts:26-36
- src/CountersigStaking.sol:137-139
- Deterministic didHash derivation avoids repeated on-chain hashing and enables efficient off-chain precomputation.
- Reputation updates are batched off-chain and written once per epoch, minimizing gas costs.
- Challenge-response verification is CPU-bound in off-chain libraries; on-chain verification is minimal and bounded.
- UUPS upgrades reduce upgrade risk and cost compared to replacement deploys.
Common issues and mitigations:
- Registration failures:
- Zero public key or agent address triggers validation errors.
- Duplicate registration prevented by didHash uniqueness.
- Status transitions:
- Only STAKING_CORE_ROLE can set Slashed; terminal state disallows further changes.
- Suspended agents may rotate keys; Slashed agents cannot.
- Staking operations:
- Withdrawals require Active status and minimum stake thresholds.
- Slash lifecycle requires proper challenge window management.
- Reputation:
- Scores validated per factor; exceeding caps reverts.
- Threshold checks enable flexible gating.
Section sources
- src/CountersigIdentity.sol:70-76
- src/CountersigIdentity.sol:164-179
- src/CountersigStaking.sol:154-193
- src/CountersigStaking.sol:205-293
- src/CountersigReputation.sol:111-117
- test/CountersigIdentity.t.sol:70-90
- test/CountersigReputation.t.sol:57-115
Countersig Network establishes a robust, layered identity and trust framework for AI agents. By anchoring W3C-compliant DIDs on-chain, enabling Ed25519-based challenge-response authentication off-chain, and securing reputation through a staked slash model, the protocol balances decentralization, interoperability, and economic accountability. UUPS upgrades and role-based access control provide a secure and evolvable governance model suitable for testnet experimentation and mainnet production.
- Off-chain:
- Ed25519 private key custody remains with operators; compromise triggers immediate suspension and key rotation.
- Challenges include timestamps and nonces to prevent replay.
- On-chain:
- didHash derivation is trustless and recomputable; no central authority controls DID assignment.
- Slashing is permissioned and economically final, preserving reputation integrity.
- Oracles:
- Reputation updates are signed off-chain and validated by on-chain caps; computation logic is separate from storage.
Section sources
- README.md:106-126
- src/CountersigStaking.sol:205-293
- docs/reputation-model.md:104-114
sequenceDiagram
participant Op as "Operator"
participant ST as "CountersigStaking"
participant ID as "CountersigIdentity"
Op->>ST : "depositStake(didHash, min CSIG)"
ST-->>Op : "stake recorded"
Op->>ID : "registerAgent(agentAddress, ed25519PubKey)"
ID->>ID : "computeDidHash()"
ID-->>Op : "AgentRegistered(didHash, operator, agentAddress, pubKey)"
Diagram sources
- README.md:194-207
- src/CountersigStaking.sol:154-165
- src/CountersigIdentity.sol:120-141
sequenceDiagram
participant A as "Agent A"
participant B as "Agent B"
participant ID as "CountersigIdentity"
participant REP as "CountersigReputation"
A->>B : "challenge payload"
B->>A : "{ did, signature }"
A->>B : "sign payload with Ed25519 private key"
B->>ID : "getIdentity(didHash)"
ID-->>B : "ed25519PubKey, status"
B->>B : "verify Ed25519 signature"
B->>REP : "meetsThreshold(didHash, threshold)"
REP-->>B : "true/false"
Diagram sources
- README.md:211-232
- packages/sdk/src/challenge.ts:11-35
- packages/sdk/src/verifier.ts:101-132
sequenceDiagram
participant UC as "User / Counterparty"
participant OR as "Oracle Network"
participant REP as "CountersigReputation"
UC->>OR : "submit attestation"
OR->>OR : "aggregate epoch"
OR->>REP : "updateReputation(didHash, data)"
REP->>REP : "validate per-factor caps"
REP-->>OR : "ReputationUpdated(didHash, total)"
Diagram sources
- README.md:236-249
- docs/reputation-model.md:141-148
Start Here
Core Concepts
Smart Contracts
Oracle System
Agent SDK
Integration Guides
Economic Model
Deployment & Ops
Advanced Topics