Roles
- Farmer
- Distributor
- Retailer
- Consumer
- Inspector
Chaincode Functions
Produce Lifecycle
-
registerProduce(farmerId, details) -> Only Farmer
-
Creates a new 'Produce' asset
- Adds it to 'actionHistory' and farmer's 'registeredProduce'
-
Creates a "REGISTER" 'actionItem'
-
updateLocation(produceId, actorId, inTransit/newLocation) -> Only Farmer/Distributor/Retailer
-
Changes 'currentLocation' or 'status' to "In Transit"
-
Adds "MOVE" 'actionItem'
-
markAsUnavailable(produceId, actorId, reason, newStatus) -> Only Farmer/Distributor/Retailer/Inspector
-
Mark 'isAvailable' as false and set 'notAvailableReason' to reason
-
Adds "REMOVED" actionItem
-
inspectProduce(produceId, inspectorId, qualityUpdate) -> Only Inspector
-
Updates 'quality'/'expiryDate'
- Adds an "INSPECT" 'actionItem'
-
Calls markAsUnavailable if asset fails inspection
-
updateDetails(produceId, actorId, details) -> Only 'currentOwner'
-
Updates 'pricePerUnit', 'storageConditions'
-
Adds "UPDATED" actionItem
-
splitProduce(produceId, qty, OwnerId) -> Only 'currentOwner'
-
Creates new assets and sets 'parentID'
- Updates parent 'qty' and sets 'children'
-
Adds a "SPLIT" 'actionItem'
-
transferOwnership(produceId, newOwnerId, qty, salePrice) -> Only 'currentOwner'
-
Verifies if asset is available
- Full or partial transfer -> Calls
splitBatch if partial
- Updates 'saleHistory' and 'actionHistory', and fields in roles
-
Adds a "SALE" 'actionItem'
-
recordPayment(produceId, transactionId, paymentStatus)
-
Update 'paymentStatus', 'paymentMethod', 'paymentRef'
- Links off-chain payment confirmation (UPI/BankRef)
Querying
-
getProduceById(produceId)
-
Returns current state
-
getProduceByOwner(ownerId)
-
Lists all assets owned by a role
Governance
-
registerUser(role, details) -> Accept user by vote
-
Registers Farmer/Distributor/Retailer/Inspector/Consumer
-
getUserDetails(userId)
-
Returns profile
-
updateUser(userId, role, details)
-
Updates user details
Schema
Produce
id:
parentId: null if original batch, otherwise reference to parent batch
children: null or [childIds]
qty:
qtyUnit: KG/Number
pricePerUnit: Asking Price
totalPrice: pricePerUnit * qty
currentOwner:
currentLocation:
actionHistory: ['actionItem']
saleHistory: ['transaction']
cropType:
harvestDate:
quality:
expiryDate:
storageConditions: [Cold Storage, High Temperature, Ambient etc.]
status: "Harvested"/"In Transit"/"Retail"/"Missing"/"Failed Inspection"/"Removed"
isAvailable: true/false -> false if asset is not available due to 'notAvailableReason'
notAvailableReason: If asset is expired/missing/fails inspection/sold to consumer
actionItem
Order by 'timestamp'
timestamp:
action: "REGISTER"/"UPDATED"/"MOVE"/"SPLIT"/"SALE"/"INSPECT"/"REMOVED"
currentLocation:
currentOwner:
transaction
Order by 'timestamp'
timestamp:
prevOwner:
newOwner:
salePrice: Total amount paid
qtyBought:
newId: If a new asset was created
paymentStatus:
paymentMethod:
paymentRef:
Farmer
role: "Farmer"
id:
name:
location:
walletId: For Payments
registeredProduce: [produceIds]
certification: ["Organic", "Fair Trade" etc]
Distributor
role: "Distributor"
id:
name:
location:
walletId:
ownedProduce: [produceIds]
Retailer
role: "Retailer"
id:
name:
shopLocation:
walletId:
inventory: [produceIds]
Inspector
role: "Inspector"
id:
name:
authority: "Govt"/"Private"/"NGO"
Consumer
We don't include any details of a particular consumer to protect their privacy, but at the same time they will be able to access all the information about the asset
1# Roles
2
31. Farmer
42. Distributor
53. Retailer
64. Consumer
75. Inspector
8
9# Chaincode Functions
10
11### Produce Lifecycle
12
131. registerProduce(farmerId, details) -> Only Farmer
14
15- Creates a new 'Produce' asset
16- Adds it to 'actionHistory' and farmer's 'registeredProduce'
17- Creates a "REGISTER" 'actionItem'
18
192. updateLocation(produceId, actorId, inTransit/newLocation) -> Only Farmer/Distributor/Retailer
20
21- Changes 'currentLocation' or 'status' to "In Transit"
22- Adds "MOVE" 'actionItem'
23
243. markAsUnavailable(produceId, actorId, reason, newStatus) -> Only Farmer/Distributor/Retailer/Inspector
25
26- Mark 'isAvailable' as false and set 'notAvailableReason' to reason
27- Adds "REMOVED" actionItem
28
294. inspectProduce(produceId, inspectorId, qualityUpdate) -> Only Inspector
30
31- Updates 'quality'/'expiryDate'
32- Adds an "INSPECT" 'actionItem'
33- Calls `markAsUnavailable` if asset fails inspection
34
355. updateDetails(produceId, actorId, details) -> Only 'currentOwner'
36
37- Updates 'pricePerUnit', 'storageConditions'
38- Adds "UPDATED" actionItem
39
406. splitProduce(produceId, qty, OwnerId) -> Only 'currentOwner'
41
42- Creates new assets and sets 'parentID'
43- Updates parent 'qty' and sets 'children'
44- Adds a "SPLIT" 'actionItem'
45
467. transferOwnership(produceId, newOwnerId, qty, salePrice) -> Only 'currentOwner'
47
48- Verifies if asset is available
49- Full or partial transfer -> Calls `splitBatch` if partial
50- Updates 'saleHistory' and 'actionHistory', and fields in roles
51- Adds a "SALE" 'actionItem'
52
538. recordPayment(produceId, transactionId, paymentStatus)
54
55- Update 'paymentStatus', 'paymentMethod', 'paymentRef'
56- Links off-chain payment confirmation (UPI/BankRef)
57
58## Querying
59
601. getProduceById(produceId)
61
62- Returns current state
63
642. getProduceByOwner(ownerId)
65
66- Lists all assets owned by a role
67
68## Governance
69
701. registerUser(role, details) -> Accept user by vote
71
72- Registers Farmer/Distributor/Retailer/Inspector/Consumer
73
742. getUserDetails(userId)
75
76- Returns profile
77
783. updateUser(userId, role, details)
79
80- Updates user details
81
82# Schema
83
84## Produce
85
86```
87id:
88parentId: null if original batch, otherwise reference to parent batch
89children: null or [childIds]
90
91qty:
92qtyUnit: KG/Number
93
94pricePerUnit: Asking Price
95totalPrice: pricePerUnit * qty
96
97currentOwner:
98currentLocation:
99actionHistory: ['actionItem']
100saleHistory: ['transaction']
101
102cropType:
103harvestDate:
104quality:
105expiryDate:
106storageConditions: [Cold Storage, High Temperature, Ambient etc.]
107
108status: "Harvested"/"In Transit"/"Retail"/"Missing"/"Failed Inspection"/"Removed"
109isAvailable: true/false -> false if asset is not available due to 'notAvailableReason'
110notAvailableReason: If asset is expired/missing/fails inspection/sold to consumer
111```
112
113### actionItem
114
115Order by 'timestamp'
116
117```
118timestamp:
119action: "REGISTER"/"UPDATED"/"MOVE"/"SPLIT"/"SALE"/"INSPECT"/"REMOVED"
120currentLocation:
121currentOwner:
122```
123
124### transaction
125
126Order by 'timestamp'
127
128```
129timestamp:
130prevOwner:
131newOwner:
132salePrice: Total amount paid
133
134qtyBought:
135newId: If a new asset was created
136
137paymentStatus:
138paymentMethod:
139paymentRef:
140```
141
142## Farmer
143
144```
145role: "Farmer"
146id:
147name:
148location:
149walletId: For Payments
150registeredProduce: [produceIds]
151certification: ["Organic", "Fair Trade" etc]
152```
153
154## Distributor
155
156```
157role: "Distributor"
158id:
159name:
160location:
161walletId:
162ownedProduce: [produceIds]
163```
164
165## Retailer
166
167```
168role: "Retailer"
169id:
170name:
171shopLocation:
172walletId:
173inventory: [produceIds]
174```
175
176## Inspector
177
178```
179role: "Inspector"
180id:
181name:
182authority: "Govt"/"Private"/"NGO"
183```
184
185## Consumer
186
187```
188role: "Consumer"
189id:
190```
191
192We don't include any details of a particular consumer to protect their privacy, but at the same time they will be able to access all the information about the asset