(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.)
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
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"
}
]
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