{"id":18964287,"url":"https://github.com/lorransutter/liken","last_synced_at":"2025-09-05T17:31:34.767Z","repository":{"id":38765833,"uuid":"283614975","full_name":"LorranSutter/Liken","owner":"LorranSutter","description":"Reliable environment for sharing AI models using Hyperledger Fabric","archived":false,"fork":false,"pushed_at":"2022-12-30T21:03:27.000Z","size":1754,"stargazers_count":4,"open_issues_count":15,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-06T10:37:33.796Z","etag":null,"topics":["artificial-intelligence","blockchain","chaincode","hyperledger","hyperledger-fabric","machine-learning","nodejs","reactjs"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LorranSutter.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-29T22:30:07.000Z","updated_at":"2024-09-22T19:53:31.000Z","dependencies_parsed_at":"2023-01-31T16:45:41.651Z","dependency_job_id":null,"html_url":"https://github.com/LorranSutter/Liken","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/LorranSutter/Liken","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LorranSutter%2FLiken","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LorranSutter%2FLiken/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LorranSutter%2FLiken/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LorranSutter%2FLiken/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LorranSutter","download_url":"https://codeload.github.com/LorranSutter/Liken/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LorranSutter%2FLiken/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273790554,"owners_count":25168674,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-05T02:00:09.113Z","response_time":402,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["artificial-intelligence","blockchain","chaincode","hyperledger","hyperledger-fabric","machine-learning","nodejs","reactjs"],"created_at":"2024-11-08T14:23:36.765Z","updated_at":"2025-09-05T17:31:34.390Z","avatar_url":"https://github.com/LorranSutter.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003cimg src='https://res.cloudinary.com/lorransutter/image/upload/v1597037735/Liken/Logo.svg' height=200/\u003e\n\n\u003c/div\u003e\n\n\u003c/br\u003e\n\n\u003cp align=\"center\"\u003e\n   Blockchain solution for sharing AI models among organizations, using Hyperledger Fabric, Node.js and ReactJS. Presented as Capstone Project for the \u003ca href='https://www.georgebrown.ca/programs/blockchain-development-program-t175/'\u003eBlockchain Development\u003c/a\u003e program from \u003ca href='https://www.georgebrown.ca'\u003eGeorge Brown College\u003c/a\u003e.   \n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n   You can check out the slides used in the final presentation here: \u003ca href='https://docs.google.com/presentation/d/1PPZ9GaLhyMMlVsDvoo3Ye-qA5rD40s_PqcJY--EsNaU/edit?usp=sharing'\u003eFinal Presentation\u003c/a\u003e.\n\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n\u003cimg src='https://res.cloudinary.com/lorransutter/image/upload/v1597466877/Liken/Liken_demo.gif'/\u003e\n\n\u003c/div\u003e\n\n## :page_with_curl: Summary\n\n- [Introduction](#-introduction)\n- [Why Liken?](#thinking-why-liken)\n- [Architecture](#bricks-architecture)\n- [Flow Chart](#ocean-flow-chart)\n- [Sequence Diagram](#film_strip-sequence-diagram)\n- [Timeline](#rocket-timeline)\n- [Ledger information](#chains-ledger-information)\n- [API information](#fishing_pole_and_fish-api-information)\n- [How to run](#runner-how-to-run)\n- [Resources](#book-resources-and-tools-hammer)\n- [Technologies](#computer-technologies)\n\n## 🧐 Introduction\n\nIn the chart below (source: \u003ca href=\"https://www.pcmag.com/news/the-big-data-market-is-set-to-skyrocket-by-2022\"\u003epcmag\u003c/a\u003e) you can see the big data growth along the last years until 2019 and a growth projection for 274 billion dollars in 2022.\n\n\u003cdiv align=\"center\"\u003e\n\n\u003cimg src='https://res.cloudinary.com/lorransutter/image/upload/v1597470077/Liken/BigData_market_growth.svg'/\u003e\n\n\u003c/div\u003e\n\n\u003c/br\u003e\n\nIn the era where data is the new gold, organizations can have predictive advantages in the market if they have access to the right tools or to the right sources. On one hand we have machine learning and deep learning algorithms, which requires a great amount of data to get better results. On the other hand we have blockchain, which focuses on the most relevant data in order to build a reliable environment.\n\n## :thinking: Why Liken?\n\n:herb: The original word, [Lichen](https://en.wikipedia.org/wiki/Lichen), is a mutually beneficial relationship of algae or bacteria and fungi.\n\n:deciduous_tree: Finding Lichen on the trees is a good sign that the environment is healthy and it is ok to breathe that air.\n\n:bulb: **Liken** will provide a save environment where every organization that joins will benefit sharing their data and AI models under terms and conditions.\n\n## :bricks: Architecture\n\nThis project combines these two cutting edge technologies. Since huge datasets are stored in data lakes, my intention is to use hyperledger fabric as a means to record only the artificial intelligence models and to control data access among organizations that are interested in these models. The ledger would act as an access management system storing the permission by which a business can access and use the organization's data.\n\nOnce the organizations join the network, their datasets, AI models and sensitive information will be safe. In a collaborative and decentralized network, AI models can find the right datasets to be improved and organizations can find the right AI models to acquire the market advantage.\n\n\u003cdiv align=\"center\"\u003e\n\n\u003cimg src='https://res.cloudinary.com/lorransutter/image/upload/v1597477615/Liken/Architecture.svg'/\u003e\n\n\u003c/div\u003e\n\n## :ocean: Flow Chart\n\nThe following chart represents the flow of this MPV. You can check the flow chart of the full solution [here](FullSolution.md#flow-chart).\n\nEvery organization that joins the network will be able to interact with the ledger through the user interface. Both registration of a new model and access to public model data can easily be requested through the interface. However, transactions that can interact with sensitive information from other network participants, such as updating and approval management, requires another level of security. In these cases, both server authentications and chaincode verifications are employed.\n\n\u003cdiv align=\"center\"\u003e\n\n\u003cimg src='https://res.cloudinary.com/lorransutter/image/upload/v1597108351/Liken/Liken_Flow_Chart_v2.png' width=800/\u003e\n\n\u003c/div\u003e\n\n## :film_strip: Sequence Diagram\n\nThe following diagram represents the flow of this MPV. You can check the full sequence diagram [here](FullSolution.md#sequence-diagram).\n\n1. Organizations are able to safely register their AI models in the ledger.\n2. Organizations can also approve other organizations to update their registered models.\n    - In HLF, a composite key is created to relate the model key to the organization. Also, the terms, conditions and expiration date are stored in the ledger along this composite key.\n3. The allowed organizations can see and update the models, which will increase the speed of improvement of the shared models.\n\n\u003cdiv align=\"center\"\u003e\n\n\u003cimg src='https://res.cloudinary.com/lorransutter/image/upload/v1597129372/Liken/Liken_Sequence_Diagram_MVP.svg'/\u003e\n\n\u003c/div\u003e\n\n## :rocket: Timeline\n\nThis is the timeline implementation and future goals for this project:\n\n1. The current code is a full blockchain-based implementation: Hyperledger Fabric, Node.js and ReactJS, which allows simple AI model sharing among organizations in the network.\n2. After new refinements form this prototype, we will be able to deploy a MVP, where organizations will be able to share their AI models safely.\n3. Finally, we want to provide integrations with datalakes and [IPFS](https://ipfs.io/).\n    - IPFS is a distributed file system. Adopting this approach we will reach more decentralization and reliability.\n    - Having the datasets and models stored in IPFS, only the file reference will be stored in the ledger, preventing overloading.\n4. As a first great goal, we want to introduce [homomorphic encryption](https://en.wikipedia.org/wiki/Homomorphic_encryption) (HE). \n    - HE will allow organizations to perform operations on encrypted private data without disclosing information, adding a new layer of security and privacy.\n\n\u003cdiv align=\"center\"\u003e\n\n\u003cimg src='https://res.cloudinary.com/lorransutter/image/upload/v1597459592/Liken/Timeline.svg'/\u003e\n\n\u003c/div\u003e\n\n## :chains: Ledger Information\n\n### Data stored in the ledger\n\n#### Model Data\n\n| Parameter          | Type     | Description                                          |\n|-                   |-         |-                                                     |\n| `owner`            | `string` | Organization who published first and owns the model. |\n| `modelObject`      | `buffer` | Buffer format of the model file.                     |\n| `modelName`        | `string` | Name of the model.                                   |\n| `modelDescription` | `string` | Description of the model.                            |\n| `publicationDate`  | `Date`   | Last time when the model was updated.                |\n| `whoPublishedLast` | `string` | Who was the organization who last updated the model. |\n\n#### Loan information\n\n| Parameter        | Type     | Description                                                        |\n|-                 |-         |-                                                                   |\n| `modelKey`       | `string` | CouchDB key used to query the model data.                          |\n| `terms`          | `buffer` | Terms of the model loan.                                           |\n| `conditions`     | `string` | Conditions of the model loan.                                      |\n| `expirationDate` | `Date`   | Deadline by which the borrowing organization can update the model. |\n| `user`           | `string` | Organization who borrowed the model.                               |\n\n### Chaincode functions\n\n| Function | Visibility | Parameters | Action | Returns |\n|-|:-:|-|-|-|\n| `initLedger` | public | `array of objects` initialData  | Populates the ledger with initialData parameter. Can be called only once. |  |\n| `registerModel` | public | `object` modelData | Stringifies model parameter. Saves the model in the ledger. | `bool` success or fail |\n| `approve` | public | `string` modelKey, `string` user | Allows users to update models. Creates composite key. | `bool` success or fail |\n| `remove` | public | `string` modelKey, `string` user | Removes user allowance. Deletes composite key. | `bool` success or fail |\n| `updateModel` | public | `string` modelKey, `object` modelUpdate | Checks if the caller is allowed to update the model. Update model. | `bool` success or fail |\n| `queryAllModelsByOwner` | public |  | Verifies if caller is owner of any registered model. Returns a list of models. | `array of objects` models |\n| `queryAllModelsByApprovedUser` | public |  | Returns a list of models approved for caller | `array of objects` models |\n| `isOwner` | private | `string` modelKey | Verifies if caller is the model owner | `bool` |\n| `isApproved` | private | `string` modelKey | Verifies if user is owner or allowed to update model | `bool` |\n| `getCallerId` | private |  | Extracts the CA Id. | `string` Id |\n| `getModelsByCaller` | private |  | Returns a list of models approved by the caller. | `array of objects` models |\n| `getRelationsArray` | private | `Iterator` relationsResultIterator | Iterates a composite key iterator. | `array of strings` model keys |\n\n## :fishing_pole_and_fish: API information\n\n|End Point                          |Method|Params                                      | HLF function                 |Returns                  |\n|:---                               |:---: | :---                                       | :---                         |             :---        |\n|`\\org\\index`                       | GET  |-                                           |      -                       |list of organizations    |\n|`\\org\\login`                       | POST |login; passowrd                             |      -                       |JWT; credentials         |\n|`\\org\\registerModel`               | POST |credentials; name; description; model object|`registerModel`               |status message; model key|\n|`\\org\\getModelData`                | GET  |modelKey; credentials                       |`getModelData`                |public model data        |\n|`\\org\\getFullModelData`            | GET  |modelKey; credentials                       |`getFullModelData`            |full model data          |\n|`\\org\\approve`                     | POST |modelKey; credentials; org; terms           |`approve`                     |status message           |\n|`\\org\\remove`                      | POST |modelKey; credentials;                      |`remove`                      |status message           |\n|`\\org\\queryAllModelsByOwner`       | GET  |credentials;                                |`queryAllModelsByOwner`       |list of models           |\n|`\\org\\queryAllModelsByApprovedUser`| GET  |credentials;                                |`queryAllModelsByApprovedUser`|list of models           |\n|`\\org\\updateModel`                 | PUT  |credentials; name; description; model object|`updateModel`                 |status message           |\n\n## :runner: How to run\n\nThis project was developed using a [Google Cloud Platform](https://cloud.google.com/) virtual machine, so every step must be performed in a VM CLI under a _sudo -s_ command.\n\nStart your VM and save the highlighted External IP:\n\n\u003cp align=\"center\"\u003e\n   \u003cimg src=\"https://res.cloudinary.com/lorransutter/image/upload/v1594076924/eKYC/VM.png\"/\u003e\n\u003c/p\u003e\n\nYou must have [Fabric samples](https://github.com/hyperledger/fabric-samples) to run this project. You will clone this project inside fabric-samples folder so as to this can use the files from bin and config folders.\n\nHere you can see the folder structure and the main files mentioned in this section:\n\n```\n📦fabric-samples\n ┣ 📂bin\n ┣ 📂config\n ┗ 📂Liken\n   ┣ 📂api\n   ┣ 📂chaincode\n   ┣ 📂frontend\n      ┗ 📂src\n         ┗ 📂service\n            ┗ 📜baseURL.json\n   ┣ 📂test-network\n   ┣ 📜.env\n   ┣ 📜networkDown.sh\n   ┗ 📜setUp.sh\n```\n\nOpen your terminal in the fabric-samples folder and clone the project.\n\n``` sh\n# Clone this repo\ngit clone https://github.com/LorranSutter/Liken.git\n\n# Go to the project folder\ncd Liken\n```\n\nTo run the application you will need to set your own configurations of _port_, _database_, _private key_ and _encryption key_. Create the following .env file in the indicated path and format with your customized configurations. You can use .env.sample and rename it to .env:\n\n``` json\n// ./.env\n\nPORT_API=5000\nPRIVATE_KEY=\"54AD766F231CCB0EA64156F1E5488\"\nENCRYPTION_KEY=\"CoCKidLqlVuB8y1EYmKaye1UGoxtHmko1LmyqOHvVht=\"\nMONGODB_URI_DEV=\"YOUR_MONGO_URI\"\n```\n\nNow you will need two opened terminals to run the project. One for the API and another one for the frontend.\n\nAPI will run on http://35.193.245.108:5000/\n\nFrontend will run on http://35.193.245.108:3000/\n\n``` sh\n\n## In the first terminal ##\n\n# Go to the chaincode folder\ncd chaincode\n\n# Install dependencies\nnpm install\n\n# Go to the API application\ncd ../api\n\n# Install dependencies\nnpm install\n```\n\n``` sh\n## In the second terminal ##\n\n# Go to the frontend application\ncd frontend\n\n# Install dependencies\nnpm install\n```\n\nIn order to connect frontend to the API, you will have to provide the base URL of the API in the following file:\n\n```sh\n## In the second terminal ##\n\n# Go to the baseURL.json file\ncd src/service/baseURL.json\n\n{\n    \"baseURL\": \"http://35.193.245.108:5000\"\n}\n```\n\nNow you can start the network and perform all necessary set up running the following magic script:\n\n``` sh\n## In the first terminal ##\n\n# Go to the root\ncd ..\n\n# Run the set up script\n./setUp.sh\n```\n\nRun the API application:\n\n``` sh\n## In the first terminal ##\n\n# Go to the API application\ncd api\n\n# Run API application\nnpm run start\n\n# Or to use nodemon\nnpm run dev\n```\n\nFinally run the frontend application:\n\n``` sh\n## In the second terminal ##\n\n# Run the project\nnpm start\n```\n\nIf you want to stop the network and delete all artifacts created, just run the next magic script below:\n\n``` sh\n## In the first terminal ##\n\n# Go to the root\ncd ..\n\n# Run the script\n./networkDown.sh\n```\n\n#### Login credentials\n\nOrganization\n* login: apple / microsoft\n* password: strongpassword\n\n# :book: Resources and Tools :hammer:\n\n- [Notion](https://www.notion.so/) - easy to use workspace\n- [Insomnia](https://insomnia.rest/) - API explorer\n- [HLF SDK documentation](https://hyperledger.github.io/fabric-chaincode-node/release-1.4/api/index.html)\n- [IPFS](https://ipfs.io/) - InterPlanetary File System\n- [Google Cloud Platform](https://cloud.google.com/) - cloud computing services from Google\n\n# :computer: Technologies\n\n1. Hyperledger\n\n    - [Fabric samples](https://github.com/hyperledger/fabric-samples) - get started samples for Hyperledger Fabric\n    - [Fabric contract API](https://www.npmjs.com/package/fabric-contract-api) - contract interface to implement smart contracts\n    - [Fabric CA Client](https://www.npmjs.com/package/fabric-ca-client) - SDK for Node.js to interact with HLF CA\n    - [Fabric Network](https://www.npmjs.com/package/fabric-network) - SDK for Node.js to interact with HLF\n\n2. Backend\n\n    - [Node.js](https://nodejs.org/en/) - executes JS scripts in server side\n    - [Express.js](http://expressjs.com/) - web application framework\n    - [ESlint](https://eslint.org/) - pluggable JS linter\n    - [Express.js](http://expressjs.com/) - web application framework\n    - [MongoDB](https://www.mongodb.com/) - NoSQL database\n    - [Mongoose](https://mongoosejs.com/) - object data modeling (ODM) library for MongoDB and Node.js\n    - [Async](https://caolan.github.io/async/v3/) - library to perform asynchronous operations\n    - [Express validator](https://express-validator.github.io/docs/) - middleware to validate data\n    - [Bcryptjs](https://www.npmjs.com/package/bcryptjs) - library to perform cryptography\n    - [JWT.IO](https://jwt.io/) - JSON Web Tokens to allow, decode, verify and generate JWT\n    - [Dotenv](https://www.npmjs.com/package/dotenv) - loads environment variables from a .env file\n    - [Jest](https://jestjs.io/) - library for tests\n    - [Nodemon](https://www.npmjs.com/package/nodemon) - monitor and restart server after changes\n\n3. Frontend\n\n    - [Rimble](https://rimble.consensys.design/) - design system\n    - [ReactJS](https://reactjs.org/) - frontend library\n    - [React Navigation](https://reactnavigation.org/) - routing and navigation for react apps\n    - [React router dom](https://www.npmjs.com/package/react-router-dom) - routing and navigation for react apps\n    - [React cookie](https://www.npmjs.com/package/react-cookie) - cookie interaction for React applications\n    - [React Icons](https://www.npmjs.com/package/react-icons) - icons library\n    - [React dropzone](https://react-dropzone.js.org/) - create zone to drop files\n    - [React collapsed](https://www.npmjs.com/package/react-collapsed) - a custom hook for creating expand/collapse components\n    - [Axios](https://www.npmjs.com/package/axios) - HTTP requests\n\n## :cookie: Credits\n\n- [Encryption/Decryption code using cipher](https://github.com/zishon89us/node-cheat/blob/master/stackoverflow_answers/crypto-create-cipheriv.js#L2)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Florransutter%2Fliken","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Florransutter%2Fliken","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Florransutter%2Fliken/lists"}