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

Cbt-Record Removed Merged

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

Cbt-Record Removed Merged

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

UNIVERSITY COLLEGE OF ENGINEERING

KANCHEEPURAM
(A Constituent college of Anna University Chennai)
DEPARTMENT OF COMPUTER SCIENCE & ENGINEERING

CCS339 - CRYPTOCURRENCY AND BLOCKCHAIN


TECHNOLOGIES

Name:
Register no:
Year/Semester: Branch:
UNIVERSITY COLLEGE OF ENGINEERING KANCHEEPURAM
KANCHEEPURAM - 631 552

BONAFIDE CERTIFICATE

REGISTER NO

Certified that this is the bonafide record of work done by


Mr/Ms……………………………………….. of …… semester B.E. Computer Science
and Engineering Branch / Batch during the academic year 20….to 20…. in the
CCS339 – CRYPTOCURRENCY AND BLOCKCHAIN TECHNOLOGIES.

Staff In-Charge Head of the Department

Submitted for the University Practical examination held on ………………………

Internal Examiner External Examiner


INDEX

EX.NO DATE LIST OF EXPERIMENTS PAGE SIGNATURE


Install and understand Docker
container, Node.js, Java and
1. Hyperledger Fabric, Ethereum
and perform necessary
software installation on Local
machine.
Create and deploy a blockchain
2. network and perform invoke
and query on your blockchain
network.

Interact with a blockchain


network. Execute transactions
3. and requests against a
blockchain network by
creating an app to test the
network and its rules.
Deploy an asset-transfer app
4. using blockchain.

Use blockchain to track fitness


club rewards. Build a web app
5. to track and trace member
rewards.

Use blockchain to create a Car


6. Auction Network
EX.NO: 1
Install and understand Docker container, Node.js, Java and
Hyperledger Fabric, Ethereum and perform necessary software
DATE:
installation on Local machine.

AIM:
• Verify the installation of Docker, Node.js, and Java.
• Set up Hyperledger Fabric using Docker.
• Set up a local Ethereum environment using Docker and Ganache.

PREREQUISITES:

• A machine running Ubuntu.


• Basic understanding of command-line operations

PROCEDURE:

VERIFYING DOCKER, NODEJS, JAVA INSTALLATION:

1. Open Linux terminal using WSL (Windows Subsystem for Linux) or using VirtualBox.

Docker:
2. Verify the installation of Docker.

3. If not download using the below command:

curl -fsSL https://get.docker.com -o get-docker.sh


sudo sh get-docker.sh

Nodejs:
4. Verify the installation of Nodejs and install if not present.
Java:
5. Verify the installation of Java and install if not present

SETUP HYPERLEDGER FABRIC USING DOCKER:

1. Install cURL

2. Cloning sample fabric repository

3. Install Fabric samples, Binaries and Docker images.

4. Start the containers


5. Verify whether the containers are running using Docker Desktop

Thus, Hyperledger Fabric is setup on Local machine through Docker.

SETUP ETHEREUM ENVIRONMENT USING DOCKER AND GANACHE:

1. Install Ganache
2. The interface will be like this :
3. Create a folder Ethereum_ganache

4. Inside it create a docker-compose.yml file.


5. Write the following code in it:

version: '3'
services:
ganache:
image: trufflesuite/ganache-cli
ports:
- "8545:8545"
command: >
ganache-cli
--host 0.0.0.0
--port 8545
--networkId 5777
--mnemonic "candy maple cake sugar pudding cream honey rich smooth crumble sweet
treat"

6. Create and start the container

7. View the Logs


8. Verify in Docker Desktop

RESULT:

Thus, Docker, Java, NodeJS have been successfully installed and the Hyperledger Fabric
and Ethereum Network have been setup on the Local machine using Docker
.
EX.NO: 2 Create and deploy a blockchain network and perform invoke and
query on your blockchain network.
DATE:

AIM:
To create a blockchain network and perform invoke and query on the deployed blockchain
network.

PROCEDURE:

1. Install Ganache and install ganache package globally.

2. Ganache Desktop version can be downloaded from


https://archive.trufflesuite.com/ganache/

3. Create a Folder and name it as ethereum_blockchain


4. Install truffle globally

5. Initialize truffle
6. Modify the truffle with the code below

module.exports = {
networks : {
development : {
host : '127.0.0.1',
port : 5777,
network_id : "*"
}
},
compilers : {
solc : {
version : "0.8.19"
}
}
}
7. Now, in the contracts folder create a contract and name it as SimpleStorage.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract SimpleStorage {
uint256 storedData;

function set(uint256 x) public {


storedData = x;
}

function get() public view returns (uint256) {


return storedData;
}
}

8. This contract allows us to invoke and query the locally deployed Ethereum Blockchain.
9. Now, in the migrations folder create a file and name it as 2_deploy_contracts.js and write
the code below
const SimpleStorage = artifacts.require("SimpleStorage");

module.exports = function (deployer) {


deployer.deploy(SimpleStorage);
};

10. Now compile the contract


11. Now, migrate to the deployed local ethereum network.

12. Now, we will be ale to interact with the blockchain, by using the command truffle console.

13. Create an instance to invoke and query the blockchain

14. Now, invoke a value to the SimpleStorage contract


15. Now, query for the value

16. Thus, the contract works perfectly.

RESULT:
Thus, created a blockchain network and performed invoke and query on the deployed
blockchain network.
EX.NO: 3
Interact with a blockchain network. Execute transactions and
requests against a blockchain network by creating an app to test the
DATE:
network and its rules.

AIM:
To setup a Blockchain network and execute Transactions and Requests against a Blockchain
network and test by developing an application.

PROCEDURE:

1. Install Nodejs and install the packages ganache and truffle.


2. Create a new folder and initialize truffle in the project by the below code
truffle init
3. Modify the truffle-config.js with the below code

module.exports = {
networks: {
development: {
host: '127.0.0.1',
port: 7545,
network_id: '*'
}
},
compilers: {
solc: {
version: "0.8.19"
}
}
}

4. Create a Smart Contract for a sample data storing app

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

contract SimpleStorage {

uint256 private storedData;

event DataStored(uint256 value);

function set(uint256 x) public {


storedData = x;
emit DataStored(x);
}

function get() public view returns (uint256) {


return storedData;
}
}

5. Compile and deploy the contract

truffle migrate –reset


truffle compile
truffle console

6. Develop a Frontend Application to test the contract


7. Create a React Vite App
npx create-vite@latest <project-name>
8. Now create a folder named utils/constants and create a file named contract_data.js
and store the abi and contract_address

9. Now create a component for interacting with the contract


import { ethers } from "ethers";
import { useEffect, useState } from "react";
import toast from "react-hot-toast";
import { abi, contractAddress } from "./utils/constants/contract_data";

const SimpleStorageComponent = () => {


const [storedValue, setStoredValue] = useState("");
const [valueToSet, setValueToSet] = useState("");
const [loading, setLoading] = useState(false);

useEffect(() => {
fetchStoredValue();
}, []);

const fetchStoredValue = async () => {


const provider = new ethers.BrowserProvider(window.ethereum);
const contract = new ethers.Contract(contractAddress, abi, provider);
try {
const value = await contract.get();
setStoredValue(value.toString());
} catch (error) {
console.error(error);
toast.error('Failed to fetch stored value from contract');
}
};

const setValue = async (e) => {


e.preventDefault();
setLoading(true);
const provider = new ethers.BrowserProvider(window.ethereum);
const contract = new ethers.Contract(contractAddress, abi, provider);
try {
const signer = await provider.getSigner();
const tx = await contract.connect(signer).set(valueToSet);
await tx.wait();
toast.success('Value set successfully!');
fetchStoredValue();
} catch (error) {
console.error(error);
toast.error('Error setting value');
} finally {
setLoading(false);
}
};

return (
<div className="flex flex-col items-center mt-16">
<h1 className="text-3xl text-neutral-700 font-bold">Simple Storage</h1>

<form onSubmit={setValue} className="flex flex-col items-center mt-6">


<input
type="number"
value={valueToSet}
onChange={(e) => setValueToSet(e.target.value)}
className="border rounded-md p-2 mb-2"
placeholder="Set a value"
required
/>
<button
type="submit"
className="bg-blue-500 text-white px-3 py-2 rounded-md shadow-sm"
disabled={loading}
>
{loading ? 'Setting Value...' : 'Set Value'}
</button>
</form>

<div className="mt-6">
<h2 className="text-xl">Stored Value: {storedValue}</h2>
</div>
</div>
);
};

export default SimpleStorageComponent;


10. Now let’s create a metamask wallet and test out our contract.

• Create a new wallet


• Add password and setup the account

11. Add ganache to the metamask


12. Now import a test wallet from ganache

13. Paste the private key of a wallet from Ganache


After pasting, we can test our app

14. Now link the contract to ganache , by opening ganache and adding truffle-config.js
15. Now, testing our web app
16. And now we can see the changed value as well as do transactions.

RESULT:
Thus, interacted with a blockchain network and executed transactions and requests against a
blockchain network by creating an app to test the network and its rules.
EX.NO: 4
Deploy an asset-transfer app using blockchain.
DATE:

AIM:
To create an asset transfer app using solidity smart contract and testing out using truffle

PROCEDURE:
1. Create a folder and initialize smart contract, using command truffle init
2. Inside the contracts folder create contract file and write the following code

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

contract SimpleAssetTransfer {
struct Asset {
string name;
address owner;
}

mapping(uint256 => Asset) public assets;


mapping(address => uint256[]) private ownerAssets;

event AssetTransferred(uint256 indexed assetId, address indexed from,


address indexed to);

function createAsset(uint256 _id, string memory _name) public {


assets[_id] = Asset(_name, msg.sender);
ownerAssets[msg.sender].push(_id);
}

function transferAsset(uint256 _assetId, address _to) public {


require(assets[_assetId].owner == msg.sender, "Not the asset owner");
require(_to != address(0), "Invalid recipient address");

address previousOwner = assets[_assetId].owner;


assets[_assetId].owner = _to;

removeAssetFromOwner(previousOwner, _assetId);
ownerAssets[_to].push(_assetId);

emit AssetTransferred(_assetId, previousOwner, _to);


}

function getAssetOwner(uint256 _assetId) public view returns (address) {


return assets[_assetId].owner;
}

function getOwnerAssets(address _owner) public view returns (uint256[]


memory) {
return ownerAssets[_owner];
}

function removeAssetFromOwner(address _owner, uint256 _assetId) internal {


uint256[] storage assetsOfOwner = ownerAssets[_owner];
for (uint256 i = 0; i < assetsOfOwner.length; i++) {
if (assetsOfOwner[i] == _assetId) {
assetsOfOwner[i] = assetsOfOwner[assetsOfOwner.length - 1];
assetsOfOwner.pop();
break;
}
}
}
}

3. Inside migrations folder create a file 2_deploy_contracts.js and write the following code

const SimpleAssetTransfer = artifacts.require("SimpleAssetTransfer");

module.exports = function (deployer) {


deployer.deploy(SimpleAssetTransfer);
};

4. Now deploy by using command truffle migrate –reset


5. After deploying, test the contract using command truffle console
6. Now develop a Frontend using React, using the code below

import { ethers } from "ethers";


import { useEffect, useState } from "react";
import toast from "react-hot-toast";
import { abi, contractAddress } from "./utils/constants/contract_data";

const SimpleAssetTransferComponent = () => {


const [assetId, setAssetId] = useState("");
const [assetName, setAssetName] = useState("");
const [storedOwner, setStoredOwner] = useState("");
console.log(storedOwner)
const [valueToTransfer, setValueToTransfer] = useState("");
const [loading, setLoading] = useState(false);
const [ownerAssets, setOwnerAssets] = useState([]);

useEffect(() => {
if (storedOwner) {
fetchOwnerAssets(storedOwner);
}
}, [storedOwner]);

const createAsset = async (e) => {


e.preventDefault();
setLoading(true);
const provider = new ethers.BrowserProvider(window.ethereum);
const contract = new ethers.Contract(contractAddress, abi, provider);
try {
const signer = await provider.getSigner();
const tx = await contract.connect(signer).createAsset(assetId, assetName);
await tx.wait();
toast.success('Asset created successfully!');
} catch (error) {
console.error(error);
toast.error('Error creating asset');
} finally {
setLoading(false);
}
};

const transferAsset = async (e) => {


e.preventDefault();
setLoading(true);
const provider = new ethers.BrowserProvider(window.ethereum);
const contract = new ethers.Contract(contractAddress, abi, provider);
try {
const signer = await provider.getSigner();
const tx = await contract.connect(signer).transferAsset(assetId,
valueToTransfer);
await tx.wait();
toast.success('Asset transferred successfully!');
fetchOwnerAssets(valueToTransfer);
} catch (error) {
console.error(error);
toast.error('Error transferring asset');
} finally {
setLoading(false);
}
};

const fetchOwner = async (id) => {


const provider = new ethers.BrowserProvider(window.ethereum);
const contract = new ethers.Contract(contractAddress, abi, provider);
try {
const owner = await contract.getAssetOwner(id);
setStoredOwner(owner);
toast.success('Fetched asset owner successfully!');
} catch (error) {
console.error(error);
toast.error('Error fetching asset owner');
}
};

const fetchOwnerAssets = async (owner) => {


const provider = new ethers.BrowserProvider(window.ethereum);
const contract = new ethers.Contract(contractAddress, abi, provider);
try {
const assets = await contract.getOwnerAssets(owner);
setOwnerAssets(assets);
console.log(assets)
} catch (error) {
console.error(error);
toast.error('Error fetching owner assets');
}
};

return (
<div className="flex flex-col items-center mt-16">
<h1 className="text-3xl text-neutral-700 font-bold">Simple Asset
Transfer</h1>

<form onSubmit={createAsset} className="flex flex-col items-center mt-6">


<input
type="number"
value={assetId}
onChange={(e) => setAssetId(e.target.value)}
className="border rounded-md p-2 mb-2"
placeholder="Asset ID"
required
/>
<input
type="text"
value={assetName}
onChange={(e) => setAssetName(e.target.value)}
className="border rounded-md p-2 mb-2"
placeholder="Asset Name"
required
/>
<button
type="submit"
className="bg-blue-500 text-white px-3 py-2 rounded-md shadow-sm"
disabled={loading}
>
{loading ? 'Creating Asset...' : 'Create Asset'}
</button>
</form>

<form onSubmit={transferAsset} className="flex flex-col items-center mt-6">


<input
type="text"
value={valueToTransfer}
onChange={(e) => setValueToTransfer(e.target.value)}
className="border rounded-md p-2 mb-2"
placeholder="Transfer to address"
required
/>
<button
type="submit"
className="bg-blue-500 text-white px-3 py-2 rounded-md shadow-sm"
disabled={loading}
>
{loading ? 'Transferring Asset...' : 'Transfer Asset'}
</button>
</form>

<div className="mt-6">
<h2 className="text-xl">Asset Owner: {storedOwner}</h2>
<button
onClick={() => fetchOwner(assetId)}
className="mt-2 bg-blue-500 text-white px-3 py-2 rounded-md"
>
Get Asset Owner
</button>
</div>

<div className="mt-6">
<h2 className="text-xl">Assets Owned:</h2>
<ul>
{ownerAssets.map((id) => (
<li key={id.toString()}>Asset ID: {id.toString()}</li>
))}
</ul>
</div>
</div>
);
};

export default SimpleAssetTransferComponent;

RESULT:
Thus, an asset transfer app created using Ethereum Blockchain.
EX.NO: 5 Use blockchain to track fitness club rewards. Build a web app
to track and trace member rewards
DATE:

AIM:
To develop a web app to track the fitness club rewards using Blockchain

PROCEDURE:

1. Develop the smart contract for tracking fitness club rewards.

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

contract Fitness {
struct Member {
address memberAddress;
uint256 points;
bool isMember;
}

mapping(address => Member) public members;


address public owner;

event MemberAdded(address indexed memberAddress);


event PointsUpdated(address indexed memberAddress, uint256 points);

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

modifier onlyMember() {
require(members[msg.sender].isMember, "Only members can execute this
function");
_;
}

constructor() {
owner = msg.sender;
}

function addMember(address _memberAddress) public onlyOwner {


require(!members[_memberAddress].isMember, "Address is already a member");
members[_memberAddress] = Member({
memberAddress: _memberAddress,
points: 0,
isMember: true
});
emit MemberAdded(_memberAddress);
}

function updatePoints(address _memberAddress, uint256 _points) public


onlyOwner {
require(members[_memberAddress].isMember, "Address is not a member");
members[_memberAddress].points += _points;
emit PointsUpdated(_memberAddress, members[_memberAddress].points);
}

function getPoints(address _memberAddress) public view onlyMember returns


(uint256) {
require(members[_memberAddress].isMember, "Address is not a member");
return members[_memberAddress].points;
}

function redeemPoints(address _memberAddress, uint256 _points) public


onlyOwner {
require(members[_memberAddress].isMember, "Address is not a member");
require(members[_memberAddress].points >= _points, "Insufficient points");
members[_memberAddress].points -= _points;
emit PointsUpdated(_memberAddress, members[_memberAddress].points);
}
}
2. Initialize a truffle project, write the above smart contract in the contracts folder and then in
migrations folder create a js file and name it as 2_deploy_contracts.js

the 2_deploy_contracts.js should be in the below format

const contract = artifacts.require(<contract-name>)


module.exports = function (deployer) {
deployer.deploy(contract);
};

3. Then, modify the truffle-config.js


module.exports = {
networks: {
development: {
host: '127.0.0.1',
port: 7545,
network_id: '*'
}
},
compilers: {
solc: {
version: "0.8.19"
}
}
}

4. After configuring, deploy the contract by truffle migrate –reset


5. From build/contracts/<contract-name>.json , copy the abi and the contract address from
networks key in the json file.

6. Now, integrate with Frontend Framework like React


7.
8. Install the following

npm i react-hot-toast ethers @metamask/detect-provider @metamask/sdk-react

9. In the src, create a folder utils/constants/contract.js and then paste the abi and
contractAddress.

10. Wrap the Providers of react-hot-toast and metamask


import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.jsx'
import './index.css'
import { Toaster } from 'react-hot-toast'
import {MetaMaskProvider} from '@metamask/sdk-react'

ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<MetaMaskProvider>
<Toaster/>
<App />
</MetaMaskProvider>
</React.StrictMode>,
)

11. Create a component for the Fitness Club Reward Tracker

import detectEthereumProvider from "@metamask/detect-provider";


import { ethers } from "ethers";
import { useEffect, useState } from "react";

import { Trophy } from "lucide-react";


import toast from "react-hot-toast";
import { abi, contractAddress } from "./utils/constants/contract";

const FitnessComponent = () => {


const [account, setAccount] = useState(null);
const [dataloading,setDataLoading] = useState(false);
const [addPointsLoading,setAddPointsLoading] = useState(false);
const [isConnected, setIsConnected] = useState(false);
const [network, setNetwork] = useState(null);
console.log(network)
const [data, setData] = useState(null);
const [pointsToAdd, setPointsToAdd] = useState(0); // State for points to add
const [addressToAdd, setAddressToAdd] = useState(""); // State for the address
to which points will be added

useEffect(() => {
const connectMetaMask = async () => {
const provider = await detectEthereumProvider();
if (provider) {
const accounts = provider.selectedAddress ? [provider.selectedAddress] :
[];
handleAccountsChanged(accounts);
handleNetworkChanged(provider.networkVersion);
provider.on('accountsChanged', handleAccountsChanged);
provider.on('chainChanged', handleNetworkChanged);
} else {
toast.error('Please install MetaMask!');
}
};

connectMetaMask();
}, []);

const handleAccountsChanged = (accounts) => {


if (accounts.length === 0) {
toast.error('Please connect to MetaMask.');
setAccount(null);
setIsConnected(false);
setData(null);
} else {
setAccount(accounts[0]);
setIsConnected(true);
}
};

const fetchData = async () => {


setDataLoading(true)
if (!account) {
toast.error('No account connected. Please connect your wallet.');
return;
}

const provider = new ethers.BrowserProvider(window.ethereum);


const contract = new ethers.Contract(contractAddress, abi, provider);
try {
const data = await contract.checkRewardPoints(account);
setData(data.toString() === '0' ? '0' : data.toString());
setDataLoading(false)
} catch (error) {
console.error(error);
toast.error('Failed to fetch data from contract');
}
};

const handleNetworkChanged = (networkId) => {


setNetwork(networkId);
};

const connectWallet = async () => {


const provider = await detectEthereumProvider();
if (provider) {
try {
const accounts = await provider.request({ method: 'eth_requestAccounts'
});
handleAccountsChanged(accounts);
} catch (err) {
if (err.code === 4001) {
toast.error('Please connect to MetaMask.');
} else {
console.error(err);
toast.error('Something went wrong');
}
}
} else {
toast.error('Please install MetaMask!');
}
};

const addRewardPoints = async () => {


setAddPointsLoading(true)
if (!account || !isConnected) {
toast.error('Please connect to MetaMask and select an account.');
return;
}

const provider = new ethers.BrowserProvider(window.ethereum);


const contract = new ethers.Contract(contractAddress, abi, provider);

try {
const signer = await provider.getSigner();
const tx = await contract.connect(signer).addRewardPoints(addressToAdd,
pointsToAdd);
await tx.wait();
fetchData();
setPointsToAdd(0);
setAddressToAdd("");
setAddPointsLoading(false) // Reset address input after adding points
toast.success('Reward points added successfully!'); // Success notification
} catch (error) {
console.error(error);
toast.error('Error adding points');
}
};

return (
<div className="">
<div className="fixed right-3 top-3">
<button onClick={connectWallet} className="flex bg-black justify-center
text-white px-3 py-2 rounded-lg">
<h1 className="w-24 truncate">{isConnected ? `${account}` : `Connect
Wallet`}</h1>
</button>
</div>
<div className="mt-16 flex items-center flex-col ">
<h1 className="text-3xl text-neutral-700 font-bold">Fitness Club Reward
Tracker</h1>

<div className="flex flex-col items-center mt-6">


<input
type="text"
value={addressToAdd}
onChange={(e) => setAddressToAdd(e.target.value)}
className="border rounded-md p-2 mb-2"
placeholder="Address to add points"
/>
<input
type="number"
value={pointsToAdd}
onChange={(e) => setPointsToAdd(e.target.value)}
className="border rounded-md p-2"
placeholder="Points to add"
/>
<button
onClick={addRewardPoints}
className="bg-green-500 mt-2 text-white px-3 py-2 rounded-md shadow-
sm"
disabled={addPointsLoading || !isConnected || pointsToAdd <= 0 ||
!addressToAdd }
>
{
addPointsLoading ? <div className="flex items-center gap-2">
<div className="h-3 w-3 border border-t-transparent rounded-full
animate-spin"></div>
Adding ...
</div> : <div> Add Points</div>
}
</button>
</div>

<button
onClick={fetchData}
className="bg-blue-700 mt-6 text-white px-3 py-2 rounded-md shadow-sm"
disabled={!isConnected}
>
{
dataloading ? <div className="flex items-center gap-2">
<div className="h-3 w-3 border border-t-transparent rounded-full
animate-spin"></div>
Fetching...
</div> : <div> My Rewards</div>
}
</button>
{data !== null && <p className="flex items-center gap-2 mt-5">{data}
<Trophy className="text-yellow-400" size={18} /></p>}
</div>
</div>
);
};

export default FitnessComponent;

12. The created web app will be like this

RESULT:
Thus, a web application for Tracking Fitness Club Rewards was doen with the help of
Ethereum Blockchain.
EX.NO: 6
Use blockchain to create a Car Auction Network
DATE:

AIM:
To create a car Auction network using Blockchain technology using Ethereum Blockchain

PROCEDURE:

1. Develop the Smart contract by applying all logics required for creating a Car Auction
Network.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract CarAuction {
struct Car {
string make;
string model;
uint256 year;
}

struct Auction {
Car car;
address payable seller;
uint256 startingBid;
uint256 highestBid;
address payable highestBidder;
bool active;
}

uint256 public auctionCount;


mapping(uint256 => Auction) public auctions;

event AuctionCreated(uint256 indexed auctionId, address indexed seller,


string make, string model, uint256 year, uint256 startingBid);
event HighestBidIncreased(uint256 indexed auctionId, address indexed bidder,
uint256 amount);
event AuctionEnded(uint256 indexed auctionId, address indexed winner,
uint256 amount);

function createAuction(string memory _make, string memory _model, uint256


_year, uint256 _startingBid) public {
auctions[auctionCount] = Auction({
car: Car({
make: _make,
model: _model,
year: _year
}),
seller: payable(msg.sender),
startingBid: _startingBid,
highestBid: 0,
highestBidder: payable(address(0)),
active: true
});
emit AuctionCreated(auctionCount, msg.sender, _make, _model, _year,
_startingBid);
auctionCount++;
}

function bid(uint256 _auctionId) public payable {


Auction storage auction = auctions[_auctionId];
require(auction.active, "Auction is not active");
require(msg.value > auction.highestBid, "There already is a higher
bid");
require(msg.value >= auction.startingBid, "Bid is lower than the starting
bid");

if (auction.highestBidder != address(0)) {
auction.highestBidder.transfer(auction.highestBid);
}

auction.highestBid = msg.value;
auction.highestBidder = payable(msg.sender);
emit HighestBidIncreased(_auctionId, msg.sender, msg.value);
}

function endAuction(uint256 _auctionId) public {


Auction storage auction = auctions[_auctionId];
require(msg.sender == auction.seller, "Only the seller can end the
auction");
require(auction.active, "Auction is not active");

auction.active = false;
auction.seller.transfer(auction.highestBid);
emit AuctionEnded(_auctionId, auction.highestBidder,
auction.highestBid);
}

function getAuctionDetails(uint256 _auctionId) public view returns (string


memory make, string memory model, uint256 year, uint256 startingBid, uint256
highestBid, address highestBidder, bool active) {
Auction storage auction = auctions[_auctionId];
return (auction.car.make, auction.car.model, auction.car.year,
auction.startingBid, auction.highestBid, auction.highestBidder,
auction.active);
}
}

2. Deploy the contract to truffle after configuring the truffle project


3. Write the test cases for the contract
const CarAuction = artifacts.require("CarAuction");

contract("CarAuction", accounts => {


it("should create an auction", async () => {
const instance = await CarAuction.deployed();
await instance.createAuction("Toyota", "Camry", 2020, web3.utils.toWei("1",
"ether"), { from: accounts[0] });
const auction = await instance.auctions(0);
assert.equal(auction.car.make, "Toyota");
assert.equal(auction.car.model, "Camry");
assert.equal(auction.car.year, 2020);
});

it("should allow bidding", async () => {


const instance = await CarAuction.deployed();
await instance.bid(0, { from: accounts[1], value: web3.utils.toWei("2",
"ether") });
const auction = await instance.auctions(0);
assert.equal(auction.highestBid, web3.utils.toWei("2", "ether"));
assert.equal(auction.highestBidder, accounts[1]);
});
it("should end the auction", async () => {
const instance = await CarAuction.deployed();
await instance.endAuction(0, { from: accounts[0] });
const auction = await instance.auctions(0);
assert.equal(auction.active, false);
});
});

RESULT:
Thus, a Car Auction network have been created by Ethereum Blockchain and tested

You might also like