Diagrams · 02
Batch lifecycle
How a batch comes into existence, moves, changes status, becomes other batches and leaves the ledger. The only fixed statuses are 0 (ACTIVE) and 255 (RETIRED, terminal); everything in between is defined by the issuer.
States and transitions
stateDiagram-v2
[*] --> ACTIVE : createBatch (ISSUER_ROLE)
[*] --> ACTIVE : transform output
ACTIVE --> ACTIVE : safeTransferFrom · burn · forcedTransfer
ACTIVE --> Custom : setBatchStatus(1..254) (STATUS_ROLE)
Custom --> Custom : setBatchStatus (STATUS_ROLE)
Custom --> ACTIVE : setBatchStatus(0)
ACTIVE --> RETIRED : setBatchStatus(255, reason)
Custom --> RETIRED : setBatchStatus(255, reason)
RETIRED --> RETIRED : burn only
RETIRED --> [*] : totalSupply == 0
note right of RETIRED
Terminal. No mint, no transfer, no transform.
Burns remain possible (write-off, delivery).
end notePre-harvest to processed good
timeline
title One lot of wheat, from forward contract to flour
Pre-harvest : createBatch with producedAt = 0 (a forward or crop receivable)
: ExpiryHook may block transfers until harvest (allowPreHarvest = false)
Harvest : setBatchMetadata with the harvest document hash
: producedAt is set by a re-batch transform or at creation
Storage : AttestationHook requires the warehouse receipt attestation
: setFrozenTokens for a lien; forcedTransfer on default
Processing : transform([wheat], [60 t]) → [flour] (45 t) by TRANSFORMER_ROLE
: BatchTransformed event = EPCIS TransformationEvent
Delivery : DeliveryHook locks units; settlement is the transfer with data = deliveryId
: setBatchStatus(255, "DELIVERED") or burn by the receiver