Skip to main content

Certichain technical documentation

Certichain is a decentralised application for tamper-evident academic records. A registered institution anchors a signed fingerprint of each credential (a degree, a transcript, a certificate) on a public Ethereum-compatible blockchain. Anyone can then check, in a browser and without an account or a wallet, that a credential exists, who signed it, that a document matches it, and whether it still stands. The document itself is encrypted in the issuer's browser and kept off the chain, and no personal data is written to the chain.

These pages describe the system as it is in the repository: the contracts, the web application, the server routes, every user flow, the file formats, the security model and the test suites. They are written for engineers who are new to the project and for reviewers who want to check how something works without reading all of the code first.

Deployment status

Certichain runs on the Ethereum Sepolia test network with synthetic data only. It has not had an external security audit, and some features (the verification API, status lists, the monitor) are built but switched off until their keys are configured. Each page says when a feature depends on configuration.

The promise in one sentence​

"Genuine, issued by a registered institution, and not cancelled" can be checked by anyone, while personal data stays with the holder.

Who uses it​

RoleWhat they doNeeds a wallet
VerifierLooks up a credential by id, link or QR code; checks a document, a package, a verifiable credential or a disclosure against the chain.No
Holder (student)Keeps the credential package, opens and shares the document, shows selected fields, carries credentials on a phone.Optional
Issuer (institution)Issues, re-issues, suspends, reinstates and revokes its own credentials; invites students; defines record types; imports a cohort.Yes
GuardianPauses new issuance in an emergency. Cannot register anyone.Yes
AdminRegisters and removes issuers, lifts pauses, manages roles. On Sepolia this is a 2-of-3 Safe, with a timelock deployed for admin actions.Yes (a Safe)

The Roles section describes each one in full.

The system at a glance​

Three principles hold the design together:

  1. The chain is the source of truth. Issuer registration, credential anchors, signatures and status live in contracts. Lists such as "my credentials" are rebuilt from contract events; there is no application database.
  2. The browser does the secret work. Hashing, encryption, key derivation, commitments and proofs happen on the user's device. The server never sees a plaintext document, a private key or a student's name.
  3. The server holds as little as possible. It checks sign-in, stores encrypted containers through a pinning service, keeps sign-in nonces, rate-limit counters and monitor state, and (when configured) signs verification answers and status lists with keys that hold no funds.

What is on the chain and what is not​

On the chain (public, permanent)Off the chain
Issuer addresses, registered names and rolesStudent names and ids, kept in the holder's credential package
Credential anchors: issuer, salted subject commitment, document SHA-256, salted metadata hash, record type, datesThe document, encrypted with AES-256-GCM, stored on IPFS
The issuer's EIP-712 signature, carried in an eventThe document key, inside the package and in wrapped grants
Status history: suspended, revoked, superseded, with reason codes and note hashesSelective disclosure salts and field values
Holder bindings as commitments, record type names, access group commitments and receiptsSign-in nonces, rate-limit counters and monitor history in Redis; sessions are signed cookies

The Privacy design page explains why each item sits where it does.

Two contract generations​

The repository holds two generations of contracts:

  • v0.3 (current): a set of small registries (IssuerRegistry, CredentialRegistry, StatusRegistry, HolderRegistry, RecordTypeRegistry) built on OpenZeppelin 5, with EIP-712 issuer signatures, a status lifecycle, issuer-attested enrolment and no plaintext personal data. Several versioned contract sets can be live at once (Sepolia has sets 0.3.0, active, and 0.5.0, deployed and not active), so an upgrade never strands old credentials.
  • v0.2 (legacy, release v2.0.0): a single AcademicRecords contract with role-based access, a linked storage library and a student module. It stays deployed on Sepolia and the app still supports it when NEXT_PUBLIC_CONTRACT_VERSION is not v03, but new work targets v0.3.

See Contract versions and sets.

How to read these docs​

If you want to...Start with
Learn the words and the cryptography firstConcepts and the Glossary
See how the system is builtArchitecture
Understand a contract ruleSmart contracts
Follow one feature end to endFlows
Know what a given user can doRoles
Parse or produce a fileData formats
Review the security modelSecurity and privacy
Run or extend the testsTesting
Integrate another systemIntegrations
Run it locally or operate a deploymentOperations

Conventions in these pages​

  • File paths are relative to the repository root, for example src/services/domain/credential-service.ts or blockchain/contracts/v03/StatusRegistry.sol.
  • "The app" is the Next.js web application in src/. "The registries" are the v0.3 contracts. "A set" is one deployment of the v0.3 registries listed in the deployment manifest.
  • Diagrams are drawn with Mermaid from the text in each page, so they change with the page.
  • Environment variables are named, never given values. Example names live in example.env.
  • The engineering handbook in docs/ (plan, specs, decisions, runbooks) records why things were decided. These pages describe what the result is and point to the handbook where the reasoning matters.