You are on page 1of 12

Decentralized KYC Verification Process for Banks

Prashant Upadhyaya
Post-Graduate Certificate Program in Blockchain
Indian Institute of Technology, Kanpur
drprashant79@protonmail.com
I. SOURCE CODE

Ethereum Smart Contract file: KYCPAU.sol

// 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.11;

contract kycpau {

// Struct Customer
// custName - username of the customer
// custData - customer data
// rating - rating given to customer given based on regularity
// upvotes - number of upvotes recieved from banks
// bank - address of bank that validated the customer account

struct Customer {
string custName;
string custData;
uint rating;
uint upvotes;
address bank;
string password;
}

// Struct Bank
// bankName - bankName of the bank
// ethAddress - ethereum address of the bank
// rating - rating based on number of valid/invalid verified accounts
// KYC_count - number of KYCs verified by the bank

struct Bank {
string bankName;
address ethAddress;
uint rating;
uint KYC_count;
string regNumber;
}

struct Request {
string custName;
address bankAddress;
bool isAllowed;
}

// list of all customers

Customer[] allCustomers;

// list of all Banks

Bank[] allBanks;

// list of all KYC Requests

Request[] allRequests;

function ifAllowed(string memory CustName, address bankAddress) public payable returns(bool) {


for(uint i = 0; i < allRequests.length; ++i) {
if(stringsEqual(allRequests[i].custName, CustName) && allRequests[i].bankAddress == bankAddress && allRequests[i].isAllowed)
{
return true;
}
}
return false;
}

function getBankRequests(string memory CustName, uint ind) public payable returns(address) {


uint j = 0;
for(uint i=0;i<allRequests.length;++i) {
if(stringsEqual(allRequests[i].custName, CustName) && j == ind && allRequests[i].isAllowed == false) {
return allRequests[i].bankAddress;
}
j ++;
}
return 0x4Ca570E48943baF02BF4D38af2189cE0208f9065;
}

function addRequest(string memory CustName, address bankAddress) public payable {


for(uint i = 0; i < allRequests.length; ++ i) {
if(stringsEqual(allRequests[i].custName, CustName) && allRequests[i].bankAddress == bankAddress) {
return;
}
}
allRequests.length;
allRequests[allRequests.length - 1] = Request(CustName, bankAddress, false);
}

function allowBank(string memory CustName, address bankAddress, bool ifallowed) public payable {
for(uint i = 0; i < allRequests.length; ++ i) {
if(stringsEqual(allRequests[i].custName, CustName) && allRequests[i].bankAddress == bankAddress) {
if(ifallowed) {
allRequests[i].isAllowed = true;
} else {
for(uint j=i;j<allRequests.length-2; ++j) {
allRequests[i] = allRequests[i+1];
}
allRequests.length;
}
return;
}
}
}

// internal function to compare strings

function stringsEqual(string storage _a, string memory _b) internal returns (bool) {
bytes storage a = bytes(_a);
bytes memory b = bytes(_b);
if (a.length != b.length)
return false;
// @todo unroll this loop
for (uint i = 0; i < a.length; i ++)
{
if (a[i] != b[i])
return false;
}
return true;
}

// function to check access rights of transaction request sender

function isPartOfOrg() public payable returns(bool) {


for(uint i = 0; i < allBanks.length; ++ i) {
if(allBanks[i].ethAddress == msg.sender)
return true;
}
return false;
}

// function that adds an Bank to the network


// returns 0 if successfull
// returns 7 if no access rights to transaction request sender
// no check on access rights if network strength in zero

function addBank(string memory custName, address eth, string memory regNum) public payable returns(uint) {
if(allBanks.length == 0 || isPartOfOrg()) {
allBanks.length;
allBanks[allBanks.length - 1] = Bank(custName, eth, 200, 0, regNum);
return 0;
}

return 7;
}

// function that removes an Bank from the network


// returns 0 if successful
// returns 7 if no access rights to transaction request sender
// returns 1 if Bank to be removed not part of network

function blockBank(address eth) public payable returns(uint) {


if(!isPartOfOrg())
return 7;
for(uint i = 0; i < allBanks.length; ++ i) {
if(allBanks[i].ethAddress == eth) {
for(uint j = i+1;j < allBanks.length; ++ j) {
allBanks[i-1] = allBanks[i];
}
allBanks.length;
return 0;
}
}
return 1;
}

// function to add a customer profile to the database


// returns 0 if successful
// returns 7 if no access rights to transaction request sender
// returns 1 if size limit of the database is reached
// returns 2 if customer already in network

function addCustomer(string memory CustName, string memory custData) public payable returns(uint) {
if(!isPartOfOrg())
return 7;
// throw error if userbankName already in use
for(uint i = 0;i < allCustomers.length; ++ i) {
if(stringsEqual(allCustomers[i].custName, CustName))
return 2;
}
allCustomers.length;
// throw error if there is overflow in uint
if(allCustomers.length < 1)
return 1;
allCustomers[allCustomers.length-1] = Customer(CustName, custData, 100, 0, msg.sender, "null");
updateRating(msg.sender,true);
return 0;
}

// function to remove fraudulent customer profile from the database


// returns 0 if successful
// returns 7 if no access rights to transaction request sender
// returns 1 if customer profile not in database

function blockCustomer(string memory CustName) public payable returns(uint) {


if(!isPartOfOrg())
return 7;
for(uint i = 0; i < allCustomers.length; ++ i) {
if(stringsEqual(allCustomers[i].custName, CustName)) {
address a = allCustomers[i].bank;
for(uint j = i+1;j < allCustomers.length; ++ j) {
allCustomers[i-1] = allCustomers[i];
}
allCustomers.length;
updateRating(a,false);
// updateRating(msg.sender, true);
return 0;
}
}
// throw error if custName not found
return 1;
}
// function to modify a customer profile in database
// returns 0 if successful
// returns 7 if no access rights to transaction request sender
// returns 1 if customer profile not in database

function modifyCustomer(string memory CustName,string memory custData) public payable returns(uint) {


if(!isPartOfOrg())
return 7;
for(uint i = 0; i < allCustomers.length; ++ i) {
if(stringsEqual(allCustomers[i].custName, CustName)) {
allCustomers[i].custData = custData;
allCustomers[i].bank = msg.sender;
return 0;
}
}
// throw error if custName not found
return 1;
}

// function to return customer profile data

function viewCustomer(string memory CustName) public payable returns(string memory) {


if(!isPartOfOrg())
return "Access denied!";
for(uint i = 0; i < allCustomers.length; ++ i) {
if(stringsEqual(allCustomers[i].custName, CustName)) {
return allCustomers[i].custData;
}
}
return "Customer not found in database!";
}

// function to modify customer rating

function updateRatingCustomer(string memory CustName, bool ifIncrease) public payable returns(uint) {


for(uint i = 0; i < allCustomers.length; ++ i) {
if(stringsEqual(allCustomers[i].custName, CustName)) {
//update rating
if(ifIncrease) {
allCustomers[i].upvotes ++;
allCustomers[i].rating += 100/(allCustomers[i].upvotes);
if(allCustomers[i].rating > 500) {
allCustomers[i].rating = 500;
}
}
else {
allCustomers[i].upvotes --;
allCustomers[i].rating -= 100/(allCustomers[i].upvotes + 1);
if(allCustomers[i].rating < 0) {
allCustomers[i].rating = 0;
}
}
return 0;
}
}
// throw error if bank not found
return 1;
}

// function to update Bank rating


// bool true indicates a succesfull addition of KYC profile
// false indicates detection of a fraudulent profile

function updateRating(address bankAddress,bool ifAdded) public payable returns(uint) {


for(uint i = 0; i < allBanks.length; ++ i) {
if(allBanks[i].ethAddress == bankAddress) {
//update rating
if(ifAdded) {
allBanks[i].KYC_count ++;
allBanks[i].rating += 100/(allBanks[i].KYC_count);
if(allBanks[i].rating > 500) {
allBanks[i].rating = 500;
}
}
else {
// allBanks[i].KYC_count --;
allBanks[i].rating -= 100/(allBanks[i].KYC_count + 1);
if(allBanks[i].rating < 0) {
allBanks[i].rating = 0;
}
}
return 0;
}
}
// throw error if bank not found
return 1;
}

// function to validate bank log in


// returns null if userbankName or password not correct
// returns bank bankName if correct
function checkBank(string memory CustName, address password) public payable returns(string memory) {
for(uint i = 0; i < allBanks.length; ++ i) {
if(allBanks[i].ethAddress == password && stringsEqual(allBanks[i].bankName, CustName)) {
return "0";
}
}
return "null";
}

function checkCustomer(string memory CustName, string memory password) public payable returns(bool) {
for(uint i = 0; i < allCustomers.length; ++ i) {
if(stringsEqual(allCustomers[i].custName, CustName) && stringsEqual(allCustomers[i].password, password)) {
return true;
}
if(stringsEqual(allCustomers[i].custName, CustName)) {
return false;
}
}
return false;
}
function setPassword(string memory CustName, string memory password) public payable returns(bool) {
for(uint i=0;i < allCustomers.length; ++ i) {
if(stringsEqual(allCustomers[i].custName, CustName) && stringsEqual(allCustomers[i].password, "null")) {
allCustomers[i].password = password;
return true;
}
}
return false;
}

// All getter functions

function getBankName(address ethAcc) public payable returns(string memory) {


for(uint i = 0; i < allBanks.length; ++ i) {
if(allBanks[i].ethAddress == ethAcc) {
return allBanks[i].bankName;
}
}
return "null";
}

function getBankEth(string memory custName) public payable returns(address) {


for(uint i = 0; i < allBanks.length; ++ i) {
if(stringsEqual(allBanks[i].bankName, custName)) {
return allBanks[i].ethAddress;
}
}
return 0x4Ca570E48943baF02BF4D38af2189cE0208f9065;
}

function getCustomerBankName(string memory CustName) public payable returns(string memory) {


for(uint i = 0;i < allCustomers.length; ++ i) {
if(stringsEqual(allCustomers[i].custName, CustName)) {
return getBankName(allCustomers[i].bank);
}
}
}

function getBankReg(address ethAcc) public payable returns(string memory) {


for(uint i = 0; i < allBanks.length; ++ i) {
if(allBanks[i].ethAddress == ethAcc) {
return allBanks[i].regNumber;
}
}
return "null";
}

function getBankKYC(address ethAcc) public payable returns(uint) {


for(uint i = 0; i < allBanks.length; ++ i) {
if(allBanks[i].ethAddress == ethAcc) {
return allBanks[i].KYC_count;
}
}
return 0;
}

function getBankRating(address ethAcc) public payable returns(uint) {


for(uint i = 0; i < allBanks.length; ++ i) {
if(allBanks[i].ethAddress == ethAcc) {
return allBanks[i].rating;
}
}
return 0;
}

function getCustomerBankRating(string memory CustName) public payable returns(uint) {


for(uint i = 0;i < allCustomers.length; ++ i) {
if(stringsEqual(allCustomers[i].custName, CustName)) {
return getBankRating(allCustomers[i].bank);
}
}
}
function getCustomerRating(string memory CustName) public payable returns(uint) {
for(uint i = 0; i < allCustomers.length; ++ i) {
if(stringsEqual(allCustomers[i].custName, CustName)) {
return allCustomers[i].rating;
}
}
return 0;
}

You might also like