Supply Chain & Traceability Scenario
This guide demonstrates how to build a supply chain traceability system using TrustWeave that enables multi-party credentials, provenance tracking, product authenticity verification, and immutable chain of custody records.
What You’ll Build
By the end of this tutorial, you’ll have:
- ✅ Created DIDs for supply chain participants (manufacturers, distributors, retailers)
- ✅ Issued product credentials at each supply chain stage
- ✅ Built provenance tracking system
- ✅ Implemented chain of custody verification
- ✅ Created product authenticity verification
- ✅ Anchored supply chain events to blockchain
- ✅ Built multi-party credential workflow
Big Picture & Significance
The Supply Chain Transparency Revolution
Modern supply chains are complex, global networks involving multiple parties. Consumers and regulators demand transparency, authenticity, and ethical sourcing. Blockchain-anchored verifiable credentials provide immutable proof of product journey from origin to consumer.
Industry Context:
- Market Size: Global supply chain management market projected to reach $37.4 billion by 2027
- Regulatory Pressure: Increasing requirements for product traceability (FDA, EU regulations)
- Consumer Demand: 73% of consumers want to know product origins
- Fraud Impact: Counterfeit goods cost $1.7 trillion annually globally
- Sustainability: Growing demand for ethical and sustainable sourcing
Why This Matters:
- Product Authenticity: Prevent counterfeiting with cryptographic proof
- Food Safety: Track food from farm to table for safety recalls
- Ethical Sourcing: Verify fair trade and ethical labor practices
- Regulatory Compliance: Meet traceability requirements
- Consumer Trust: Build trust through transparency
- Sustainability: Track carbon footprint and environmental impact
The Supply Chain Challenge
Traditional supply chains face critical issues:
- Lack of Transparency: No visibility into product journey
- Counterfeiting: Fake products enter supply chain
- Data Silos: Each party maintains separate records
- Trust Issues: No cryptographic proof of authenticity
- Regulatory Compliance: Difficult to prove compliance
- Recall Challenges: Slow and incomplete recall processes
Value Proposition
Problems Solved
- Provenance Tracking: Complete product journey from origin to consumer
- Authenticity Verification: Cryptographic proof prevents counterfeiting
- Multi-Party Coordination: Standard format works across all participants
- Regulatory Compliance: Immutable records meet traceability requirements
- Recall Efficiency: Instant identification of affected products
- Consumer Trust: Transparent product information
- Sustainability: Track environmental impact
Business Benefits
For Manufacturers:
- Brand Protection: Prevent counterfeiting
- Compliance: Meet regulatory requirements
- Efficiency: Faster recall processes
- Trust: Build consumer confidence
For Retailers:
- Authenticity: Verify product authenticity
- Compliance: Meet regulatory requirements
- Consumer Trust: Provide product transparency
- Risk Reduction: Reduce liability from counterfeit products
For Consumers:
- Authenticity: Verify product is genuine
- Transparency: See product journey
- Safety: Track product safety information
- Ethics: Verify ethical sourcing
ROI Considerations
- Counterfeit Prevention: Saves millions in lost revenue
- Recall Efficiency: 10x faster recall processes
- Compliance: Automated regulatory compliance
- Consumer Trust: Increased brand loyalty
- Sustainability: Enable premium pricing for verified products
Understanding the Problem
Supply chain management faces several critical challenges:
- Provenance: Track product from origin to consumer
- Authenticity: Verify products are genuine
- Multi-Party: Coordinate across multiple organizations
- Data Integrity: Ensure records aren’t tampered with
- Regulatory Compliance: Meet traceability requirements
- Recall Management: Quickly identify affected products
- Consumer Trust: Provide transparent product information
Real-World Pain Points
Example 1: Food Safety Recall
- Current: Manual tracking, slow identification, incomplete recalls
- Problem: Public health risk, financial losses
- Solution: Instant product tracking with verifiable credentials
Example 2: Counterfeit Products
- Current: No way to verify authenticity
- Problem: Brand damage, lost revenue, consumer harm
- Solution: Cryptographic proof of authenticity
Example 3: Ethical Sourcing
- Current: Difficult to verify supply chain ethics
- Problem: Consumer distrust, regulatory issues
- Solution: Verifiable credentials for each supply chain stage
How It Works: Supply Chain Traceability Flow
flowchart TD
A["Manufacturer<br/>Creates Product Credential<br/>Issues Origin Credential"] -->|transfers product| B["Distributor<br/>Receives Product<br/>Issues Transfer Credential<br/>Updates Chain of Custody"]
B -->|transfers product| C["Retailer<br/>Receives Product<br/>Issues Sale Credential<br/>Provides Consumer Access"]
C -->|anchors to blockchain| D["Blockchain Anchor<br/>Immutable Supply Chain Record<br/>Provenance Trail"]
style A fill:#1976d2,stroke:#0d47a1,stroke-width:2px,color:#fff
style B fill:#f57c00,stroke:#e65100,stroke-width:2px,color:#fff
style C fill:#388e3c,stroke:#1b5e20,stroke-width:2px,color:#fff
style D fill:#c2185b,stroke:#880e4f,stroke-width:2px,color:#fff
Key Concepts
Supply Chain Participants
- Manufacturer: Creates products, issues origin credentials
- Distributor: Transports products, issues transfer credentials
- Retailer: Sells products, issues sale credentials
- Consumer: Receives products, can verify provenance
Product Credentials
- Origin Credential: Product creation at manufacturer
- Transfer Credential: Product transfer between parties
- Processing Credential: Product processing or transformation
- Sale Credential: Product sale to consumer
- Chain of Custody: Complete history of product ownership
Provenance Tracking
- Product ID: Unique identifier for each product
- Event Chain: Sequence of credentials showing product journey
- Verification: Verify each step in the chain
- Blockchain Anchoring: Immutable record of supply chain events
Prerequisites
- Java 21+
- Kotlin 2.2.0+
- Gradle 8.5+
- Basic understanding of Kotlin and coroutines
- Familiarity with supply chain concepts (helpful but not required)
Step 1: Add Dependencies
Add TrustWeave dependencies to your build.gradle.kts. These modules provide DID/credential APIs plus the in-memory services used to simulate the supply chain workflow.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
dependencies {
// Core TrustWeave modules
implementation("com.trustweave:trustweave-core:1.0.0-SNAPSHOT")
implementation("com.trustweave:trustweave-json:1.0.0-SNAPSHOT")
implementation("com.trustweave:trustweave-kms:1.0.0-SNAPSHOT")
implementation("com.trustweave:trustweave-did:1.0.0-SNAPSHOT")
implementation("com.trustweave:trustweave-anchor:1.0.0-SNAPSHOT")
// Test kit for in-memory implementations
implementation("com.trustweave:trustweave-testkit:1.0.0-SNAPSHOT")
// Kotlinx Serialization
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
// Coroutines
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
}
Result: After syncing, you can run the supply chain examples end-to-end without extra wiring.
Step 2: Complete Example
Here’s a complete example demonstrating supply chain traceability:
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
import com.trustweave.credential.models.VerifiableCredential
import com.trustweave.credential.models.VerifiablePresentation
import com.trustweave.credential.CredentialIssuanceOptions
import com.trustweave.credential.CredentialVerificationOptions
import com.trustweave.credential.PresentationOptions
import com.trustweave.credential.issuer.CredentialIssuer
import com.trustweave.credential.verifier.CredentialVerifier
import com.trustweave.credential.proof.Ed25519ProofGenerator
import com.trustweave.credential.proof.ProofGeneratorRegistry
import com.trustweave.testkit.credential.InMemoryWallet
import com.trustweave.testkit.did.DidKeyMockMethod
import com.trustweave.testkit.kms.InMemoryKeyManagementService
import com.trustweave.testkit.anchor.InMemoryBlockchainAnchorClient
import com.trustweave.anchor.BlockchainAnchorRegistry
import com.trustweave.anchor.anchorTyped
import com.trustweave.did.DidMethodRegistry
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put
import kotlinx.serialization.json.Json
import java.time.Instant
import java.util.UUID
@Serializable
data class SupplyChainEvent(
val productId: String,
val eventType: String,
val participantDid: String,
val timestamp: String,
val credentialDigest: String,
val previousEventDigest: String? = null
)
fun main() = runBlocking {
println("=== Supply Chain & Traceability Scenario ===\n")
// Step 1: Setup services
println("Step 1: Setting up services...")
val manufacturerKms = InMemoryKeyManagementService()
val distributorKms = InMemoryKeyManagementService()
val retailerKms = InMemoryKeyManagementService()
val didMethod = DidKeyMockMethod(manufacturerKms)
val didRegistry = DidMethodRegistry().apply { register(didMethod) }
// Setup blockchain for anchoring
val anchorClient = InMemoryBlockchainAnchorClient("eip155:1", emptyMap())
val blockchainRegistry = BlockchainAnchorRegistry().apply {
register("eip155:1", anchorClient)
}
// Step 2: Create supply chain participant DIDs
println("\nStep 2: Creating supply chain participant DIDs...")
val manufacturerDid = didMethod.createDid()
println("Manufacturer DID: ${manufacturerDid.id}")
val distributorDid = didMethod.createDid()
println("Distributor DID: ${distributorDid.id}")
val retailerDid = didMethod.createDid()
println("Retailer DID: ${retailerDid.id}")
// Step 3: Create product
println("\nStep 3: Creating product...")
val productId = "PROD-${UUID.randomUUID()}"
val productName = "Organic Coffee Beans"
val batchNumber = "BATCH-2024-001"
println("Product created:")
println(" - Product ID: $productId")
println(" - Name: $productName")
println(" - Batch: $batchNumber")
// Step 4: Manufacturer issues origin credential
println("\nStep 4: Manufacturer issues origin credential...")
val originCredential = createOriginCredential(
productId = productId,
productName = productName,
batchNumber = batchNumber,
manufacturerDid = manufacturerDid.id,
originLocation = "Farm XYZ, Colombia",
productionDate = Instant.now().toString(),
certifications = listOf("Organic", "Fair Trade")
)
val manufacturerKey = manufacturerKms.generateKey("Ed25519")
val manufacturerProofGenerator = Ed25519ProofGenerator(
signer = { data, keyId -> manufacturerKms.sign(keyId, data) },
getPublicKeyId = { keyId -> manufacturerKey.id }
)
val manufacturerProofRegistry = ProofGeneratorRegistry().apply { register(manufacturerProofGenerator) }
val didResolver = CredentialDidResolver { did ->
didRegistry.resolve(did).toCredentialDidResolution()
}
val manufacturerIssuer = CredentialIssuer(
proofGenerator = manufacturerProofGenerator,
resolveDid = { did -> didResolver.resolve(did)?.isResolvable == true },
proofRegistry = manufacturerProofRegistry
)
val issuedOriginCredential = manufacturerIssuer.issue(
credential = originCredential,
issuerDid = manufacturerDid.id,
keyId = manufacturerKey.id,
options = CredentialIssuanceOptions(proofType = "Ed25519Signature2020")
)
println("Origin credential issued:")
println(" - Product: $productName")
println(" - Origin: Farm XYZ, Colombia")
println(" - Certifications: Organic, Fair Trade")
// Step 5: Anchor origin event to blockchain
println("\nStep 5: Anchoring origin event to blockchain...")
val originDigest = com.trustweave.json.DigestUtils.sha256DigestMultibase(
Json.encodeToJsonElement(
com.trustweave.credential.models.VerifiableCredential.serializer(),
issuedOriginCredential
)
)
val originEvent = SupplyChainEvent(
productId = productId,
eventType = "origin",
participantDid = manufacturerDid.id,
timestamp = Instant.now().toString(),
credentialDigest = originDigest
)
val originAnchorResult = blockchainRegistry.anchorTyped(
value = originEvent,
serializer = SupplyChainEvent.serializer(),
targetChainId = "eip155:1"
)
println("Origin event anchored:")
println(" - Transaction hash: ${originAnchorResult.ref.txHash}")
println(" - Digest: $originDigest")
// Step 6: Distributor receives product and issues transfer credential
println("\nStep 6: Distributor receives product...")
val transferCredential = createTransferCredential(
productId = productId,
fromDid = manufacturerDid.id,
toDid = distributorDid.id,
transferDate = Instant.now().toString(),
transferLocation = "Distribution Center A",
previousCredentialDigest = originDigest
)
val distributorKey = distributorKms.generateKey("Ed25519")
val distributorProofGenerator = Ed25519ProofGenerator(
signer = { data, keyId -> distributorKms.sign(keyId, data) },
getPublicKeyId = { keyId -> distributorKey.id }
)
val distributorProofRegistry = ProofGeneratorRegistry().apply { register(distributorProofGenerator) }
val distributorIssuer = CredentialIssuer(
proofGenerator = distributorProofGenerator,
resolveDid = { did -> didResolver.resolve(did)?.isResolvable == true },
proofRegistry = distributorProofRegistry
)
val issuedTransferCredential = distributorIssuer.issue(
credential = transferCredential,
issuerDid = distributorDid.id,
keyId = distributorKey.id,
options = CredentialIssuanceOptions(proofType = "Ed25519Signature2020")
)
println("Transfer credential issued:")
println(" - From: Manufacturer")
println(" - To: Distributor")
println(" - Location: Distribution Center A")
// Step 7: Anchor transfer event
println("\nStep 7: Anchoring transfer event...")
val transferDigest = com.trustweave.json.DigestUtils.sha256DigestMultibase(
Json.encodeToJsonElement(
com.trustweave.credential.models.VerifiableCredential.serializer(),
issuedTransferCredential
)
)
val transferEvent = SupplyChainEvent(
productId = productId,
eventType = "transfer",
participantDid = distributorDid.id,
timestamp = Instant.now().toString(),
credentialDigest = transferDigest,
previousEventDigest = originDigest
)
val transferAnchorResult = blockchainRegistry.anchorTyped(
value = transferEvent,
serializer = SupplyChainEvent.serializer(),
targetChainId = "eip155:1"
)
println("Transfer event anchored")
// Step 8: Retailer receives product and issues sale credential
println("\nStep 8: Retailer receives product...")
val saleCredential = createSaleCredential(
productId = productId,
fromDid = distributorDid.id,
toDid = retailerDid.id,
saleDate = Instant.now().toString(),
saleLocation = "Retail Store B",
previousCredentialDigest = transferDigest
)
val retailerKey = retailerKms.generateKey("Ed25519")
val retailerProofGenerator = Ed25519ProofGenerator(
signer = { data, keyId -> retailerKms.sign(keyId, data) },
getPublicKeyId = { keyId -> retailerKey.id }
)
val retailerProofRegistry = ProofGeneratorRegistry().apply { register(retailerProofGenerator) }
val retailerIssuer = CredentialIssuer(
proofGenerator = retailerProofGenerator,
resolveDid = { did -> didResolver.resolve(did)?.isResolvable == true },
proofRegistry = retailerProofRegistry
)
val issuedSaleCredential = retailerIssuer.issue(
credential = saleCredential,
issuerDid = retailerDid.id,
keyId = retailerKey.id,
options = CredentialIssuanceOptions(proofType = "Ed25519Signature2020")
)
println("Sale credential issued")
// Step 9: Verify product provenance
println("\nStep 9: Verifying product provenance...")
val provenanceChain = listOf(
issuedOriginCredential,
issuedTransferCredential,
issuedSaleCredential
)
val provenanceValid = verifyProvenanceChain(provenanceChain)
if (provenanceValid) {
println("✅ Product provenance verified!")
println(" - Origin: Farm XYZ, Colombia")
println(" - Transfer: Manufacturer → Distributor")
println(" - Sale: Distributor → Retailer")
} else {
println("❌ Provenance verification failed")
}
// Step 10: Verify product authenticity
println("\nStep 10: Verifying product authenticity...")
val verifier = CredentialVerifier(
didResolver = CredentialDidResolver { did ->
didRegistry.resolve(did).toCredentialDidResolution()
}
)
val authenticityValid = verifier.verify(
credential = issuedOriginCredential,
options = CredentialVerificationOptions(
checkRevocation = true,
checkExpiration = false,
validateSchema = true
)
)
if (authenticityValid.valid) {
println("✅ Product is authentic!")
println(" - Verified manufacturer: ${manufacturerDid.id}")
println(" - Certifications: Organic, Fair Trade")
}
// Step 11: Trace product history
println("\nStep 11: Tracing product history...")
val productHistory = traceProductHistory(
productId = productId,
events = listOf(originEvent, transferEvent)
)
println("Product history:")
productHistory.forEach { event ->
println(" - ${event.eventType}: ${event.participantDid} at ${event.timestamp}")
}
println("\n=== Scenario Complete ===")
}
fun createOriginCredential(
productId: String,
productName: String,
batchNumber: String,
manufacturerDid: String,
originLocation: String,
productionDate: String,
certifications: List<String>
): VerifiableCredential {
return VerifiableCredential(
id = "https://manufacturer.example.com/products/$productId/origin",
type = listOf("VerifiableCredential", "OriginCredential", "SupplyChainCredential"),
issuer = manufacturerDid,
credentialSubject = buildJsonObject {
put("productId", productId)
put("productName", productName)
put("batchNumber", batchNumber)
put("origin", buildJsonObject {
put("location", originLocation)
put("productionDate", productionDate)
put("certifications", certifications)
})
},
issuanceDate = Instant.now().toString(),
expirationDate = null,
credentialSchema = com.trustweave.credential.models.CredentialSchema(
id = "https://example.com/schemas/origin-credential.json",
type = "JsonSchemaValidator2018",
schemaFormat = com.trustweave.spi.SchemaFormat.JSON_SCHEMA
)
)
}
fun createTransferCredential(
productId: String,
fromDid: String,
toDid: String,
transferDate: String,
transferLocation: String,
previousCredentialDigest: String
): VerifiableCredential {
return VerifiableCredential(
id = "https://distributor.example.com/transfers/$productId-${Instant.now().toEpochMilli()}",
type = listOf("VerifiableCredential", "TransferCredential", "SupplyChainCredential"),
issuer = toDid,
credentialSubject = buildJsonObject {
put("productId", productId)
put("transfer", buildJsonObject {
put("fromDid", fromDid)
put("toDid", toDid)
put("transferDate", transferDate)
put("transferLocation", transferLocation)
put("previousCredentialDigest", previousCredentialDigest)
})
},
issuanceDate = Instant.now().toString(),
expirationDate = null,
credentialSchema = com.trustweave.credential.models.CredentialSchema(
id = "https://example.com/schemas/transfer-credential.json",
type = "JsonSchemaValidator2018",
schemaFormat = com.trustweave.spi.SchemaFormat.JSON_SCHEMA
)
)
}
fun createSaleCredential(
productId: String,
fromDid: String,
toDid: String,
saleDate: String,
saleLocation: String,
previousCredentialDigest: String
): VerifiableCredential {
return VerifiableCredential(
id = "https://retailer.example.com/sales/$productId-${Instant.now().toEpochMilli()}",
type = listOf("VerifiableCredential", "SaleCredential", "SupplyChainCredential"),
issuer = toDid,
credentialSubject = buildJsonObject {
put("productId", productId)
put("sale", buildJsonObject {
put("fromDid", fromDid)
put("toDid", toDid)
put("saleDate", saleDate)
put("saleLocation", saleLocation)
put("previousCredentialDigest", previousCredentialDigest)
})
},
issuanceDate = Instant.now().toString(),
expirationDate = null,
credentialSchema = com.trustweave.credential.models.CredentialSchema(
id = "https://example.com/schemas/sale-credential.json",
type = "JsonSchemaValidator2018",
schemaFormat = com.trustweave.spi.SchemaFormat.JSON_SCHEMA
)
)
}
fun verifyProvenanceChain(credentials: List<VerifiableCredential>): Boolean {
if (credentials.isEmpty()) return false
// Verify each credential
val verifier = CredentialVerifier(
didResolver = CredentialDidResolver { did ->
didRegistry.resolve(did).toCredentialDidResolution()
}
)
credentials.forEach { credential ->
val verification = verifier.verify(
credential = credential,
options = CredentialVerificationOptions(
checkRevocation = true,
checkExpiration = false
)
)
if (!verification.valid) return false
}
// Verify chain continuity (each credential references previous)
for (i in 1 until credentials.size) {
val current = credentials[i]
val previous = credentials[i - 1]
val previousDigest = com.trustweave.json.DigestUtils.sha256DigestMultibase(
Json.encodeToJsonElement(
com.trustweave.credential.models.VerifiableCredential.serializer(),
previous
)
)
val referencedDigest = current.credentialSubject.jsonObject
.get("transfer")?.jsonObject
?.get("previousCredentialDigest")?.jsonPrimitive?.content
?: current.credentialSubject.jsonObject
.get("sale")?.jsonObject
?.get("previousCredentialDigest")?.jsonPrimitive?.content
if (referencedDigest != previousDigest) return false
}
return true
}
fun traceProductHistory(
productId: String,
events: List<SupplyChainEvent>
): List<SupplyChainEvent> {
return events.filter { it.productId == productId }
.sortedBy { it.timestamp }
}
Extensive Step-by-Step Breakdown
Step 1: Setup and Initialization
Purpose: Initialize supply chain traceability system with proper key management for multiple participants.
Detailed Explanation:
- Multiple Participant KMS: Separate key management for manufacturer, distributor, retailer ensures proper key isolation
- DID Method Registration: Register DID method for creating participant identities
- Blockchain Setup: Initialize blockchain for anchoring supply chain events
Why This Matters: Supply chains involve multiple independent parties. Proper initialization ensures each party has secure, independent cryptographic capabilities.
Step 2: Create Supply Chain Participant DIDs
Purpose: Establish verifiable identities for all supply chain participants.
Detailed Explanation:
- Manufacturer DID: Represents product manufacturer
- Distributor DID: Represents product distributor
- Retailer DID: Represents product retailer
Key Considerations:
- Each participant has independent DID
- DIDs provide persistent, verifiable identities
- No central registry required
- Works across different systems
Step 3: Create Product
Purpose: Define product with unique identifier.
Detailed Explanation:
- Product ID: Unique identifier for tracking
- Product Name: Human-readable product name
- Batch Number: Batch identifier for grouping products
Why This Matters: Unique product identification enables precise tracking throughout the supply chain.
Step 4: Manufacturer Issues Origin Credential
Purpose: Create verifiable credential for product origin.
Detailed Explanation:
- Origin Data: Location, production date, certifications
- Credential Structure: Follows W3C VC standard
- Proof Generation: Cryptographic signature from manufacturer
- Certifications: Include certifications (Organic, Fair Trade, etc.)
Security Features:
- Tamper-proof cryptographic proof
- Verifiable manufacturer
- Certifications provide additional trust signals
- Can be verified by any party
Step 5: Anchor Origin Event to Blockchain
Purpose: Create immutable record of product origin.
Detailed Explanation:
- Event Record: Create structured record of origin event
- Blockchain Anchoring: Anchor to blockchain for immutability
- Digest: Cryptographic hash of credential
Benefits:
- Immutable record
- Timestamped origin
- Cannot be tampered with
- Provides audit trail
Step 6: Distributor Issues Transfer Credential
Purpose: Create verifiable credential for product transfer.
Detailed Explanation:
- Transfer Data: From/to parties, location, date
- Chain Continuity: References previous credential digest
- Proof Generation: Cryptographic signature from distributor
Chain of Custody:
- Links to previous credential
- Maintains provenance chain
- Verifiable transfer
- Immutable record
Step 7: Anchor Transfer Event
Purpose: Create immutable record of product transfer.
Detailed Explanation:
- Event Record: Create structured record of transfer
- Previous Event Reference: Links to origin event
- Blockchain Anchoring: Anchor to blockchain
Provenance Benefits:
- Complete product journey
- Verifiable chain of custody
- Immutable transfer records
- Audit trail
Step 8: Retailer Issues Sale Credential
Purpose: Create verifiable credential for product sale.
Detailed Explanation:
- Sale Data: From/to parties, location, date
- Chain Continuity: References previous credential digest
- Proof Generation: Cryptographic signature from retailer
Final Step:
- Completes supply chain journey
- Enables consumer verification
- Provides sale record
- Maintains provenance chain
Step 9: Verify Product Provenance
Purpose: Verify complete product journey from origin to sale.
Detailed Explanation:
- Credential Verification: Verify each credential in chain
- Chain Continuity: Verify each credential references previous
- Participant Verification: Verify all participants are legitimate
Verification Process:
- Check cryptographic proofs
- Verify credential signatures
- Check chain continuity
- Validate participant DIDs
Step 10: Verify Product Authenticity
Purpose: Verify product is genuine and from claimed manufacturer.
Detailed Explanation:
- Origin Verification: Verify origin credential
- Manufacturer Verification: Verify manufacturer DID
- Certification Verification: Verify certifications
Authenticity Benefits:
- Prevents counterfeiting
- Verifies manufacturer
- Confirms certifications
- Builds consumer trust
Step 11: Trace Product History
Purpose: Retrieve complete product history from blockchain.
Detailed Explanation:
- Event Retrieval: Retrieve all events for product
- Chronological Order: Sort events by timestamp
- History Display: Show complete product journey
Traceability Benefits:
- Complete visibility
- Consumer transparency
- Regulatory compliance
- Recall efficiency
Advanced Features
Multi-Stage Processing
Track product through processing stages:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
fun createProcessingCredential(
productId: String,
processorDid: String,
processingType: String,
processingDate: String,
previousCredentialDigest: String
): VerifiableCredential {
return VerifiableCredential(
type = listOf("VerifiableCredential", "ProcessingCredential", "SupplyChainCredential"),
issuer = processorDid,
credentialSubject = buildJsonObject {
put("productId", productId)
put("processing", buildJsonObject {
put("processingType", processingType)
put("processingDate", processingDate)
put("processorDid", processorDid)
put("previousCredentialDigest", previousCredentialDigest)
})
},
issuanceDate = Instant.now().toString()
)
}
Quality Certifications
Add quality certifications at each stage:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
fun addQualityCertification(
productId: String,
certifierDid: String,
certificationType: String,
testResults: Map<String, String>
): VerifiableCredential {
return VerifiableCredential(
type = listOf("VerifiableCredential", "QualityCertificationCredential"),
issuer = certifierDid,
credentialSubject = buildJsonObject {
put("productId", productId)
put("certification", buildJsonObject {
put("certificationType", certificationType)
put("testResults", buildJsonObject {
testResults.forEach { (key, value) ->
put(key, value)
}
})
})
},
issuanceDate = Instant.now().toString()
)
}
Recall Management
Enable efficient product recalls:
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
fun recallProducts(
batchNumber: String,
recallReason: String,
affectedProducts: List<String>
): List<VerifiableCredential> {
return affectedProducts.map { productId ->
VerifiableCredential(
type = listOf("VerifiableCredential", "RecallCredential"),
issuer = "did:example:regulatory-authority",
credentialSubject = buildJsonObject {
put("productId", productId)
put("batchNumber", batchNumber)
put("recallReason", recallReason)
put("recallDate", Instant.now().toString())
},
issuanceDate = Instant.now().toString()
)
}
}
fun checkProductRecall(productId: String, credentials: List<VerifiableCredential>): Boolean {
return credentials.any { credential ->
credential.type.contains("RecallCredential") &&
credential.credentialSubject.jsonObject["productId"]?.jsonPrimitive?.content == productId
}
}
Real-World Use Cases
1. Food Traceability (Farm to Table)
Scenario: Track organic produce from farm to consumer.
Implementation:
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
fun createFarmToTableTraceability(
productId: String,
farmDid: String,
processorDid: String,
distributorDid: String,
retailerDid: String
): List<VerifiableCredential> {
// Farm origin
val farmCredential = createOriginCredential(
productId = productId,
productName = "Organic Tomatoes",
batchNumber = "BATCH-2024-001",
manufacturerDid = farmDid,
originLocation = "Organic Farm XYZ",
productionDate = Instant.now().toString(),
certifications = listOf("Organic", "Non-GMO")
)
// Processing
val processingCredential = createProcessingCredential(
productId = productId,
processorDid = processorDid,
processingType = "Washing and Packaging",
processingDate = Instant.now().toString(),
previousCredentialDigest = "farm-digest"
)
// Distribution
val distributionCredential = createTransferCredential(
productId = productId,
fromDid = processorDid,
toDid = distributorDid,
transferDate = Instant.now().toString(),
transferLocation = "Cold Storage Facility",
previousCredentialDigest = "processing-digest"
)
// Retail sale
val saleCredential = createSaleCredential(
productId = productId,
fromDid = distributorDid,
toDid = retailerDid,
saleDate = Instant.now().toString(),
saleLocation = "Grocery Store ABC",
previousCredentialDigest = "distribution-digest"
)
return listOf(farmCredential, processingCredential, distributionCredential, saleCredential)
}
2. Pharmaceutical Tracking
Scenario: Track pharmaceuticals through supply chain to prevent counterfeiting.
Implementation:
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
35
36
37
38
39
40
41
42
43
44
45
46
47
fun createPharmaceuticalTracking(
productId: String,
manufacturerDid: String,
distributorDid: String,
pharmacyDid: String,
lotNumber: String,
expirationDate: String
): List<VerifiableCredential> {
// Manufacturer origin
val originCredential = VerifiableCredential(
type = listOf("VerifiableCredential", "PharmaceuticalOriginCredential"),
issuer = manufacturerDid,
credentialSubject = buildJsonObject {
put("productId", productId)
put("pharmaceutical", buildJsonObject {
put("drugName", "Medication XYZ")
put("lotNumber", lotNumber)
put("manufacturingDate", Instant.now().toString())
put("expirationDate", expirationDate)
put("manufacturerDid", manufacturerDid)
})
},
issuanceDate = Instant.now().toString()
)
// Distribution
val distributionCredential = createTransferCredential(
productId = productId,
fromDid = manufacturerDid,
toDid = distributorDid,
transferDate = Instant.now().toString(),
transferLocation = "Pharmaceutical Distribution Center",
previousCredentialDigest = "origin-digest"
)
// Pharmacy receipt
val pharmacyCredential = createSaleCredential(
productId = productId,
fromDid = distributorDid,
toDid = pharmacyDid,
saleDate = Instant.now().toString(),
saleLocation = "Pharmacy ABC",
previousCredentialDigest = "distribution-digest"
)
return listOf(originCredential, distributionCredential, pharmacyCredential)
}
3. Luxury Goods Authentication
Scenario: Verify authenticity of luxury goods.
Implementation:
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
fun verifyLuxuryGoodAuthenticity(
productId: String,
brandDid: String,
credentials: List<VerifiableCredential>
): Boolean {
// Find origin credential from brand
val originCredential = credentials.firstOrNull { credential ->
credential.type.contains("OriginCredential") &&
credential.issuer == brandDid
} ?: return false
// Verify origin credential
val verifier = CredentialVerifier(
didResolver = CredentialDidResolver { did ->
didRegistry.resolve(did).toCredentialDidResolution()
}
)
val verification = verifier.verify(
credential = originCredential,
options = CredentialVerificationOptions(
checkRevocation = true,
checkExpiration = false
)
)
if (!verification.valid) return false
// Verify provenance chain
return verifyProvenanceChain(credentials)
}
Benefits
- Provenance Tracking: Complete product journey visibility
- Authenticity Verification: Cryptographic proof prevents counterfeiting
- Multi-Party Coordination: Standard format works across all participants
- Regulatory Compliance: Immutable records meet traceability requirements
- Recall Efficiency: Instant identification of affected products
- Consumer Trust: Transparent product information
- Sustainability: Track environmental impact
- Fraud Prevention: Tamper-proof credentials prevent fraud
- Efficiency: Faster verification processes
- Interoperability: Works across different systems
Best Practices
- Unique Product IDs: Use unique identifiers for each product
- Chain Continuity: Always reference previous credential digest
- Blockchain Anchoring: Anchor critical events to blockchain
- Verification: Verify credentials at each stage
- Schema Validation: Validate credential structure
- Error Handling: Handle verification failures gracefully
- Audit Logging: Log all supply chain events
- Key Management: Use secure key storage
- Participant Verification: Verify participant DIDs
- Recall Planning: Plan for efficient recalls
Next Steps
- Learn about Blockchain Anchoring
- Explore Proof of Location Scenario for geospatial tracking
- Check out Financial Services & KYC Scenario for related verification
- Review Core Concepts: Verifiable Credentials for credential details