Skip to main content

Certificates

When a submission is approved and TRUFA scores are assigned, DobValidator issues a certificate -- a cryptographically verifiable attestation that a real-world asset has been reviewed and scored. Certificates are anchored on-chain and can be publicly verified by anyone.

Certificate Structure

Each certificate contains the following data:

FieldDescriptionExample
Certificate HashSHA-256 of canonical submission + scores + wallets0xa6352db1...
Submission IDInternal reference to the submission recordsub_a8f3c2d1
Owner WalletWallet address of the asset ownerGBDM6KRX... or 0x305DaB...
TRUFA ScoresAll five dimension scores{tech: 95, reg: 92, fin: 85, env: 88, overall: 90}
StatusCurrent certificate statusACTIVE
Issued AtTimestamp of certificate issuance2026-03-07T14:30:00Z
Stellar Tx HashStellar on-chain attestation transactionnull or tx hash
EVM Tx HashEVM on-chain attestation transaction0x5563...

Hash Computation

The certificate hash is the SHA-256 digest of a canonical JSON object that includes:

  1. Submission data -- Device info, location, financials (normalized and sorted)
  2. TRUFA scores -- All five scores as integers
  3. Wallet addresses -- The owner's wallet address(es)
canonical_json = normalize({
submission: { deviceInfo, location, financials },
scores: { technical, regulatory, financial, environmental, overall },
wallets: { owner: "GBDM6KRX..." }
})

certificate_hash = "0x" + SHA256(canonical_json)

The 0x prefix follows Ethereum convention and is used consistently across both Stellar and EVM attestations.

On-Chain Attestation

Certificate hashes and scores are written to blockchain through a two-step process on the DOBValidator.sol smart contract.

Step 1: Add Project

The validator calls addProject(bytes32 hash) to register the certificate hash on-chain:

function addProject(bytes32 _hash) external onlyRole(VALIDATOR_ROLE) {
// Registers the project hash
// Sets initial state (not yet approved)
}

This creates an on-chain record that the hash exists and has been submitted for validation.

Step 2: Approve with Scores

The validator then calls setProjectApproved(bytes32 hash, TrufaScores scores) to write the TRUFA scores:

function setProjectApproved(
bytes32 _hash,
TrufaScores calldata _scores
) external onlyRole(VALIDATOR_ROLE) {
// Stores TRUFA scores on-chain
// Marks project as approved
}

Once this transaction confirms, the certificate is fully anchored on-chain with its scores.

Supported Networks

NetworkContract AddressStatus
Ethereum SepoliaDeployedActive
Polygon AmoyDeployedActive
Base SepoliaDeployedActive
Base MainnetDeployedActive

PDF Generation

Upon approval, a PDF certificate is generated with the following elements:

  • Header -- DobProtocol branding and "Certificate of Verification" title
  • Asset Summary -- Device name, type, location
  • TRUFA Scores -- Visual representation of all four dimensions plus overall
  • Certificate Details -- Hash, issuance date, owner wallet
  • QR Code -- Links to the public verification URL for instant mobile verification
  • Digital Signature -- Cryptographic reference to the on-chain attestation

The QR code encodes the verification URL: https://validator.dobprotocol.com/verify/{certificateHash}

Certificate Statuses

StatusDescriptionTransitions From
ACTIVECertificate is valid and verifiableInitial state after approval
EXPIREDCertificate has passed its validity periodACTIVE (automatic)
REVOKEDCertificate has been explicitly invalidatedACTIVE (admin action)

Status Rules

  • ACTIVE -- The default state. The certificate is valid, and verification returns a positive result.
  • EXPIRED -- Certificates may have a validity period. Once expired, verification still returns the data but indicates the certificate is no longer current.
  • REVOKED -- An admin can revoke a certificate if the asset is found to be non-compliant, decommissioned, or fraudulently represented. Revocation is permanent.

Public Verification

Anyone can verify a certificate without authentication through the public verification endpoint:

GET /api/public/certificate/verify/:hash

Response

{
"valid": true,
"certificate": {
"hash": "0xa6352db1...",
"status": "ACTIVE",
"issuedAt": "2026-03-07T14:30:00Z",
"scores": {
"technical": 95,
"regulatory": 92,
"financial": 85,
"environmental": 88,
"overall": 90
},
"asset": {
"deviceName": "AquaPure Water Purifier WP-3000",
"deviceType": "Water Purification System",
"location": "Arica, Chile"
},
"onChain": {
"evmTxHash": "0x5563...",
"stellarTxHash": null,
"network": "Base Mainnet"
}
}
}

Verification Logic

  1. Look up the certificate by hash in the database
  2. Check that the status is ACTIVE
  3. Optionally cross-reference the on-chain record to confirm the hash and scores match
  4. Return the certificate data with the verification result

Integration with Token Studio

Certificates are linked to distribution pools on Token Studio through the following flow:

  1. During pool creation -- A ?certificateHash= query parameter pre-fills the certificate selector in the create-pool form.
  2. After pool creation -- Pool creators can link or unlink certificates from the pool dashboard's validation panel.
  3. API linkage -- The POST /api/validation/pool/:address/link endpoint writes the certificate hash and TRUFA score to the pool record.

Pool Fields

ColumnTypeDescription
validator_certificate_hashVARCHARThe 0x-prefixed certificate hash
validator_submission_idVARCHARReference to the submission
validator_overall_scoreINTEGERTRUFA overall score (0--100)
validated_atTIMESTAMPWhen the certificate was linked
validation_statusVARCHAR'validated', 'revoked', etc.

Webhook Notifications

DobValidator can notify Token Studio of certificate status changes via webhook:

POST /api/validation/webhook/status
Headers: x-internal-api-key: <shared secret>

{
"certificateHash": "0xa6352db1...",
"status": "revoked",
"reason": "Asset decommissioned"
}

This allows Token Studio to automatically update pool validation status when a certificate is revoked or expires, without requiring manual intervention.