A smart-contract verification architecture for managing agent lifecycle, logging actions, and computing trust scores on-chain.
AgentChain is a Solidity-based system designed to provide decentralized agent verification, action logging, and trust scoring. The architecture ensures immutability, transparency, and scalability through optimized smart contracts deployed on EVM-compatible blockchains.
AgentChain consists of three core smart contracts:
Manages the complete agent lifecycle with role-based access control (RBAC).
Features:
- Self-registration with metadata commitment (bytes32 hash)
- Four agent states: PENDING, ACTIVE, SUSPENDED, REVOKED
- Verifier-only activation, suspension, and revocation
- Revocation tracking with counter
- OpenZeppelin AccessControl for RBAC
Key Functions:
registerAgent(bytes32 metadataHash)- Self-register as PENDINGactivateAgent(address agent)- Verifier activates agent to ACTIVEsuspendAgent(address agent)- Verifier suspends agentrevokeAgent(address agent)- Verifier revokes agent
Append-only immutable log of agent actions with cryptographic data commitment.
Features:
- Only ACTIVE agents can log actions
- Payload hashing (keccak256) for data privacy
- Per-agent action counting
- Monotonic action IDs
- Immutable registry reference (prevents re-initialization)
Key Functions:
logAction(bytes32 actionType, address targetAddress, bytes calldata payload)- Log agent actiongetActionCount(address agent)- Retrieve action count for agent
Read-only derivable trust scoring using fixed-point arithmetic.
Features:
- Fixed-point scoring (0-100) with no floating-point operations
- Fully deterministic on-chain computation
- Score components:
- Base score: 30%
- Action volume (capped): 40%
- Agent age (capped): 30%
- Penalties for suspension/revocation
- Gas-optimized calculation
Key Functions:
scoreOf(address agent)- Compute trust score (0-100)
agentchain/
├── contracts/
│ ├── AgentRegistry.sol
│ ├── ActionLogger.sol
│ ├── TrustScorer.sol
│ └── interfaces/
│ ├── IAgentRegistry.sol
│ └── IActionLogger.sol
├── scripts/
│ └── deploy.js # Deployment orchestration
├── test/
│ └── AgentChain.test.js # Comprehensive test suite
├── hardhat.config.js
├── package.json
└── deployments.json # Network-keyed deployment output
- Node.js >= 18.0.0
- npm >= 9.0.0
# Clone the repository
git clone https://github.com/harshil748/AgentChain.git
cd AgentChain
# Install dependencies
npm installThe project is configured in hardhat.config.js:
- Solidity Version: 0.8.20
- EVM Target: Paris
- Optimizer: Enabled (200 runs)
npm run compileCompiles all Solidity contracts to the artifacts/ directory.
npm testExecutes the comprehensive Mocha/Chai test suite with gas metrics:
- 8 tests covering AgentRegistry, ActionLogger, and TrustScorer
- Gas analysis for 100 sequential actions (~111k gas per action)
- Event verification with anyValue matchers
- Status transitions and access control validation
Test Coverage:
- Agent registration and activation
- Action logging with authentication
- Trust score calculation
- Penalty application (suspension/revocation)
- Gas efficiency benchmarks
npm run deployDeploys all three contracts to a local Hardhat network:
- Deploys
AgentRegistry(admin) - Deploys
ActionLoggerwith registry reference - Deploys
TrustScorerwith registry and logger references - Writes deployment addresses to
deployments.jsonkeyed by chain ID
Output Example:
{
"31337": {
"deployedAt": "2026-04-30T...",
"deployer": "0x...",
"contracts": {
"AgentRegistry": "0x...",
"ActionLogger": "0x...",
"TrustScorer": "0x..."
}
}
}The contracts implement several gas optimization strategies:
Replace costly require messages with targeted custom errors:
error AgentAlreadyRegistered();
error AgentNotActive();Optimize storage layout to use fewer storage slots:
ActionRecord:
bytes32 actionType(32 bytes)address targetAddress(20 bytes)uint64 timestamp(8 bytes)bytes32 dataHash(32 bytes)- Total: 3 storage slots (vs. 4 without packing)
AgentRecord:
bytes32 metadataHash(32 bytes)uint64 registeredAt(8 bytes)uint64 lastUpdatedAt(8 bytes)uint32 revocationCount(4 bytes)AgentStatus status(1 byte)- Total: 2 storage slots (vs. 5 without packing)
Avoid floating-point operations with fixed-point math (1M scale):
uint256 private constant SCALE = 1_000_000;
uint256 private constant BASE_SCORE = 30_000_000; // 30%
uint256 private constant ACTION_CAP = 40_000_000; // 40%
uint256 private constant AGE_CAP = 30_000_000; // 30%Prevent re-initialization and reduce storage reads:
IAgentRegistry private immutable agentRegistry;The test suite (test/AgentChain.test.js) includes:
-
Registry Tests:
- Agent registration and self-service activation
- Verifier access control for suspension/revocation
- Status transition validation
-
Logger Tests:
- Non-active agent rejection
- Payload hashing and data commitment
- Per-agent action tracking
- 100-action sequential gas benchmark
-
Scorer Tests:
- Unregistered agent score (0)
- Score improvement with time and actions
- Penalty application post-revocation
- Deterministic on-chain computation
All tests pass with 8/8 success rate.
npx hardhat run scripts/deploy.js --network localhostBefore deploying to mainnet or testnet:
- Audit: Have contracts professionally audited
- Gas Optimization: Verify optimizer settings match production targets
- Verify Source: Generate verification metadata for block explorers
- Access Control: Assign VERIFIER_ROLE to trusted addresses
- Testing: Run against testnet first (Sepolia, Goerli, etc.)
interface IAgentRegistry {
function isRegistered(address agent) external view returns (bool);
function isActiveAgent(address agent) external view returns (bool);
function getAgentMetadataHash(address agent) external view returns (bytes32);
function getAgentStatus(address agent) external view returns (AgentStatus);
function getRegistrationTimestamp(address agent) external view returns (uint64);
function getRevocationCount(address agent) external view returns (uint32);
}interface IActionLogger {
function getActionCount(address agent) external view returns (uint256);
}All contracts include comprehensive NatSpec comments covering:
- Function purpose and behavior
- Parameter descriptions
- Return value documentation
- Event details
- Custom error explanations
Generate documentation with:
npx hardhat docgen- Smart Contracts: Solidity 0.8.20
- Framework: Hardhat 2.22.17
- Ethers: v6.13.5
- Testing: Mocha/Chai with @nomicfoundation helpers
- Access Control: OpenZeppelin AccessControl v5.0.2
This project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch (
git checkout -b feature/YourFeature) - Commit your changes (
git commit -m 'Add YourFeature') - Push to the branch (
git push origin feature/YourFeature) - Open a Pull Request
For issues, questions, or suggestions, please open a GitHub issue on the repository.