Evidence & disclosure
Combine metadata, credentials and zero-knowledge proofs.
← All implementation patternsConnect inspection reports to credentials that recipients can verify
Store an equipment inspection report and record a pass value plus the report hash in MultiTrustCredential. A recipient can hash the same file and compare it with the recorded value.
Recipients can check that a report matches its recorded hash and review the issuer, subject and expiry. Inspection accuracy still depends on the inspector and source-data controls.
Architecture and responsibilities
Inspection and source records
Manage equipment, inspectors, inspection dates and report versions.
Inspection system / DBDocument storage and sharing
Store originals and control access for recipients.
Storage / Access controlCredential recording
Record a metric ID, public value, document hash and expiry.
MultiTrustCredentialHelperPresentation and verification
Check the file hash, trusted issuer, expiry and subject.
Verifier UI / Application policy
Example data model
Map application records to the data managed by the chain or APIs. Field names and values below illustrate the application model for this architecture.
| Field and example | Stored in | Purpose and mapping |
|---|---|---|
assetId / subjectWalletROBOT-A-001 / 0x… | Application DB | Map the credential subject wallet to the asset. The application is responsible for this association. |
documentId / versionINSPECT-001 / v1 | DB and storage | Store reports by version and hash the exact bytes saved and shared, without regenerating them. |
metricId / valueINSPECTION_PASS_V1 / 1 | Chain | Here, 1 is a public inspection-pass value. The issuer defines the metric semantics. |
anchorRootBigInt(documentHash) | Chain | This example stores the document’s keccak256 hash. It is a different design from a ZK Merkle root. |
expiresAtUNIX seconds | Chain and application DB | Credential expiry. Define application policies for reinspection and corrections. |
chainId / credentialAddress / transactionHashchain / 0x… / 0x… | Application DB | Identify the recorded report using chain, contract and transaction. |
Processing flow
Configure the metric and issuer
An administrator registers INSPECTION_PASS_V1 and grants its writer role to the issuer. For this public-value example, use commitment false and mask zero because comparisons are not used.
registerMetric(id, label, writerRole, false, 0) / grantRoleSave and hash the original
Save the finalized report bytes and compute keccak256 from those exact bytes. Manage signed-URL expiry separately from credential expiry.
Storage upload → keccak256(reportBytes)Record the metric for the subject
Mint value 1, the document hash and expiry for the subject wallet. Minting the same metric for the same wallet updates it, so retain historical reports separately by version and transaction hash.
MultiTrustCredentialHelper.mint(subjectWallet, input)Verify the presentation
The recipient checks the trusted contract and issuer, report hash, metric, subject and expiry. Use MetricUpdated history and current-status information to avoid treating a superseded record as current.
queryMetricUpdated(fromBlock, toBlock) / application validity checksHandle corrections and reinspection
Save the new version, update the metric and retain the link to the previous record. Since historical public data cannot be erased, combine cancellation and supersession indicators with application history.
updateMetric / document version history
Before using the code
- Provide an initialized MultiTrustCredential contract and a signer authorized to write the registered metric.
- This example treats INSPECTION_PASS_V1 as public. Manage the subject-wallet mapping so another asset does not overwrite the same metric.
- Pass the finalized original in reportBytes. metadataUri should point to public metadata; protect access to private originals separately.
npm install --save-exact @hazbase/kit@0.9.0 ethers@6.16.0The TypeScript functions below are called from your application with the appropriate connections, permissions and data. Integrate the UI, persistence and recovery using the architecture above.
Record the report hash and inspection-pass value
Pass the report bytes, subject, expiry and issuer to publishInspection. This implements document anchoring; ZK predicate proofs are a separate extension.
import { MultiTrustCredentialHelper } from '@hazbase/kit';
import { id, keccak256 } from 'ethers';
type Signer = Parameters<typeof MultiTrustCredentialHelper.deploy>[1];
const metricId = id('INSPECTION_PASS_V1');
export async function publishInspection(input: {
credentialAddress: string;
subjectWallet: string;
reportBytes: Uint8Array;
metadataUri: string;
expiresAt: bigint;
writer: Signer;
}) {
// Register this metric and grant its writer role before calling.
const credential = MultiTrustCredentialHelper.attach(input.credentialAddress, input.writer);
const documentHash = keccak256(input.reportBytes);
const receipt = await credential.mint(input.subjectWallet, {
metricId,
value: 1,
anchorRoot: BigInt(documentHash),
uri: input.metadataUri,
expiresAt: input.expiresAt,
});
// This example anchors document bytes; it does not generate a ZK proof.
return {
subject: input.subjectWallet,
metricId,
documentHash,
transactionHash: receipt.hash,
blockNumber: receipt.blockNumber,
};
}
Result and application integration
Store documentHash and the transaction hash against the report version. anchorRoot corresponds to the on-chain leafFull field. Recipients can hash the same document and compare it with the target transaction record.
Implementation considerations
Different bytes produce different hashes
Regenerating a PDF or changing line endings changes the hash. Verify the original bytes recorded, not a regenerated document.
Hash integrity versus factual accuracy
A match establishes correspondence with the document. Verify the inspector, equipment association, expiry and cancellation status separately.
Disclosure and updates
Wallets, public values and expiry remain on chain. Model subject and metric boundaries for multiple assets and reports, and separate current values from historical documents.
Extending the architecture
Prove a condition without revealing the value
To prove utilization exceeds a threshold without revealing the value, combine a supported @hazbase/zk circuit, source-data commitment, public inputs and verifier. Storing a document hash alone does not create a ZK proof.
Connect credentials to eligibility
A verified result can feed eligibility, for example by registering a qualified user in Whitelist. Align the verifier, root, subject address, expiry and revocation policy.