Showing posts with label Web3. Show all posts
Showing posts with label Web3. Show all posts

Thursday, September 15, 2022

Decentralized College Tracker Using Solidity

(Blockchain Series)

I'm presenting here an academic project on blockchain technology. In the DLT (Distributed Ledger Technology) arena, there are several players and platforms but the most popular ones right now are Ethereum (maybe because of THE MERGE or ETH 2.0) and Bitcoin (being the grandpa of blockchain based cryptocurrency and papa of several sidechains and Multichain). 

Here, you can learn about deploying a Smart Contract written in Solidity for a specific use case over RSK Testnet - a BTC sidechain that supports EVM.

The tools required are:

  • Remix IDE
  • Solidity Programming Language
  • Metamask Wallet
  • Injected Web3 Provider (Ganache with Ropsten Testnet, RSK Testnet, etc.)
  • Compatible browser (Chrome, Brave, etc.)
Here's quick video on the same:



Agenda

It is becoming difficult to track down illegal colleges. Many students' careers are spoiled as they enroll in them. A solution is needed that can ensure transparency and integrity of the admission process. 

Background

In many parts of India, illegal colleges are run, which are not affiliated to any university. Many students enroll in these colleges without knowing that and in turn they end up having no jobs or colleges get shut down after some time, which ruins their career.

Business Logic

If the database of colleges is created over a decentralized blockchain then it would ensure that only authorized / verified colleges are able to admit students. This can be achieved by deploying a smart contract over a public blockchain. 

The above items are added as input variables for two structs named “College” & “Student”. 

Smart Contract Features


Project Reference Outputs



Actual screenshots are added in further sections. 

Smart Contract Main Functions

Function Name

Description

Input

Response

addNewCollege ()

Only university admin can add new college

cName, cAddress, cAdmin, cRegNo

Integer success response

viewCollegeDetails ()

Anyone can view college details

cAddress

Displays cName, cRegNo

blockCollegeToAddNewStudents ()

Only university admin can block colleges from adding new students

cAddress

Integer success response

unblockCollegeToAddNewStudents ()

Only university admin can unblock colleges from adding new students

cAddress

Integer success response

addNewStudentToCollege ()

Only approved college admin can add new student to college

sName, sPhone, sAddress

Integer success response

getNumberOfStudentsForCollege ()

Anyone can view total number of students in any college

cAddress

Displays totalNoOfStudents

viewStudentDetails ()

Anyone can view student details

sName

Displays sName, sPhone, courseEnrolled

changeStudentCourse ()

Only approved college admin can change student course enrollment

sName, courseEnrolled, newCourse

Integer success response

Note: All inputs are string except cAddress which is the unique ETH address of each college and cAdmin too is the unique ETH address of the University Admin.

Source Code

// SPDX-License-Identifier: MIT

// compiler version must be greater than or equal to 0.8.10 and less than 0.9.0

 

pragma solidity ^0.8.13;

 

contract DecentralizedCollegeTracker {

   

address universityAdmin;

uint256 public totalNoOfColleges;

uint256 public totalNoOfStudents;

 

constructor() public {

   universityAdmin = msg.sender;

}

modifier onlyAdmin() {

   require(msg.sender == universityAdmin);

   _;}

   

struct College {

   string cName;  

   address cAddress;

   address cAdmin;

   string cRegNo;

   bool isAllowedToAddStudents;

   uint totalNoOfStudents;

}

 

struct Student {

   string sName;  

   uint sPhone;

   string courseEnrolled;

}

 

mapping (address => College) colleges; //  Mapping a college's address to college

mapping (string => Student) students; //  Mapping a student's name to student

 

function addNewCollege(string memory collegeName, address add, address cAdmin, string memory regNo) public onlyAdmin {

   require(!areBothStringSame(colleges[add].cName,collegeName), "College already exists with same name");

   colleges[add]= College(collegeName,add,cAdmin,regNo,true,0);

   totalNoOfColleges++;

}

     

function viewCollegeDetails(address add) public view returns (string memory, string memory, uint) {

   return (colleges[add].cName,colleges[add].cRegNo, colleges[add].totalNoOfStudents);

}

 

function blockCollegeToAddNewStudents(address add) public onlyAdmin {

   require(colleges[add].isAllowedToAddStudents, "College is already blocked to add new students");

   colleges[add].isAllowedToAddStudents=false;

}

 

function unblockCollegeToAddNewStudents(address add) public onlyAdmin {

   require(!colleges[add].isAllowedToAddStudents, "College is already unblocked to add new students");

   colleges[add].isAllowedToAddStudents=true;

}

   

function addNewStudentToCollege(address add,string memory sName, uint sPhone, string memory courseName ) public {

   require(colleges[add].isAllowedToAddStudents, "This College is blocked to add new students");

   require(colleges[add].cAdmin == msg.sender, "Only College admin can add the new student");

   students[sName] = Student(sName,sPhone,courseName);

   colleges[add].totalNoOfStudents += 1;

   totalNoOfStudents++;

    }

   

function getNumberOfStudentsForCollege(address add) public view returns(uint){

   return (colleges[add].totalNoOfStudents);

    }

     

function viewStudentDetails(string memory sName) public view returns (string memory, uint, string memory) {

   return (students[sName].sName,students[sName].sPhone, students[sName].courseEnrolled);

}

     

function changeStudentCourse(address add, string memory sName, string memory newCourse) public {

   require(!areBothStringSame(students[sName].courseEnrolled,newCourse), "Student already enrolled to same course");

   require(colleges[add].cAdmin == msg.sender, "Only College admin can change the student course");

   students[sName].courseEnrolled=newCourse;

}

 

function areBothStringSame(string memory a, string memory b) private pure returns (bool) {

   if(bytes(a).length != bytes(b).length) {

   return false;

   } else {

   return keccak256(bytes(a)) == keccak256(bytes(b));

   }

   }

 

}

Application Binary Interface

[

            {

                        "inputs": [

                                    {

                                                "internalType": "string",

                                                "name": "collegeName",

                                                "type": "string"

                                    },

                                    {

                                                "internalType": "address",

                                                "name": "add",

                                                "type": "address"

                                    },

                                    {

                                                "internalType": "address",

                                                "name": "cAdmin",

                                                "type": "address"

                                    },

                                    {

                                                "internalType": "string",

                                                "name": "regNo",

                                                "type": "string"

                                    }

                        ],

                        "name": "addNewCollege",

                        "outputs": [],

                        "stateMutability": "nonpayable",

                        "type": "function"

            },

            {

                        "inputs": [

                                    {

                                                "internalType": "address",

                                                "name": "add",

                                                "type": "address"

                                    },

                                    {

                                                "internalType": "string",

                                                "name": "sName",

                                                "type": "string"

                                    },

                                    {

                                                "internalType": "uint256",

                                                "name": "sPhone",

                                                "type": "uint256"

                                    },

                                    {

                                                "internalType": "string",

                                                "name": "courseName",

                                                "type": "string"

                                    }

                        ],

                        "name": "addNewStudentToCollege",

                        "outputs": [],

                        "stateMutability": "nonpayable",

                        "type": "function"

            },

            {

                        "inputs": [

                                    {

                                                "internalType": "address",

                                                "name": "add",

                                                "type": "address"

                                    }

                        ],

                        "name": "blockCollegeToAddNewStudents",

                        "outputs": [],

                        "stateMutability": "nonpayable",

                        "type": "function"

            },

            {

                        "inputs": [

                                    {

                                                "internalType": "address",

                                                "name": "add",

                                                "type": "address"

                                    },

                                    {

                                                "internalType": "string",

                                                "name": "sName",

                                                "type": "string"

                                    },

                                    {

                                                "internalType": "string",

                                                "name": "newCourse",

                                                "type": "string"

                                    }

                        ],

                        "name": "changeStudentCourse",

                        "outputs": [],

                        "stateMutability": "nonpayable",

                        "type": "function"

            },

            {

                        "inputs": [

                                    {

                                                "internalType": "address",

                                                "name": "add",

                                                "type": "address"

                                    }

                        ],

                        "name": "unblockCollegeToAddNewStudents",

                        "outputs": [],

                        "stateMutability": "nonpayable",

                        "type": "function"

            },

            {

                        "inputs": [],

                        "stateMutability": "nonpayable",

                        "type": "constructor"

            },

            {

                        "inputs": [

                                    {

                                                "internalType": "address",

                                                "name": "add",

                                                "type": "address"

                                    }

                        ],

                        "name": "getNumberOfStudentsForCollege",

                        "outputs": [

                                    {

                                                "internalType": "uint256",

                                                "name": "",

                                                "type": "uint256"

                                    }

                        ],

                        "stateMutability": "view",

                        "type": "function"

            },

            {

                        "inputs": [],

                        "name": "totalNoOfColleges",

                        "outputs": [

                                    {

                                                "internalType": "uint256",

                                                "name": "",

                                                "type": "uint256"

                                    }

                        ],

                        "stateMutability": "view",

                        "type": "function"

            },

            {

                        "inputs": [],

                        "name": "totalNoOfStudents",

                        "outputs": [

                                    {

                                                "internalType": "uint256",

                                                "name": "",

                                                "type": "uint256"

                                    }

                        ],

                        "stateMutability": "view",

                        "type": "function"

            },

            {

                        "inputs": [

                                    {

                                                "internalType": "address",

                                                "name": "add",

                                                "type": "address"

                                    }

                        ],

                        "name": "viewCollegeDetails",

                        "outputs": [

                                    {

                                                "internalType": "string",

                                                "name": "",

                                                "type": "string"

                                    },

                                    {

                                                "internalType": "string",

                                                "name": "",

                                                "type": "string"

                                    },

                                    {

                                                "internalType": "uint256",

                                                "name": "",

                                                "type": "uint256"

                                    }

                        ],

                        "stateMutability": "view",

                        "type": "function"

            },

            {

                        "inputs": [

                                    {

                                                "internalType": "string",

                                                "name": "sName",

                                                "type": "string"

                                    }

                        ],

                        "name": "viewStudentDetails",

                        "outputs": [

                                    {

                                                "internalType": "string",

                                                "name": "",

                                                "type": "string"

                                    },

                                    {

                                                "internalType": "uint256",

                                                "name": "",

                                                "type": "uint256"

                                    },

                                    {

                                                "internalType": "string",

                                                "name": "",

                                                "type": "string"

                                    }

                        ],

                        "stateMutability": "view",

                        "type": "function"

            }

]

This can be copied directly from the ABI button in the REMIX IDE window

Screenshots

Before Deployment


After Deployment

After Transactions


Transaction Evidence 

  • SC Deployment Addresses =>           
    • From: 0x63FD4b19801e31e5c4020D7f8e7298530E2586AE
    • To: 0x0000000000000000000000000000000001000008
  • Genesis Block => 
    • 0x87b39d18522397f40fe98143eacbe6888ec3cc3dd5747ec2514aad131b8c50f7
  • Transaction Hashes =>  
    • 0x87b39d18522397f40fe98143eacbe6888ec3cc3dd5747ec2514aad131b8c50f  
    • 0x5f662d57165051dd4ceaba8c54c377fd5311a07f16d98f6de22b3be554941fbb
    • 0x6b706f5b110b5965204486aa20d3cf5fc8a57fdb0e9ae82063b4e780562598e4
    • 0xb0e46d0a779ce162a885ca6f02dc501fa873713298e6b4198f2574c0a320b771
    • 0xf816854af5f5beeb6f2fc607820bd69bd4908805db20b6be3b656c8059d9d469
    • 0x8135849b0432dc2a5e6afa7d63abf3aa21cef218aa1ff047ecfd27b553a73c28
    • 0xc713d6aba41af2000537e8d84af936a8540deea43c42427151b215f9c38746f1
    • 0x8135849b0432dc2a5e6afa7d63abf3aa21cef218aa1ff047ecfd27b553a73c28

Conclusion

The smart contract when deployed on a large scale will enable transparency and integrity in the process of education. Further, several more features can be added into this SC like upvoting of colleges, transfer of students from one college to another, etc. Here, only the basic features have been added to demonstrate the business logic that is required as a solution. There are also ways to develop a frontend to access the SC features e.g. React.js. Those interested can even build a dAPP / DAO around this idea. 

A summary of the project is given below:

  • Smart Contract = DCTPAU.sol
  • Functions = 09 nos.
  • Lines of Code = 86
  • SC Deployment cost = 0.00003441 tRBTC
  • Total Transaction cost = 0.0000084 tRBTC
  • Cumulative Cost = 0.00004281 tRBTC
Note: The SC was deployed on RSK Testnet (Bitcoin Sidechain) where the cryptocurrency is RBTC / tRBTC.

Books By Dr. Prashant A U

  🔐 "ManusCrypt: Designed for Mankind" by Prashant A Upadhyaya 🔐 🚀 Revolutionizing Information Security for the Human Era! 🚀 ...