├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md ├── client ├── .env ├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public │ ├── favicon.ico │ ├── homeArt.png │ ├── index.html │ ├── logo.png │ ├── logo192.png │ ├── logo512.png │ ├── manifest.json │ └── robots.txt ├── src │ ├── App.css │ ├── App.js │ ├── App.test.js │ ├── components │ │ ├── Loader.js │ │ ├── Modal.js │ │ ├── Navbar.js │ │ ├── ReciptModal.js │ │ ├── Search.js │ │ ├── Styles.js │ │ ├── Theme.js │ │ └── map.js │ ├── context │ │ └── RoleDataContext.js │ ├── getWeb3.js │ ├── index.css │ ├── index.js │ ├── logo.svg │ ├── pages │ │ ├── Customer │ │ │ ├── PurchaseCustomer.js │ │ │ ├── ReceiveCustomer.js │ │ │ └── ReceivedByCustomer.js │ │ ├── DeliveryHub │ │ │ ├── ReceiveDeliveryHub.js │ │ │ └── ShipDeliveryHub.js │ │ ├── Explorer.js │ │ ├── Home.js │ │ ├── Manufacturer │ │ │ ├── AllManufacture.js │ │ │ ├── Manufacture.js │ │ │ └── ShipManufacture.js │ │ ├── RoleAdmin.js │ │ └── ThirdParty │ │ │ ├── PurshaseThirdParty.js │ │ │ ├── ReceiveThirdParty.js │ │ │ └── ShipThirdParty.js │ ├── server.js │ └── serviceWorker.js └── yarn.lock ├── contracts ├── Migrations.sol ├── Structure.sol ├── SupplyChain.sol └── rolesUtils[deprecated] │ ├── Customer.sol │ ├── DeliveryHub.sol │ ├── Manufacturer.sol │ ├── Roles.sol │ ├── SortationHub.sol │ └── Thirdparty.sol ├── images ├── Solidity.svg ├── activitydiagram.png ├── architecture.png ├── architecturefinal.png ├── dataflow.png ├── express.jpg ├── express.svg ├── flow.png ├── ganachetrans.png ├── logo.png ├── mat.png ├── nginx.png ├── react.png ├── sequencediagram.png ├── truffle.png ├── trufflenew.png └── web3.jpg ├── migrations ├── 1_initial_migration.js └── 2_deploy_contracts.js ├── package-lock.json ├── package.json ├── test ├── TestSimpleStorage.sol └── simplestorage.js └── truffle-config.js /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sol linguist-language=Solidity 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Truffle 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |
3 | 4 |
5 | Supply-Chain-Dapp 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 |

A simple Supply Chain setup with Solidity.

39 | 40 |

41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |

51 | 52 |

53 | Description • 54 | Architecture • 55 | Flow • 56 | Working • 57 | Contract Diagrams • 58 | Installation and Setup • 59 | License 60 |

61 | 62 | ## Description 63 | Supply chain is always hard to manage and requires a lot of admistrative machinery. However, when managed with smart contracts using blockchain, a lot of the paperwork is reduced. 64 | Also it leads to an increase in transparency and helps to build an efficient Root of Trust. Spply-chain-dapp is such an implementation of a supply chian management system wich uses blockchain to ensure a transparent and secure transfer of product from the manufacturer to the customer via the online e-commerce websites. 65 | ## Architecture 66 | The smart contract is being written with Solidity which is then compiled, migrated and deployed using Truffle.js on the local blockchain network created using Ganache-cli.The frontend uses Web3.js to communicate with the smart contract and local blockchain network and is written using React.js framework for better component and state lifecycle management.The requests from user are forwarded to frontend through Nginx(load balancer) and Express.js for dynamic routing. 67 |

68 | 69 |

70 | 71 | ## Flow 72 |

73 | 74 |

75 | 76 | ## Working 77 |

78 | The lifecycle of a product starts when manufactureProduct() is called(while making an entry) after the final product is manufactured and the product and manufacturer details are entered in the blockchain. The productHistory[] gets initialized and the current product data is stored with the current owner(manufacturer). 79 |

80 |

81 | Now this product shall be available to the Third Party for purchase. On being purchased by a third party seller, the purchasedByThirdParty() gets called where the owner is set to thirdParty and the present data gets pushed to the productHistory[] (which helps us to track the origin and handling of the product). Simultaneously, the product is shipped by the manufacturer (shipToThirdParty()) and is received by the Third Party where receivedByThirdParty() is called and the details of the Third Party seller are entered. Each of these checkpoint's data is stored in product history with the state being updated at each step. 82 |

83 |

84 | The online purchase of the product takes place from the Third Party. When the customer orders the product, it is shipped by the Third Party (shipByThirdParty()) and received by the delivery hub where the receivedByDeliveryHub() is called. Here the customer address is stored, owner is set to Delivery Hub, details of the Delivery Hub are fed and the current data state gets pushed to the productHistory[]. 85 |

86 |

87 | Finally the product is shipped by the Delivery Hub (shipByDeliveryHub()) and received by the customer where the receivedByCustomer() is called and the current and final state gets pushed to the productHistory[]. 88 |

89 |

90 | All of these juncture functions shall be called only after complete verification of product and productHistory[] while entering a checkpoint. (eg:- Customer accepts and confirms the product by clicking the receive button from his account only after it verifies the product). 91 |

92 |

93 | fetchProductPart1(), fetchProductPart2(), fetchProductPart3(), fetchProductHistoryLength(), fetchProductCount(), fetchProductState() are the functions to retreive data of a product queried with UID and data type as product(current state) or history. 94 |

95 |

96 | The hashes(read certificates) are generated using the Solidity cryptographic function keccak256() which implements a SHA-3 hash in the blockchain setup. keccak256() generates a secure 256-bit hash which is the main basis of security in the entire mainnet apart from the smart contracts being immutable. In our supply chain setup certificates are generated at every stage of shipping of the product. 97 |

98 | 99 | ## Contract Diagrams 100 | ### Activity Diagram 101 | The overall flow of the project is described as follows. 102 |

103 | 104 | 105 | 106 |

107 |

Sequence Diagram

108 | The flow of the functions in the smart contracts. 109 |

110 | 111 | 112 | 113 |

114 |

Data Flow Diagram

115 | The entire structure of the code. 116 |

117 | 118 | 119 | 120 |

121 | 122 | ## Installation and Setup 123 | Prerequisites : `npm, git, docker(optional)` 124 | 125 | Clone the repository 126 | ```Bash 127 | git clone https://github.com/rishav4101/eth-supplychain-dapp.git && cd eth-supplychain-dapp 128 | ``` 129 | Install dependencies 130 | ```Bash 131 | npm i 132 | ``` 133 | Install ganache-cli 134 | ```Bash 135 | npm i -g ganache-cli 136 | ``` 137 | Configure ganache-cli for 10 accounts and extend gasLimit to 6721975000 and beyond, so as to have enough gas for migrating the smart contracts and a data flow for the prototype. 138 | ```Bash 139 | ganache-cli --accounts 10 --gasLimit 6721975000 140 | ``` 141 | If you want to run the ganache-cli on docker then use the following command 142 | ```Bash 143 | sudo docker run -d -p 8545:8545 trufflesuite/ganache-cli:latest -h 0.0.0.0 --accounts 10 --gasLimit 6721975000 144 | ``` 145 | Open a second terminal and enter the client folder 146 | ```Bash 147 | cd client 148 | ``` 149 | Install all packages in the package.json file 150 | ```Bash 151 | npm i 152 | ``` 153 | Setup an .env file using the `nano .env` command and enter the google maps api key and set the react rpc port to 8545 since the ganache-cli runs on the same port by default. 154 | The final .env file must look like this 155 | ```Bash 156 | REACT_APP_GOOGLE_MAP_API_KEY=************************* 157 | REACT_APP_RPC=http://127.0.0.1:8545/ 158 | 159 | ``` 160 | Run the app 161 | ```Bash 162 | npm start 163 | ``` 164 | The app gets hosted by default at port 3000. 165 | 166 | 167 | 168 | ## License 169 | This project uses an [MIT](https://opensource.org/licenses/MIT) license. 170 | ## Documentation to help with Solidity 171 | https://docs.soliditylang.org/en/v0.8.4/ 172 | ## Documentation to help with React 173 | https://reactjs.org/docs/getting-started.html 174 | ## Documentation to help with Truffle 175 | https://www.trufflesuite.com/docs/truffle/reference/configuration 176 | ## Documentation to help with Ganache-cli 177 | https://www.trufflesuite.com/docs/ganache/overview 178 | -------------------------------------------------------------------------------- /client/.env: -------------------------------------------------------------------------------- 1 | REACT_APP_GOOGLE_MAP_API_KEY=AIzaSyA6WqMeNU1cT5SdPi5MhmUrAqKTjUaZNGY 2 | REACT_APP_RPC=http://127.0.0.1:7545/ -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | /src/contracts 8 | 9 | # testing 10 | /coverage 11 | 12 | # production 13 | /build 14 | 15 | # misc 16 | .DS_Store 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | .env -------------------------------------------------------------------------------- /client/README.md: -------------------------------------------------------------------------------- 1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `yarn start` 8 | 9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 11 | 12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console. 14 | 15 | ### `yarn test` 16 | 17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 19 | 20 | ### `yarn build` 21 | 22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance. 24 | 25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed! 27 | 28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 29 | 30 | ### `yarn eject` 31 | 32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 33 | 34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 35 | 36 | Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 37 | 38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 39 | 40 | ## Learn More 41 | 42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 43 | 44 | To learn React, check out the [React documentation](https://reactjs.org/). 45 | 46 | ### Code Splitting 47 | 48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 49 | 50 | ### Analyzing the Bundle Size 51 | 52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 53 | 54 | ### Making a Progressive Web App 55 | 56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 57 | 58 | ### Advanced Configuration 59 | 60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 61 | 62 | ### Deployment 63 | 64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 65 | 66 | ### `yarn build` fails to minify 67 | 68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 69 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@material-ui/core": "^4.11.4", 7 | "@material-ui/icons": "^4.11.2", 8 | "clsx": "^1.1.1", 9 | "express": "^4.17.1", 10 | "ganache-cli": "^6.12.2", 11 | "ganache-core": "^2.13.2", 12 | "google-maps-react": "^2.0.6", 13 | "react": "16.11.0", 14 | "react-dom": "16.11.0", 15 | "react-router-dom": "^5.2.0", 16 | "react-scripts": "^3.2.0", 17 | "web3": "1.2.2" 18 | }, 19 | "scripts": { 20 | "start": "react-scripts start", 21 | "build": "react-scripts build", 22 | "test": "react-scripts test", 23 | "eject": "react-scripts eject" 24 | }, 25 | "eslintConfig": { 26 | "extends": "react-app" 27 | }, 28 | "browserslist": { 29 | "production": [ 30 | ">0.2%", 31 | "not dead", 32 | "not op_mini all" 33 | ], 34 | "development": [ 35 | "last 1 chrome version", 36 | "last 1 firefox version", 37 | "last 1 safari version" 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /client/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/client/public/favicon.ico -------------------------------------------------------------------------------- /client/public/homeArt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/client/public/homeArt.png -------------------------------------------------------------------------------- /client/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 19 | 20 | 29 | Supplychain-dapp 30 | 31 | 32 | 33 |
34 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /client/public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/client/public/logo.png -------------------------------------------------------------------------------- /client/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/client/public/logo192.png -------------------------------------------------------------------------------- /client/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/client/public/logo512.png -------------------------------------------------------------------------------- /client/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /client/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | -------------------------------------------------------------------------------- /client/src/App.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | font-family: 'Poppins', sans-serif; 3 | } 4 | 5 | .App { 6 | text-align: center; 7 | } 8 | 9 | .App-logo { 10 | height: 40vmin; 11 | } 12 | 13 | .App-header { 14 | background-color: #282c34; 15 | min-height: 100vh; 16 | display: flex; 17 | flex-direction: column; 18 | align-items: center; 19 | justify-content: center; 20 | font-size: calc(10px + 2vmin); 21 | color: white; 22 | } 23 | 24 | .App-link { 25 | color: #09d3ac; 26 | } 27 | -------------------------------------------------------------------------------- /client/src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import SupplyChainContract from "./contracts/SupplyChain.json"; 3 | import { Router, Switch, Route } from "react-router-dom"; 4 | import { RoleDataContextProvider } from "./context/RoleDataContext"; 5 | // import history from "./history"; 6 | import {createBrowserHistory} from 'history'; 7 | import getWeb3 from "./getWeb3"; 8 | 9 | import Manufacture from "./pages/Manufacturer/Manufacture"; 10 | import AllManufacture from "./pages/Manufacturer/AllManufacture"; 11 | import ShipManufacture from "./pages/Manufacturer/ShipManufacture"; 12 | 13 | import "./App.css"; 14 | import ReceiveThirdParty from "./pages/ThirdParty/ReceiveThirdParty"; 15 | import PurchaseCustomer from "./pages/Customer/PurchaseCustomer"; 16 | import ShipThirdParty from "./pages/ThirdParty/ShipThirdParty"; 17 | import ReceiveDeliveryHub from "./pages/DeliveryHub/ReceiveDeliveryHub"; 18 | import ShipDeliveryHub from "./pages/DeliveryHub/ShipDeliveryHub"; 19 | import ReceiveCustomer from "./pages/Customer/ReceiveCustomer"; 20 | import ReceivedByCustomer from "./pages/Customer/ReceivedByCustomer"; 21 | import PurchaseThirdParty from "./pages/ThirdParty/PurshaseThirdParty"; 22 | import RoleAdmin from "./pages/RoleAdmin"; 23 | 24 | import { ThemeProvider } from "@material-ui/core/styles"; 25 | import theme from "./components/Theme"; 26 | 27 | import Explorer from './pages/Explorer'; 28 | import Home from "./pages/Home"; 29 | 30 | class App extends Component { 31 | state = { web3: null, accounts: null, contract: null, mRole: null, tpRole: null, dhRole: null, cRole: null }; 32 | 33 | componentDidMount = async () => { 34 | try { 35 | const web3 = await getWeb3(); 36 | const accounts = await web3.eth.getAccounts(); 37 | 38 | const networkId = await web3.eth.net.getId(); 39 | const deployedNetwork = SupplyChainContract.networks[networkId]; 40 | const instance = new web3.eth.Contract( 41 | SupplyChainContract.abi, 42 | deployedNetwork && deployedNetwork.address, 43 | ); 44 | 45 | const mRole = localStorage.getItem("mRole"); 46 | const tpRole = localStorage.getItem("tpRole"); 47 | const dhRole = localStorage.getItem("dhRole"); 48 | const cRole = localStorage.getItem("cRole"); 49 | 50 | this.setState({ web3, accounts, contract: instance, mRole: mRole, tpRole: tpRole, dhRole: dhRole, cRole: cRole }, this.runExample); 51 | } catch (error) { 52 | alert( 53 | `Failed to load web3, accounts, or contract. Check console for details.`, 54 | ); 55 | console.error(error); 56 | } 57 | }; 58 | 59 | runExample = async () => { 60 | const { contract } = this.state; 61 | console.log(contract); 62 | }; 63 | 64 | render() { 65 | if (!this.state.web3) { 66 | return
Loading Web3, accounts, and contract...
; 67 | } 68 | return ( 69 |
70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | {this.state.mRole !== "" ? 88 | 89 | :

Assign Manufacturer Role at /RoleAdmin

} 90 |
91 | 92 | {this.state.mRole !== "" ? 93 | 94 | :

Assign Manufacturer Role at /RoleAdmin

} 95 |
96 | 97 | {this.state.mRole !== "" ? 98 | 99 | :

Assign Manufacturer Role at /RoleAdmin

} 100 |
101 | 102 | {this.state.tpRole !== "" ? 103 | 104 | :

Assign Third Party Role at /RoleAdmin

} 105 |
106 | 107 | {this.state.tpRole !== "" ? 108 | 109 | :

Assign Third Party Role at /RoleAdmin

} 110 |
111 | 112 | {this.state.cRole !== "" ? 113 | 114 | :

Assign Customer Role at /RoleAdmin

} 115 |
116 | 117 | {this.state.tpRole !== "" ? 118 | 119 | :

Assign Third Party Role at /RoleAdmin

} 120 |
121 | 122 | {this.state.dhRole !== "" ? 123 | 124 | :

Assign Delivery Hub Role at /RoleAdmin

} 125 |
126 | 127 | {this.state.dhRole !== "" ? 128 | 129 | :

Assign Delivery Hub Role at /RoleAdmin

} 130 |
131 | 132 | {this.state.cRole !== "" ? 133 | 134 | :

Assign Customer Role at /RoleAdmin

} 135 |
136 | 137 | {this.state.cRole !== "" ? 138 | 139 | :

Assign Customer Role at /RoleAdmin

} 140 |
141 | 142 |
143 |
144 |
145 | 146 |
147 |
148 | ); 149 | } 150 | } 151 | 152 | export default App; 153 | -------------------------------------------------------------------------------- /client/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /client/src/components/Loader.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { makeStyles } from "@material-ui/core/styles"; 3 | import CircularProgress from "@material-ui/core/CircularProgress"; 4 | 5 | const useStyles = makeStyles(() => ({ 6 | root: { 7 | display: "flex", 8 | justifyContent: "center", 9 | alignItems: "center", 10 | verticalAlign: "middle", 11 | paddingTop: "300px", 12 | }, 13 | })); 14 | 15 | export default function Loader() { 16 | const classes = useStyles(); 17 | 18 | return ( 19 |
20 | 21 |
22 | ); 23 | } -------------------------------------------------------------------------------- /client/src/components/Modal.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Modal from "@material-ui/core/Modal"; 3 | import Backdrop from "@material-ui/core/Backdrop"; 4 | import Fade from "@material-ui/core/Fade"; 5 | import Button from "@material-ui/core/Button"; 6 | import TextField from "@material-ui/core/TextField"; 7 | import { useStyles } from "./Styles"; 8 | 9 | export default function ProductModal({ 10 | prod, 11 | open, 12 | handleClose, 13 | handleReceiveButton, 14 | aText 15 | }) { 16 | const [rdata, setRdata] = React.useState({ 17 | long: "", 18 | lat: "", 19 | }); 20 | 21 | const handleChangeForm = async (e) => { 22 | setRdata({ 23 | ...rdata, 24 | [e.target.name]: e.target.value, 25 | }); 26 | }; 27 | 28 | const classes = useStyles(); 29 | return ( 30 |
31 | 43 | 44 |
45 | {prod.length === 0 ? ( 46 | <> 47 | ) : ( 48 | <> 49 |

Details

50 |
51 |
52 |
Universal ID:
53 |
{prod[0][0]}
54 |
55 |
56 |
SKU:
{" "} 57 |
{prod[0][1]}
58 |
59 |
60 |
Owner:
{" "} 61 |
{prod[0][2]}
62 |
63 | 64 |
65 |
Manufacturer:
{" "} 66 |
{prod[0][3]}
67 |
68 | 69 |
70 |
Name of Manufacturer:
{" "} 71 |
{prod[0][4]}
72 |
73 | 74 |
75 |
Manufactured date:
{" "} 76 |
77 | {new Date(parseInt(prod[1][0] * 1000)).toDateString() + 78 | " " + 79 | new Date(parseInt(prod[1][0] * 1000)).toTimeString()} 80 |
81 |
82 | 83 |
84 |
85 | Details of Manufacturer: 86 |
{" "} 87 |
{prod[0][5]}
88 |
89 | 90 |
91 |
92 | Longitude of Manufature:{" "} 93 |
{" "} 94 |
{prod[0][6]}
95 |
96 |
97 |
Latitude of Manufature:
{" "} 98 |
{prod[0][7]}
99 |
100 | 101 |
102 |
Product Name:
{" "} 103 |
{prod[1][1]}
104 |
105 |
106 |
Product Code:
{" "} 107 |
{prod[1][2]}
108 |
109 | 110 |
111 |
Product Price:
{" "} 112 |
{prod[1][3]}
113 |
114 | 115 |
116 |
Product Category:
117 |
{prod[1][4]}
118 |
119 |
120 |
Product State:
{" "} 121 |
{prod[1][5]}
122 |
123 |
124 |
Third Party Address:
{" "} 125 |
{prod[1][6]}
126 |
127 |
128 |
Third Party Longitude:
{" "} 129 |
{prod[1][7]}
130 |
131 |
132 |
Third Party Latitude:
{" "} 133 |
{prod[2][0]}
134 |
135 | 136 |
137 |
Delivery Hub Address:
{" "} 138 |
{prod[2][1]}
139 |
140 |
141 |
142 | Delivery Hub Longitude:{" "} 143 |
{" "} 144 |
{prod[2][2]}
145 |
146 |
147 |
Delivery Hub Latitude:
{" "} 148 |
{prod[2][3]}
149 |
150 |
151 |
Customer Address:
{" "} 152 |
{prod[2][4]}
153 |
154 |
155 |
Tx Hash:
{" "} 156 |
157 | {/* {prod[2][5]} */} 158 | {prod[2][5].length > 40 159 | ? prod[2][5].substring(0, 40) + "..." 160 | : prod[2][5]} 161 |
162 |
163 |
164 | {console.log(handleReceiveButton)} 165 | {handleReceiveButton ? ( 166 | prod[1][5] === "2" || prod[1][5] === "5" ? ( 167 | <> 168 | 175 |   176 | 183 | 184 | ) : ( 185 | <> 186 | ) 187 | ) : ( 188 | <> 189 | )} 190 | {handleReceiveButton ? ( 191 | prod[1][5] === "2" || 192 | prod[1][5] === "5" || 193 | prod[1][5] === "7" ? ( 194 | <> 195 | 210 |

{aText.length !== 0 ? aText : ""}

211 | 212 | ) : ( 213 | <> 214 | ) 215 | ) : ( 216 | <> 217 | )} 218 |
219 | 220 | )} 221 |
222 |
223 |
224 |
225 | ); 226 | } 227 | -------------------------------------------------------------------------------- /client/src/components/Navbar.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import clsx from "clsx"; 3 | import { makeStyles, useTheme } from "@material-ui/core/styles"; 4 | import Drawer from "@material-ui/core/Drawer"; 5 | import CssBaseline from "@material-ui/core/CssBaseline"; 6 | import AppBar from "@material-ui/core/AppBar"; 7 | import Toolbar from "@material-ui/core/Toolbar"; 8 | import List from "@material-ui/core/List"; 9 | import Typography from "@material-ui/core/Typography"; 10 | import IconButton from "@material-ui/core/IconButton"; 11 | import MenuIcon from "@material-ui/icons/Menu"; 12 | import ChevronLeftIcon from "@material-ui/icons/ChevronLeft"; 13 | import ChevronRightIcon from "@material-ui/icons/ChevronRight"; 14 | import ListItem from "@material-ui/core/ListItem"; 15 | import ListItemText from "@material-ui/core/ListItemText"; 16 | import { Link } from "react-router-dom"; 17 | import GitHubIcon from "@material-ui/icons/GitHub"; 18 | 19 | const drawerWidth = 240; 20 | 21 | const useStyles = makeStyles((theme) => ({ 22 | root: { 23 | display: "flex", 24 | }, 25 | appBar: { 26 | transition: theme.transitions.create(["margin", "width"], { 27 | easing: theme.transitions.easing.sharp, 28 | duration: theme.transitions.duration.leavingScreen, 29 | }), 30 | }, 31 | appBarShift: { 32 | width: `calc(100% - ${drawerWidth}px)`, 33 | marginLeft: drawerWidth, 34 | transition: theme.transitions.create(["margin", "width"], { 35 | easing: theme.transitions.easing.easeOut, 36 | duration: theme.transitions.duration.enteringScreen, 37 | }), 38 | }, 39 | menuButton: { 40 | marginRight: theme.spacing(2), 41 | }, 42 | hide: { 43 | display: "none", 44 | }, 45 | drawer: { 46 | width: drawerWidth, 47 | flexShrink: 0, 48 | }, 49 | drawerPaper: { 50 | width: drawerWidth, 51 | backgroundColor: "#09126d", 52 | color: "#fff", 53 | }, 54 | drawerHeader: { 55 | display: "flex", 56 | alignItems: "center", 57 | padding: theme.spacing(0, 1), 58 | // necessary for content to be below app bar 59 | ...theme.mixins.toolbar, 60 | justifyContent: "flex-end", 61 | }, 62 | content: { 63 | flexGrow: 1, 64 | padding: theme.spacing(3), 65 | transition: theme.transitions.create("margin", { 66 | easing: theme.transitions.easing.sharp, 67 | duration: theme.transitions.duration.leavingScreen, 68 | }), 69 | marginLeft: -drawerWidth, 70 | }, 71 | contentShift: { 72 | transition: theme.transitions.create("margin", { 73 | easing: theme.transitions.easing.easeOut, 74 | duration: theme.transitions.duration.enteringScreen, 75 | }), 76 | marginLeft: 0, 77 | }, 78 | })); 79 | 80 | export default function PersistentDrawerLeft({ pageTitle,navItems, children }) { 81 | const classes = useStyles(); 82 | const theme = useTheme(); 83 | const [open, setOpen] = React.useState(true); 84 | 85 | const handleDrawerOpen = () => { 86 | setOpen(true); 87 | }; 88 | 89 | const handleDrawerClose = () => { 90 | setOpen(false); 91 | }; 92 | 93 | return ( 94 |
95 | 96 | 102 | 103 | 110 | 111 | 112 | 117 | . 122 |  SupplyChain-Dapp 123 | 124 | 125 | 126 | 135 |
136 | {pageTitle} 137 | 138 | {theme.direction === "ltr" ? ( 139 | 140 | ) : ( 141 | 142 | )} 143 | 144 |
145 | 146 | 147 | 148 | Home 149 | 150 | 151 | 155 | 156 | Explorer 157 | 158 | 159 | 160 | 161 | {navItems.length !== 0 ? ( 162 | navItems.map((item) => ( 163 | 167 | 168 | 169 | 170 | 171 | )) 172 | ) : ( 173 | <> 174 | )} 175 | 176 |
179 |
191 | By Team Akatsuki    192 | 196 | 197 | 198 |
199 |
200 |
201 |
206 |
207 |
{children}
208 |
209 |
210 | ); 211 | } 212 | -------------------------------------------------------------------------------- /client/src/components/ReciptModal.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Modal from "@material-ui/core/Modal"; 3 | import Backdrop from "@material-ui/core/Backdrop"; 4 | import Fade from "@material-ui/core/Fade"; 5 | import { useStyles } from "./Styles"; 6 | 7 | export default function ReciptModal({ recipt, openRecipt, handleCloseRecipt }) { 8 | const classes = useStyles(); 9 | return ( 10 | 22 | 23 |
24 |

Recipt

25 |
26 | {recipt !== null ? ( 27 | <> 28 |
29 |
Tx hash:
30 |
{recipt.hash}
31 |
32 |
33 |
Block hash:
34 |
{recipt.blockHash}
35 |
36 |
37 |
Block Number:
38 |
{recipt.blockNumber}
39 |
40 |
41 |
From:
42 |
{recipt.from}
43 |
44 |
45 |
To:
46 |
{recipt.to}
47 |
48 |
49 |
Nonce:
50 |
{recipt.nonce}
51 |
52 |
53 |
Input:
54 |
{recipt.input}
55 |
56 |
57 |
Gas:
58 |
{recipt.gas}
59 |
60 |
61 |
Value:
62 |
{recipt.value}
63 |
64 | 65 | ) : ( 66 | <> 67 | )} 68 |
69 |
70 |
71 |
72 | ); 73 | } 74 | -------------------------------------------------------------------------------- /client/src/components/Search.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { makeStyles } from '@material-ui/core/styles'; 3 | import Paper from '@material-ui/core/Paper'; 4 | import IconButton from '@material-ui/core/IconButton'; 5 | import SearchIcon from '@material-ui/icons/Search'; 6 | 7 | const useStyles = makeStyles((theme) => ({ 8 | root: { 9 | padding: '2px 10px', 10 | display: 'flex', 11 | margin:'20px auto', 12 | width: '40%', 13 | border:"2px solid #1a237e", 14 | borderRadius:50, 15 | boxShadow:"2px 2px 10px #9fa8da" 16 | 17 | }, 18 | input: { 19 | justifyContent:'center', 20 | flex: 1, 21 | outline:"none", 22 | border:"none", 23 | padding:0, 24 | borderRadius:40, 25 | fontSize: 17 26 | }, 27 | iconButton: { 28 | padding: 10, 29 | }, 30 | divider: { 31 | height: 28, 32 | margin: 4, 33 | }, 34 | })); 35 | 36 | export default function CustomizedInputBase(props) { 37 | const classes = useStyles(); 38 | const [search , setSearch] = React.useState(""); 39 | const onTextChage = async (e) =>{ 40 | setSearch(e.target.value); 41 | } 42 | 43 | return ( 44 | <> 45 | 46 | e.key === 'Enter' ? props.findProduct(search): onTextChage} 52 | /> 53 | props.findProduct(search)}> 54 | 55 | 56 | 57 | 58 | ); 59 | } -------------------------------------------------------------------------------- /client/src/components/Styles.js: -------------------------------------------------------------------------------- 1 | import { makeStyles } from "@material-ui/core/styles"; 2 | 3 | export const useStyles = makeStyles({ 4 | pageWrap: { 5 | textAlign: "center", 6 | color: "#1a237e", 7 | }, 8 | pageHeading: { 9 | textAlign: "center", 10 | margin: "10px auto", 11 | padding: 0, 12 | color: "#1a237e", 13 | }, 14 | 15 | TableRoot: { 16 | width: "100%", 17 | maxWidth: 1200, 18 | margin: "5px auto", 19 | border: "2px solid #1a237e", 20 | borderRadius: 10, 21 | boxShadow: "2px 2px 10px #9fa8da", 22 | }, 23 | TableContainer: { 24 | maxHeight: 600, 25 | borderRadius: 7, 26 | }, 27 | AddressCell: { 28 | maxWidth: 150, 29 | overflow: "hidden", 30 | textOverflow: "ellipsis", 31 | }, 32 | tableCount: { 33 | textAlign: "center", 34 | margin: "10px auto", 35 | padding: 0, 36 | color: "#1a237e", 37 | }, 38 | TableHead: { 39 | backgroundColor: "#1a237e !important", 40 | color: "#fff !important", 41 | }, 42 | TableCell: { 43 | color: "#1a237e !important", 44 | }, 45 | 46 | FormWrap: { 47 | maxWidth: 900, 48 | margin: "30px auto", 49 | padding: 20, 50 | borderRadius: 10, 51 | boxShadow: "2px 2px 10px #9fa8da", 52 | }, 53 | 54 | RoleForm: { 55 | display: "flex", 56 | alignItems: "center", 57 | margin: "20px auto", 58 | }, 59 | 60 | //Explorer 61 | Explorerroot: { 62 | padding: "2px 4px", 63 | margin: "10px", 64 | width: "100%", 65 | }, 66 | ProductPaper: { 67 | padding: 10, 68 | borderRadius: 10, 69 | boxShadow: "2px 2px 10px #9fa8da", 70 | border: "2px solid #1a237e", 71 | }, 72 | ExplorerdRow: { 73 | width: "100%", 74 | borderBottom: `0px solid #222`, 75 | display: "flex", 76 | justifyContent: "center", 77 | alignItems: "center", 78 | padding: 5, 79 | margin: "0 auto", 80 | fontWeight: 600, 81 | color: "#1a237e", 82 | }, 83 | TableRoot2: { 84 | width: "100%", 85 | maxWidth: 1300, 86 | margin: "5px auto", 87 | border: "2px solid #1a237e", 88 | borderRadius: 10, 89 | boxShadow: "2px 2px 10px #9fa8da", 90 | }, 91 | 92 | //Modal 93 | modal: { 94 | display: "flex", 95 | alignItems: "center", 96 | justifyContent: "center", 97 | }, 98 | paper: { 99 | backgroundColor: "#fff", 100 | padding: 15, 101 | outline: "none", 102 | width: "min(90%, 650px)", 103 | height: "80%", 104 | border: "2px solid #1a237e", 105 | borderRadius: 10, 106 | boxShadow: "2px 2px 10px #9fa8da", 107 | overflow: "scroll", 108 | }, 109 | Reciptpaper: { 110 | backgroundColor: "#fff", 111 | border: "0px solid #000", 112 | padding: 15, 113 | outline: "none", 114 | width: "min(95%, 950px)", 115 | height: "500px", 116 | border: "2px solid #1a237e", 117 | borderRadius: 10, 118 | boxShadow: "2px 2px 10px #9fa8da", 119 | overflow: "scroll", 120 | }, 121 | dRow: { 122 | width: "100%", 123 | borderBottom: `1px solid #222`, 124 | display: "flex", 125 | justifyContent: "center", 126 | alignItems: "center", 127 | padding: 10, 128 | margin: "0 auto", 129 | }, 130 | 131 | dCol1: { 132 | width: "30%", 133 | textAlign: "left", 134 | fontWeight: 600, 135 | color: "#1a237e", 136 | }, 137 | dCol2: { 138 | width: "70%", 139 | textAlign: "left", 140 | fontWeight: 600, 141 | color: "#1a237e", 142 | overflow: "hidden", 143 | textOverflow: "ellipsis", 144 | }, 145 | 146 | //Home 147 | HomeBtn: { 148 | margin: 10, 149 | }, 150 | HomeCardWrap: { 151 | maxWidth: 500, 152 | width: "90%", 153 | padding: 20, 154 | borderRadius: 10, 155 | boxShadow: "2px 2px 10px #9fa8da", 156 | border: "2px solid #1a237e", 157 | margin: "10px auto", 158 | }, 159 | }); 160 | -------------------------------------------------------------------------------- /client/src/components/Theme.js: -------------------------------------------------------------------------------- 1 | import createMuiTheme from "@material-ui/core/styles/createMuiTheme"; 2 | 3 | const theme = createMuiTheme({ 4 | palette: { 5 | primary: { 6 | main: "#1a237e", 7 | }, 8 | secondary: { 9 | main: "#1a237e", 10 | }, 11 | 12 | }, 13 | }); 14 | 15 | export default theme; 16 | -------------------------------------------------------------------------------- /client/src/components/map.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Map, GoogleApiWrapper, Marker } from 'google-maps-react'; 3 | const mapStyles = { 4 | width: '95%', 5 | // height: '50%', 6 | 7 | borderRadius:"10px", 8 | // maxWidth:"400px", 9 | height: "350px", 10 | zIndex: "10 !important", 11 | border:"2px solid #1a237e", 12 | }; 13 | 14 | export class MapContainer extends Component { 15 | constructor(props) { 16 | super(props); 17 | // var point = []; 18 | // prodData.map((data) =>{ 19 | // point.push({latitude:data[0][7],longitude: data[0][7]}); 20 | 21 | // }); 22 | var points =[]; 23 | if(props.prodData[0][7].length !== 0) { points.push({latitude: props.prodData[0][7], longitude: props.prodData[0][6]})}; 24 | if(props.prodData[2][0].length !== 0) {points.push( {latitude: props.prodData[2][0], longitude: props.prodData[1][7]})}; 25 | if(props.prodData[2][3].length !== 0) {points.push({latitude: props.prodData[2][3], longitude: props.prodData[2][2]})}; 26 | 27 | this.state = { 28 | stores: points 29 | } 30 | } 31 | 32 | displayMarkers = () => { 33 | return this.state.stores.map((store, index) => { 34 | return console.log("You clicked me!")} /> 39 | }) 40 | } 41 | 42 | render() { 43 | return ( 44 | 50 | {this.displayMarkers()} 51 | 52 | ); 53 | } 54 | } 55 | 56 | MapContainer = GoogleApiWrapper({ 57 | apiKey: process.env.REACT_APP_GOOGLE_MAP_API_KEY 58 | })(MapContainer); -------------------------------------------------------------------------------- /client/src/context/RoleDataContext.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createContext, useState } from "react"; 3 | 4 | const RoleDataContext = createContext(null); 5 | 6 | export const RoleDataContextProvider = ({ mRole, tpRole, dhRole, cRole, children }) => { 7 | 8 | const [roles, setRoles] = useState({ 9 | manufacturer : mRole, 10 | thirdparty : tpRole, 11 | deliveryhub : dhRole, 12 | customer : cRole 13 | }); 14 | 15 | return ( 16 | 17 | {children} 18 | 19 | ); 20 | }; 21 | 22 | export const useRole = () => React.useContext(RoleDataContext); 23 | -------------------------------------------------------------------------------- /client/src/getWeb3.js: -------------------------------------------------------------------------------- 1 | import Web3 from "web3"; 2 | 3 | 4 | const getWeb3 = () => 5 | new Promise((resolve, reject) => { 6 | // Wait for loading completion to avoid race conditions with web3 injection timing. 7 | window.addEventListener("load", async () => { 8 | // Modern dapp browsers... 9 | if (window.ethereum) { 10 | const web3 = new Web3(window.ethereum); 11 | try { 12 | // Request account access if needed 13 | await window.ethereum.enable(); 14 | // Acccounts now exposed 15 | resolve(web3); 16 | } catch (error) { 17 | reject(error); 18 | } 19 | } 20 | // Legacy dapp browsers... 21 | else if (window.web3) { 22 | // Use Mist/MetaMask's provider. 23 | const web3 = window.web3; 24 | console.log("Injected web3 detected."); 25 | resolve(web3); 26 | } 27 | // Fallback to localhost; use dev console port by default... 28 | else { 29 | const provider = new Web3.providers.HttpProvider( 30 | process.env.REACT_APP_RPC 31 | ); 32 | const web3 = new Web3(provider); 33 | 34 | console.log("No web3 instance injected, using Local web3."); 35 | resolve(web3); 36 | } 37 | }); 38 | }); 39 | 40 | export default getWeb3; 41 | -------------------------------------------------------------------------------- /client/src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 4 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 5 | sans-serif; 6 | -webkit-font-smoothing: antialiased; 7 | -moz-osx-font-smoothing: grayscale; 8 | } 9 | 10 | code { 11 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 12 | monospace; 13 | } 14 | -------------------------------------------------------------------------------- /client/src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | 9 | // If you want your app to work offline and load faster, you can change 10 | // unregister() to register() below. Note this comes with some pitfalls. 11 | // Learn more about service workers: https://bit.ly/CRA-PWA 12 | serviceWorker.unregister(); 13 | -------------------------------------------------------------------------------- /client/src/logo.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/src/pages/Customer/PurchaseCustomer.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Navbar from "../../components/Navbar"; 3 | import Button from "@material-ui/core/Button"; 4 | import { useRole } from "../../context/RoleDataContext"; 5 | import Table from "@material-ui/core/Table"; 6 | import TableBody from "@material-ui/core/TableBody"; 7 | import TableCell from "@material-ui/core/TableCell"; 8 | import TableContainer from "@material-ui/core/TableContainer"; 9 | import TableHead from "@material-ui/core/TableHead"; 10 | import TableRow from "@material-ui/core/TableRow"; 11 | import Paper from "@material-ui/core/Paper"; 12 | import TablePagination from "@material-ui/core/TablePagination"; 13 | import { useStyles } from "../../components/Styles"; 14 | import ProductModal from "../../components/Modal"; 15 | import clsx from "clsx"; 16 | import Loader from "../../components/Loader"; 17 | 18 | export default function PurchaseCustomer(props) { 19 | const classes = useStyles(); 20 | const supplyChainContract = props.supplyChainContract; 21 | const { roles } = useRole(); 22 | const [count, setCount] = React.useState(0); 23 | const [allProducts, setAllProducts] = React.useState([]); 24 | const [loading, setLoading] = React.useState(false); 25 | const navItem = [ 26 | ["Purchase Product", "/Customer/buy"], 27 | ["Receive Product", "/Customer/receive"], 28 | ["Your Products", "/Customer/allReceived"], 29 | ]; 30 | React.useEffect(() => { 31 | (async () => { 32 | setLoading(true); 33 | const cnt = await supplyChainContract.methods.fetchProductCount().call(); 34 | setCount(cnt); 35 | })(); 36 | 37 | (async () => { 38 | const arr = []; 39 | for (var i = 1; i < count; i++) { 40 | const prodState = await supplyChainContract.methods 41 | .fetchProductState(i) 42 | .call(); 43 | 44 | if (prodState === "3") { 45 | const prodData = []; 46 | const a = await supplyChainContract.methods 47 | .fetchProductPart1(i, "product", 0) 48 | .call(); 49 | const b = await supplyChainContract.methods 50 | .fetchProductPart2(i, "product", 0) 51 | .call(); 52 | const c = await supplyChainContract.methods 53 | .fetchProductPart3(i, "product", 0) 54 | .call(); 55 | prodData.push(a); 56 | prodData.push(b); 57 | prodData.push(c); 58 | arr.push(prodData); 59 | } 60 | } 61 | setAllProducts(arr); 62 | setLoading(false); 63 | })(); 64 | }, [count]); 65 | const [page, setPage] = React.useState(0); 66 | const [rowsPerPage, setRowsPerPage] = React.useState(10); 67 | 68 | const handleChangePage = (event, newPage) => { 69 | setPage(newPage); 70 | }; 71 | 72 | const handleChangeRowsPerPage = (event) => { 73 | setRowsPerPage(+event.target.value); 74 | setPage(0); 75 | }; 76 | 77 | const [open, setOpen] = React.useState(false); 78 | const [modalData, setModalData] = React.useState([]); 79 | 80 | const handleClose = () => setOpen(false); 81 | 82 | const handleClick = async (prod) => { 83 | await setModalData(prod); 84 | setOpen(true); 85 | }; 86 | 87 | const handleBuyButton = async (id) => { 88 | await supplyChainContract.methods 89 | .purchaseByCustomer(id) 90 | .send({ from: roles.customer, gas: 1000000 }) 91 | .on("transactionHash", function (hash) { 92 | handleSetTxhash(id, hash); 93 | }); 94 | setCount(0); 95 | }; 96 | 97 | const handleSetTxhash = async (id, hash) => { 98 | await supplyChainContract.methods 99 | .setTransactionHash(id, hash) 100 | .send({ from: roles.manufacturer, gas: 900000 }); 101 | }; 102 | 103 | return ( 104 | <> 105 |
106 | 107 | {loading ? ( 108 | 109 | ) : ( 110 | <> 111 | 116 | 117 |

Purchase Products

118 |

119 | Total : {allProducts.length} 120 |

121 | 122 |
123 | 124 | 125 | 126 | 127 | 128 | 129 | Universal ID 130 | 131 | 135 | Product Code 136 | 137 | 141 | Manufacturer 142 | 143 | 147 | Manufacture Date 148 | 149 | 153 | Product Name 154 | 155 | 162 | Owner 163 | 164 | 168 | Buy 169 | 170 | 171 | 172 | 173 | {allProducts.length !== 0 ? ( 174 | allProducts 175 | .slice( 176 | page * rowsPerPage, 177 | page * rowsPerPage + rowsPerPage 178 | ) 179 | .map((prod) => { 180 | const d = new Date(parseInt(prod[1][0] * 1000)); 181 | return ( 182 | <> 183 | 189 | handleClick(prod)} 195 | > 196 | {prod[0][0]} 197 | 198 | handleClick(prod)} 202 | > 203 | {prod[1][2]} 204 | 205 | handleClick(prod)} 209 | > 210 | {prod[0][4]} 211 | 212 | handleClick(prod)} 215 | > 216 | {d.toDateString() + 217 | " " + 218 | d.toTimeString()} 219 | 220 | handleClick(prod)} 224 | > 225 | {prod[1][1]} 226 | 227 | handleClick(prod)} 234 | > 235 | {prod[0][2]} 236 | 237 | 241 | 251 | 252 | 253 | 254 | ); 255 | }) 256 | ) : ( 257 | <> 258 | )} 259 | 260 |
261 |
262 | 271 |
272 |
273 | 274 | )} 275 |
276 |
277 | 278 | ); 279 | } 280 | -------------------------------------------------------------------------------- /client/src/pages/Customer/ReceiveCustomer.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import Navbar from "../../components/Navbar"; 3 | import Button from "@material-ui/core/Button"; 4 | import ProductModal from "../../components/Modal"; 5 | import { useRole } from "../../context/RoleDataContext"; 6 | import Table from "@material-ui/core/Table"; 7 | import TableBody from "@material-ui/core/TableBody"; 8 | import TableCell from "@material-ui/core/TableCell"; 9 | import TableContainer from "@material-ui/core/TableContainer"; 10 | import TableHead from "@material-ui/core/TableHead"; 11 | import TableRow from "@material-ui/core/TableRow"; 12 | import Paper from "@material-ui/core/Paper"; 13 | import TablePagination from "@material-ui/core/TablePagination"; 14 | import { useStyles } from "../../components/Styles"; 15 | import clsx from "clsx"; 16 | import Loader from "../../components/Loader"; 17 | 18 | export default function ReceiveCustomer(props) { 19 | const supplyChainContract = props.supplyChainContract; 20 | const { roles } = useRole(); 21 | const [count, setCount] = React.useState(0); 22 | const [allReceiveProducts, setAllReceiveProducts] = React.useState([]); 23 | const [modalData, setModalData] = useState([]); 24 | const [open, setOpen] = useState(false); 25 | const classes = useStyles(); 26 | const [loading, setLoading] = React.useState(false); 27 | const navItem = [ 28 | ["Purchase Product", "/Customer/buy"], 29 | ["Receive Product", "/Customer/receive"], 30 | ["Your Products", "/Customer/allReceived"], 31 | ]; 32 | const [alertText, setalertText] = React.useState(""); 33 | React.useEffect(() => { 34 | (async () => { 35 | setLoading(true); 36 | const cnt = await supplyChainContract.methods.fetchProductCount().call(); 37 | setCount(cnt); 38 | })(); 39 | 40 | (async () => { 41 | const arr = []; 42 | for (var i = 1; i < count; i++) { 43 | const prodState = await supplyChainContract.methods 44 | .fetchProductState(i) 45 | .call(); 46 | 47 | if (prodState === "7") { 48 | const prodData = []; 49 | const a = await supplyChainContract.methods 50 | .fetchProductPart1(i, "product", 0) 51 | .call(); 52 | const b = await supplyChainContract.methods 53 | .fetchProductPart2(i, "product", 0) 54 | .call(); 55 | const c = await supplyChainContract.methods 56 | .fetchProductPart3(i, "product", 0) 57 | .call(); 58 | prodData.push(a); 59 | prodData.push(b); 60 | prodData.push(c); 61 | arr.push(prodData); 62 | } 63 | } 64 | setAllReceiveProducts(arr); 65 | setLoading(false); 66 | })(); 67 | }, [count]); 68 | 69 | const handleReceiveButton = async (id) => { 70 | try{ 71 | await supplyChainContract.methods 72 | .receiveByCustomer(parseInt(id)) 73 | .send({ from: roles.customer, gas: 1000000 }) 74 | .on("transactionHash", function (hash) { 75 | handleSetTxhash(id, hash); 76 | }); 77 | setCount(0); 78 | setOpen(false); 79 | }catch{ 80 | setalertText("You are not the owner of the Product"); 81 | } 82 | 83 | }; 84 | 85 | const handleSetTxhash = async (id, hash) => { 86 | await supplyChainContract.methods 87 | .setTransactionHash(id, hash) 88 | .send({ from: roles.manufacturer, gas: 900000 }); 89 | }; 90 | 91 | const [page, setPage] = React.useState(0); 92 | const [rowsPerPage, setRowsPerPage] = React.useState(10); 93 | 94 | const handleChangePage = (event, newPage) => { 95 | setPage(newPage); 96 | }; 97 | 98 | const handleChangeRowsPerPage = (event) => { 99 | setRowsPerPage(+event.target.value); 100 | setPage(0); 101 | }; 102 | 103 | const handleClose = () => setOpen(false); 104 | 105 | const handleClick = async (prod) => { 106 | await setModalData(prod); 107 | setOpen(true); 108 | }; 109 | 110 | return ( 111 |
112 | 113 | {loading ? ( 114 | 115 | ) : ( 116 | <> 117 | 124 | 125 |

Products to be Received

126 |

127 | Total : {allReceiveProducts.length} 128 |

129 | 130 |
131 | 132 | 133 | 134 | 135 | 136 | 137 | Universal ID 138 | 139 | 140 | Product Code 141 | 142 | 143 | Manufacturer 144 | 145 | 146 | Manufacture Date 147 | 148 | 149 | Product Name 150 | 151 | 158 | Owner 159 | 160 | 164 | RECEIVE 165 | 166 | 167 | 168 | 169 | {allReceiveProducts.length !== 0 ? ( 170 | allReceiveProducts 171 | .slice( 172 | page * rowsPerPage, 173 | page * rowsPerPage + rowsPerPage 174 | ) 175 | .map((prod) => { 176 | const d = new Date(parseInt(prod[1][0] * 1000)); 177 | return ( 178 | <> 179 | 185 | handleClick(prod)} 191 | > 192 | {prod[0][0]} 193 | 194 | handleClick(prod)} 198 | > 199 | {prod[1][2]} 200 | 201 | handleClick(prod)} 205 | > 206 | {prod[0][4]} 207 | 208 | handleClick(prod)} 211 | > 212 | {d.toDateString() + " " + d.toTimeString()} 213 | 214 | handleClick(prod)} 218 | > 219 | {prod[1][1]} 220 | 221 | handleClick(prod)} 228 | > 229 | {prod[0][2]} 230 | 231 | 235 | 243 | 244 | 245 | 246 | ); 247 | }) 248 | ) : ( 249 | <> 250 | )} 251 | 252 |
253 |
254 | 263 |
264 |
265 | 266 | {/* {allReceiveProducts.length !== 0 ? (allReceiveProducts.map((prod) => ( 267 | <> 268 |
269 |

Universal ID : {prod[0][0]}

270 |

SKU : {prod[0][1]}

271 |

Owner : {prod[0][2]}

272 |

Manufacturer : {prod[0][3]}

273 |

Name of Manufacturer : {prod[0][4]}

274 |

Details of Manufacturer : {prod[0][5]}

275 |

Longitude of Manufature : {prod[0][6]}

276 |

Latitude of Manufature : {prod[0][7]}

277 | 278 |

Manufactured date : {prod[1][0]}

279 | 287 |
288 | 289 | 290 | ))) : <> } */} 291 | 292 | )} 293 |
294 |
295 | ); 296 | } 297 | -------------------------------------------------------------------------------- /client/src/pages/Customer/ReceivedByCustomer.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Navbar from "../../components/Navbar"; 3 | import Table from "@material-ui/core/Table"; 4 | import TableBody from "@material-ui/core/TableBody"; 5 | import TableCell from "@material-ui/core/TableCell"; 6 | import TableContainer from "@material-ui/core/TableContainer"; 7 | import TableHead from "@material-ui/core/TableHead"; 8 | import TableRow from "@material-ui/core/TableRow"; 9 | import Paper from "@material-ui/core/Paper"; 10 | import TablePagination from "@material-ui/core/TablePagination"; 11 | import { useStyles } from "../../components/Styles"; 12 | import ProductModal from "../../components/Modal"; 13 | import clsx from "clsx"; 14 | import Loader from "../../components/Loader"; 15 | 16 | export default function ReceivedByCustomer(props) { 17 | const classes = useStyles(); 18 | const supplyChainContract = props.supplyChainContract; 19 | const [count, setCount] = React.useState(0); 20 | const [allReceived, setAllReceived] = React.useState([]); 21 | const [loading, setLoading] = React.useState(false); 22 | const navItem = [ 23 | ["Purchase Product", "/Customer/buy"], 24 | ["Receive Product", "/Customer/receive"], 25 | ["Your Products", "/Customer/allReceived"], 26 | ]; 27 | React.useEffect(() => { 28 | (async () => { 29 | setLoading(true); 30 | const cnt = await supplyChainContract.methods.fetchProductCount().call(); 31 | setCount(cnt); 32 | })(); 33 | 34 | (async () => { 35 | const arr = []; 36 | for (var i = 1; i < count; i++) { 37 | const prodState = await supplyChainContract.methods 38 | .fetchProductState(i) 39 | .call(); 40 | 41 | if (prodState === "8") { 42 | const prodData = []; 43 | const a = await supplyChainContract.methods 44 | .fetchProductPart1(i, "product", 0) 45 | .call(); 46 | const b = await supplyChainContract.methods 47 | .fetchProductPart2(i, "product", 0) 48 | .call(); 49 | const c = await supplyChainContract.methods 50 | .fetchProductPart3(i, "product", 0) 51 | .call(); 52 | prodData.push(a); 53 | prodData.push(b); 54 | prodData.push(c); 55 | arr.push(prodData); 56 | } 57 | } 58 | setAllReceived(arr); 59 | setLoading(false); 60 | })(); 61 | }, [count]); 62 | 63 | const [page, setPage] = React.useState(0); 64 | const [rowsPerPage, setRowsPerPage] = React.useState(10); 65 | 66 | const handleChangePage = (event, newPage) => { 67 | setPage(newPage); 68 | }; 69 | 70 | const handleChangeRowsPerPage = (event) => { 71 | setRowsPerPage(+event.target.value); 72 | setPage(0); 73 | }; 74 | 75 | const [open, setOpen] = React.useState(false); 76 | const [modalData, setModalData] = React.useState([]); 77 | 78 | const handleClose = () => setOpen(false); 79 | 80 | const handleClick = async (prod) => { 81 | await setModalData(prod); 82 | setOpen(true); 83 | }; 84 | 85 | return ( 86 | <> 87 |
88 | 89 | {loading ? ( 90 | 91 | ) : ( 92 | <> 93 | 98 |

Your Products

99 |

100 | Total : {allReceived.length} 101 |

102 | <> 103 |
104 | 105 | 106 | 107 | 108 | 109 | 113 | Universal ID 114 | 115 | 119 | Product Code 120 | 121 | 125 | Manufacturer 126 | 127 | 131 | Manufacture Date 132 | 133 | 137 | Product Name 138 | 139 | 146 | Owner 147 | 148 | 149 | 150 | 151 | {allReceived.length !== 0 ? ( 152 | allReceived 153 | .slice( 154 | page * rowsPerPage, 155 | page * rowsPerPage + rowsPerPage 156 | ) 157 | .map((prod) => { 158 | const d = new Date(parseInt(prod[1][0] * 1000)); 159 | return ( 160 | handleClick(prod)} 166 | > 167 | 173 | {prod[0][0]} 174 | 175 | 179 | {prod[1][2]} 180 | 181 | 185 | {prod[0][4]} 186 | 187 | 188 | {d.toDateString() + 189 | " " + 190 | d.toTimeString()} 191 | 192 | 196 | {prod[1][1]} 197 | 198 | 205 | {prod[0][2]} 206 | 207 | 208 | ); 209 | }) 210 | ) : ( 211 | <> 212 | )} 213 | 214 |
215 |
216 | 225 |
226 |
227 | 228 | 229 | )} 230 |
231 |
232 | 233 | ); 234 | } 235 | -------------------------------------------------------------------------------- /client/src/pages/DeliveryHub/ReceiveDeliveryHub.js: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import Navbar from "../../components/Navbar"; 3 | import Button from "@material-ui/core/Button"; 4 | import ProductModal from "../../components/Modal"; 5 | import { useRole } from "../../context/RoleDataContext"; 6 | import Table from "@material-ui/core/Table"; 7 | import TableBody from "@material-ui/core/TableBody"; 8 | import TableCell from "@material-ui/core/TableCell"; 9 | import TableContainer from "@material-ui/core/TableContainer"; 10 | import TableHead from "@material-ui/core/TableHead"; 11 | import TableRow from "@material-ui/core/TableRow"; 12 | import Paper from "@material-ui/core/Paper"; 13 | import TablePagination from "@material-ui/core/TablePagination"; 14 | import { useStyles } from "../../components/Styles"; 15 | import clsx from "clsx"; 16 | import Loader from "../../components/Loader"; 17 | 18 | export default function ReceiveDeliveryHub(props) { 19 | const supplyChainContract = props.supplyChainContract; 20 | const { roles } = useRole(); 21 | const [count, setCount] = React.useState(0); 22 | const [allReceiveProducts, setAllReceiveProducts] = React.useState([]); 23 | const [modalData, setModalData] = useState([]); 24 | const [open, setOpen] = useState(false); 25 | const classes = useStyles(); 26 | const [loading, setLoading] = React.useState(false); 27 | const navItem = [ 28 | ["Receive Product", "/DeliveryHub/receive"], 29 | ["Ship Product", "/DeliveryHub/ship"], 30 | ]; 31 | const [alertText, setalertText] = React.useState(""); 32 | React.useEffect(() => { 33 | (async () => { 34 | setLoading(true); 35 | const cnt = await supplyChainContract.methods.fetchProductCount().call(); 36 | setCount(cnt); 37 | })(); 38 | 39 | (async () => { 40 | const arr = []; 41 | for (var i = 1; i < count; i++) { 42 | const prodState = await supplyChainContract.methods 43 | .fetchProductState(i) 44 | .call(); 45 | 46 | if (prodState === "5") { 47 | const prodData = []; 48 | const a = await supplyChainContract.methods 49 | .fetchProductPart1(i, "product", 0) 50 | .call(); 51 | const b = await supplyChainContract.methods 52 | .fetchProductPart2(i, "product", 0) 53 | .call(); 54 | const c = await supplyChainContract.methods 55 | .fetchProductPart3(i, "product", 0) 56 | .call(); 57 | prodData.push(a); 58 | prodData.push(b); 59 | prodData.push(c); 60 | arr.push(prodData); 61 | } 62 | } 63 | setAllReceiveProducts(arr); 64 | setLoading(false); 65 | })(); 66 | }, [count]); 67 | 68 | const handleSetTxhash = async (id, hash) => { 69 | await supplyChainContract.methods 70 | .setTransactionHash(id, hash) 71 | .send({ from: roles.manufacturer, gas: 900000 }); 72 | }; 73 | 74 | const handleReceiveButton = async (id, long, lat) => { 75 | try{ 76 | await supplyChainContract.methods 77 | .receiveByDeliveryHub(parseInt(id), long, lat) 78 | .send({ from: roles.deliveryhub, gas: 1000000 }) 79 | .on("transactionHash", function (hash) { 80 | handleSetTxhash(id, hash); 81 | }); 82 | setCount(0); 83 | setOpen(false); 84 | }catch{ 85 | setalertText("You are not the owner of the Product"); 86 | } 87 | 88 | }; 89 | 90 | const [page, setPage] = React.useState(0); 91 | const [rowsPerPage, setRowsPerPage] = React.useState(10); 92 | 93 | const handleChangePage = (event, newPage) => { 94 | setPage(newPage); 95 | }; 96 | 97 | const handleChangeRowsPerPage = (event) => { 98 | setRowsPerPage(+event.target.value); 99 | setPage(0); 100 | }; 101 | 102 | const handleClose = () => setOpen(false); 103 | 104 | const handleClick = async (prod) => { 105 | await setModalData(prod); 106 | 107 | setOpen(true); 108 | }; 109 | 110 | return ( 111 |
112 | 113 | {loading ? ( 114 | 115 | ) : ( 116 | <> 117 | 124 | 125 |

Products To be Received

126 |

127 | Total : {allReceiveProducts.length} 128 |

129 | 130 |
131 | 132 | 133 | 134 | 135 | 136 | 137 | Universal ID 138 | 139 | 140 | Product Code 141 | 142 | 143 | Manufacturer 144 | 145 | 146 | Manufacture Date 147 | 148 | 149 | Product Name 150 | 151 | 158 | Owner 159 | 160 | 164 | RECEIVE 165 | 166 | 167 | 168 | 169 | {allReceiveProducts.length !== 0 ? ( 170 | allReceiveProducts 171 | .slice( 172 | page * rowsPerPage, 173 | page * rowsPerPage + rowsPerPage 174 | ) 175 | .map((prod) => { 176 | const d = new Date(parseInt(prod[1][0] * 1000)); 177 | return ( 178 | <> 179 | 185 | handleClick(prod)} 191 | > 192 | {prod[0][0]} 193 | 194 | handleClick(prod)} 198 | > 199 | {prod[1][2]} 200 | 201 | handleClick(prod)} 205 | > 206 | {prod[0][4]} 207 | 208 | handleClick(prod)} 211 | > 212 | {d.toDateString() + " " + d.toTimeString()} 213 | 214 | handleClick(prod)} 218 | > 219 | {prod[1][1]} 220 | 221 | handleClick(prod)} 228 | > 229 | {prod[0][2]} 230 | 231 | 235 | 243 | 244 | 245 | 246 | ); 247 | }) 248 | ) : ( 249 | <> 250 | )} 251 | 252 |
253 |
254 | 263 |
264 |
265 | 266 | {/* {allReceiveProducts.length !== 0 ? (allReceiveProducts.map((prod) => ( 267 | <> 268 |
269 |

Universal ID : {prod[0][0]}

270 |

SKU : {prod[0][1]}

271 |

Owner : {prod[0][2]}

272 |

Manufacturer : {prod[0][3]}

273 |

Name of Manufacturer : {prod[0][4]}

274 |

Details of Manufacturer : {prod[0][5]}

275 |

Longitude of Manufature : {prod[0][6]}

276 |

Latitude of Manufature : {prod[0][7]}

277 | 278 |

Manufactured date : {prod[1][0]}

279 | 287 |
288 | 289 | 290 | ))) : <> } */} 291 | 292 | )} 293 |
294 |
295 | ); 296 | } 297 | -------------------------------------------------------------------------------- /client/src/pages/DeliveryHub/ShipDeliveryHub.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Navbar from "../../components/Navbar"; 3 | import Button from "@material-ui/core/Button"; 4 | import { useRole } from "../../context/RoleDataContext"; 5 | import Table from "@material-ui/core/Table"; 6 | import TableBody from "@material-ui/core/TableBody"; 7 | import TableCell from "@material-ui/core/TableCell"; 8 | import TableContainer from "@material-ui/core/TableContainer"; 9 | import TableHead from "@material-ui/core/TableHead"; 10 | import TableRow from "@material-ui/core/TableRow"; 11 | import Paper from "@material-ui/core/Paper"; 12 | import TablePagination from "@material-ui/core/TablePagination"; 13 | import { useStyles } from "../../components/Styles"; 14 | import ProductModal from "../../components/Modal"; 15 | import clsx from "clsx"; 16 | import Loader from "../../components/Loader"; 17 | 18 | export default function ShipDeliveryHub(props) { 19 | const classes = useStyles(); 20 | const supplyChainContract = props.supplyChainContract; 21 | const { roles } = useRole(); 22 | const [count, setCount] = React.useState(0); 23 | const [allSoldProducts, setAllSoldProducts] = React.useState([]); 24 | const [loading, setLoading] = React.useState(false); 25 | const navItem = [ 26 | ["Receive Product", "/DeliveryHub/receive"], 27 | ["Ship Product", "/DeliveryHub/ship"], 28 | ]; 29 | const [alertText, setalertText] = React.useState(""); 30 | React.useEffect(() => { 31 | (async () => { 32 | setLoading(true); 33 | const cnt = await supplyChainContract.methods.fetchProductCount().call(); 34 | setCount(cnt); 35 | })(); 36 | 37 | (async () => { 38 | const arr = []; 39 | for (var i = 1; i < count; i++) { 40 | const prodState = await supplyChainContract.methods 41 | .fetchProductState(i) 42 | .call(); 43 | 44 | if (prodState === "6") { 45 | const prodData = []; 46 | const a = await supplyChainContract.methods 47 | .fetchProductPart1(i, "product", 0) 48 | .call(); 49 | const b = await supplyChainContract.methods 50 | .fetchProductPart2(i, "product", 0) 51 | .call(); 52 | const c = await supplyChainContract.methods 53 | .fetchProductPart3(i, "product", 0) 54 | .call(); 55 | prodData.push(a); 56 | prodData.push(b); 57 | prodData.push(c); 58 | arr.push(prodData); 59 | } 60 | } 61 | setAllSoldProducts(arr); 62 | setLoading(false); 63 | })(); 64 | }, [count]); 65 | 66 | const handleSetTxhash = async (id, hash) => { 67 | await supplyChainContract.methods 68 | .setTransactionHash(id, hash) 69 | .send({ from: roles.manufacturer, gas: 900000 }); 70 | }; 71 | 72 | const handleShipButton = async (id) => { 73 | try{ 74 | await supplyChainContract.methods 75 | .shipByDeliveryHub(id) 76 | .send({ from: roles.deliveryhub, gas: 1000000 }) 77 | .on("transactionHash", function (hash) { 78 | handleSetTxhash(id, hash); 79 | }); 80 | setCount(0); 81 | }catch{ 82 | setalertText("You are not the owner of the Product"); 83 | } 84 | }; 85 | const [page, setPage] = React.useState(0); 86 | const [rowsPerPage, setRowsPerPage] = React.useState(10); 87 | 88 | const handleChangePage = (event, newPage) => { 89 | setPage(newPage); 90 | }; 91 | 92 | const handleChangeRowsPerPage = (event) => { 93 | setRowsPerPage(+event.target.value); 94 | setPage(0); 95 | }; 96 | 97 | const [open, setOpen] = React.useState(false); 98 | const [modalData, setModalData] = React.useState([]); 99 | 100 | const handleClose = () => setOpen(false); 101 | 102 | const handleClick = async (prod) => { 103 | await setModalData(prod); 104 | setOpen(true); 105 | }; 106 | 107 | return ( 108 | <> 109 |
110 | 111 | {loading ? ( 112 | 113 | ) : ( 114 | <> 115 | 120 |

Products To be Shipped

121 |

122 | Total : {allSoldProducts.length} 123 |

124 | 125 |
126 |

{alertText.length !== 0 ? alertText : ""}

127 | 128 | 129 | 130 | 131 | 132 | 133 | Universal ID 134 | 135 | 139 | Product Code 140 | 141 | 145 | Manufacturer 146 | 147 | 151 | Manufacture Date 152 | 153 | 157 | Product Name 158 | 159 | 166 | Owner 167 | 168 | 172 | Ship 173 | 174 | 175 | 176 | 177 | {allSoldProducts.length !== 0 ? ( 178 | allSoldProducts 179 | .slice( 180 | page * rowsPerPage, 181 | page * rowsPerPage + rowsPerPage 182 | ) 183 | .map((prod) => { 184 | const d = new Date(parseInt(prod[1][0] * 1000)); 185 | return ( 186 | <> 187 | 193 | handleClick(prod)} 199 | > 200 | {prod[0][0]} 201 | 202 | handleClick(prod)} 206 | > 207 | {prod[1][2]} 208 | 209 | handleClick(prod)} 213 | > 214 | {prod[0][4]} 215 | 216 | handleClick(prod)} 219 | > 220 | {d.toDateString() + 221 | " " + 222 | d.toTimeString()} 223 | 224 | handleClick(prod)} 228 | > 229 | {prod[1][1]} 230 | 231 | handleClick(prod)} 238 | > 239 | {prod[0][2]} 240 | 241 | 245 | 255 | 256 | 257 | 258 | ); 259 | }) 260 | ) : ( 261 | <> 262 | )} 263 | 264 |
265 |
266 | 275 |
276 |
277 | 278 | )} 279 |
280 |
281 | 282 | ); 283 | } 284 | -------------------------------------------------------------------------------- /client/src/pages/Home.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Navbar from "../components/Navbar"; 3 | import Button from "@material-ui/core/Button"; 4 | import { useStyles } from "../components/Styles"; 5 | import Grid from "@material-ui/core/Grid"; 6 | import { Link } from "react-router-dom"; 7 | 8 | export default function Home() { 9 | const classes = useStyles(); 10 | const navItem = []; 11 | 12 | return ( 13 | <> 14 |
15 | 16 | 21 | 34 | . 39 | 40 | 41 | 55 |
56 |

Assign Roles

57 | 61 | 69 | 70 |
71 | 72 |

Visit As

73 | 77 | 85 | 86 | 90 | 98 | 99 | 103 | 111 | 112 | 116 | 124 | 125 |
126 |
127 |
128 |
129 |
130 | 131 | ); 132 | } 133 | -------------------------------------------------------------------------------- /client/src/pages/Manufacturer/AllManufacture.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Navbar from "../../components/Navbar"; 3 | import Table from "@material-ui/core/Table"; 4 | import TableBody from "@material-ui/core/TableBody"; 5 | import TableCell from "@material-ui/core/TableCell"; 6 | import TableContainer from "@material-ui/core/TableContainer"; 7 | import TableHead from "@material-ui/core/TableHead"; 8 | import TableRow from "@material-ui/core/TableRow"; 9 | import Paper from "@material-ui/core/Paper"; 10 | import TablePagination from "@material-ui/core/TablePagination"; 11 | import { useStyles } from "../../components/Styles"; 12 | import ProductModal from "../../components/Modal"; 13 | import clsx from "clsx"; 14 | import Loader from "../../components/Loader"; 15 | 16 | export default function AllManufacture(props) { 17 | const supplyChainContract = props.supplyChainContract; 18 | const classes = useStyles(); 19 | const [count, setCount] = React.useState(0); 20 | const [allManufacture, setAllManufacture] = React.useState([]); 21 | const [loading, setLoading] = React.useState(false); 22 | const navItem = [ 23 | ["Add Product", "/manufacturer/manufacture"], 24 | ["Ship Product", "/manufacturer/ship"], 25 | ["All Products", "/manufacturer/allManufacture"], 26 | ]; 27 | React.useEffect(() => { 28 | setLoading(true); 29 | (async () => { 30 | setLoading(true); 31 | const cnt = await supplyChainContract.methods.fetchProductCount().call(); 32 | setCount(cnt); 33 | })(); 34 | 35 | (async () => { 36 | const arr = []; 37 | for (var i = 1; i < count; i++) { 38 | const prodState = await supplyChainContract.methods 39 | .fetchProductState(i) 40 | .call(); 41 | 42 | if (prodState === "0") { 43 | const prodData = []; 44 | const a = await supplyChainContract.methods 45 | .fetchProductPart1(i, "product", 0) 46 | .call(); 47 | const b = await supplyChainContract.methods 48 | .fetchProductPart2(i, "product", 0) 49 | .call(); 50 | const c = await supplyChainContract.methods 51 | .fetchProductPart3(i, "product", 0) 52 | .call(); 53 | prodData.push(a); 54 | prodData.push(b); 55 | prodData.push(c); 56 | arr.push(prodData); 57 | } 58 | } 59 | setAllManufacture(arr); 60 | setLoading(false); 61 | })(); 62 | }, [count]); 63 | 64 | const [page, setPage] = React.useState(0); 65 | const [rowsPerPage, setRowsPerPage] = React.useState(10); 66 | 67 | const handleChangePage = (event, newPage) => { 68 | setPage(newPage); 69 | }; 70 | 71 | const handleChangeRowsPerPage = (event) => { 72 | setRowsPerPage(+event.target.value); 73 | setPage(0); 74 | }; 75 | 76 | const [open, setOpen] = React.useState(false); 77 | const [modalData, setModalData] = React.useState([]); 78 | 79 | const handleClose = () => setOpen(false); 80 | 81 | const handleClick = async (prod) => { 82 | await setModalData(prod); 83 | setOpen(true); 84 | }; 85 | 86 | return ( 87 |
88 | 89 | {loading ? ( 90 | 91 | ) : ( 92 |
93 | 98 |

Manufactured Products

99 |

100 | Total : {allManufacture.length} 101 |

102 | <> 103 |
104 | 105 | 106 | 107 | 108 | 109 | 110 | Universal ID 111 | 112 | 116 | Product Code 117 | 118 | 122 | Manufacturer 123 | 124 | 128 | Manufacture Date 129 | 130 | 134 | Product Name 135 | 136 | 143 | Owner 144 | 145 | 146 | 147 | 148 | {allManufacture.length !== 0 ? ( 149 | allManufacture 150 | .slice( 151 | page * rowsPerPage, 152 | page * rowsPerPage + rowsPerPage 153 | ) 154 | .map((prod) => { 155 | const d = new Date(parseInt(prod[1][0] * 1000)); 156 | return ( 157 | handleClick(prod)} 163 | > 164 | 170 | {prod[0][0]} 171 | 172 | 176 | {prod[1][2]} 177 | 178 | 182 | {prod[0][4]} 183 | 184 | 185 | {d.toDateString() + " " + d.toTimeString()} 186 | 187 | 191 | {prod[1][1]} 192 | 193 | 200 | {prod[0][2]} 201 | 202 | 203 | ); 204 | }) 205 | ) : ( 206 | <> 207 | )} 208 | 209 |
210 |
211 | 220 |
221 |
222 | 223 |
224 | )} 225 |
226 |
227 | ); 228 | } 229 | -------------------------------------------------------------------------------- /client/src/pages/Manufacturer/Manufacture.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import TextField from "@material-ui/core/TextField"; 3 | import Button from "@material-ui/core/Button"; 4 | import { useRole } from "../../context/RoleDataContext"; 5 | import Navbar from "../../components/Navbar"; 6 | import { useStyles } from "../../components/Styles"; 7 | import Grid from "@material-ui/core/Grid"; 8 | import Loader from "../../components/Loader"; 9 | 10 | export default function Manufacture(props) { 11 | const supplyChainContract = props.supplyChainContract; 12 | const classes = useStyles(); 13 | const { roles } = useRole(); 14 | const [loading, setLoading] = React.useState(false); 15 | const [fvalid, setfvalid] = React.useState(false); 16 | const navItem = [ 17 | ["Add Product", "/manufacturer/manufacture"], 18 | ["Ship Product", "/manufacturer/ship"], 19 | ["All Products", "/manufacturer/allManufacture"], 20 | ]; 21 | const [manuForm, setManuForm] = React.useState({ 22 | id: 0, 23 | manufacturerName: "", 24 | manufacturerDetails: "", 25 | manufacturerLongitude: "", 26 | manufacturerLatitude: "", 27 | productName: "", 28 | productCode: 0, 29 | productPrice: 0, 30 | productCategory: "", 31 | }); 32 | 33 | const handleChangeManufacturerForm = async (e) => { 34 | setManuForm({ 35 | ...manuForm, 36 | [e.target.name]: e.target.value, 37 | }); 38 | }; 39 | 40 | const handleSubmitManufacturerForm = async () => { 41 | setLoading(true); 42 | 43 | if (manuForm.manufacturerName !== "" && manuForm.manufacturerDetails !== "" && manuForm.manufacturerLongitude !== "" && manuForm.manufacturerLatitude !== "" && manuForm.productName !== "" && manuForm.productCode !== 0 && manuForm.productPrice !== 0 && manuForm.productCategory !== "") { 44 | setfvalid(false); 45 | await supplyChainContract.methods.manufactureProduct(manuForm.manufacturerName, manuForm.manufacturerDetails, manuForm.manufacturerLongitude, manuForm.manufacturerLatitude, manuForm.productName, parseInt(manuForm.productCode), parseInt(manuForm.productPrice), manuForm.productCategory).send({ from: roles.manufacturer, gas: 999999 }) 46 | // .then(console.log) 47 | .on('transactionHash', function (hash) { 48 | handleSetTxhash(hash); 49 | }); 50 | setManuForm({ 51 | id: 0, 52 | manufacturerName: "", 53 | manufacturerDetails: "", 54 | manufacturerLongitude: "", 55 | manufacturerLatitude: "", 56 | productName: "", 57 | productCode: 0, 58 | productPrice: 0, 59 | productCategory: "", 60 | }) 61 | } else { 62 | setfvalid(true); 63 | } 64 | setLoading(false); 65 | }; 66 | 67 | const handleSetTxhash = async (hash) => { 68 | await supplyChainContract.methods 69 | .setTransactionHashOnManufacture(hash) 70 | .send({ from: roles.manufacturer, gas: 900000 }); 71 | }; 72 | 73 | const createProduct = async () => { 74 | setLoading(true); 75 | for (var i = 0; i < 5; i++) { 76 | await supplyChainContract.methods 77 | .manufactureProduct( 78 | "product" + i, 79 | "manufacturer" + 1, 80 | "98", 81 | "89", 82 | "mi" + i, 83 | 99 + i, 84 | 12000, 85 | "electronics" 86 | ) 87 | .send({ from: roles.manufacturer, gas: 999999 }) 88 | .on("transactionHash", function (hash) { 89 | handleSetTxhash(hash); 90 | }); 91 | } 92 | setLoading(false); 93 | }; 94 | 95 | return ( 96 | <> 97 | 98 | {loading ? ( 99 | 100 | ) : ( 101 | <> 102 |
103 |

Add Product

104 | 105 | 106 | 115 | 116 | 117 | 126 | 127 | 128 | 137 | 138 | 139 | 148 | 149 | 150 | 159 | 160 | 161 | 170 | 171 | 172 | 181 | 182 | 183 | 192 | 193 | 194 |
195 |

{fvalid ? "Please enter all data" : ""}

196 | 204 | 205 |
206 |
207 | 208 | 209 |
210 | 211 | )} 212 |
213 | 214 | ); 215 | } 216 | -------------------------------------------------------------------------------- /client/src/pages/Manufacturer/ShipManufacture.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Navbar from "../../components/Navbar"; 3 | import Button from "@material-ui/core/Button"; 4 | import { useRole } from "../../context/RoleDataContext"; 5 | import Table from "@material-ui/core/Table"; 6 | import TableBody from "@material-ui/core/TableBody"; 7 | import TableCell from "@material-ui/core/TableCell"; 8 | import TableContainer from "@material-ui/core/TableContainer"; 9 | import TableHead from "@material-ui/core/TableHead"; 10 | import TableRow from "@material-ui/core/TableRow"; 11 | import Paper from "@material-ui/core/Paper"; 12 | import TablePagination from "@material-ui/core/TablePagination"; 13 | import { useStyles } from "../../components/Styles"; 14 | import ProductModal from "../../components/Modal"; 15 | import clsx from "clsx"; 16 | import Loader from "../../components/Loader"; 17 | 18 | export default function ShipManufacture(props) { 19 | const supplyChainContract = props.supplyChainContract; 20 | const { roles } = useRole(); 21 | const classes = useStyles(); 22 | const [count, setCount] = React.useState(0); 23 | const [allSoldProducts, setAllSoldProducts] = React.useState([]); 24 | const [loading, setLoading] = React.useState(false); 25 | const navItem = [ 26 | ["Add Product", "/manufacturer/manufacture"], 27 | ["Ship Product", "/manufacturer/ship"], 28 | ["All Products", "/manufacturer/allManufacture"], 29 | ]; 30 | const [alertText, setalertText] = React.useState(""); 31 | React.useEffect(() => { 32 | (async () => { 33 | setLoading(true); 34 | const cnt = await supplyChainContract.methods.fetchProductCount().call(); 35 | setCount(cnt); 36 | 37 | })(); 38 | 39 | (async () => { 40 | const arr = []; 41 | for (var i = 1; i < count; i++) { 42 | const prodState = await supplyChainContract.methods 43 | .fetchProductState(i) 44 | .call(); 45 | 46 | if (prodState === "1") { 47 | const prodData = []; 48 | const a = await supplyChainContract.methods 49 | .fetchProductPart1(i, "product", 0) 50 | .call(); 51 | const b = await supplyChainContract.methods 52 | .fetchProductPart2(i, "product", 0) 53 | .call(); 54 | const c = await supplyChainContract.methods 55 | .fetchProductPart3(i, "product", 0) 56 | .call(); 57 | prodData.push(a); 58 | prodData.push(b); 59 | prodData.push(c); 60 | arr.push(prodData); 61 | } 62 | } 63 | setAllSoldProducts(arr); 64 | setLoading(false); 65 | })(); 66 | }, [count]); 67 | 68 | const [page, setPage] = React.useState(0); 69 | const [rowsPerPage, setRowsPerPage] = React.useState(10); 70 | 71 | const handleChangePage = (event, newPage) => { 72 | setPage(newPage); 73 | }; 74 | 75 | const handleChangeRowsPerPage = (event) => { 76 | setRowsPerPage(+event.target.value); 77 | setPage(0); 78 | }; 79 | 80 | const [open, setOpen] = React.useState(false); 81 | const [modalData, setModalData] = React.useState([]); 82 | 83 | const handleClose = () => setOpen(false); 84 | 85 | const handleClick = async (prod) => { 86 | await setModalData(prod); 87 | setOpen(true); 88 | }; 89 | 90 | const handleSetTxhash = async (id, hash) => { 91 | await supplyChainContract.methods 92 | .setTransactionHash(id, hash) 93 | .send({ from: roles.manufacturer, gas: 900000 }); 94 | }; 95 | 96 | const handleShipButton = async (id) => { 97 | try{ 98 | await supplyChainContract.methods 99 | .shipToThirdParty(id) 100 | .send({ from: roles.manufacturer, gas: 1000000 }) 101 | .on("transactionHash", function (hash) { 102 | handleSetTxhash(id, hash); 103 | }); 104 | setCount(0); 105 | }catch{ 106 | setalertText("You are not the owner of the Product"); 107 | } 108 | 109 | }; 110 | 111 | return ( 112 |
113 | 114 | {loading ? ( 115 | 116 | ) : ( 117 | <> 118 | 123 |

Products To be Shipped

124 |

125 | Total : {allSoldProducts.length} 126 |

127 | 128 |
129 |

{alertText.length !== 0 ? alertText : ""}

130 | 131 | 132 | 133 | 134 | 135 | 136 | Universal ID 137 | 138 | 139 | Product Code 140 | 141 | 142 | Manufacturer 143 | 144 | 145 | Manufacture Date 146 | 147 | 148 | Product Name 149 | 150 | 157 | Owner 158 | 159 | 163 | Ship 164 | 165 | 166 | 167 | 168 | {allSoldProducts.length !== 0 ? ( 169 | allSoldProducts 170 | .slice( 171 | page * rowsPerPage, 172 | page * rowsPerPage + rowsPerPage 173 | ) 174 | .map((prod) => { 175 | const d = new Date(parseInt(prod[1][0] * 1000)); 176 | return ( 177 | <> 178 | 184 | handleClick(prod)} 190 | > 191 | {prod[0][0]} 192 | 193 | handleClick(prod)} 197 | > 198 | {prod[1][2]} 199 | 200 | handleClick(prod)} 204 | > 205 | {prod[0][4]} 206 | 207 | handleClick(prod)} 210 | > 211 | {d.toDateString() + " " + d.toTimeString()} 212 | 213 | handleClick(prod)} 217 | > 218 | {prod[1][1]} 219 | 220 | handleClick(prod)} 227 | > 228 | {prod[0][2]} 229 | 230 | 234 | 244 | 245 | 246 | 247 | ); 248 | }) 249 | ) : ( 250 | <> 251 | )} 252 | 253 |
254 |
255 | 264 |
265 |
266 | 267 | {/* {allSoldProducts.length !== 0 ? ( 268 | allSoldProducts.map((prod) => ( 269 | <> 270 |
271 |

Universal ID : {prod[0][0]}

272 |

SKU : {prod[0][1]}

273 |

Owner : {prod[0][2]}

274 |

Manufacturer : {prod[0][3]}

275 |

Name of Manufacturer : {prod[0][4]}

276 |

Details of Manufacturer : {prod[0][5]}

277 |

Longitude of Manufature : {prod[0][6]}

278 |

Latitude of Manufature : {prod[0][7]}

279 | 280 |

Manufactured date : {prod[1][0]}

281 | 289 |
290 | 291 | )) 292 | ) : ( 293 | <> 294 | )} */} 295 | 296 | )} 297 |
298 |
299 | ); 300 | } 301 | -------------------------------------------------------------------------------- /client/src/pages/RoleAdmin.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ResponsiveDrawer from "../components/Navbar"; 3 | import TextField from "@material-ui/core/TextField"; 4 | import Button from "@material-ui/core/Button"; 5 | import { useRole } from "../context/RoleDataContext"; 6 | import { useStyles } from "../components/Styles"; 7 | 8 | function RoleAdmin(props) { 9 | const accounts = props.accounts; 10 | const supplyChainContract = props.supplyChainContract; 11 | const { roles, setRoles } = useRole(); 12 | 13 | const classes = useStyles(); 14 | const [manufacturerRole, setManufacturerRole] = React.useState(""); 15 | const [thirdPartyRole, setThirdPartyRole] = React.useState(""); 16 | const [deliveryHubRole, setDeliveryHubRole] = React.useState(""); 17 | const [customerRole, setCustomerRole] = React.useState(""); 18 | const navItem = []; 19 | 20 | const handleAddManufacturerRole = async () => { 21 | await setRoles({ 22 | ...roles, 23 | manufacturer : manufacturerRole 24 | }) 25 | 26 | localStorage.setItem("mRole", manufacturerRole); 27 | await supplyChainContract.methods.addManufacturerRole(manufacturerRole).send({ from: accounts[0], gas:100000 }) 28 | .then(console.log); 29 | 30 | 31 | 32 | setManufacturerRole(""); 33 | } 34 | 35 | const handleAddThirdPartyRole = async () => { 36 | await setRoles({ 37 | ...roles, 38 | thirdparty : thirdPartyRole 39 | }) 40 | 41 | localStorage.setItem("tpRole", thirdPartyRole); 42 | await supplyChainContract.methods.addThirdPartyRole(thirdPartyRole).send({ from: accounts[0], gas:100000 }) 43 | .then(console.log); 44 | 45 | 46 | 47 | setThirdPartyRole(""); 48 | } 49 | 50 | const handleAddDeliveryHubRole = async () => { 51 | await setRoles({ 52 | ...roles, 53 | deliveryhub : deliveryHubRole 54 | }) 55 | 56 | localStorage.setItem("dhRole", deliveryHubRole); 57 | await supplyChainContract.methods.addDeliveryHubRole(deliveryHubRole).send({ from: accounts[0], gas:100000 }) 58 | .then(console.log); 59 | 60 | 61 | 62 | setDeliveryHubRole(""); 63 | } 64 | 65 | const handleAddCustomerRole = async () => { 66 | await setRoles({ 67 | ...roles, 68 | customer : customerRole 69 | }) 70 | 71 | localStorage.setItem("cRole", customerRole); 72 | await supplyChainContract.methods.addCustomerRole(customerRole).send({ from: accounts[0], gas:100000 }) 73 | .then(console.log); 74 | 75 | 76 | 77 | setCustomerRole(""); 78 | } 79 | 80 | 81 | return ( 82 |
83 | 84 |
85 |

Add Roles

86 | {console.log(roles)} 87 | 88 |
89 |
90 | setManufacturerRole(e.target.value)} 96 | style={{width:"70%"}} 97 | /> 98 | 106 |
107 |
108 | 109 |
110 |
111 | setThirdPartyRole(e.target.value)} 117 | style={{width:"70%"}} 118 | /> 119 | 127 |
128 |
129 | 130 |
131 |
132 | setDeliveryHubRole(e.target.value)} 138 | style={{width:"70%"}} 139 | /> 140 | 148 |
149 |
150 | 151 |
152 |
153 | setCustomerRole(e.target.value)} 159 | style={{width:"70%"}} 160 | /> 161 | 169 |
170 |
171 |
172 |
173 |

Local Accounts

174 | {accounts.slice(1).map((acc) => ( 175 |

{acc}

176 | ))} 177 | 178 |
179 | 180 |
181 |
182 | ); 183 | } 184 | 185 | export default RoleAdmin; 186 | -------------------------------------------------------------------------------- /client/src/pages/ThirdParty/PurshaseThirdParty.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Navbar from "../../components/Navbar"; 3 | import Button from "@material-ui/core/Button"; 4 | import { useRole } from "../../context/RoleDataContext"; 5 | import Table from "@material-ui/core/Table"; 6 | import TableBody from "@material-ui/core/TableBody"; 7 | import TableCell from "@material-ui/core/TableCell"; 8 | import TableContainer from "@material-ui/core/TableContainer"; 9 | import TableHead from "@material-ui/core/TableHead"; 10 | import TableRow from "@material-ui/core/TableRow"; 11 | import Paper from "@material-ui/core/Paper"; 12 | import TablePagination from "@material-ui/core/TablePagination"; 13 | import { useStyles } from "../../components/Styles"; 14 | import ProductModal from "../../components/Modal"; 15 | import clsx from "clsx"; 16 | import Loader from "../../components/Loader"; 17 | 18 | export default function PurchaseThirdParty(props) { 19 | const classes = useStyles(); 20 | const supplyChainContract = props.supplyChainContract; 21 | const { roles } = useRole(); 22 | const [count, setCount] = React.useState(0); 23 | const [allProducts, setAllProducts] = React.useState([]); 24 | const [loading, setLoading] = React.useState(false); 25 | const navItem = [ 26 | ["Buy Product", "/ThirdParty/allProducts"], 27 | ["Receive Product", "/ThirdParty/receive"], 28 | ["Ship Products", "/ThirdParty/ship"], 29 | ]; 30 | React.useEffect(() => { 31 | (async () => { 32 | setLoading(true); 33 | const cnt = await supplyChainContract.methods.fetchProductCount().call(); 34 | setCount(cnt); 35 | 36 | })(); 37 | 38 | (async () => { 39 | const arr = []; 40 | for (var i = 1; i < count; i++) { 41 | const prodState = await supplyChainContract.methods 42 | .fetchProductState(i) 43 | .call(); 44 | 45 | if (prodState === "0") { 46 | const prodData = []; 47 | const a = await supplyChainContract.methods 48 | .fetchProductPart1(i, "product", 0) 49 | .call(); 50 | const b = await supplyChainContract.methods 51 | .fetchProductPart2(i, "product", 0) 52 | .call(); 53 | const c = await supplyChainContract.methods 54 | .fetchProductPart3(i, "product", 0) 55 | .call(); 56 | prodData.push(a); 57 | prodData.push(b); 58 | prodData.push(c); 59 | arr.push(prodData); 60 | } 61 | } 62 | setAllProducts(arr); 63 | setLoading(false); 64 | })(); 65 | }, [count]); 66 | 67 | const [page, setPage] = React.useState(0); 68 | const [rowsPerPage, setRowsPerPage] = React.useState(10); 69 | 70 | const handleChangePage = (event, newPage) => { 71 | setPage(newPage); 72 | }; 73 | 74 | const handleChangeRowsPerPage = (event) => { 75 | setRowsPerPage(+event.target.value); 76 | setPage(0); 77 | }; 78 | 79 | const [open, setOpen] = React.useState(false); 80 | const [modalData, setModalData] = React.useState([]); 81 | 82 | const handleClose = () => setOpen(false); 83 | 84 | const handleClick = async (prod) => { 85 | await setModalData(prod); 86 | setOpen(true); 87 | }; 88 | 89 | const handleSetTxhash = async (id, hash) => { 90 | await supplyChainContract.methods 91 | .setTransactionHash(id, hash) 92 | .send({ from: roles.manufacturer, gas: 900000 }); 93 | }; 94 | 95 | const handleBuyButton = async (id) => { 96 | await supplyChainContract.methods 97 | .purchaseByThirdParty(id) 98 | .send({ from: roles.thirdparty, gas: 1000000 }) 99 | .on("transactionHash", function (hash) { 100 | handleSetTxhash(id, hash); 101 | }); 102 | setCount(0); 103 | }; 104 | 105 | return ( 106 |
107 | 108 | {loading ? ( 109 | 110 | ) : ( 111 | <> 112 | 117 | 118 |

All Products

119 |

Total : {allProducts.length}

120 | 121 |
122 | 123 | 124 | 125 | 126 | 127 | 128 | Universal ID 129 | 130 | 131 | Product Code 132 | 133 | 134 | Manufacturer 135 | 136 | 137 | Manufacture Date 138 | 139 | 140 | Product Name 141 | 142 | 149 | Owner 150 | 151 | 155 | Buy 156 | 157 | 158 | 159 | 160 | {allProducts.length !== 0 ? ( 161 | allProducts 162 | .slice( 163 | page * rowsPerPage, 164 | page * rowsPerPage + rowsPerPage 165 | ) 166 | .map((prod) => { 167 | const d = new Date(parseInt(prod[1][0] * 1000)); 168 | return ( 169 | <> 170 | 176 | handleClick(prod)} 182 | > 183 | {prod[0][0]} 184 | 185 | handleClick(prod)} 189 | > 190 | {prod[1][2]} 191 | 192 | handleClick(prod)} 196 | > 197 | {prod[0][4]} 198 | 199 | handleClick(prod)} 202 | > 203 | {d.toDateString() + " " + d.toTimeString()} 204 | 205 | handleClick(prod)} 209 | > 210 | {prod[1][1]} 211 | 212 | handleClick(prod)} 219 | > 220 | {prod[0][2]} 221 | 222 | 226 | 236 | 237 | 238 | 239 | ); 240 | }) 241 | ) : ( 242 | <> 243 | )} 244 | 245 |
246 |
247 | 256 |
257 |
258 | 259 | {/* {allProducts.length !== 0 ? (allProducts.map((prod) => ( 260 | <> 261 |
262 |

Universal ID : {prod[0][0]}

263 |

SKU : {prod[0][1]}

264 |

Owner : {prod[0][2]}

265 |

Manufacturer : {prod[0][3]}

266 |

Name of Manufacturer : {prod[0][4]}

267 |

Details of Manufacturer : {prod[0][5]}

268 |

Longitude of Manufature : {prod[0][6]}

269 |

Latitude of Manufature : {prod[0][7]}

270 | 271 |

Manufactured date : {prod[1][0]}

272 | 280 |
281 | 282 | 283 | ))) : <> } */} 284 | 285 | )} 286 |
287 |
288 | ); 289 | } 290 | -------------------------------------------------------------------------------- /client/src/pages/ThirdParty/ShipThirdParty.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Navbar from "../../components/Navbar"; 3 | import Button from "@material-ui/core/Button"; 4 | import { useRole } from "../../context/RoleDataContext"; 5 | import Table from "@material-ui/core/Table"; 6 | import TableBody from "@material-ui/core/TableBody"; 7 | import TableCell from "@material-ui/core/TableCell"; 8 | import TableContainer from "@material-ui/core/TableContainer"; 9 | import TableHead from "@material-ui/core/TableHead"; 10 | import TableRow from "@material-ui/core/TableRow"; 11 | import Paper from "@material-ui/core/Paper"; 12 | import TablePagination from "@material-ui/core/TablePagination"; 13 | import { useStyles } from "../../components/Styles"; 14 | import ProductModal from "../../components/Modal"; 15 | import clsx from "clsx"; 16 | import Loader from "../../components/Loader"; 17 | 18 | export default function ShipThirdParty(props) { 19 | const classes = useStyles(); 20 | const supplyChainContract = props.supplyChainContract; 21 | const { roles } = useRole(); 22 | const [count, setCount] = React.useState(0); 23 | const [allSoldProducts, setAllSoldProducts] = React.useState([]); 24 | const [loading, setLoading] = React.useState(false); 25 | const navItem = [ 26 | ["Buy Product", "/ThirdParty/allProducts"], 27 | ["Receive Product", "/ThirdParty/receive"], 28 | ["Ship Products", "/ThirdParty/ship"], 29 | ]; 30 | const [alertText, setalertText] = React.useState(""); 31 | React.useEffect(() => { 32 | (async () => { 33 | setLoading(true); 34 | const cnt = await supplyChainContract.methods.fetchProductCount().call(); 35 | setCount(cnt); 36 | 37 | })(); 38 | 39 | (async () => { 40 | const arr = []; 41 | for (var i = 1; i < count; i++) { 42 | const prodState = await supplyChainContract.methods 43 | .fetchProductState(i) 44 | .call(); 45 | 46 | if (prodState === "4") { 47 | const prodData = []; 48 | const a = await supplyChainContract.methods 49 | .fetchProductPart1(i, "product", 0) 50 | .call(); 51 | const b = await supplyChainContract.methods 52 | .fetchProductPart2(i, "product", 0) 53 | .call(); 54 | const c = await supplyChainContract.methods 55 | .fetchProductPart3(i, "product", 0) 56 | .call(); 57 | prodData.push(a); 58 | prodData.push(b); 59 | prodData.push(c); 60 | arr.push(prodData); 61 | } 62 | } 63 | setAllSoldProducts(arr); 64 | setLoading(false); 65 | })(); 66 | }, [count]); 67 | 68 | const handleSetTxhash = async (id, hash) => { 69 | await supplyChainContract.methods 70 | .setTransactionHash(id, hash) 71 | .send({ from: roles.manufacturer, gas: 900000 }); 72 | }; 73 | 74 | const handleShipButton = async (id) => { 75 | try{ 76 | await supplyChainContract.methods 77 | .shipByThirdParty(id) 78 | .send({ from: roles.thirdparty, gas: 1000000 }) 79 | .on("transactionHash", function (hash) { 80 | handleSetTxhash(id, hash); 81 | }); 82 | setCount(0); 83 | }catch{ 84 | setalertText("You are not the owner of the Product") 85 | } 86 | 87 | }; 88 | const [page, setPage] = React.useState(0); 89 | const [rowsPerPage, setRowsPerPage] = React.useState(10); 90 | 91 | const handleChangePage = (event, newPage) => { 92 | setPage(newPage); 93 | }; 94 | 95 | const handleChangeRowsPerPage = (event) => { 96 | setRowsPerPage(+event.target.value); 97 | setPage(0); 98 | }; 99 | 100 | const [open, setOpen] = React.useState(false); 101 | const [modalData, setModalData] = React.useState([]); 102 | 103 | const handleClose = () => setOpen(false); 104 | 105 | const handleClick = async (prod) => { 106 | await setModalData(prod); 107 | setOpen(true); 108 | }; 109 | 110 | return ( 111 | <> 112 |
113 | 114 | {loading ? ( 115 | 116 | ) : ( 117 | <> 118 | 123 |

Products To be Shipped

124 |

125 | Total : {allSoldProducts.length} 126 |

127 | 128 |
129 |

{alertText.length !== 0 ? alertText : ""}

130 | 131 | 132 | 133 | 134 | 135 | 136 | Universal ID 137 | 138 | 142 | Product Code 143 | 144 | 148 | Manufacturer 149 | 150 | 154 | Manufacture Date 155 | 156 | 160 | Product Name 161 | 162 | 169 | Owner 170 | 171 | 175 | Ship 176 | 177 | 178 | 179 | 180 | {allSoldProducts.length !== 0 ? ( 181 | allSoldProducts 182 | .slice( 183 | page * rowsPerPage, 184 | page * rowsPerPage + rowsPerPage 185 | ) 186 | .map((prod) => { 187 | const d = new Date(parseInt(prod[1][0] * 1000)); 188 | return ( 189 | <> 190 | 196 | handleClick(prod)} 202 | > 203 | {prod[0][0]} 204 | 205 | handleClick(prod)} 209 | > 210 | {prod[1][2]} 211 | 212 | handleClick(prod)} 216 | > 217 | {prod[0][4]} 218 | 219 | handleClick(prod)} 222 | > 223 | {d.toDateString() + 224 | " " + 225 | d.toTimeString()} 226 | 227 | handleClick(prod)} 231 | > 232 | {prod[1][1]} 233 | 234 | handleClick(prod)} 241 | > 242 | {prod[0][2]} 243 | 244 | 248 | 258 | 259 | 260 | 261 | ); 262 | }) 263 | ) : ( 264 | <> 265 | )} 266 | 267 |
268 |
269 | 278 |
279 |
280 | 281 | )} 282 |
283 |
284 | 285 | ); 286 | } 287 | -------------------------------------------------------------------------------- /client/src/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const http = require('http'); 3 | const path = require('path'); 4 | const app = express(); 5 | app.use(express.static(path.join(__dirname,'..', 'build'))); 6 | app.user(express.static("public")); 7 | app.get('/*', function (req, res) { 8 | res.sendFile(path.join(__dirname,'..', 'build', 'index.html')); 9 | }); 10 | 11 | 12 | // const server = http.createServer(app); 13 | 14 | const port = 3000; 15 | 16 | app.listen(port, () => { 17 | console.log('Server is up on port ' + port); 18 | }); -------------------------------------------------------------------------------- /client/src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://bit.ly/CRA-PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.1/8 is considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | export function register(config) { 24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 25 | // The URL constructor is available in all browsers that support SW. 26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); 27 | if (publicUrl.origin !== window.location.origin) { 28 | // Our service worker won't work if PUBLIC_URL is on a different origin 29 | // from what our page is served on. This might happen if a CDN is used to 30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 31 | return; 32 | } 33 | 34 | window.addEventListener('load', () => { 35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 36 | 37 | if (isLocalhost) { 38 | // This is running on localhost. Let's check if a service worker still exists or not. 39 | checkValidServiceWorker(swUrl, config); 40 | 41 | // Add some additional logging to localhost, pointing developers to the 42 | // service worker/PWA documentation. 43 | navigator.serviceWorker.ready.then(() => { 44 | console.log( 45 | 'This web app is being served cache-first by a service ' + 46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA' 47 | ); 48 | }); 49 | } else { 50 | // Is not localhost. Just register service worker 51 | registerValidSW(swUrl, config); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | function registerValidSW(swUrl, config) { 58 | navigator.serviceWorker 59 | .register(swUrl) 60 | .then(registration => { 61 | registration.onupdatefound = () => { 62 | const installingWorker = registration.installing; 63 | if (installingWorker == null) { 64 | return; 65 | } 66 | installingWorker.onstatechange = () => { 67 | if (installingWorker.state === 'installed') { 68 | if (navigator.serviceWorker.controller) { 69 | // At this point, the updated precached content has been fetched, 70 | // but the previous service worker will still serve the older 71 | // content until all client tabs are closed. 72 | console.log( 73 | 'New content is available and will be used when all ' + 74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' 75 | ); 76 | 77 | // Execute callback 78 | if (config && config.onUpdate) { 79 | config.onUpdate(registration); 80 | } 81 | } else { 82 | // At this point, everything has been precached. 83 | // It's the perfect time to display a 84 | // "Content is cached for offline use." message. 85 | console.log('Content is cached for offline use.'); 86 | 87 | // Execute callback 88 | if (config && config.onSuccess) { 89 | config.onSuccess(registration); 90 | } 91 | } 92 | } 93 | }; 94 | }; 95 | }) 96 | .catch(error => { 97 | console.error('Error during service worker registration:', error); 98 | }); 99 | } 100 | 101 | function checkValidServiceWorker(swUrl, config) { 102 | // Check if the service worker can be found. If it can't reload the page. 103 | fetch(swUrl) 104 | .then(response => { 105 | // Ensure service worker exists, and that we really are getting a JS file. 106 | const contentType = response.headers.get('content-type'); 107 | if ( 108 | response.status === 404 || 109 | (contentType != null && contentType.indexOf('javascript') === -1) 110 | ) { 111 | // No service worker found. Probably a different app. Reload the page. 112 | navigator.serviceWorker.ready.then(registration => { 113 | registration.unregister().then(() => { 114 | window.location.reload(); 115 | }); 116 | }); 117 | } else { 118 | // Service worker found. Proceed as normal. 119 | registerValidSW(swUrl, config); 120 | } 121 | }) 122 | .catch(() => { 123 | console.log( 124 | 'No internet connection found. App is running in offline mode.' 125 | ); 126 | }); 127 | } 128 | 129 | export function unregister() { 130 | if ('serviceWorker' in navigator) { 131 | navigator.serviceWorker.ready.then(registration => { 132 | registration.unregister(); 133 | }); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.4.21 <0.9.0; 3 | 4 | contract Migrations { 5 | address public owner; 6 | uint public last_completed_migration; 7 | 8 | modifier restricted() { 9 | if (msg.sender == owner) _; 10 | } 11 | 12 | constructor() public { 13 | owner = msg.sender; 14 | } 15 | 16 | function setCompleted(uint completed) public restricted { 17 | last_completed_migration = completed; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /contracts/Structure.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.4.21 <0.9.0; 3 | 4 | library Structure { 5 | enum State { 6 | Manufactured, 7 | PurchasedByThirdParty, 8 | ShippedByManufacturer, 9 | ReceivedByThirdParty, 10 | PurchasedByCustomer, 11 | ShippedByThirdParty, 12 | ReceivedByDeliveryHub, 13 | ShippedByDeliveryHub, 14 | ReceivedByCustomer 15 | } 16 | struct ManufactureDetails { 17 | address manufacturer; 18 | string manufacturerName; 19 | string manufacturerDetails; 20 | string manufacturerLongitude; 21 | string manufacturerLatitude; 22 | uint256 manufacturedDate; 23 | } 24 | struct ProductDetails { 25 | string productName; 26 | uint256 productCode; 27 | uint256 productPrice; 28 | string productCategory; 29 | } 30 | struct ThirdPartyDetails { 31 | address thirdParty; 32 | string thirdPartyLongitude; 33 | string thirdPartyLatitude; 34 | } 35 | struct DeliveryHubDetails { 36 | address deliveryHub; 37 | string deliveryHubLongitude; 38 | string deliveryHubLatitude; 39 | } 40 | struct Product { 41 | uint256 uid; 42 | uint256 sku; 43 | address owner; 44 | State productState; 45 | ManufactureDetails manufacturer; 46 | ThirdPartyDetails thirdparty; 47 | ProductDetails productdet; 48 | DeliveryHubDetails deliveryhub; 49 | address customer; 50 | string transaction; 51 | } 52 | 53 | struct ProductHistory { 54 | Product[] history; 55 | } 56 | 57 | struct Roles { 58 | bool Manufacturer; 59 | bool ThirdParty; 60 | bool DeliveryHub; 61 | bool Customer; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /contracts/rolesUtils[deprecated]/Customer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.4.21 <0.9.0; 3 | 4 | import "./Roles.sol"; 5 | 6 | contract Customer { 7 | using Roles for Roles.Role; 8 | 9 | event CustomerAdded(address indexed _account); 10 | event CustomerRemoved(address indexed _account); 11 | 12 | Roles.Role private customersList; 13 | 14 | constructor() public { 15 | customersList.addRole(msg.sender); 16 | emit CustomerAdded(msg.sender); 17 | } 18 | 19 | ///@dev Modifiers for Customer. 20 | modifier onlyCustomer() { 21 | require(isCustomer(msg.sender)); 22 | _; 23 | } 24 | /*-----------------------------*/ 25 | 26 | ///@dev Customer Utility functions. 27 | function isCustomer(address _account) public view returns (bool) { 28 | return customersList.hasRole(_account); 29 | } 30 | 31 | function addCustomer(address _account) public onlyCustomer { 32 | customersList.addRole(_account); 33 | emit CustomerAdded(_account); 34 | } 35 | 36 | function removeCustomer() public { 37 | customersList.removeRole(msg.sender); 38 | emit CustomerRemoved(msg.sender); 39 | } 40 | /*-----------------------------*/ 41 | 42 | } 43 | -------------------------------------------------------------------------------- /contracts/rolesUtils[deprecated]/DeliveryHub.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.4.21 <0.9.0; 3 | 4 | import "./Roles.sol"; 5 | 6 | contract DeliveryHub { 7 | using Roles for Roles.Role; 8 | 9 | event DeliveryHubAdded(address indexed _account); 10 | event DeliveryHubRemoved(address indexed _account); 11 | 12 | Roles.Role private deliveryHubsList; 13 | 14 | constructor() public { 15 | deliveryHubsList.addRole(msg.sender); 16 | emit DeliveryHubAdded(msg.sender); 17 | } 18 | 19 | ///@dev Modifiers for DeliveryHub. 20 | modifier onlyDeliveryHub() { 21 | require(isDeliveryHub(msg.sender)); 22 | _; 23 | } 24 | /*-----------------------------*/ 25 | 26 | ///@dev DeliveryHub Utility functions. 27 | function isDeliveryHub(address _account) public view returns (bool) { 28 | return deliveryHubsList.hasRole(_account); 29 | } 30 | 31 | function addDeliveryHub(address _account) public onlyDeliveryHub { 32 | deliveryHubsList.addRole(_account); 33 | emit DeliveryHubAdded(_account); 34 | } 35 | 36 | function removeDeliveryHub() public { 37 | deliveryHubsList.removeRole(msg.sender); 38 | emit DeliveryHubRemoved(msg.sender); 39 | } 40 | /*-----------------------------*/ 41 | 42 | } 43 | -------------------------------------------------------------------------------- /contracts/rolesUtils[deprecated]/Manufacturer.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.4.21 <0.9.0; 3 | 4 | import "./Roles.sol"; 5 | 6 | contract Manufacturer { 7 | using Roles for Roles.Role; 8 | 9 | event ManufacturerAdded(address indexed _account); 10 | event ManufacturerRemoved(address indexed _account); 11 | 12 | Roles.Role manufacturersList; 13 | 14 | constructor() public { 15 | manufacturersList.addRole(msg.sender); 16 | emit ManufacturerAdded(msg.sender); 17 | } 18 | 19 | ///@dev Modifiers for Manufacturer. 20 | modifier onlyManufacturer() { 21 | require(isManufacturer(msg.sender)); 22 | _; 23 | } 24 | /*-----------------------------*/ 25 | 26 | ///@dev Manufacturer Utility functions. 27 | function isManufacturer(address _account) public view returns (bool) { 28 | return manufacturersList.hasRole(_account); 29 | } 30 | 31 | function addManufacturer(address _account ) public { 32 | manufacturersList.addRole(_account); 33 | emit ManufacturerAdded(_account); 34 | } 35 | 36 | function removeManufacturer() public { 37 | manufacturersList.removeRole(msg.sender); 38 | emit ManufacturerRemoved(msg.sender); 39 | } 40 | /*-----------------------------*/ 41 | 42 | } 43 | -------------------------------------------------------------------------------- /contracts/rolesUtils[deprecated]/Roles.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.4.21 <0.9.0; 3 | 4 | ///@title Library to add, remove and verify role. 5 | ///@author Rishav Raj Kumar, Ramiz Mollah. 6 | ///@notice You can use this as helper functions for contracts making use of Roles. 7 | ///@dev All internal functions from use by contracts internally only. 8 | library Roles{ 9 | struct Role { 10 | mapping (address => bool) list; 11 | } 12 | 13 | ///@notice Checks is the given account has the given role. 14 | function hasRole(Role storage role, address _account) 15 | internal 16 | view 17 | returns (bool) 18 | { 19 | require(_account != address(0)); 20 | return role.list[_account]; 21 | } 22 | 23 | ///@notice Adds the given role to the given account. 24 | function addRole(Role storage role, address _account) 25 | internal 26 | { 27 | require(_account != address(0)); 28 | require(!hasRole(role, _account)); 29 | 30 | role.list[_account] = true; 31 | } 32 | 33 | ///@notice Removes the given role from the given account. 34 | function removeRole(Role storage role, address _account) 35 | internal 36 | { 37 | require(_account != address(0)); 38 | require(hasRole(role, _account)); 39 | 40 | role.list[_account] = false; 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /contracts/rolesUtils[deprecated]/SortationHub.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.4.21 <0.9.0; 3 | 4 | import "./Roles.sol"; 5 | 6 | contract SortationHub { 7 | using Roles for Roles.Role; 8 | 9 | event SortationHubAdded(address indexed _account); 10 | event SortationHubRemoved(address indexed _account); 11 | 12 | Roles.Role private sortationHubsList; 13 | 14 | constructor() public { 15 | sortationHubsList.addRole(msg.sender); 16 | emit SortationHubAdded(msg.sender); 17 | } 18 | 19 | ///@dev Modifiers for SortationHub. 20 | modifier onlySortationHub() { 21 | require(isSortationHub(msg.sender)); 22 | _; 23 | } 24 | /*-----------------------------*/ 25 | 26 | ///@dev SortationHub Utility functions. 27 | function isSortationHub(address _account) public view returns (bool) { 28 | return sortationHubsList.hasRole(_account); 29 | } 30 | 31 | function addSortationHub(address _account) public onlySortationHub { 32 | sortationHubsList.addRole(_account); 33 | emit SortationHubAdded(_account); 34 | } 35 | 36 | function removeSortationHub() public { 37 | sortationHubsList.removeRole(msg.sender); 38 | emit SortationHubRemoved(msg.sender); 39 | } 40 | /*-----------------------------*/ 41 | 42 | } 43 | -------------------------------------------------------------------------------- /contracts/rolesUtils[deprecated]/Thirdparty.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.4.21 <0.9.0; 3 | 4 | import "./Roles.sol"; 5 | 6 | contract Thirdparty { 7 | using Roles for Roles.Role; 8 | 9 | event ThirdpartyAdded(address indexed _account); 10 | event ThirdpartyRemoved(address indexed _account); 11 | 12 | Roles.Role private thirdpartysList; 13 | 14 | constructor() public { 15 | thirdpartysList.addRole(msg.sender); 16 | emit ThirdpartyAdded(msg.sender); 17 | } 18 | 19 | ///@dev Modifiers for Thirdparty. 20 | modifier onlyThirdparty() { 21 | require(isThirdparty(msg.sender)); 22 | _; 23 | } 24 | /*-----------------------------*/ 25 | 26 | ///@dev Thirdparty Utility functions. 27 | function isThirdparty(address _account) public view returns (bool) { 28 | return thirdpartysList.hasRole(_account); 29 | } 30 | 31 | function addThirdparty(address _account) public onlyThirdparty { 32 | thirdpartysList.addRole(_account); 33 | emit ThirdpartyAdded(_account); 34 | } 35 | 36 | function removeThirdparty() public { 37 | thirdpartysList.removeRole(msg.sender); 38 | emit ThirdpartyRemoved(msg.sender); 39 | } 40 | /*-----------------------------*/ 41 | 42 | } 43 | -------------------------------------------------------------------------------- /images/Solidity.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/activitydiagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/activitydiagram.png -------------------------------------------------------------------------------- /images/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/architecture.png -------------------------------------------------------------------------------- /images/architecturefinal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/architecturefinal.png -------------------------------------------------------------------------------- /images/dataflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/dataflow.png -------------------------------------------------------------------------------- /images/express.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/express.jpg -------------------------------------------------------------------------------- /images/express.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/flow.png -------------------------------------------------------------------------------- /images/ganachetrans.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/ganachetrans.png -------------------------------------------------------------------------------- /images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/logo.png -------------------------------------------------------------------------------- /images/mat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/mat.png -------------------------------------------------------------------------------- /images/nginx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/nginx.png -------------------------------------------------------------------------------- /images/react.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/react.png -------------------------------------------------------------------------------- /images/sequencediagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/sequencediagram.png -------------------------------------------------------------------------------- /images/truffle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/truffle.png -------------------------------------------------------------------------------- /images/trufflenew.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/trufflenew.png -------------------------------------------------------------------------------- /images/web3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/deadlycoder07/eth-supplychain-dapp/07d9db60cd84f2f804f4f971432ad218273ab530/images/web3.jpg -------------------------------------------------------------------------------- /migrations/1_initial_migration.js: -------------------------------------------------------------------------------- 1 | var Migrations = artifacts.require("./Migrations.sol"); 2 | 3 | module.exports = function(deployer) { 4 | deployer.deploy(Migrations); 5 | }; 6 | -------------------------------------------------------------------------------- /migrations/2_deploy_contracts.js: -------------------------------------------------------------------------------- 1 | var SupplyChainContract = artifacts.require("./SupplyChain.sol"); 2 | var RolesContract = artifacts.require("./rolesUtils/Roles.sol") 3 | var ManufacturerContract = artifacts.require("./rolesUtils/Manufacturer.sol"); 4 | 5 | module.exports = function(deployer) { 6 | deployer.deploy(ManufacturerContract); 7 | deployer.deploy(RolesContract); 8 | deployer.deploy(SupplyChainContract, {gas: 15555555}); 9 | // deployer.deploy(FetchContract, {gas: 15555555}); 10 | }; 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eth-supplychain-dapp", 3 | "version": "0.1.0", 4 | "dependencies": { 5 | "solc": "^0.8.4", 6 | "truffle": "^5.3.7" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /test/TestSimpleStorage.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.4.21 <0.7.0; 2 | 3 | import "truffle/Assert.sol"; 4 | import "truffle/DeployedAddresses.sol"; 5 | import "../contracts/SimpleStorage.sol"; 6 | 7 | contract TestSimpleStorage { 8 | 9 | function testItStoresAValue() public { 10 | SimpleStorage simpleStorage = SimpleStorage(DeployedAddresses.SimpleStorage()); 11 | 12 | simpleStorage.set(89); 13 | 14 | uint expected = 89; 15 | 16 | Assert.equal(simpleStorage.get(), expected, "It should store the value 89."); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /test/simplestorage.js: -------------------------------------------------------------------------------- 1 | const SimpleStorage = artifacts.require("./SimpleStorage.sol"); 2 | 3 | contract("SimpleStorage", accounts => { 4 | it("...should store the value 89.", async () => { 5 | const simpleStorageInstance = await SimpleStorage.deployed(); 6 | 7 | // Set value of 89 8 | await simpleStorageInstance.set(89, { from: accounts[0] }); 9 | 10 | // Get stored value 11 | const storedData = await simpleStorageInstance.get.call(); 12 | 13 | assert.equal(storedData, 89, "The value 89 was not stored."); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /truffle-config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | 3 | module.exports = { 4 | compilers: { 5 | solc: { 6 | settings: { 7 | optimizer: { 8 | enabled: true, 9 | runs: 200 10 | } 11 | } 12 | } 13 | }, 14 | // See 15 | // to customize your Truffle configuration! 16 | contracts_build_directory: path.join(__dirname, "client/src/contracts"), 17 | networks: { 18 | develop: { 19 | host: "127.0.0.1", 20 | port: 8545, 21 | network_id: "*", // match any network 22 | websockets: true 23 | } 24 | } 25 | 26 | }; 27 | --------------------------------------------------------------------------------