0% found this document useful (0 votes)
37 views30 pages

Block Chain Lab Manual

......
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
37 views30 pages

Block Chain Lab Manual

......
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 30

LAB MANUAL

BLOCK CHAIN TECHNOLOGY

SCHOOL OF COMPUTING SCIENCE


& ENGINEERING

COMPUTER SCIENCE &

ENGINEERING 2024-2025
NAME OF STUDENT: Sarthak Mallick

ADMISSION NUMBER: 21SCSE1290011

1. Develop a Solidity-based marketplace where users can buy and sell digital goods.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Marketplace {
struct Item {
uint256 id;
string name;
address payable seller;
uint256 price;
address buyer;
bool isSold;
}

uint256 public itemCount;


mapping(uint256 => Item) public items;
mapping(address => uint256) public balances;

// Events
event ItemListed(uint256 id, string name, uint256 price, address seller);
event ItemPurchased(uint256 id, address buyer);
event Withdrawal(address seller, uint256 amount);

// List an item for sale


function listItem(string memory _name, uint256 _price) public {
require(_price > 0, "Price must be greater than zero");
itemCount++;
items[itemCount] = Item({
id: itemCount,
name: _name,
seller: payable(msg.sender),
price: _price,
buyer: address(0),
isSold: false
});
Here is the output.
2. Create a Solidity contract to automate the settlement of insurance claims.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Insurance {
// Structure for an insurance policy
struct Policy {
uint256 id;
address payable policyHolder;
uint256 premium;
uint256 coverageAmount;
bool isActive;
}

// Structure for a claim


struct Claim {
uint256 id;
uint256 policyId;
uint256 claimAmount;
bool isSettled;
bool isApproved;
}

uint256 public policyCount;


uint256 public claimCount;

mapping(uint256 => Policy) public policies;


mapping(uint256 => Claim) public claims;

event PolicyCreated(uint256 id, address policyHolder, uint256 premium, uint256 coverageAmount);


event ClaimSubmitted(uint256 claimId, uint256 policyId, uint256 claimAmount);
event ClaimSettled(uint256 claimId, bool approved, uint256 payoutAmount);

// Create a new insurance policy


function createPolicy(uint256 _premium, uint256 _coverageAmount) public payable {
require(msg.value == _premium, "You must pay the premium to create a policy");

policyCount++;
policies[policyCount] = Policy({
id: policyCount,
policyHolder: payable(msg.sender),
premium: _premium,
coverageAmount: _coverageAmount,
isActive: true
});

emit PolicyCreated(policyCount, msg.sender, _premium, _coverageAmount);


}

// Submit a claim for a policy


function submitClaim(uint256 _policyId, uint256 _claimAmount) public {
Policy storage policy = policies[_policyId];
require(policy.isActive, "Policy is not active");
require(policy.policyHolder == msg.sender, "Only the policyholder can submit a claim");
require(_claimAmount <= policy.coverageAmount, "Claim amount exceeds coverage");

claimCount++;
claims[claimCount] = Claim({
id: claimCount,
policyId: _policyId,
claimAmount: _claimAmount,
isSettled: false,
isApproved: false
});

emit ClaimSubmitted(claimCount, _policyId, _claimAmount);


}

// Settle a claim (automated based on conditions)


function settleClaim(uint256 _claimId, bool _approve) public {
Claim storage claim = claims[_claimId]; require(!
claim.isSettled, "Claim has already been settled");

claim.isSettled = true;
claim.isApproved = _approve;

if (_approve) {
Policy storage policy = policies[claim.policyId];
uint256 payoutAmount = claim.claimAmount;
policy.policyHolder.transfer(payoutAmount);

emit ClaimSettled(_claimId, true, payoutAmount);


} else {
emit ClaimSettled(_claimId, false, 0);
}
}

// Get policy details by ID


function getPolicy(uint256 _policyId) public view returns (Policy memory) {
return policies[_policyId];
}

// Get claim details by ID


function getClaim(uint256 _claimId) public view returns (Claim memory) {
return claims[_claimId];
}
}
Output
3. Apply blockchain technology to create a secure and transparent system for crowdfunding.
How would it operate.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Crowdfunding {
struct Campaign {
address payable creator;
uint256 goal;
uint256 deadline;
uint256 amountRaised;
bool isGoalMet;
mapping(address => uint256) contributions;
}

uint256 public campaignCount;


mapping(uint256 => Campaign) public campaigns;

// Events
event CampaignCreated(uint256 id, address creator, uint256 goal, uint256 deadline);
event ContributionReceived(uint256 campaignId, address contributor, uint256 amount);
event GoalReached(uint256 campaignId, uint256 amountRaised);
event RefundIssued(uint256 campaignId, address contributor, uint256 amount);

// Create a new crowdfunding campaign


function createCampaign(uint256 _goal, uint256 _duration) public {
campaignCount++;
Campaign storage campaign = campaigns[campaignCount];
campaign.creator = payable(msg.sender);
campaign.goal = _goal;
campaign.deadline = block.timestamp + _duration;
campaign.amountRaised = 0;
campaign.isGoalMet = false;

emit CampaignCreated(campaignCount, msg.sender, _goal, campaign.deadline);


}

// Contribute to a campaign
function contribute(uint256 _campaignId) public payable {
Campaign storage campaign = campaigns[_campaignId];
require(block.timestamp <= campaign.deadline, "Campaign is over");
require(msg.value > 0, "Contribution must be greater than zero");

campaign.contributions[msg.sender] += msg.value;
campaign.amountRaised += msg.value;

emit ContributionReceived(_campaignId, msg.sender, msg.value);

// Check if goal is met


if (campaign.amountRaised >= campaign.goal) {
campaign.isGoalMet = true;
campaign.creator.transfer(campaign.amountRaised);
emit GoalReached(_campaignId, campaign.amountRaised);
}
}

// Claim refund if goal is not met after deadline


function claimRefund(uint256 _campaignId) public
{
Campaign storage campaign = campaigns[_campaignId];
require(block.timestamp > campaign.deadline, "Campaign is still active");
require(!campaign.isGoalMet, "Campaign goal was met, no refunds available");

uint256 contribution = campaign.contributions[msg.sender];


require(contribution > 0, "No contributions to refund");

campaign.contributions[msg.sender] = 0;
payable(msg.sender).transfer(contribution);

emit RefundIssued(_campaignId, msg.sender, contribution);


}
}

OUTPUT
4. Build a contract for a lottery system where users can buy tickets and a winner is randomly
chosen.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Lottery {
address public manager;
address[] public players;
uint256 public ticketPrice;
bool public lotteryActive;

// Modifier to restrict functions to the manager


modifier onlyManager() {
require(msg.sender == manager, "Only the manager can call this function.");
_;
}

// Modifier to check if lottery is active


modifier isActive() {
require(lotteryActive, "The lottery is not active.");
_;
}

// Events for logging actions


event TicketPurchased(address indexed player, uint256 amount);
event WinnerSelected(address indexed winner, uint256
prizeAmount); event LotteryStarted(uint256 ticketPrice);
event LotteryEnded();

constructor() {
manager = msg.sender;
lotteryActive = false;
}

// Start the lottery and set the ticket price


function startLottery(uint256 _ticketPrice) public onlyManager { require(!
lotteryActive, "A lottery is already active.");

ticketPrice = _ticketPrice;
lotteryActive = true;
delete players; // Reset the players for a new round

emit LotteryStarted(ticketPrice);
}

// Buy a ticket by sending Ether


function buyTicket() public payable isActive {
require(msg.value == ticketPrice, "The ticket price must be paid in full.");

players.push(msg.sender);
emit TicketPurchased(msg.sender, msg.value);
}

// Pick a random winner (only manager can call this function)


function pickWinner() public onlyManager isActive {
require(players.length > 0, "No players have participated.");

// Pick a random index based on block data (not perfectly random)


uint256 randomIndex = random() % players.length;
address winner = players[randomIndex];

// Transfer the entire pool to the winner


uint256 prizeAmount = address(this).balance;
payable(winner).transfer(prizeAmount);

emit WinnerSelected(winner, prizeAmount);

// End the lottery after picking a winner


lotteryActive = false;
emit LotteryEnded();
}

// Generate a pseudo-random number (not suitable for production-level randomness)


function random() private view returns (uint256) {
return uint256(keccak256(abi.encodePacked(block.difficulty, block.timestamp, players)));
}

// Get the list of players


function getPlayers() public view returns (address[] memory) {
return players;
}

// Get the current lottery pool balance


function getBalance() public view returns (uint256) {
return address(this).balance;
}
}

OUTPUT
5. Build a smart contract with a modifier to check if a function is called by the owner.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract OwnerCheck {
address public owner;

// Constructor: sets the deployer as the owner


constructor() {
owner = msg.sender;
}

// Modifier to restrict access to only the owner


modifier onlyOwner() {
require(msg.sender == owner, "You are not the owner");
_;
}

// Function that only the owner can call


function restrictedAction() public onlyOwner {
// Code that only the owner can execute
}

// Function to change the owner (only the current owner can do this)
function changeOwner(address newOwner) public onlyOwner {
owner = newOwner;
}
}

OUTPUT
6. Create a smart contract for a simple auction where users can place bids.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SimpleAuction {
address payable public auctionOwner;
uint256 public auctionEndTime;
address public highestBidder;
uint256 public highestBid;
bool public auctionEnded;

mapping(address => uint256) public pendingReturns;

// Events for logging actions


event AuctionStarted(uint256 endTime);
event HighestBidIncreased(address bidder, uint256 amount);
event AuctionEnded(address winner, uint256 amount);
event Withdraw(address bidder, uint256 amount);

// Modifier to check if the auction is still running


modifier auctionActive() {
require(block.timestamp < auctionEndTime, "Auction is not active"); require(!
auctionEnded, "Auction has already ended");
_;
}

// Modifier to restrict access to the auction owner


modifier onlyOwner() {
require(msg.sender == auctionOwner, "Only the owner can call this function");
_;
}

// Constructor: sets the auction owner


constructor(uint256 _biddingTime) {
auctionOwner = payable(msg.sender);
auctionEndTime = block.timestamp + _biddingTime;

emit AuctionStarted(auctionEndTime);
}

// Place a bid
function placeBid() public payable auctionActive {
require(msg.value > highestBid, "There already is a higher bid");

// If there is a previous highest bidder, store their bid so they can withdraw it later
if (highestBid != 0) {
pendingReturns[highestBidder] += highestBid;
}

// Update the highest bid and bidder


highestBidder = msg.sender;
highestBid = msg.value;

emit HighestBidIncreased(msg.sender, msg.value);


}

// Withdraw overbid funds


function withdraw() public {
uint256 amount = pendingReturns[msg.sender];
require(amount > 0, "No funds to withdraw");

// Reset the pending return amount before transferring to avoid re-entrancy attacks
pendingReturns[msg.sender] = 0;

payable(msg.sender).transfer(amount);

emit Withdraw(msg.sender, amount);


}

// End the auction and transfer the highest bid to the auction owner
function endAuction() public onlyOwner {
require(block.timestamp >= auctionEndTime, "Auction has not ended yet"); require(!
auctionEnded, "Auction is already ended");

auctionEnded = true;

// Transfer the highest bid to the auction owner


auctionOwner.transfer(highestBid);

emit AuctionEnded(highestBidder, highestBid);


}
}

OUTPUT
7. Write a simple Solidity contract that stores a user's name

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract UserStorage {
string public userName;

// Constructor to initialize the contract with a name


constructor(string memory _name) {
userName = _name;
}

// Function to update the user's name


function setName(string memory _name) public
{ userName = _name;
}

// Function to get the user's name (optional, since userName is public)


function getName() public view returns (string memory) {
return userName;
}
}

OUTPUT
8. Implement Markel tree to encoded block chain data.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract MerkleTree {
// State variable to store the Merkle root
bytes32 public merkleRoot;

// Helper function to compute the hash of two nodes


function hashPair(bytes32 _a, bytes32 _b) private pure returns (bytes32) {
return keccak256(abi.encodePacked(_a, _b));
}

// Function to create a Merkle root from an array of transactions (or data hashes)
function createMerkleRoot(bytes32[] memory _dataHashes) public returns (bytes32) {
require(_dataHashes.length > 0, "Data hashes array cannot be empty");

// If the array has only one element, return it as the Merkle root
if (_dataHashes.length == 1) {
merkleRoot = _dataHashes[0];
return merkleRoot;
}

// While more than one node remains, combine nodes in pairs


while (_dataHashes.length > 1) {
uint256 length = _dataHashes.length;
uint256 newLength = (length + 1) / 2; // Handle odd number of elements
bytes32[] memory newLevel = new bytes32[](newLength);

for (uint256 i = 0; i < length / 2; i++) {


newLevel[i] = hashPair(_dataHashes[2 * i], _dataHashes[2 * i + 1]);
}

// If there's an odd number of nodes, hash the last one with itself
if (length % 2 == 1) {
newLevel[newLength - 1] = hashPair(_dataHashes[length - 1], _dataHashes[length - 1]);
}

// Proceed to the next level of the tree


_dataHashes = newLevel;
}

// The last remaining node is the Merkle root


merkleRoot = _dataHashes[0];
return merkleRoot;
}

// Function to verify a Merkle proof


function verifyMerkleProof(
bytes32[] memory proof,
bytes32 root,
bytes32 leaf,
uint256 index
) public pure returns (bool) {
bytes32 hash = leaf;

// Recompute the hash up the tree based on the proof


for (uint256 i = 0; i < proof.length; i++) {
if (index % 2 == 0) {
hash = keccak256(abi.encodePacked(hash, proof[i]));
} else {
hash = keccak256(abi.encodePacked(proof[i], hash));
}
index /= 2;
}

// Return whether the recalculated root matches the stored Merkle root
return hash == root;
}
}

OUTPUT
9. How to Create a Consecutive Block

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract ConsecutiveBlocks {
struct Block {
uint256 blockNumber;
bytes32 prevHash;
bytes32 blockHash;
uint256 timestamp;
string data; // This represents the data or transactions stored in the block
}

Block[] public blockchain;

// Constructor to initialize the first block (genesis block)


constructor(string memory genesisData) {
// The first block does not have a previous hash, so we use an empty hash
bytes32 genesisHash = keccak256(abi.encodePacked(genesisData, block.timestamp));
blockchain.push(Block({
blockNumber: 0,
prevHash: bytes32(0),
blockHash: genesisHash,
timestamp: block.timestamp,
data: genesisData
}));
}

// Function to add a new block to the chain


function addBlock(string memory _data) public {
// Get the previous block
Block storage prevBlock = blockchain[blockchain.length - 1];

// Calculate the new block's hash based on the previous block's hash and new data
bytes32 newBlockHash = keccak256(abi.encodePacked(prevBlock.blockHash, _data,
block.timestamp));

// Add the new block


blockchain.push(Block({
blockNumber: prevBlock.blockNumber + 1,
prevHash: prevBlock.blockHash,
blockHash: newBlockHash,
timestamp: block.timestamp,
data: _data
}));
}

// Function to get the total number of blocks


function getBlockCount() public view returns (uint256) {
return blockchain.length;
}

// Function to get details of a block by index


function getBlockDetails(uint256 index) public view returns (uint256, bytes32, bytes32, uint256, string
memory) {
require(index < blockchain.length, "Block does not exist");
Block memory blk = blockchain[index];
return (blk.blockNumber, blk.prevHash, blk.blockHash, blk.timestamp, blk.data);
}
}

OUTPUT
10. Write a program in Solidity Language.

OUTPUT
11. Implementation of a blockchain in C++ - Peer-to-Peer network, SHA-256.

#include <iostream>
#include <sstream>
#include <vector>
#include <ctime>
#include <string>
#include <openssl/sha.h> // SHA-256 library from OpenSSL

// Helper function to calculate SHA-256 hash


std::string sha256(const std::string str) {
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, str.c_str(),
str.size()); SHA256_Final(hash, &sha256);

std::stringstream ss;
for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
ss << std::hex << (int)hash[i];
}
return ss.str();
}

// Block class representing each block in the blockchain


class Block {
public:
int index; // Block index
std::string previousHash; // Hash of the previous block
std::string timestamp; // Timestamp of block creation
std::string data; // Data (e.g., transaction data)
std::string hash; // Hash of this block

Block(int idx, std::string prevHash, std::string data) {


index = idx;
previousHash = prevHash;
this->data = data;
timestamp = std::to_string(time(nullptr)); // Get current time as string
hash = calculateHash(); // Calculate the hash for this block
}

// Function to calculate the hash of the block


std::string calculateHash() const {
std::stringstream ss;
ss << index << previousHash << timestamp << data;
return sha256(ss.str()); // Return the SHA-256 hash of the concatenated string
}
};

// Blockchain class to manage a chain of blocks


class Blockchain {
public:
Blockchain() {
chain.push_back(createGenesisBlock()); // Add the genesis block at creation
}

// Function to create the genesis (first) block


Block createGenesisBlock() {
return Block(0, "0", "Genesis Block");
}

// Function to return the latest block in the chain


Block getLatestBlock() const {
return chain.back();
}

// Function to add a new block to the blockchain


void addBlock(Block newBlock) {
newBlock.previousHash = getLatestBlock().hash; // Set the previous hash
newBlock.hash = newBlock.calculateHash(); // Calculate the new block's hash
chain.push_back(newBlock); // Add the block to the chain
}

// Function to print the entire blockchain


void printBlockchain() const {
for (const Block &block : chain) {
std::cout << "Block #" << block.index << "\n";
std::cout << "Previous Hash: " << block.previousHash << "\n";
std::cout << "Timestamp: " << block.timestamp << "\n";
std::cout << "Data: " << block.data << "\n";
std::cout << "Hash: " << block.hash << "\n\n";
}
}

private:
std::vector<Block> chain; // Vector to store the blockchain
};

int main() {
// Create a new blockchain
Blockchain myBlockchain;

// Add blocks with data to the blockchain


myBlockchain.addBlock(Block(1, "", "Transaction 1: Alice pays Bob 10 BTC"));
myBlockchain.addBlock(Block(2, "", "Transaction 2: Bob pays Charlie 5 BTC"));

// Print the blockchain


myBlockchain.printBlockchain();

return 0;
}
12. Implement Diffie-Hellman Algorithm in C++.

#include <iostream>
#include <cmath> // For pow
#include <cstdlib> // For rand()
#include <ctime> // For srand()

// Function to perform modular exponentiation (x^y mod p)


// It returns (x^y) % p
long long modExp(long long base, long long exp, long long mod) {
long long result = 1;
base = base % mod;
while (exp > 0) {
// If exp is odd, multiply base with result
if (exp % 2 == 1)
result = (result * base) % mod;

// exp must be even now


exp = exp >> 1; // Divide exp by 2
base = (base * base) % mod; // Square the base
}
return result;
}

int main() {
// 1. Publicly agreed values (prime p and base g)
long long p = 23; // A prime number
long long g = 5; // A primitive root modulo p

std::cout << "Publicly shared prime number (p): " << p << std::endl;
std::cout << "Publicly shared base (g): " << g << std::endl;

// 2. Secret keys generated by both parties


srand(time(0)); // Seed for random number generation
long long a = rand() % 10 + 1; // Secret key for Party 1
long long b = rand() % 10 + 1; // Secret key for Party 2

std::cout << "Party 1's secret key (a): " << a << std::endl;
std::cout << "Party 2's secret key (b): " << b << std::endl;

// 3. Public keys calculated and exchanged


long long A = modExp(g, a, p); // Party 1's public key A = g^a mod p
long long B = modExp(g, b, p); // Party 2's public key B = g^b mod p

std::cout << "Party 1's public key (A): " << A << std::endl;
std::cout << "Party 2's public key (B): " << B << std::endl;

// 4. Shared secret computation


long long sharedSecret1 = modExp(B, a, p); // Party 1 calculates: (B^a mod p)
long long sharedSecret2 = modExp(A, b, p); // Party 2 calculates: (A^b mod p)

std::cout << "Shared secret calculated by Party 1: " << sharedSecret1 << std::endl;
std::cout << "Shared secret calculated by Party 2: " << sharedSecret2 << std::endl;
if (sharedSecret1 == sharedSecret2) {
std::cout << "Success! Both parties have the same shared secret: " << sharedSecret1 <<
std::endl;
} else {
std::cout << "Error! The shared secrets do not match." << std::endl;
}

return 0;
}

OUTPUT
13. Using RSA algorithm encrypt a text data and decrypt the same.

#include <iostream>
#include <cmath> // For pow()
#include <cstdlib> // For rand() and srand()
#include <ctime> // For time()

// Function to compute the greatest common divisor (GCD)


int gcd(int a, int b) {
while (b != 0) {
int t = b;
b = a % b;
a = t;
}
return a;
}

// Function to perform modular exponentiation (base^exp %


mod) long long modExp(long long base, long long exp, long long
mod) {
long long result = 1;
base = base % mod;
while (exp > 0) {
if (exp % 2 == 1) // If exp is odd
result = (result * base) % mod;
exp = exp >> 1; // Divide exp by 2
base = (base * base) % mod; // Square the base
}
return result;
}

// Function to compute the modular inverse of e under modulo phi


int modInverse(int e, int phi) {
for (int x = 1; x < phi; x++) {
if ((e * x) % phi == 1)
return x;
}
return -1; // If modular inverse doesn't exist
}

// RSA encryption function


long long encrypt(long long message, int e, long long n) {
return modExp(message, e, n); // c = m^e % n
}

// RSA decryption function


long long decrypt(long long ciphertext, int d, long long n) {
return modExp(ciphertext, d, n); // m = c^d % n
}

int main() {
// Step 1: Key generation
srand(time(0));

// Two prime numbers


int p = 61; // Prime number 1
int q = 53; // Prime number 2

// n = p * q
long long n = p * q;

// Euler's totient function phi(n) = (p-1) * (q-1)


long long phi = (p - 1) * (q - 1);

// Public key exponent e (choose e such that 1 < e < phi(n) and gcd(e, phi(n)) == 1)
int e = 17; // Commonly used value for e

// Ensure e and phi are coprime


if (gcd(e, phi) != 1) {
std::cout << "e and phi are not coprime!" << std::endl;
return 1;
}

// Private key exponent d (modular inverse of e modulo phi)


int d = modInverse(e, phi);

// Ensure d is computed correctly


if (d == -1) {
std::cout << "Modular inverse of e does not exist!" << std::endl;
return 1;
}

std::cout << "Public key (e, n): (" << e << ", " << n << ")" << std::endl;
std::cout << "Private key (d, n): (" << d << ", " << n << ")" << std::endl;

// Step 2: Encryption
std::string message;
std::cout << "Enter the message to encrypt (as a number): ";
std::cin >> message;

long long numericMessage = std::stoll(message); // Convert message to number


long long ciphertext = encrypt(numericMessage, e, n); // Encrypt the message
std::cout << "Encrypted message (ciphertext): " << ciphertext << std::endl;

// Step 3: Decryption
long long decryptedMessage = decrypt(ciphertext, d, n); // Decrypt the message
std::cout << "Decrypted message: " << decryptedMessage << std::endl;

return 0;
}
OUTPUT

14. Implementation Supply chain Management system through Blockchain Technology.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract SupplyChain {

// Enum to track the status of a product


enum Status { Manufactured, Shipped, InTransit, Delivered }

struct Product {
uint productId;
string name;
string manufacturer;
string currentLocation;
Status status;
address owner;
}

// State variables
mapping(uint => Product) public products;
uint public productCounter = 0;
// Events to log significant changes in product status
event ProductManufactured(uint productId, string name, string manufacturer);
event ProductShipped(uint productId, string location);
event ProductInTransit(uint productId, string location);
event ProductDelivered(uint productId, string location);

// Modifier to check that only the owner of the product can perform certain actions
modifier onlyOwner(uint _productId) {
require(products[_productId].owner == msg.sender, "Not the owner of the product");
_;
}

// Function to manufacture a product


function manufactureProduct(string memory _name, string memory _manufacturer, string
memory _location) public {
productCounter++;
products[productCounter] = Product(productCounter, _name, _manufacturer, _location,
Status.Manufactured, msg.sender);

// Emit event
emit ProductManufactured(productCounter, _name, _manufacturer);
}

// Function to ship the product to a new location


function shipProduct(uint _productId, string memory _newLocation) public
onlyOwner(_productId) {
require(products[_productId].status == Status.Manufactured, "Product is not in the
Manufactured state");

products[_productId].currentLocation = _newLocation;
products[_productId].status = Status.Shipped;

// Emit event
emit ProductShipped(_productId, _newLocation);
}

// Function to update the product status to In Transit


function updateInTransit(uint _productId, string memory _location) public onlyOwner(_productId)
{
require(products[_productId].status == Status.Shipped, "Product is not in the Shipped state");

products[_productId].currentLocation = _location;
products[_productId].status = Status.InTransit;

// Emit event
emit ProductInTransit(_productId, _location);
}

// Function to deliver the product


function deliverProduct(uint _productId, string memory _location) public onlyOwner(_productId) {
require(products[_productId].status == Status.InTransit, "Product is not in the InTransit
state");

products[_productId].currentLocation = _location;
products[_productId].status = Status.Delivered;
// Emit event
emit ProductDelivered(_productId, _location);
}

// Function to get the details of a product


function getProduct(uint _productId) public view returns (
string memory name,
string memory manufacturer,
string memory currentLocation,
Status status,
address owner
){
Product memory product = products[_productId];
return (product.name, product.manufacturer, product.currentLocation, product.status,
product.owner);
}
}

OUTPUT
15. Implementation of Healthcare solutions through blockchain.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Healthcare {

// Struct to store medical record details


struct MedicalRecord {
uint recordId;
string diagnosis;
string treatment;
uint date;
address doctor;
}

// Struct to store patient details


struct Patient {
uint patientId;
string name;
address patientAddress;
MedicalRecord[] medicalRecords;
mapping(address => bool) authorizedDoctors;
}

// State variables
mapping(address => Patient) public patients;
mapping(uint => address) public
patientById; uint public patientCount = 0;
uint public recordCount = 0;

// Event to log new medical record creation


event MedicalRecordCreated(uint recordId, uint patientId, address doctor, string diagnosis);

// Modifier to restrict access to the patient or authorized doctor


modifier onlyPatientOrAuthorizedDoctor(uint _patientId) {
require(
patientById[_patientId] == msg.sender ||
patients[patientById[_patientId]].authorizedDoctors[msg.sender],
"Access denied"
);
_;
}

// Function for a patient to register themselves


function registerPatient(string memory _name) public {
require(bytes(_name).length > 0, "Name cannot be empty");
require(patients[msg.sender].patientId == 0, "Patient already registered");

patientCount++;
patients);
patientById[patientCount] = msg.sender;
}
// Function to authorize a doctor to access the patient's medical records
function authorizeDoctor(uint _patientId, address _doctor) public {
require(patientById[_patientId] == msg.sender, "Only the patient can authorize");
patients[msg.sender].authorizedDoctors[_doctor] = true;
}

// Function to revoke a doctor's access to the patient's medical records


function revokeDoctor(uint _patientId, address _doctor) public {
require(patientById[_patientId] == msg.sender, "Only the patient can revoke authorization");
patients[msg.sender].authorizedDoctors[_doctor] = false;
}

// Function for a doctor to add a medical record for a patient


function addMedicalRecord(uint _patientId, string memory _diagnosis, string memory _treatment)
public onlyPatientOrAuthorizedDoctor(_patientId) {
require(patientById[_patientId] != address(0), "Patient does not exist");

recordCount++;
MedicalRecord memory newRecord = MedicalRecord(recordCount, _diagnosis, _treatment,
block.timestamp, msg.sender);
patients[patientById[_patientId]].medicalRecords.push(newRecord);

// Emit an event for the new medical record


emit MedicalRecordCreated(recordCount, _patientId, msg.sender, _diagnosis);
}

// Function for a patient or authorized doctor to view a patient's medical records


function viewMedicalRecords(uint _patientId) public view onlyPatientOrAuthorizedDoctor(_patientId)
returns (MedicalRecord[] memory) {
return patients[patientById[_patientId]].medicalRecords;
}

// Function to get a patient's details


function getPatientDetails(uint _patientId) public view returns (string memory name, address
patientAddress, uint numRecords) {
Patient memory patient = patients[patientById[_patientId]];
return (patient.name, patient.patientAddress, patient.medicalRecords.length);
}
}

You might also like