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).
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