示意图 · 02
批次生命周期
批次如何产生、转移、变更状态、变成其他批次并离开账本。唯一固定的状态是 0(ACTIVE)和 255(RETIRED,终态);介于两者之间的一切都由签发方定义。
状态与转换
stateDiagram-v2
[*] --> ACTIVE : createBatch (ISSUER_ROLE)
[*] --> ACTIVE : transform 的输出
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
RETIRED --> [*] : totalSupply == 0
note right of RETIRED
终态。不可铸造,不可转移,不可转化。
销毁仍然可以进行(核销、交付)。
end note从收获前到加工品
timeline
title 一批小麦,从远期合约到面粉
收获前 : 以 producedAt = 0 调用 createBatch(远期合约或作物应收账款)
: ExpiryHook 可在收获之前阻止转移(allowPreHarvest = false)
收获 : setBatchMetadata 写入收获文档的哈希
: producedAt 通过重新分批的 transform 设置,或在创建时设置
储存 : AttestationHook 要求有仓单证明
: setFrozenTokens 用于留置权,违约时使用 forcedTransfer
加工 : TRANSFORMER_ROLE 执行 transform([wheat], [60 t]) → [flour](45 t)
: BatchTransformed 事件 = EPCIS TransformationEvent
交付 : DeliveryHook 锁定单位,结算就是携带 data = deliveryId 的转移
: setBatchStatus(255, "DELIVERED"),或由接收方 burn