1+ // SPDX-License-Identifier: MIT
2+ pragma solidity ^ 0.8.20 ;
3+
4+ contract ProductRegistry {
5+ struct Product {
6+ string name;
7+ string batch;
8+ string manufacturer;
9+ string status;
10+ uint256 timestamp;
11+ bool exists;
12+ }
13+
14+ struct TraceRecord {
15+ string stage;
16+ string company;
17+ string location;
18+ uint256 timestamp;
19+ bool exists;
20+ }
21+
22+ mapping (string => Product) public products;
23+ mapping (string => TraceRecord[]) public productTraces;
24+ mapping (string => uint256 ) public traceCount;
25+
26+ event ProductRegistered (string productId , string name , string manufacturer );
27+ event ProductStatusUpdated (string productId , string newStatus );
28+ event TraceRecordAdded (string productId , string stage , string company , string location );
29+
30+ modifier productExists (string memory productId ) {
31+ require (products[productId].exists, "Product does not exist " );
32+ _;
33+ }
34+
35+ function registerProduct (
36+ string memory productId ,
37+ string memory name ,
38+ string memory batch ,
39+ string memory manufacturer
40+ ) public {
41+ require (! products[productId].exists, "Product already exists " );
42+ require (bytes (productId).length > 0 , "Product ID cannot be empty " );
43+ require (bytes (name).length > 0 , "Product name cannot be empty " );
44+ require (bytes (manufacturer).length > 0 , "Manufacturer cannot be empty " );
45+
46+ products[productId] = Product ({
47+ name: name,
48+ batch: batch,
49+ manufacturer: manufacturer,
50+ status: "Created " ,
51+ timestamp: block .timestamp ,
52+ exists: true
53+ });
54+
55+ emit ProductRegistered (productId, name, manufacturer);
56+ }
57+
58+ function updateProductStatus (string memory productId , string memory newStatus )
59+ public
60+ productExists (productId)
61+ {
62+ require (bytes (newStatus).length > 0 , "Status cannot be empty " );
63+
64+ products[productId].status = newStatus;
65+ emit ProductStatusUpdated (productId, newStatus);
66+ }
67+
68+ function addTraceRecord (
69+ string memory productId ,
70+ string memory stage ,
71+ string memory company ,
72+ string memory location
73+ ) public productExists (productId) {
74+ require (bytes (stage).length > 0 , "Stage cannot be empty " );
75+ require (bytes (company).length > 0 , "Company cannot be empty " );
76+ require (bytes (location).length > 0 , "Location cannot be empty " );
77+
78+ TraceRecord memory newTrace = TraceRecord ({
79+ stage: stage,
80+ company: company,
81+ location: location,
82+ timestamp: block .timestamp ,
83+ exists: true
84+ });
85+
86+ productTraces[productId].push (newTrace);
87+ traceCount[productId] = productTraces[productId].length ;
88+
89+ emit TraceRecordAdded (productId, stage, company, location);
90+ }
91+
92+ function getProduct (string memory productId )
93+ public
94+ view
95+ returns (
96+ string memory ,
97+ string memory ,
98+ string memory ,
99+ string memory ,
100+ uint256
101+ )
102+ {
103+ require (products[productId].exists, "Product not found " );
104+ Product memory p = products[productId];
105+ return (p.name, p.batch, p.manufacturer, p.status, p.timestamp);
106+ }
107+
108+ function getTraceRecord (string memory productId , uint256 index )
109+ public
110+ view
111+ returns (
112+ string memory ,
113+ string memory ,
114+ string memory ,
115+ uint256
116+ )
117+ {
118+ require (products[productId].exists, "Product not found " );
119+ require (index < productTraces[productId].length , "Trace record index out of bounds " );
120+
121+ TraceRecord memory trace = productTraces[productId][index];
122+ return (trace.stage, trace.company, trace.location, trace.timestamp);
123+ }
124+
125+ function getTraceCount (string memory productId )
126+ public
127+ view
128+ returns (uint256 )
129+ {
130+ require (products[productId].exists, "Product not found " );
131+ return traceCount[productId];
132+ }
133+
134+ function getAllTraces (string memory productId )
135+ public
136+ view
137+ returns (
138+ string [] memory stages ,
139+ string [] memory companies ,
140+ string [] memory locations ,
141+ uint256 [] memory timestamps
142+ )
143+ {
144+ require (products[productId].exists, "Product not found " );
145+
146+ uint256 count = productTraces[productId].length ;
147+ stages = new string [](count);
148+ companies = new string [](count);
149+ locations = new string [](count);
150+ timestamps = new uint256 [](count);
151+
152+ for (uint256 i = 0 ; i < count; i++ ) {
153+ TraceRecord memory trace = productTraces[productId][i];
154+ stages[i] = trace.stage;
155+ companies[i] = trace.company;
156+ locations[i] = trace.location;
157+ timestamps[i] = trace.timestamp;
158+ }
159+
160+ return (stages, companies, locations, timestamps);
161+ }
162+
163+ function productExistsCheck (string memory productId )
164+ public
165+ view
166+ returns (bool )
167+ {
168+ return products[productId].exists;
169+ }
170+
171+ // Emergency function to verify contract integrity
172+ function getContractInfo ()
173+ public
174+ pure
175+ returns (string memory , string memory )
176+ {
177+ return ("ProductRegistry " , "2.0.0 " );
178+ }
179+ }
0 commit comments