Evidence & disclosure https://docs.hazbase.com/en/patterns/evidence/ IMPLEMENTATION PATTERNS Evidence & disclosure Combine metadata, credentials and zero-knowledge proofs. ← All implementation patterns EXAMPLE Connect 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 0 1 Inspection and source records Manage equipment, inspectors, inspection dates and report versions. Inspection system / DB 0 2 Document storage and sharing Store originals and control access for recipients. Storage / Access control 0 3 Credential recording Record a metric ID, public value, document hash and expiry. MultiTrustCredentialHelper 0 4 Presentation 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 / subjectWallet ROBOT-A-001 / 0x… Application DB Map the credential subject wallet to the asset. The application is responsible for this association. documentId / version INSPECT-001 / v1 DB and storage Store reports by version and hash the exact bytes saved and shared, without regenerating them. metricId / value INSPECTION_PASS_V1 / 1 Chain Here, 1 is a public inspection-pass value. The issuer defines the metric semantics. anchorRoot BigInt(documentHash) Chain This example stores the document’s keccak256 hash. It is a different design from a ZK Merkle root. expiresAt UNIX seconds Chain and application DB Credential expiry. Define application policies for reinspection and corrections. chainId / credentialAddress / transactionHash chain / 0x… / 0x… Application DB Identify the recorded report using chain, contract and transaction. Processing flow 1 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) / grantRole 2 Save 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) 3 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) 4 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 checks 5 Handle 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. Install npm install --save-exact @hazbase/kit@0.9.0 ethers@6.16.0 The 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. pattern-evidence.ts 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 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 , } ; } Download the example 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. Related API and SDK reference MultiTrustCredentialHelper @hazbase/storage @hazbase/zk WhitelistHelper Start with the sample application Deployment and operations