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);
}
}