Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abhishek sub #3

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
117 changes: 117 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Introduction
This repository contrain Assessment Submission of task given by HogoByte.

## Blockchain Ledger
This is a simple implementation of a blockchain ledger in C++. It allows you to add transactions, create blocks, validate the ledger, and print the ledger.

## Prerequisites
To compile and run this code, you need to have the following installed on your system:

- C++ compiler (supporting C++11 or later)
- OpenSSL library


## Compilation
To compile the code, follow these steps:

1. Clone the repository or download the source code files.
2. Open a terminal or command prompt.
3. Navigate to the directory where the source code files are located.
4. Run the following command to compile the code:
- g++ blockchain.cpp -o program -lssl -lcrypto (This command uses the g++ compiler, sets the C++ version to C++11, and links against the OpenSSL library.)

## Execution
1. Open a terminal or command prompt.
2. If there are no compilation errors, an executable file named `program` will be generated in the same directory.
Navigate to the directory where the `program` executable is located.
- ./program

## Usage
Here's a brief description of the available operations:

1. **Add Transaction**: Allows you to add a transaction to the transaction pool.
2. **Add Block**: Creates a new block with the transactions in the transaction pool and adds it to the blockchain.
3. **Validate Ledger**: Checks the integrity and validity of the blockchain.
4. **Print Ledger**: Displays the entire blockchain with block details and transactions.
5. **Exit**: Quits the program.

## Example
Starting Blockchain Ledger...

Enter a number to perform an operation:
1: Add Transaction
2: Add Block
3: Validate Ledger
4: Print Ledger
5: Exit

1

Enter Transaction: Abhishek to Rajat, 50 INR
Transaction Successfully added..

Enter a number to perform an operation:
1: Add Transaction
2: Add Block
3: Validate Ledger
4: Print Ledger
5: Exit

1

Enter Transaction: Abhishek to Swapnil, 40 INR
Transaction Successfully added..

Enter a number to perform an operation:
1: Add Transaction
2: Add Block
3: Validate Ledger
4: Print Ledger
5: Exit

2

Block successfully added to Blockchain...

Enter a number to perform an operation:
1: Add Transaction
2: Add Block
3: Validate Ledger
4: Print Ledger
5: Exit

4

Block Index: 1
Block Hash: 2f64366f6d4433eaf48293313f1f82668afcee78f5f0394042dda4327a20cc8e
Previous Hash: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Transactions:
- Abhishek to Swapnil, 40 INR
- Abhishek to Rajat, 50 INR
------------------------
Block Index: 0
Block Hash: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Previous Hash:
Transactions:

-------------------------
Enter a number to perform an operation:
1: Add Transaction
2: Add Block
3: Validate Ledger
4: Print Ledger
5: Exit

3

Blockchain is valid.

Enter a number to perform an operation:
1: Add Transaction
2: Add Block
3: Validate Ledger
4: Print Ledger
5: Exit



3 changes: 3 additions & 0 deletions Solution/block.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "block.h"

// No additional implementation required for the block structure
17 changes: 17 additions & 0 deletions Solution/block.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef BLOCK_H
#define BLOCK_H

#include <string>
#include "transaction.h"

struct Block {
int index;
std::string blockHash;
std::string previousHash;
TransactionNode* transactions;
Block* previousBlock;

Block() : transactions(nullptr), previousBlock(nullptr) {}
};

#endif // BLOCK_H
201 changes: 201 additions & 0 deletions Solution/blockchain.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
#include "blockchain.h"
#include <iostream>
#include <functional>
#include <openssl/sha.h>
#include <openssl/evp.h>
#include <iomanip>

using namespace std;

Blockchain::Blockchain() {

//Initialize the transactionPool to nullptr
transactionPool = nullptr;

// Initialize the chain with a genesis block
chainHead = new Block;
chainHead->index = 0;
chainHead->blockHash = calculateHash("");
chainHead->previousHash = "";
chainHead->transactions = nullptr;
}

Blockchain::~Blockchain() {
// Delete the blockchain chain
Block* currentBlock = chainHead;
while (currentBlock != nullptr) {
TransactionNode* currentTransaction = currentBlock->transactions;
while (currentTransaction != nullptr) {
TransactionNode* nextTransaction = currentTransaction->next;
delete currentTransaction;
currentTransaction = nextTransaction;
}
Block* nextBlock = currentBlock->previousBlock;
delete currentBlock;
currentBlock = nextBlock;
}
}

void Blockchain::addBlock(TransactionNode* transactions) {
// Create a new block
Block* newBlock = new Block;

// Concanate all transactions to stringBuilder and calculate Hash
TransactionNode* tempHead = transactions;
string transactionBuilder = "";
while(tempHead != NULL) {
transactionBuilder += tempHead->transaction;
tempHead = tempHead->next;
}
string blockHash = calculateHash(transactionBuilder);

// new block have it's own hash and previous block hash
newBlock->blockHash = blockHash;
newBlock->previousHash = chainHead->blockHash;
newBlock->transactions = transactions;
newBlock->index = chainHead->index + 1;

// Update the chain head
newBlock->previousBlock = chainHead;
chainHead = newBlock;

// Remove old transactions
transactionPool = nullptr;
cout<<"Block successfully added to Blockchain..."<<endl;
cout<<endl;
}


void Blockchain::addTransaction(const string& transaction) {
// Create a new transaction node
TransactionNode* newTransaction = new TransactionNode(transaction);

// Add the transaction to the current block's linked list of transactions
newTransaction->next = transactionPool;
transactionPool = newTransaction;
cout<<"Transaction Successfully added.."<<endl;
cout<<endl;
}

bool Blockchain::validateChain() const {
// Traverse the chain and validate each block's hash
Block* currentBlock = chainHead;
while (currentBlock->previousBlock != nullptr) {
//calculate hash of previous block
TransactionNode* transactionhead = currentBlock->previousBlock->transactions;
string transactions = "";
while(transactionhead != NULL) {
transactions += transactionhead->transaction;
transactionhead = transactionhead->next;
}

string prevBlockHash = calculateHash(transactions);

if (currentBlock->previousHash != prevBlockHash) {
return false; // Invalid chain
}
currentBlock = currentBlock->previousBlock;
}

return true; // return true if Valid chain
}




void Blockchain::printChain() const {
Block* currentBlock = chainHead;
while (currentBlock != nullptr) {
cout << "Block Index: " << currentBlock->index << endl;
cout << "Block Hash: " << currentBlock->blockHash << endl;
cout << "Previous Hash: " << currentBlock->previousHash << endl;

cout << "Transactions:" << endl;
TransactionNode* currentTransaction = currentBlock->transactions;
while (currentTransaction != nullptr) {
cout << " - " << currentTransaction->transaction << endl;
currentTransaction = currentTransaction->next;
}

cout << "------------------------" << endl;
cout<<endl;
currentBlock = currentBlock->previousBlock;
}
}



string Blockchain::calculateHash(const string& data) const {
EVP_MD_CTX* mdContext = EVP_MD_CTX_new();

EVP_DigestInit(mdContext, EVP_sha256());
EVP_DigestUpdate(mdContext, data.c_str(), data.length());

unsigned char hash[EVP_MAX_MD_SIZE];
unsigned int hashLength;
EVP_DigestFinal(mdContext, hash, &hashLength);

EVP_MD_CTX_free(mdContext);

stringstream ss;
ss << hex << setfill('0');
for (unsigned int i = 0; i < hashLength; ++i) {
ss << setw(2) << static_cast<int>(hash[i]);
}

return ss.str();
}



//main function
int main() {
cout << "Starting Blockchain Ledger..." << endl;
Blockchain blockchain;

while (true) {
int inputNumber;
cout << "Enter a number to perform an operation:" << endl;
cout << "1: Add Transaction" << endl;
cout << "2: Add Block" << endl;
cout << "3: Validate Ledger" << endl;
cout << "4: Print Ledger" << endl;
cout << "5: Exit" << endl;
cin >> inputNumber;
cout<<endl;

switch (inputNumber) {
case 1: {
cout << "Enter Transaction: ";
string transactionInput;
cin.ignore();
getline(cin, transactionInput);
blockchain.addTransaction(transactionInput);
break;
}
case 2:
blockchain.addBlock(blockchain.transactionPool);
break;
case 3: {
bool isValid = blockchain.validateChain();
if (isValid) {
cout << "Blockchain is valid." << endl;
} else {
cout << "Blockchain is invalid." << endl;
}
break;
}
case 4:
blockchain.printChain();
break;
case 5:
cout << "Exiting..." << endl;
return 0;
default:
cout << "Error: Unknown operation." << endl;
break;
}
}

return 0;
}
24 changes: 24 additions & 0 deletions Solution/blockchain.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef BLOCKCHAIN_H
#define BLOCKCHAIN_H

#include <string>
#include "block.h"
#include "transaction.h"

class Blockchain {
private:
Block* chainHead;
public:
TransactionNode* transactionPool;
Blockchain();
~Blockchain();
void addBlock(TransactionNode* transactions);
void addTransaction(const std::string& transaction);
bool validateChain() const;
void printChain() const;

private:
std::string calculateHash(const std::string& data) const;
};

#endif // BLOCKCHAIN_H
Loading