Certifi is a blockchain-based credential verification system built on Stacks. It consists of two main smart contracts that work together to create an immutable, transparent, and instantly verifiable credential ecosystem.
Purpose: Manages educational institution registration and verification
Key Data Structures:
institutions: {
institution-id: uint
name: string-ascii 256
country: string-ascii 128
registration-number: string-ascii 128
owner: principal
verified: bool
verified-at: optional uint
created-at: uint
metadata-uri: string-ascii 512
}
verifiers: {
verifier: principal -> bool
}Key Functions:
| Function | Type | Access | Description |
|---|---|---|---|
register-institution |
Public | Any | Register a new institution |
add-verifier |
Public | Owner | Add a verifier |
remove-verifier |
Public | Owner | Remove a verifier |
verify-institution |
Public | Verifier | Verify an institution |
get-institution |
Read-Only | Any | Get institution details |
get-institution-by-owner |
Read-Only | Any | Get institution by owner |
is-institution-verified |
Read-Only | Any | Check verification status |
get-institution-count |
Read-Only | Any | Get total institutions |
get-verified-count |
Read-Only | Any | Get verified count |
is-verifier |
Read-Only | Any | Check if user is verifier |
State Variables:
institution-counter: Total institutions registeredtotal-verified: Total verified institutions
Purpose: Manages credential issuance, verification, and revocation
Key Data Structures:
credentials: {
credential-id: uint
student: principal
institution-id: uint
credential-type: string-ascii 128
credential-hash: buff 32
issue-date: uint
expiry-date: optional uint
status: uint (0=active, 1=revoked, 2=expired)
metadata-uri: string-ascii 512
issued-by: principal
}
credential-by-hash: {
credential-hash: buff 32 -> credential-id: uint
}
student-credentials: {
student: principal, index: uint -> credential-id: uint
}
verification-log: {
credential-id: uint, verifier: principal -> {
verified-at: uint
verification-hash: buff 32
}
}
revocation-log: {
credential-id: uint -> {
revoked-at: uint
revoked-by: principal
reason: string-ascii 256
}
}Key Functions:
| Function | Type | Access | Description |
|---|---|---|---|
issue-credential |
Public | Any | Issue a credential |
verify-credential |
Public | Any | Verify a credential |
revoke-credential |
Public | Issuer/Owner | Revoke a credential |
get-credential |
Read-Only | Any | Get credential details |
get-credential-by-hash |
Read-Only | Any | Get credential by hash |
get-student-credential-count |
Read-Only | Any | Get student's credential count |
get-student-credential |
Read-Only | Any | Get student's credential by index |
is-credential-valid |
Read-Only | Any | Check if credential is valid |
get-revocation-info |
Read-Only | Any | Get revocation details |
get-verification-info |
Read-Only | Any | Get verification details |
verify-credential-hash |
Read-Only | Any | Verify by hash |
get-credential-status |
Read-Only | Any | Get credential status |
State Variables:
credential-counter: Total credentials issuedtotal-issued: Total credentials issuedtotal-revoked: Total credentials revoked
Institution Owner
↓
register-institution()
↓
Create institution record
↓
Map owner to institution
↓
Increment counter
↓
Return institution-id
Verifier
↓
verify-institution(institution-id)
↓
Check verifier status
↓
Update institution verified flag
↓
Set verified-at timestamp
↓
Increment verified counter
Institution
↓
issue-credential(student, institution-id, type, hash, expiry, metadata)
↓
Validate inputs
↓
Check hash uniqueness
↓
Create credential record
↓
Map hash to credential-id
↓
Add to student's credentials
↓
Increment counters
↓
Return credential-id
Employer/Verifier
↓
verify-credential-hash(credential-hash)
↓
Look up credential by hash
↓
Check credential status
↓
Return verification result
↓
Log verification
Institution/Owner
↓
revoke-credential(credential-id, reason)
↓
Check authorization
↓
Verify not already revoked
↓
Update status to REVOKED
↓
Log revocation with reason
↓
Increment revoked counter
| Code | Meaning |
|---|---|
| u401 | Unauthorized - insufficient permissions |
| u404 | Not found - resource doesn't exist |
| u409 | Conflict - resource already exists |
| u420 | Invalid input - validation failed |
| u421 | Invalid country |
| u422 | Not verified - institution not verified |
| u423 | Already verified |
| u424 | Invalid registration |
| u425 | Verification failed |
| u426 | Invalid student |
- Institution Registration: Any principal can register
- Institution Verification: Only designated verifiers
- Credential Issuance: Any principal (typically institutions)
- Credential Revocation: Only issuer or contract owner
- Verifier Management: Only contract owner
- Immutable Records: All records stored on blockchain
- Hash Verification: SHA-256 hashing for credential integrity
- Audit Trail: Complete history of all operations
- Revocation Support: Credentials can be marked as revoked
- Input Validation: All inputs validated before processing
- Uniqueness Checks: Credential hashes must be unique
- Status Checks: Credentials can't be revoked twice
- Authorization Checks: All sensitive operations require authorization
- Map Size: Clarity maps have practical limits
- Batch Operations: Limited to small batches
- Query Complexity: Complex queries require multiple calls
- Pagination: Implement pagination for large datasets
- Indexing: Add secondary indexes for faster lookups
- Caching: Implement off-chain caching layer
- Sharding: Consider contract sharding for scale
// Example: Verify credential
const credentialHash = sha256(credentialData);
const result = await callReadOnly(
'certifi-credentials',
'verify-credential-hash',
[credentialHash]
);- Metadata Storage: IPFS or similar for credential metadata
- Notification Service: Email/SMS for credential events
- Analytics: Track verification patterns
- Compliance: Audit trail for regulatory requirements
- Individual function behavior
- Error handling
- Edge cases
- Contract interactions
- State consistency
- Multi-step workflows
- Institution registration and verification
- Credential issuance and revocation
- Credential verification
- Access control
- Error conditions
- Deploy contracts to testnet
- Run full test suite
- Verify all functions work
- Get community feedback
- Security audit
- Final testing
- Gradual rollout
- Monitor for issues
- Batch credential issuance
- Advanced search capabilities
- Credential expiry handling
- Credential transfer/delegation
- Cross-chain verification
- Integration with other blockchains
- Advanced analytics
- Compliance reporting
- AI-powered fraud detection
- Biometric verification
- Real-time credential updates
- Advanced access control
- Credential issuance: ~1 transaction
- Credential verification: ~1 read-only call
- Institution registration: ~1 transaction
- Verification time: <10 seconds (testnet)
- Batch operations
- Off-chain indexing
- Caching layer
- Query optimization
- No PII stored on-chain
- Metadata stored off-chain
- Hash-based verification
- Audit trail for all operations
- Revocation support for compliance
- Access control for data protection
- Total institutions registered
- Total credentials issued
- Verification success rate
- Revocation rate
- Average verification time
- Monitor contract health
- Update verifier list
- Handle disputes
- Security updates
- certifi-delegation.clar: Delegation management
- certifi-endorsements.clar: Third-party endorsements
- certifi-achievements.clar: Digital badges