FIN451 / MBA651 Blockchain Class Web Page, Fall ' 24
Instructor: Maggie Foley
Jacksonville University
The Syllabus           Risk
Tolerance Assessment       Term
Project: Just complete a smart contract and a DApp
 
Weekly SCHEDULE, LINKS, FILES and Questions
| Chapter | Coverage,
  HW, Supplements -      
  Required | References 
 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Week 1 | 
 |  Useful
  Websites: 1. Ethereum.org 
 2.    
  Solidity
  Documentation // https://docs.soliditylang.org/en/v0.8.26/ 
 
 4. OpenZeppelin 
 5. CryptoZombies 
 6. Truffle Suite 
 7. Hardhat 
 8. Dapp University 
 9. Solidity by Example 
 10. EthHub https://docs.ethhub.io/ 
 11. Chainlink Documentation https://docs.chain.link 
 12.  Ethers.js  https://docs.ethers.org/v6/ 
 13. DeFi Pulse 
 14. State of the DApps 
 15. Github 
 Websites for beginners learning about Ethereum and
  blockchain: 1.    
  Ethereum Foundation
  Blog https://blog.ethereum.org/ 
 2.    
  Consensys
  Academy  https://consensys.io/academy 
 3. Blockgeeks 
 4. Coursera - Blockchain Specialization 
 5. CryptoCompare 
 6. CoinDesk 
 7. DappRadar 
 8. The Ethereum Reddit Community 
 9. Binance Academy https://academy.binance.com/\ 
 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Week 2 | Week 2 –
  Ethereum Part I – What is
  Ethereum? A Comparison between Ethereum and Bitcoin    Quiz2 What is Ethereum?    PPT  Simplilearn
  4 hour Blockchain Video (from 
  1:26:00 – 2:19:34 )·      
  Self-produced video: Ethereum 2.0 &
  Smart Contracts: Simple Guide to Key Concepts1. Introduction to Ethereum
 2. Key Features of Ethereum
 3.    
  A Comparison between Bitcoin and Ethereum  PPT   Simplilearn 4
  hour video (2:57:06 – 3:03:00) 
 Part II – Ethereum
  Mining  ppt     1. What is Ether Mining?
 2. How Ether Mining Works
 3. Equipment Needed
 4. Mining Solo vs. Joining a Pool
 5. Steps to Start Mining Ether
 6. Transition to Proof of Stake (PoS)
 Part III – Smart
  Contract   PPT  
  Simplilearn
  4 hour video (from 1:27:14  to
  2:13:44  )   Quiz 1. Definition
 2. How Smart Contracts Work
 3. Example of a Smart Contract
 Software Needed for Smart Contracts1. Development Environment
 2. Blockchain Network
 3. Wallet and Blockchain Interface
 Why Do We Need Smart Contracts?1. Automation
 2. Trust and Transparency
 3. Cost Efficiency
 4. Security
 5. Global Reach
 Summary
 Part IV – Solidity
  Coding    PPT   Simplilearn 6
  hour video (from 1:26:00 – 2:41:55 
  ) 1. Introduction to Solidity
 2. Purpose of Solidity
 How to Compile and Deploy a Solidity Contract1. Writing a Smart Contract
 
 
 2. Compiling the Smart Contract
 
 
 3. Deploying the Smart Contract
 
 Procedure Summary
 Main Troubleshooting Issues1. Compilation Errors
 2. Deployment Issues
 3. Interaction Issues
 4. Gas Estimation Errors
 Conclusion
 Part V – DApp
  (Decentralized Application) and DAO    
  PPT  
  Quiz Simplilearn 4
  hour video (from  3:02:31 
  to 3:09:15  ) 1. Definition
 2. Key Characteristics of DApps
 3. How DApps Work
 4. Examples of DApps
 Why Do We Need DApps?1. Trust and Security
 2. User Control and Ownership
 3. Innovation and Accessibility
 Challenges and Considerations1. Scalability
 2. User Experience
 Conclusion
   (Disclaimer: Some of the slides posted on this website
  are screenshots from the Simplilearn
  4 Hour Blockchain video at https://www.youtube.com/watch?v=SyVMma1IkXM&t=4849s and Simplilearn 6 HourBlockchain Video at https://www.youtube.com/watch?v=9aXHQ98TMRY&t=6626s) Part VI – Real World
  Examples     Quiz 1. Walmart – Supply Chain Management·       
  Overview:
  Walmart uses blockchain technology to improve the traceability and
  transparency of its food supply chain. This implementation helps Walmart
  quickly identify and address issues such as contamination or recalls,
  ensuring food safety and reducing waste. ·       
  Blockchain Platform: IBM
  Food Trust (built on Hyperledger Fabric) 
  https://www.ibm.com/products/supply-chain-intelligence-suite/food-trust ·       
  Website: 
 ·       
  Additional Information:
  Walmart was one of the first major retailers to adopt blockchain for supply
  chain management, initially focusing on tracing pork and leafy greens to
  enhance food safety. 2. Maersk – Shipping and Logistics
  with TradeLens·       
  Overview:
  Maersk, in collaboration with IBM, developed TradeLens, a blockchain-based
  platform designed to streamline global shipping processes. TradeLens enhances
  transparency, reduces paperwork, and increases efficiency by providing
  real-time access to shipping data and documents. ·       
  Blockchain Platform: TradeLens
  (built on Hyperledger Fabric) ·       
  Website: TradeLens   https://www.tradelens.com/ ·       
  Additional Information:
  TradeLens has partnered with numerous shipping companies, ports, and customs
  authorities worldwide to create a more connected and efficient global trade
  ecosystem. 3. De Beers – Diamond Provenance
  Tracking with Tracr·       
  Overview: De
  Beers uses the Tracr platform to track diamonds from the mine to the retail
  point. This ensures that each diamond is ethically sourced and conflict-free,
  enhancing consumer trust and maintaining the integrity of their supply chain. ·       
  Blockchain Platform: Tracr
  (developed by De Beers) ·       
  Website: De
  Beers Tracr   https://www.tracr.com/ ·       
  Additional Information:
  Tracr allows consumers to verify the origin and journey of their diamonds,
  promoting transparency and ethical sourcing in the diamond industry. 4. Nestlé – Food Supply Chain
  Transparency·       
  Overview:
  Nestlé leverages blockchain technology to enhance the
  transparency and traceability of its food products. By tracking ingredients
  through the supply chain, Nestlé ensures quality,
  safety, and ethical sourcing. ·       
  Blockchain Platform: IBM
  Food Trust (built on Hyperledger Fabric) ·       
  Website:
  Nestlé and IBM Food Trust  https://www.ibm.com/blogs/think/2019/04/tracing-your-mashed-potatoes-on-ibm-blockchain/ ·       
  Additional Information:
  Nestlé's participation in IBM Food Trust helps the
  company monitor the supply chain in real-time, ensuring that products meet
  safety standards and are sourced responsibly. 5. FedEx – Package Tracking and
  Logistics·       
  Overview:
  FedEx explores blockchain technology to improve its package tracking system,
  aiming for more secure and transparent tracking information for shipments.
  Blockchain enhances the reliability and efficiency of tracking packages through
  the supply chain. ·       
  Blockchain Platform: Potential
  Platforms: Hyperledger Fabric, Ethereum, or proprietary
  solutions ·       
  Website:
  FedEx Blockchain Initiatives   https://www.fedex.com/en-us/about/policy/technology-innovation/blockchain.html · Additional Information: FedEx has been involved in blockchain pilot projects to explore how distributed ledger technology can optimize logistics and reduce fraud. 6. Provenance – Supply Chain
  Transparency for Various Industries·       
  Overview:
  Provenance is a platform that helps businesses track the origins and journey
  of their products using blockchain. This ensures transparency, ethical
  sourcing, and allows consumers to verify product claims. ·       
  Blockchain Platform: Ethereum
  and other blockchain technologies ·       
  Website: Provenance  https://www.provenance.org/ ·       
  Additional Information:
  Provenance works with various industries, including fashion, food, and
  consumer goods, to provide detailed product histories and build consumer
  trust through transparency. 7. Microsoft – Azure Blockchain
  Services·       
  Overview:
  Microsoft offers Azure Blockchain Services, enabling businesses to build,
  deploy, and manage blockchain applications easily. Numerous companies use
  Azure Blockchain to develop solutions across different industries such as
  finance, supply chain, and healthcare. ·       
  Blockchain Platform: Azure
  Blockchain (supports multiple blockchain frameworks including
  Ethereum, Hyperledger Fabric) ·       
  Website:
  Microsoft Azure Blockchain https://azure.microsoft.com/en-us/blog/digitizing-trust-azure-blockchain-service-simplifies-blockchain-development/ ·       
  Additional Information:
  Azure Blockchain provides tools and templates to help enterprises integrate
  blockchain into their existing systems, facilitating faster and more secure
  transactions. 8. JPMorgan Chase – Financial Services
  with Quorum·       
  Overview:
  JPMorgan Chase developed Quorum, an enterprise-focused version of Ethereum, to
  facilitate secure and efficient financial transactions. Quorum is used for
  various applications, including payment processing, interbank transfers, and
  blockchain-based financial instruments. ·       
  Blockchain Platform: Quorum
  (a fork of Ethereum developed by JPMorgan Chase) https://phemex.com/academy/what-is-quorum-jp-morgan ·       
  Website:
  Quorum by ConsenSys  https://consensys.io/blog/what-is-consensys-quorum ·       
  Additional Information:
  Quorum enhances Ethereum's capabilities by adding privacy features and
  improving performance, making it suitable for enterprise use cases in the
  financial sector. 9. IBM – Various Enterprise Blockchain
  Solutions·       
  Overview:
  IBM offers a range of blockchain solutions tailored for different industries,
  including supply chain, finance, healthcare, and more. IBM Blockchain, built
  on Hyperledger Fabric, provides the infrastructure for businesses to create
  secure and scalable blockchain applications. ·       
  Blockchain Platform: IBM
  Blockchain (built on Hyperledger Fabric)   ·       
  Website:
  IBM Blockchain  https://www.ibm.com/blockchain ·       
  Additional Information:
  IBM collaborates with numerous enterprises to implement blockchain solutions
  that enhance transparency, security, and efficiency in their operations. 10. Amazon Web Services (AWS) –
  Managed Blockchain Services·       
  Overview: Amazon
  Web Services offers Amazon Managed Blockchain, a fully managed service that
  makes it easy to create and manage scalable blockchain networks using popular
  frameworks like Hyperledger Fabric and Ethereum. ·       
  Blockchain Platform: Amazon
  Managed Blockchain (supports Hyperledger Fabric and Ethereum) ·       
  Website: Amazon
  Managed Blockchain  Distributed Ledger Software
  & Technology - Amazon Managed Blockchain - AWS ·       
  Additional Information:
  AWS Managed Blockchain allows businesses to quickly set up and manage
  blockchain networks without the overhead of maintaining the underlying
  infrastructure, supporting various use cases from supply chain to digital
  identity. 11. Coca-Cola – Supply Chain and
  Product Authentication·       
  Overview:
  Coca-Cola utilizes blockchain technology to enhance its supply chain
  management and product authentication processes. Blockchain helps Coca-Cola
  track ingredients, ensure quality, and authenticate products to prevent
  counterfeiting. ·       
  Blockchain Platform: IBM
  Food Trust (built on Hyperledger Fabric) ·       
  Website:
  Coca-Cola and IBM Food Trust https://shping.com/shping-and-ibm-food-trust-pioneering-a-new-era-of-product-transparency-for-consumers/ ·       
  Additional Information: By
  integrating blockchain into its supply chain, Coca-Cola ensures better
  transparency and efficiency, from sourcing raw materials to delivering
  finished products. 12. Pfizer – Pharmaceutical Supply
  Chain Management·       
  Overview:
  Pfizer uses blockchain to improve the traceability and security of its
  pharmaceutical supply chain. Blockchain helps Pfizer ensure the authenticity
  of medicines, prevent counterfeiting, and comply with regulatory
  requirements. ·       
  Blockchain Platform: Provenance,
  IBM Blockchain, or other enterprise blockchains ·       
  Website:
  Pfizer and Blockchain Initiatives   https://news.crunchbase.com/health-wellness-biotech/pharmaceuticals-blockchain-crypto-web3-pfizer-pfe/ ·       
  Additional Information:
  Blockchain technology enables Pfizer to maintain a secure and transparent
  record of its supply chain, enhancing trust and safety in its pharmaceutical
  products. 13. Starbucks – Coffee Supply Chain
  Tracking·       
  Overview:
  Starbucks has explored using blockchain to track the provenance of its coffee
  beans, ensuring quality and ethical sourcing. Blockchain helps verify the
  journey of the coffee from farm to cup, enhancing transparency and consumer
  trust. ·       
  Blockchain Platform: IBM
  Food Trust (similar to Walmart and Nestlé) ·       
  Website:
  Starbucks and Blockchain  https://stories.starbucks.com/press/2022/starbucks-brewing-revolutionary-web3-experience-for-its-starbucks-rewards-members/ ·       
  Additional Information: By
  leveraging blockchain, Starbucks can provide customers with detailed
  information about the origin and quality of their coffee, supporting
  sustainable and ethical sourcing practices. 14. BP – Energy Supply Chain
  Management·       
  Overview: BP
  utilizes blockchain technology to manage and optimize its energy supply
  chain. Blockchain helps BP track the movement of energy resources, ensure
  compliance with regulations, and improve the efficiency of transactions. ·       
  Blockchain Platform: IBM
  Blockchain or other enterprise solutions ·       
  Website: BP
  and Blockchain  https://www.hartenergy.com/exclusives/bp-tries-out-blockchain-energy-trading-30388 ·       
  Additional Information:
  BP's adoption of blockchain in the energy sector demonstrates how blockchain
  can enhance transparency, reduce costs, and improve operational efficiency in
  complex supply chains. 15. Anheuser-Busch InBev – Beverage
  Supply Chain Transparency·       
  Overview:
  Anheuser-Busch InBev uses blockchain to enhance the transparency and
  efficiency of its beverage supply chain. Blockchain enables the company to
  track ingredients, monitor production processes, and ensure the authenticity
  of its products. ·       
  Blockchain Platform: IBM
  Food Trust (built on Hyperledger Fabric) ·       
  Website: AB
  InBev and IBM Food Trust   https://www.foodnavigator.com/Article/2019/08/06/Anheuser-Busch-InBev-joins-new-IBM-blockchain ·       
  Additional Information: By
  integrating blockchain into its supply chain, Anheuser-Busch InBev ensures better
  quality control, traceability, and consumer trust in its beverage products. 
 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Part
  VII –  Understanding Web3                    QuizRefer
  to Chapter 8 of Hands-On Smart Contract Development with Solidity & Ethereum
  by Solorio, Kanna, and Hoover                 1.    
  What is
  Web3?Web3
  refers to a collection of JavaScript libraries that allow developers to
  interact with the Ethereum blockchain, either remotely or locally. Think of it
  as the connection point between the blockchain and your smart contract or
  decentralized app (DApp). Web3 uses JSON RPC
  (Remote Procedure Call) to communicate with Ethereum nodes and helps you
  perform transactions, call smart contract methods, and read/write data from
  the blockchain. 2.    
  How Web3
  Differs from Web 2.0In
  traditional web applications (Web 2.0), a frontend (like React) interacts
  with a backend (a server and database) to process and store data. In
  contrast, Web3 allows your frontend to interact directly with the blockchain
  as if it were the backend. This eliminates the need for centralized databases
  and servers. Web3 Application Flow
 
 
 3.    
  Why Web3 is
  ImportantWeb3
  is at the core of decentralized applications (DApps). Instead of relying on
  centralized servers and databases, Web3 allows applications to interact
  directly with the decentralized blockchain, enhancing security, transparency,
  and trust. 4.    
  Setting Up
  Web3To
  use Web3 in your project, you first need to set up a provider
  that tells Web3 which Ethereum node to connect to. For example, if you are
  working with Ganache (a local Ethereum blockchain), you would connect as
  follows: constThe provider is like the URL you use in a traditional web app to communicate with an API. It directs RPC calls from Web3 to the correct Ethereum node. Providers
 5.    
  MetaMask for
  Web3 InjectionMetaMask is
  a browser extension that makes interacting with Web3 much easier. It: 
 Web3
  detects MetaMask as a Web3 provider, enabling you to interact with the
  blockchain seamlessly. 6.    
  Application
  of Web3 in the Blockchain SpaceBenefits
  of Web3: 
 Applications
  of Web3: ·  
  Decentralized Finance
  (DeFi): Web3 is the backbone of DeFi
  applications, enabling peer-to-peer financial transactions. ·  
  Voting Systems:
  As demonstrated by the Voting DApp you built, Web3 allows decentralized and
  tamper-proof voting mechanisms. ·  
  Supply Chain:
  Companies use Web3 to track goods in a transparent and immutable way. ·  
  Gaming:
  Web3 powers blockchain-based games that allow players to earn and trade assets. 
 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Homework of  Week2 - Guide to
  Interacting with a Smart Contract Using Truffle 1. Setting Up
  the Environment 
 npm install -g truffle 
 mkdir my_truffle_project cd my_truffle_project 
 truffle init 2. Write and
  Compile the Smart Contract 
 // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract Greeter {     string
  public greeting; constructor(string memory _greeting) {        
  greeting = _greeting;     }     function
  greet() public view returns (string memory) {        
  return greeting;     } } 
 const Greeter =
  artifacts.require("Greeter"); module.exports = function(deployer) { deployer.deploy(Greeter, "Hello,
  JU!"); // Change greeting here }; 
 truffle compile 3. Deploy the
  Contract 
 truffle develop 
 truffle migrate 4. Interact
  with the Contract Using a Script 
 const Greeter =
  artifacts.require("Greeter"); module.exports = async function(callback) {     try {         //
  Get the deployed instance of the contract        
  const instance = await Greeter.deployed();         //
  Print the address of the deployed contract console.log("Contract address:",
  instance.address);         //
  Call the greet function        
  const greeting = await instance.greet(); console.log("Greeting:", greeting);     }
  catch (error) { console.error(error);     } callback(); }; 
 truffle exec scripts/scripts_test.js 5.
  Troubleshooting 
 npm uninstall
  -g truffle npm install -g
  truffle 6. Example
  Output When running
  the script, you should see: Contract address: 0x... (your contract address) Greeting: Hello, JU! This guide
  covers the entire process from setting up the environment to interacting with
  your smart contract. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Homework of Week 3 - Interacting with a
  Smart Contract Using MetaMask, Ganache,
  and Remix Step by Step
  Instructional Video Part I
  (Metamask)  .     Part II
  (Remix)   Refer to
   https://github.com/arshdeepbahga/blockchain-applications-book/tree/master/Chapter-5 1. Install and
  Set Up MetaMask Why: MetaMask is a
  digital wallet used to manage accounts and interact with Ethereum-based applications.
  It acts as the bridge between the blockchain (Ganache) and the application
  (Remix). 
 Expected
  Outcome:
  MetaMask is installed and your first Ethereum account is created. 2. Set Up
  Ganache Why: Ganache
  simulates a blockchain environment locally, allowing you to deploy and test
  smart contracts without using real money. 
 Expected Outcome: Ganache is
  running locally, and you have access to 10 accounts with 100 ETH each. 3. Connect
  MetaMask to Ganache Why: To deploy
  contracts and send transactions, MetaMask must be connected to the local
  blockchain (Ganache). 
 Expected
  Outcome:
  MetaMask is now connected to the local blockchain provided by Ganache. 4. Import an
  Account from Ganache to MetaMask Why: You need to
  use one of Ganache’s accounts to deploy contracts and interact with them. 
 Expected
  Outcome:
  The Ganache account with 100 ETH is now added to your MetaMask. 5. Open Remix
  and Write the Smart Contract Why: Remix is an
  online tool used to write, compile, and deploy smart contracts. 
 // SPDX-License-Identifier:
  MIT pragma solidity ^0.8.0; contract Voting {     string[] public candidateList;     mapping(string => uint256) public
  votesReceived;     constructor(string[] memory
  candidateNames) {         candidateList = candidateNames;     }     function voteForCandidate(string memory
  candidate) public {         require(validCandidate(candidate),
  "Candidate does not exist");         votesReceived[candidate] += 1;     }     function totalVotesFor(string memory
  candidate) public view returns (uint256) {         require(validCandidate(candidate),
  "Candidate does not exist");         return votesReceived[candidate];     }     function validCandidate(string memory
  candidate) public view returns (bool) {         for (uint i = 0; i <
  candidateList.length; i++) {             if
  (keccak256(abi.encodePacked(candidateList[i])) ==
  keccak256(abi.encodePacked(candidate))) {                 return true;             }         }         return false;     } } Expected
  Outcome:
  The smart contract code is ready in Remix. 6. Compile the
  Smart Contract Why: Compilation
  converts the Solidity code into bytecode that can be deployed to the
  blockchain. 
 Expected
  Outcome:
  The contract is compiled successfully, and you should see a green checkmark. 7. Deploy the
  Smart Contract to Ganache Why: Deploying the
  contract to the blockchain makes it accessible for interaction. 
 Expected
  Outcome:
  The contract is deployed to Ganache, and you’ll see it listed under
  "Deployed Contracts" in Remix. 8. Cast a Vote
  for a Candidate Step: 
 Expected
  Outcome:
  The vote is cast for "Alice," and a transaction is confirmed in
  MetaMask. 9. Validate a
  Candidate Name Step: 
 Expected
  Outcome:
  You can validate whether "Bob" is a valid candidate in the
  contract. 10. Count the
  Votes for a Candidate Step: 
 Expected
  Outcome:
  You can see the number of votes "Alice" has received. Summary: This guide
  will allow you to: 
 | Blockchain
  Concepts As
  you go through the steps of deploying and interacting with a smart contract
  using MetaMask, Ganache, and Remix, you'll be learning essential concepts
  related to blockchain technology. Below is a comprehensive guide that
  outlines these key concepts in detail, along with how they relate to the
  tasks you'll be performing. 1.
  Blockchain Basics
 2.
  Ethereum Wallets·       
  Ethereum Wallet: A
  digital wallet is a tool that allows you to interact with the Ethereum blockchain.
  It holds your private keys and enables you to send and receive Ether (ETH)
  and other tokens. ·       
  MetaMask:
  MetaMask is an Ethereum wallet in the form of a browser extension. It acts as
  a bridge between your browser and the Ethereum blockchain, allowing you to
  interact with dApps like the one you're creating. Key
  Points: 
 3.
  Ethereum Networks
 4.
  Smart Contracts·       
  Smart Contract: A
  smart contract is a self-executing contract with the terms of the agreement
  directly written into code. It automatically enforces the rules and penalties
  of an agreement. ·       
  Solidity:
  Solidity is the programming language used to write smart contracts on
  Ethereum. In this exercise, you’re using Solidity to write a simple Voting
  contract. Key
  Points: 
 5.
  Ganache: Local Blockchain·       
  Ganache:
  Ganache is a personal blockchain for Ethereum development. It allows you to
  deploy contracts, develop applications, and run tests in a controlled
  environment. Ganache simulates a real blockchain network but runs locally on
  your computer. Key
  Points: 
 6.
  Connecting MetaMask with Ganache
 7.
  Deploying and Interacting with Smart Contracts·       
  Deployment:
  Deployment refers to the process of sending your smart contract code to the
  blockchain so that it becomes an active contract that others can interact
  with. ·       
  Constructor Arguments:
  Some smart contracts require input when they are first deployed. For example,
  in the Voting contract, you provide an array of candidate names when
  deploying. Key
  Points: 
 8.
  Transactions and Confirmations·       
  Transaction: A
  transaction is a signed piece of data that represents an action on the
  blockchain, such as deploying a contract or calling a function within a
  contract. Each transaction requires a fee (paid in gas). ·       
  Confirmation:
  After submitting a transaction, it is broadcast to the network. Miners will
  pick it up and include it in a block. Once included, the transaction is confirmed
  and the changes it represents are applied to the blockchain. Key
  Points: 
 Security Considerations
  in Blockchain and Smart Contracts1.
  Importance of Security in Smart Contracts
 Security
  Best Practices: 
 2.
  Deploying the Smart Contract on the Ethereum Mainnet
 How
  Miners Find and Mine It: 
 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Homework of Week 4 - 
  Step-by-Step Guide to Setting Up and Running the Voting dApp with Truffle 1. Set Up Your Environment 
 npm install -g truffle npm install -g ganache-cli Alternatively, you can
  download the Ganache desktop application from the official website. 2. Create a
  New Truffle Project 
 mkdir voting-dapp cd voting-dapp 
 truffle init 
 // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract Voting {    
  string[] public candidateList;    
  mapping(string => uint256) public votesReceived;    
  constructor(string[] memory candidateNames) {        
  candidateList = candidateNames;     }    
  function voteForCandidate(string memory candidate) public {        
  votesReceived[candidate] += 1;     }    
  function totalVotesFor(string memory candidate) public view returns
  (uint256) {        
  return votesReceived[candidate];     } } 3. Create a
  Migration Script 
 const Voting =
  artifacts.require("Voting"); module.exports = function (deployer) {   const
  candidates = ["Alice", "Bob", "Charlie"];  
  deployer.deploy(Voting, candidates); }; 4. Truffle
  Configuration: truffle-config.js The Truffle
  configuration file is automatically generated when you initialize a Truffle
  project, but you should ensure it is properly set up for your local
  development environment. Here is a basic setup for using Ganache: module.exports = {  
  networks: {    
  development: {      
  host: "127.0.0.1",    
  // Localhost (default: none)      
  port: 7545,            //
  Standard Ganache port      
  network_id: "*",      
  // Any network (default: none)     },   },  
  compilers: {     solc:
  {      
  version: "0.8.0",      
  // Fetch exact version from solc-bin (default: truffle's version)     },   }, }; 5. Compile and
  Deploy the Contract 
 ganache-cli If you're
  using the Ganache desktop application, simply launch it. 
 truffle compile 
 truffle migrate 6. Interact
  with the Deployed Contract 
 const Voting =
  artifacts.require("Voting"); module.exports = async function (callback) {     try {         //
  Get the deployed instance of the contract        
  const votingInstance = await Voting.deployed();         //
  List of candidates        
  const candidates = ["Alice", "Bob",
  "Charlie"];         // Vote for a candidate        
  await votingInstance.voteForCandidate(candidates[0], { from: (await
  web3.eth.getAccounts())[0] });        
  console.log(`Voted for ${candidates[0]}`);         //
  Get total votes for a candidate        
  const votes = await votingInstance.totalVotesFor(candidates[0]);        
  console.log(`${candidates[0]} has ${votes} vote(s)`);        
  callback();     }
  catch (error) {        
  console.error("Error interacting with the contract:",
  error);        
  callback(error);     } }; 
 truffle exec scripts/interact.js 7. Verify the
  Results 
 8. Update the
  interact.js File to Cast More Votes for the Three Candidates Update the
  interact.js file with the following code to cast multiple votes for each
  candidate:   const Voting = artifacts.require("Voting"); module.exports = async function (callback) {     try {         //
  Get the deployed instance of the contract        
  const votingInstance = await Voting.deployed();         //
  List of candidates        
  const candidates = ["Alice", "Bob",
  "Charlie"];        
  const accounts = await web3.eth.getAccounts();         //
  Function to vote multiple times for a candidate        
  async function voteMultipleTimes(candidate, numVotes) {            
  for (let i = 0; i < numVotes; i++) {                 await
  votingInstance.voteForCandidate(candidate, { from: accounts[0] });            
  }            
  console.log(`Voted ${numVotes} times for ${candidate}`);         }         //
  Cast votes        
  await voteMultipleTimes(candidates[0], 10); // 10 votes for Alice        
  await voteMultipleTimes(candidates[1], 5);  // 5 votes for Bob        
  await voteMultipleTimes(candidates[2], 20); // 20 votes for Charlie         //
  Get total votes for each candidate        
  for (let candidate of candidates) {            
  const votes = await votingInstance.totalVotesFor(candidate);            
  console.log(`${candidate} has ${votes} vote(s)`);         }        
  callback();     }
  catch (error) {        
  console.error("Error interacting with the contract:", error);        
  callback(error);     } }; Run the
  Interaction Script Execute the
  script to interact with the deployed contract by running the following
  command in your terminal:   truffle exec scripts/interact.js Expected
  Outcome After running the
  script, you should see the following output: Voted 10 times
  for Alice Voted 5 times
  for Bob Voted 20 times
  for Charlie Alice has 11
  vote(s) Bob has 5
  vote(s) Charlie has 20
  vote(s) Notes: 
 | 3.
  Interacting with the Deployed Contract on the Ethereum Mainnet
 Steps
  for Outsiders to Vote: 
 4.
  Creating a Decentralized Application (dApp)
 Steps
  to Create a dApp: 
 5.
  Real-World Example of a Voting dApp
 Benefits
  of a Voting dApp: 
 Summary:·  Learn the Technical Steps: 
 ·  Gain a Deep Understanding of Blockchain
  Concepts: 
 ·  Appreciate the Importance of Security: ·  Explore Decentralized Applications
  (dApps): ·  Understand the Real-World Applications
  of Blockchain: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Homework of Week 5 -  Web3 - A DApp for Voting on a
  Private Blockchain Using Ganache and Metamask 
   Refer to  https://github.com/arshdeepbahga/blockchain-applications-book/tree/master/Chapter-5           Instructional
  Video Part I(smart contract)      Part II (NPM,
  React app, web3) Objective To build a
  simple Voting DApp that allows users to vote for candidates and view
  the vote results.   Part 1: Setup
  and Tools Installation 1. Install
  MetaMask MetaMask is a
  browser extension that allows you to interact with the Ethereum blockchain. Here's
  how to install and set it up: 
 2. Install
  Ganache Ganache is a
  personal blockchain that you’ll use to deploy your smart contracts locally.
  It provides you with a set of test accounts pre-loaded with fake Ether. 
 3. Install
  Truffle Truffle is a
  development framework for Ethereum, which helps you compile, migrate, and
  manage smart contracts. 
 
 npm install -g
  truffle 
 Part 2: Setup
  the Voting DApp 1. Create a
  New Project Directory Open your
  terminal or command prompt and create a directory for your project: mkdir voting-dapp cd voting-dapp 2. Initialize
  a Truffle Project Run the
  following command to initialize your Truffle project: truffle init This creates
  the basic structure of the Truffle project, including folders for your
  contracts, migrations, and configuration. 3. Write the
  Voting Smart Contract 
 // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract Voting {    
  string[] public candidateList;    
  mapping(string => uint256) public votesReceived;    
  constructor(string[] memory candidateNames) {        
  candidateList = candidateNames;     }    
  function getCandidateList() public view returns (string[] memory) {        
  return candidateList;     }    
  function voteForCandidate(string memory candidate) public {        
  require(validCandidate(candidate), "Candidate not valid.");        
  votesReceived[candidate] += 1;     }    
  function totalVotesFor(string memory candidate) public view returns
  (uint256) {         require(validCandidate(candidate),
  "Candidate not valid.");        
  return votesReceived[candidate];     }    
  function validCandidate(string memory candidate) public view returns
  (bool) {        
  for (uint i = 0; i < candidateList.length; i++) {             if (keccak256(bytes(candidateList[i]))
  == keccak256(bytes(candidate))) {                
  return true;            
  }         }        
  return false;     } }  4. Compile the
  Smart Contract Now, compile
  the smart contract using Truffle: truffle compile This will
  compile Voting.sol and create the necessary artifacts in the
  build/contracts folder. Part 3: Deploy
  the Contract 1. Set Up
  Migration File In the
  migrations folder, create a new file called 2_deploy_contracts.js and add the following code
  to deploy the contract: const Voting =
  artifacts.require("Voting"); module.exports = function (deployer) {   const
  candidates = ["Alice", "Bob", "Charlie"];  
  deployer.deploy(Voting, candidates); }; This deploys the
  Voting contract with three candidates: Alice, Bob, and Charlie. 2. Update
  truffle-config.js Make sure the truffle-config.js file
  points to the correct network (Ganache):   module.exports = {  
  networks: {    
  development: {      
  host: "127.0.0.1",  //
  Localhost for Ganache      
  port: 7545,         // Port
  Ganache is using      
  network_id: "*", // The Chain ID for Ganache CLI     },   },  
  compilers: {     solc:
  {      
  version: "0.8.0",   //
  Make sure this is your correct Solidity version     },   }, };  3. Deploy the
  Contract Now deploy the
  contract to Ganache: truffle migrate --network development You should see
  a successful deployment message and a contract address. Part 4: Create
  the Frontend for Web3 1. Set Up
  React Frontend To build the
  frontend, you can use React: 1. Create
  React App: npx create-react-app client cd client 2. Install
  Web3.js and Dependencies First, ensure
  you have Web3.js installed in your React app. Web3.js is a library
  that allows you to interact with the Ethereum blockchain. Run the
  following command in the client folder of your project: npm install web3 3.
  Copy Voting.json file to client/src/contracts The Voting.json
  file is automatically generated by Truffle when you compile your smart
  contracts. It contains important details needed to interact with your smart
  contract from the frontend (React app) using Web3.js. Here’s why
  it’s important: 
 Why do you need
  to copy the Voting.json file? To interact
  with your smart contract from your React app, you need the ABI from
  the Voting.json file. The ABI allows Web3.js to understand how to communicate
  with the smart contract. Without it, your frontend won’t know how to call the
  functions in your smart contract. Steps to Copy
  Voting.json Manually: 
 4. Create a
  New File Called app.js
  in the src Folder In your React
  project, you will have a src folder inside the client
  folder where you place the app’s main JavaScript files. 
 This file will
  be your main component, and it will handle: 
 5. Add Code to
  app.js. This app.js would work as a voting interface.  Here’s how you
  can structure your UI to interact with the Voting Smart Contract: Explanation of
  Voting Interface 
 import React, { useState, useEffect } from 'react'; import Web3 from 'web3'; import VotingContract from './contracts/Voting.json';  // Ensure
  this path is correct const App = () => {   const [account, setAccount] = useState('');   const [contract, setContract] = useState(null);   useEffect(() => {     const initWeb3 = async () => {       if (window.ethereum) {         window.web3 = new Web3(window.ethereum);         try {           await window.ethereum.request({
  method: 'eth_requestAccounts' });  // Request account access           const accounts = await
  window.web3.eth.getAccounts();           setAccount(accounts[0]);           // Get network and contract
  instance           const networkId = await
  window.web3.eth.net.getId();           const deployedNetwork =
  VotingContract.networks[networkId];           const contractInstance = new
  window.web3.eth.Contract(             VotingContract.abi,             deployedNetwork &&
  deployedNetwork.address,           );           setContract(contractInstance);         } catch (error) {           console.error("MetaMask
  connection failed", error);         }       } else {         console.error("No Ethereum browser
  extension detected");       }     };     initWeb3();   }, []);   const voteForCandidate = async (candidate) => {     if (contract) {       try {         await contract.methods.voteForCandidate(candidate).send({
  from: account });         console.log(`Voted for ${candidate}`);       } catch (error) {         console.error("Error during
  voting:", error);       }     } else {       console.error("Contract is not initialized");     }   };   return (     <div>       <h1>Voting DApp</h1>       <p>Your account: {account}</p>       <button onClick={() =>
  voteForCandidate('Alice')}>Vote for Alice</button>       <button onClick={() =>
  voteForCandidate('Bob')}>Vote for Bob</button>       <button onClick={() =>
  voteForCandidate('Charlie')}>Vote for Charlie</button>     </div>   ); }; export default App; Part 5: Test
  the DApp 
 npm start The app should
  open in your browser at http://localhost:3000. 
 
 Expected
  Outcome By following this
  guide: 
 Part 6:  Invite others
  to vote on Voting DAPP:  To ask others
  to vote on your Voting DApp, you can create and host a simple web-based
  dApp where users can interact with the contract via MetaMask. Here's a
  step-by-step guide to make your DApp available for others to use through a
  website. Step 1: Set Up
  the Voting DApp Frontend – Web3 You’ve already
  built the frontend using React and Web3.js. Now we need to
  ensure that everything is set up properly so that other users can interact
  with it. 
 Step 2: How
  Can Others Vote on Your Local Network (Ganache + React)? For others to
  vote on your DApp, they would need to be on the same physical or virtual
  network as you. This typically means: ·       Same Physical
  Network (Wi-Fi/LAN): o  
  If someone is connected to the same Wi-Fi
  or local network (LAN) as your computer, they can access your Ganache
  instance and the DApp frontend if you expose the ports (7545 and
  3000) to them. ·       Local Network
  Setup: o  
  Localhost (127.0.0.1) refers to your own
  computer, so someone on your network will not be able to directly access
  http://localhost:3000 or http://127.0.0.1:7545 on your machine. o  
  However, if you share your local IP address
  with them, they can access your machine's services. §  Example: If your
  machine's local IP address is 192.168.1.10, they would access your
  DApp at http://192.168.1.10:3000 and Ganache at http://192.168.1.10:7545. ·       Run the DApp: 
 Important:
  Exposing Localhost to the Web If you want
  others who are not on your local network (i.e., people on the internet)
  to vote, you would need to host your DApp on a public server or use a
  service like ngrok to expose your localhost temporarily to the
  internet. Using ngrok to
  Expose Your Local DApp: 
 ngrok http
  3000 
 ngrok http
  7545 
 Limitations: 
 What is a
  Private Blockchain? A private
  blockchain is a blockchain that is: 
 When you run
  Ganache, you are running a local instance of an Ethereum blockchain where
  you: 
   How Private
  Blockchains Work 
 Why You Use a
  Private Blockchain (Ganache) 
 · No real Ether is needed. · No gas fees are incurred. · You can quickly reset the blockchain if something goes wrong. · It’s fast and designed for developers to interact with Ethereum contracts easily. 
   Invite others
  to vote on Voting DAPP:  To ask others
  to vote on your Voting DApp, you can create and host a simple web-based
  dApp where users can interact with the contract via MetaMask. Here's a
  step-by-step guide to make your DApp available for others to use through a
  website. |  | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Deploying
  a Voting DApp to the Sepolia Testnet: A Step-by-Step Guide (optional)Step 1: Set Up Infura for Sepolia
 ·      
  Go to Infura and create a
  free account if you don’t have one. ·      
  Once logged in, create a new project and
  select Sepolia as the network. ·      
  Copy the Project ID
  from your Infura project dashboard. Step 2: Modify  |  | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Step-by-Step Guide for Deploying with Truffle1. Set Up Your Truffle EnvironmentIf you haven’t already, you’ll need to install Truffle and Ganache: · Install Truffle:  · Install Ganache: Download Ganache from Truffle Suite and run it. 2. Initialize a New Truffle ProjectCreate a new project directory and initialize a Truffle project:  mkdircdThis
  will create a basic folder structure for your Truffle project, including  3. Write Your VotingToken ContractIn the
    cdtouchNow,
  copy the   4. Install OpenZeppelin ERC20 DependencyYou need to install the OpenZeppelin contracts in your project (in the project root directory): This will allow you to use OpenZeppelin’s ERC20 implementation. 5. Create a Migration FileIn the
    touchAdd
  the following content to the   constmoduleThis
  migration file tells Truffle to deploy the  6. Configure Truffle for GanacheIn the
   
 moduleThis
  configuration connects Truffle to the local Ganache instance running on  7. Compile the ContractNow, compile the contract using Truffle:  This
  will compile the  8. Deploy the ContractNow deploy the contract to the local Ganache blockchain:  This
  will deploy the  9. Interact with the Contract Using Truffle ConsoleOnce the contract is deployed, you can interact with it using the Truffle console:  In the Truffle console, you can interact with the deployed contract: · Get the deployed instance:  const· Check the token supply: · Register a voter: await· Cast a vote: await10. Monitor Transactions in GanacheIn Ganache, you will see all the transactions made by Truffle, including contract deployment and function calls. Summary
 You
  can now deploy your  |  | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Homework of Week 6 – Building an ERC20-Based Token on Ethereum Instructional Video                                 Quiz ·     Part 1 (Ganache
  Window Platform, ?)  ·     Part II  (Ganache on Truffle, works) ·     PartIII   (Metamask, works)        What is ERC20?ERC20 is a widely-used standard for creating tokens on the Ethereum blockchain. It defines a set of rules that all Ethereum-based tokens must follow to ensure interoperability between different tokens and decentralized applications (dApps). These rules define functions that allow tokens to be easily transferred, approved for use by other accounts, and checked for balance. Technically, Bitcoin and ERC20 tokens
  operate on two different blockchain. ·      
  Bitcoin
  operates on its own Bitcoin blockchain, while ERC20 tokens are designed for
  the Ethereum blockchain. What is this Standard
  for Tokens?The ERC20 standard provides a blueprint for how tokens behave and interact with other smart contracts or wallets. The standard functions include: 
 These functions allow ERC20 tokens to behave consistently and be used across different dApps without requiring special modifications. What is a Token For?A token
  is a digital asset that can represent various forms of value. On Ethereum,
  tokens can be used to represent things like: 
 What Can Tokens Be
  Used For in a dApp?In
  decentralized applications (dApps), tokens can serve different roles. For
  example: 
 ERC20 Token Solidity
  Code ExampleHere's a basic example of an ERC20 token that could be used for voting in a dApp: // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import
  "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import
  "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import
  "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import
  "@openzeppelin/contracts/utils/Context.sol"; import
  "@openzeppelin/contracts/interfaces/draft-IERC6093.sol"; contract VotingToken is ERC20 {    
  address public owner;    
  // Constructor to initialize the contract with a given supply    
  constructor(uint256 initialSupply) ERC20("VotingToken",
  "VOTE") {         owner = msg.sender; // Set the owner
  to the contract deployer         _mint(owner, initialSupply); // Mint
  the initial supply of tokens    
  }    
  // Other functions can be added here as needed } This  
 How to Deploy Using
  Remix, Ganache, and MetaMaskHere’s
  how you can deploy the  Step 1: Setup Ganache
  and Metamask1.
  Set Up a New
  Workspace in Ganache1.    
  Open Ganache: 
 2.    
  Create a New Workspace: 
 3.    
  Configure Workspace
  Settings: 
 2.
  Change the Default
  ETH Balance to 100001.    
  Go to Accounts &
  Keys: 
 2.    
  Set the Default Balance: 
 3.
  Set the Gas
  Limit to 8,000,0001.    
  Go to Server Settings: 
 2.    
  Update Gas Limit: 
 3.    
  Save and Start: 
 4.
  Connect MetaMask to the New Workspace1.    
  Open MetaMask: 
 2.    
  Connect to the New
  Ganache Workspace: 
 Step 2: Deploy the
  Contract with Remix1.    
  Open Remix: 
 2.    
  Create a New File: 
 3.    
  Compile the Contract: 
 4.    
  Deploy the Contract: 
 5.    
  Confirm in MetaMask: 
 Step 3: Interact with
  the Contract
 
 Step 4: Testing Voting with
  TokensIf
  you want to build a voting system, you can write a function in Solidity to
  count votes based on token balances. Tokens can represent voting power, and
  participants can cast votes by transferring tokens or through a more complex
  function that records votes without transferring tokens.  |  | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| If the above code
  does not work: Step-by-Step Guide: Setting Up Ganache, MetaMask, and Remix1. Stop Any Existing Process on Port 8545:If Ganache
  or another application is already using port 8545, we need to stop it. Find
  and Kill the Process:
 
 
 TCP    127.0.0.1:8545    0.0.0.0:0    LISTENING    <PID>Note the PID (Process ID) for the process. 
 
 Replace
   2. Start Ganache (Local Blockchain):Once
  port 8545 is free, you can start Ganache on the correct settings. Run
  Ganache on Port 8545:
 
 
 ganacheStarting
 3. Connect MetaMask to Ganache:To
  interact with Ganache using MetaMask, you need to configure MetaMask to
  connect to the local blockchain. Set
  Up MetaMask:
 4. Use Remix to Deploy Smart Contracts:Now,
  we’ll use Remix to write and deploy smart contracts on the local Ganache
  network. Configure
  Remix to Use MetaMask:
 5. Deploy a Smart Contract:Now
  that everything is connected, you can deploy a contract. Deploy
  a Contract in Remix:
 6. Verify the Deployment:If
  everything is set up correctly, the contract will be deployed to Ganache, and
  you can interact with it using the Remix
  interface or MetaMask. Optional: Use a Different Port:If
  port 8545 is already in use and you don't want to stop the process, you can
  start Ganache on a different port (e.g., port 8546): Run
  Ganache on Port 8546: 
 Make
  sure to update the RPC URL in MetaMask to  Summary
 By
  following these steps, you will be able to successfully set up a local
  blockchain, connect it to MetaMask, and deploy contracts using Remix.   |  | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Voting Token
  Assignment (Optional. Simply replace the Solidity code with the following and
  repeat the process you have done earlier:) Solidity code: // SPDX-License-Identifier:
  MIT pragma solidity ^0.8.20;  import
  "@openzeppelin/contracts/token/ERC20/ERC20.sol";  contract VotingToken is ERC20 {     address public owner;     mapping(address => bool) public
  voters;  // To keep track of registered
  voters      // Event to log when a voter is
  registered     event VoterRegistered(address voter);      // Event to log when votes are cast     event VotesCasted(address voter, address
  to, uint256 amount);       constructor(uint256 initialSupply)
  ERC20("VotingToken", "VOTE") {         owner = msg.sender;  // The deployer of the contract becomes the
  owner         _mint(owner, initialSupply);  // Mint the initial supply of tokens to the
  owner     }      // Function for the owner to register
  voters     function registerVoter(address voter)
  public onlyOwner {         require(!voters[voter], "Voter
  is already registered");  //
  Prevent duplicate registration         voters[voter] = true;  // Mark voter as registered         emit VoterRegistered(voter);  // Emit event to signal voter registration     }      // Function for registered voters to
  vote (transfer tokens)     function vote(address to, uint256 amount)
  public {         require(voters[msg.sender], "You
  are not registered to vote");  //
  Ensure voter is registered         require(balanceOf(msg.sender) >=
  amount, "Insufficient balance to vote");  // Ensure voter has enough tokens         transfer(to, amount);  // Transfer tokens (cast votes)         emit VotesCasted(msg.sender, to,
  amount);  // Emit event to log the vote     }      // Modifier to restrict certain
  functions to only the owner of the contract     modifier onlyOwner() {         require(msg.sender == owner,
  "Only the owner can perform this action");         _;     } } Explanation: In this contract, the token serves as the unit of voting. Here's how it works and why the token is important: 1. Voting Power: The token represents voting power. Each token gives its holder the ability to cast a certain number of votes. The more tokens a voter holds, the more voting power they have. When a registered voter transfers tokens to another address, it is considered casting votes for that address. 2.     Transfer
  of Votes: The  3.    
  Ownership and Control: The
  initial supply of tokens is minted to the contract owner when
  the contract is deployed. The owner can distribute these tokens among
  registered voters, giving them voting power. The number of tokens a voter has
  determines how many votes they can cast. Use Cases for the Token:
 In
  short, the token in this contract acts as a voting token,
  allowing registered users to vote by transferring tokens to other addresses,
  where the number of tokens transferred represents the number of votes cast. |  | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Term Project  1 (option 1)- Deploy and Interact
  with a Smart Contract KYC (Know your customer, a DApp used by banks)) ·     
    Instructional
  Video1 (smart
  contract) ·     
    Video2  (truffle console, optional) ·     
    Video3
  (web3 part1)     ·     
    Video4
  (web3, part2) 1. Set Up Your
  Development Environment 1.1 Install
  Node.js and npm: 
 1.2 Install
  Truffle and Ganache: 
 npm install -g truffle 
 2. Initialize
  a Truffle Project 2.1 Create a
  New Directory for Your Project: mkdir my-project cd my-project 2.2 Initialize
  Truffle: truffle init This command
  creates a basic Truffle project structure. 3. Write Your
  KYC Smart Contract 3.1 Create a
  New Solidity File:Create
  a new file KYC.sol in the contracts directory: // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract KYC {     //
  Define Bank and Customer structs     struct
  Bank {        
  string name;        
  address bankAddress;     }     struct
  Customer {        
  string name;        
  address customerAddress;        
  bool isVerified;     }     //
  Mappings to store bank and customer data mapping(address => Bank) public banks; mapping(address => Customer) public
  customers;     //
  Arrays to store the list of bank and customer addresses address[] public bankList; address[] public customerList;     //
  Event to emit when a new bank is added     event
  BankAdded(string name, address bankAddress);     //
  Event to emit when a new customer is added     event
  CustomerAdded(string name, address customerAddress);     //
  Event to emit when a customer is verified     event
  CustomerVerified(address customerAddress);     //
  Function to add a new bank    
  function addNewBank(string memory name, address bankAddress) public { require(bankAddress != address(0), "Invalid
  address");        
  require(bytes(name).length> 0, "Bank name cannot be
  empty");        
  banks[bankAddress] = Bank(name, bankAddress); bankList.push(bankAddress);        
  emit BankAdded(name, bankAddress);     }     //
  Function to add a new customer     function
  addNewCustomer(string memory name, address customerAddress) public { require(customerAddress != address(0),
  "Invalid address");        
  require(bytes(name).length> 0, "Customer name cannot be
  empty");         customers[customerAddress]
  = Customer(name, customerAddress, false); customerList.push(customerAddress);        
  emit CustomerAdded(name, customerAddress);     }     //
  Function to verify a customer    
  function verifyCustomer(address customerAddress) public { require(customerAddress != address(0),
  "Invalid address");        
  require(customers[customerAddress].customerAddress != address(0),
  "Customer does not exist");        
  customers[customerAddress].isVerified = true;        
  emit CustomerVerified(customerAddress);     }     //
  Function to retrieve all banks    
  function getBanks() public view returns (Bank[] memory) { Bank[] memory allBanks = new
  Bank[](bankList.length);        
  for (uint i = 0; i<bankList.length; i++) { allBanks[i] = banks[bankList[i]];         }        
  return allBanks;     }     //
  Function to retrieve all customers    
  function getCustomers() public view returns (Customer[] memory) { Customer[] memory allCustomers = new
  Customer[](customerList.length);        
  for (uint i = 0; i<customerList.length; i++) { allCustomers[i] = customers[customerList[i]];         }        
  return allCustomers;     } } 3.2 Compile
  Your Contract: truffle compile 4. Migrate
  Your Smart Contract 4.1 Create a
  Migration Script: Create
  a new file 2_deploy_contracts.js
  in the migrations directory: // migrations/2_deploy_contracts.js const KYC = artifacts.require("KYC"); module.exports = function(deployer) {  
  deployer.deploy(KYC); }; 4.2 Run
  Migrations: truffle migrate --network development 5. Interact
  with Your Smart Contract Using Truffle Console 5.1 Start
  Ganache: 
 5.2 Open
  Truffle Console: truffle console --network development 5.3 Interact
  with Your Contract: In the Truffle Console:   const KYC = artifacts.require("KYC"); const kyc = await KYC.deployed(); const accounts = await web3.eth.getAccounts(); // Add new banks await kyc.addNewBank("Bank1",
  accounts[1]); await kyc.addNewBank("Bank2",
  accounts[2]); // Add new customers await kyc.addNewCustomer("Customer1",
  accounts[3]); await kyc.addNewCustomer("Customer2",
  accounts[4]); // Verify a customer await kyc.verifyCustomer(accounts[3]); // Retrieve and log banks and customers const banks = await kyc.getBanks(); console.log("Banks:", banks); const customers = await kyc.getCustomers(); console.log("Customers:", customers); 5.4 DApp and Web3 Step 1:
  Writing the Frontend1.     Install
  Dependencies for Web3 Interaction: Install Web3.js and other
  dependencies that will allow your frontend to interact with the smart
  contract (you need to create
  a folder called kyc-dapp first and install web3 in the kyc-dapp folder) 
 2.     Set
  Up a Basic Frontend: You can create a simple webpage using  3.    
  Install Lite Server
  (for serving the webpage locally): 
 4.     Set
  Up  /your-react-app (such as kyc-dapp folder) ├── /node_modules ├── /public │ ├── index.html // Main HTML file │ ├── favicon.ico // Favicon │ └── manifest.json // Web app manifest ├── /src │ ├── App.js // Main app component │ ├── index.js // Entry point for React │ ├── kyc.js // Your KYC contract file │ └── web3.js // Web3 initialization file (if any) ├── package.json // Project metadata and dependencies └── README.md // Project documentation <!DOCTYPE html> <html
  lang="en"> <head>   <meta charset="UTF-8">   <meta name="viewport"
  content="width=device-width, initial-scale=1.0">   <title>KYC DApp</title>   <!-- Web3.js CDN -->   <script
  src="https://cdn.jsdelivr.net/gh/ethereum/web3.js@1.6.1/dist/web3.min.js"></script>   <!-- CSS Styling for a better appearance
  -->   <style>     body {       font-family: Arial, sans-serif;       margin: 0;       padding: 20px;       background-color: #f0f0f0;     }     h1, h2 {       color: #333;     }     input {       padding: 10px;       margin: 5px;       border: 1px solid #ccc;       border-radius: 5px;       width: 300px;     }     button {       padding: 10px 20px;       margin: 5px;       background-color: #28a745;       color: white;       border: none;       border-radius: 5px;       cursor: pointer;     }     button:hover {       background-color: #218838;     }     .container {       max-width: 600px;       margin: 0 auto;       background-color: white;       padding: 20px;       border-radius: 10px;       box-shadow: 0 0 10px rgba(0, 0, 0,
  0.1);     }     .form-group {       margin-bottom: 20px;     }   </style> </head> <body>   <div id="root"></div>   <script>     // Setup Web3     let web3 = new Web3(Web3.givenProvider ||
  "http://localhost:7545");     // ABI and contract address will come from
  Truffle deployment     const contractAddress =
  "PASTE_YOUR_CONTRACT_ADDRESS_HERE";     const abi = /*
  PASTE_YOUR_CONTRACT_ABI_HERE */;     const kycContract = new
  web3.eth.Contract(abi, contractAddress);     // React component for the KYC DApp     class App extends React.Component {       constructor(props) {         super(props);         this.state = {           bankName: '',           bankAddress: '',           customerName: '',           customerAddress: '',           verifyAddress: ''         };       }       handleChange = (e) => {         this.setState({ [e.target.name]:
  e.target.value });       };       addNewBank = async () => {         const { bankName, bankAddress } =
  this.state;         const accounts = await
  web3.eth.getAccounts();         try {           await
  kycContract.methods.addNewBank(bankName, bankAddress).send({ from:
  accounts[0] });           alert("Bank Added");           this.setState({ bankName: '',
  bankAddress: '' }); // Clear input fields         } catch (error) {           console.error("Error adding bank:
  ", error);           alert("Error adding
  bank.");         }       };       addNewCustomer = async () => {         const { customerName, customerAddress
  } = this.state;         const accounts = await
  web3.eth.getAccounts();         try {           await
  kycContract.methods.addNewCustomer(customerName, customerAddress).send({
  from: accounts[0] });           alert("Customer Added");           this.setState({ customerName: '',
  customerAddress: '' }); // Clear input fields         } catch (error) {           console.error("Error adding
  customer: ", error);           alert("Error adding
  customer.");         }       };       verifyCustomer = async () => {         const { verifyAddress } = this.state;         const accounts = await
  web3.eth.getAccounts();         try {           await
  kycContract.methods.verifyCustomer(verifyAddress).send({ from: accounts[0]
  });           alert("Customer
  Verified");           this.setState({ verifyAddress: ''
  }); // Clear input field         } catch (error) {           console.error("Error verifying
  customer: ", error);           alert("Error verifying
  customer.");         }       };       render() {         return (           <div
  className="container">             <h1>KYC DApp</h1>             <div
  className="form-group">               <h2>Add New
  Bank</h2>               <input                 type="text"                 name="bankName"                 value={this.state.bankName}                 onChange={this.handleChange}                 placeholder="Bank
  Name"               />               <input                 type="text"                 name="bankAddress"                
  value={this.state.bankAddress}                 onChange={this.handleChange}                 placeholder="Bank
  Address"               />               <button
  onClick={this.addNewBank}>Add Bank</button>             </div>             <div
  className="form-group">               <h2>Add New
  Customer</h2>               <input                 type="text"                 name="customerName"                
  value={this.state.customerName}                 onChange={this.handleChange}                 placeholder="Customer
  Name"               />               <input                 type="text"                 name="customerAddress"                
  value={this.state.customerAddress}                 onChange={this.handleChange}                 placeholder="Customer
  Address"               />               <button
  onClick={this.addNewCustomer}>Add Customer</button>             </div>             <div
  className="form-group">               <h2>Verify
  Customer</h2>               <input                 type="text"                
  name="verifyAddress"                
  value={this.state.verifyAddress}                 onChange={this.handleChange}                 placeholder="Customer
  Address"               />               <button
  onClick={this.verifyCustomer}>Verify</button>             </div>           </div>         );       }     }     const rootElement = document.getElementById("root");     if (rootElement) {       const root =
  ReactDOM.createRoot(rootElement);       root.render(<App />);     } else {       console.error("Target container is
  not a DOM element.");     }   </script> </body> </html> Step 2: Get Contract ABI and Address: After
  deploying your smart contract using Truffle (or any other deployment tool),
  you'll typically find the ABI and contract address in the  ·       
  Open  | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Term Proejct 2 - Simple
  Fraternity Dapp (Option 2)
 Fraternity DApp Project
  Folder Structurefraternity-dapp/             # Root project folder │ ├──
  contracts/               # Folder where
  Solidity contracts are stored │   └── FraternityRegistration.sol  # Your smart contract code │ ├──
  migrations/              # Migration
  files for deploying contracts │   └── 2_deploy_contracts.js  # Deployment script for Truffle │ ├──
  build/                   # Truffle's
  build folder (generated after compilation) │   └── contracts/           # Contains the compiled contracts
  and ABI │         └──
  FraternityRegistration.json  # ABI JSON file of your contract │ ├──
  frontend/                # Folder for
  your front-end code (web3 and lite-server) │   ├── index.html           # HTML file for the front-end │   └── app.js               # JavaScript to interact with
  the smart contract │   ├── package.json             # Node.js package manager file
  for managing dependencies ├── truffle-config.js        # Truffle configuration file (to
  configure network, compiler, etc.) └──
  README.md                # Optional:
  Instructions or project description 1. Create a new project directory: mkdircd2.     Initialize
  Truffle: Inside the  
 This will create a project structure with the following folders: 
 3. Write the Smart ContractCreate a new file in the contracts/ folder called FraternityRegistration.sol and write the following code: // SPDX-License-Identifier:
  MIT pragma solidity ^0.8.0; contract
  FraternityRegistration {     address public owner;     uint256 public totalMembers;     struct Member {         string name;         bool isRegistered;     }     mapping(address => Member) public
  members;     event MemberRegistered(address indexed
  memberAddress, string name);     event MemberRemoved(address indexed
  memberAddress);     modifier onlyOwner() {         require(msg.sender == owner,
  "Only the contract owner can execute this action");         _;     }     constructor() {         owner = msg.sender;     }     function registerMember(address
  _memberAddress, string memory _name) public onlyOwner {         require(!members[_memberAddress].isRegistered,
  "Member is already registered");         members[_memberAddress] =
  Member({name: _name, isRegistered: true});         totalMembers++;         emit MemberRegistered(_memberAddress,
  _name);     }     function isMember(address _memberAddress)
  public view returns (bool) {         return
  members[_memberAddress].isRegistered;     }     function getMemberDetails(address
  _memberAddress) public view returns (string memory) {        
  require(members[_memberAddress].isRegistered, "Member is not
  registered");         return members[_memberAddress].name;     }     function removeMember(address
  _memberAddress) public onlyOwner {        
  require(members[_memberAddress].isRegistered, "Member is not
  registered");         delete members[_memberAddress];         totalMembers--;         emit MemberRemoved(_memberAddress);     }     function transferOwnership(address
  _newOwner) public onlyOwner {         require(_newOwner != address(0),
  "Invalid new owner address");         owner = _newOwner;     } } 4. Compile the ContractRun the following command to compile the smart contract: 
 This
  will compile the contract and create JSON files in the  5    
  Deploy the
  Deployment ScriptCreate
  a new migration file in the  constmodule
 Run Ganache
 Deploy the Contract1. Deploy the contract to the local blockchain: 
 If everything works correctly, you will see the contract deployed on Ganache, and the contract address will be displayed. 6. Front-End SetupInitialize a Front-End Project6.1 
  Inside your project folder
  ( mkdircd6.2 Initialize a Node.js project: 
 6.3 Install necessary dependencies: 
 6.4 Create your front-end files: Create the following files: ·  
   ·  
    | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| index.htmlCreate a basic HTML page in
  the frontend/index.html: <!DOCTYPE html><html
  lang="en"><head>    <meta charset="UTF-8">    <meta name="viewport"
  content="width=device-width, initial-scale=1.0">    <title>Jacksonville University
  Baseball and Cross Team Decentralized Registration Form</title></head><body
  style="font-family: Arial, sans-serif; background-color: #f4f4f4; color:
  #333;">    <h1 style="text-align: center;
  color: navy;">Jacksonville University Baseball and Cross Team
  Decentralized Registration Form</h1>    <div style="width: 60%; margin:
  auto; padding: 20px; background-color: white; border-radius: 10px; box-shadow:
  0 0 10px rgba(0, 0, 0, 0.1);">        <h2 style="color:
  darkblue;">Register a New Member</h2>        <label>Member Address:
  </label>        <input type="text"
  id="memberAddress" placeholder="Enter member's Ethereum
  address" style="width: 100%; padding: 10px; margin-bottom: 10px;
  border: 1px solid #ccc; border-radius: 5px;">        <label>Member Name:
  </label>        <input type="text"
  id="memberName" placeholder="Enter member's name"
  style="width: 100%; padding: 10px; margin-bottom: 10px; border: 1px
  solid #ccc; border-radius: 5px;">        <button
  onclick="registerMember()" style="width: 100%; padding: 10px;
  background-color: darkblue; color: white; border: none; border-radius: 5px;
  cursor: pointer;">Register Member</button>       
  <h2 style="color: darkblue; margin-top: 20px;">Check
  Membership</h2>        <button
  onclick="checkMembership()" style="width: 100%; padding: 10px;
  background-color: navy; color: white; border: none; border-radius: 5px;
  cursor: pointer;">Check Membership</button>        <div id="result"
  style="margin-top: 20px; color: darkred;"></div>        <div id="owner"
  style="margin-top: 20px; color: green;"></div>    </div>    <script
  src="https://cdn.jsdelivr.net/npm/web3/dist/web3.min.js"></script>    <script
  src="app.js"></script></body></html>app.jsCreate a JavaScript file (frontend/app.js) for
  interacting with the smart contract:// Check if Web3 is
  injected by the browser (MetaMask)if (typeof
  window.ethereum !== 'undefined') {    console.log('MetaMask is installed!');    window.web3 = new Web3(window.ethereum);    ethereum.request({ method:
  'eth_requestAccounts' }).then(() => {        // After MetaMask connects,
  initialize the contract        initializeContract();    });} else {    console.log('Please install MetaMask!');}// ABI from your
  uploaded JSON file under build folderconst contractABI = [    {        "inputs": [],        "stateMutability":
  "nonpayable",        "type":
  "constructor"    },    {        "anonymous": false,        "inputs": [            {                "indexed": true,                "internalType":
  "address",                "name":
  "memberAddress",                "type":
  "address"            },            {                "indexed": false,                "internalType":
  "string",                "name":
  "name",                "type":
  "string"            }        ],        "name":
  "MemberRegistered",        "type": "event"    },    {        "anonymous": false,        "inputs": [            {                "indexed": true,                "internalType":
  "address",                "name":
  "memberAddress",                "type":
  "address"            }        ],        "name":
  "MemberRemoved",        "type": "event"    },    {        "inputs": [            {                "internalType":
  "address",                "name":
  "_memberAddress",                "type":
  "address"            }        ],        "name":
  "members",        "outputs": [            {                "internalType":
  "string",                "name":
  "name",                "type":
  "string"            },            {                "internalType":
  "bool",                "name":
  "isRegistered",                "type":
  "bool"            }        ],        "stateMutability":
  "view",        "type":
  "function",        "constant": true    },    {        "inputs": [],        "name": "owner",        "outputs": [            {                "internalType":
  "address",                "name": "",                "type":
  "address"            }        ],        "stateMutability":
  "view",        "type":
  "function",        "constant": true    },    {        "inputs": [],        "name":
  "totalMembers",        "outputs": [            {                "internalType":
  "uint256",                "name":
  "",                "type":
  "uint256"            }        ],        "stateMutability":
  "view",        "type":
  "function",        "constant": true    },    {        "inputs": [            {                "internalType":
  "address",                "name":
  "_memberAddress",                "type":
  "address"            },            {                "internalType":
  "string",                "name":
  "_name",                "type":
  "string"            }        ],        "name":
  "registerMember",        "outputs": [],        "stateMutability":
  "nonpayable",        "type":
  "function"    },    {        "inputs": [            {                "internalType":
  "address",                "name":
  "_newOwner",                "type":
  "address"            }        ],        "name":
  "transferOwnership",        "outputs": [],        "stateMutability":
  "nonpayable",        "type":
  "function"    }];// Replace this with
  your deployed contract addressconst contractAddress =
  '0xff25815599aB4cb56B83CB2B9d0D26626f8b7E05';// Initialize the
  contract after MetaMask is connectedfunction
  initializeContract() {    try {        const contract = new web3.eth.Contract(contractABI,
  contractAddress);        console.log('Contract initialized
  successfully.');        // Set the contract globally to be
  used later        window.contract = contract;        // Log the contract owner        checkContractOwner();    } catch (error) {        console.error('Error initializing
  contract:', error);    }}// Function to register
  a member with gas estimationfunction
  registerMember() {    const memberAddress =
  document.getElementById('memberAddress').value;    const memberName =
  document.getElementById('memberName').value;    // Disable the button to prevent multiple
  clicks    document.querySelector('button').disabled
  = true;    if (!web3.utils.isAddress(memberAddress))
  {        document.getElementById('result').innerHTML
  = 'Invalid member address.';       
  document.querySelector('button').disabled = false; // Re-enable the
  button        return;    }    web3.eth.getAccounts().then(accounts
  => {        const account = accounts[0];        // Estimate gas for the transaction       
  window.contract.methods.registerMember(memberAddress, memberName)            .estimateGas({ from: account })            .then(gasAmount => {                console.log('Estimated Gas:',
  gasAmount);                // Send the transaction with
  estimated gas                return
  window.contract.methods.registerMember(memberAddress, memberName)                    .send({ from: account,
  gas: gasAmount });            })            .then(() => {                document.getElementById('result').innerHTML
  = 'Member registered successfully!';               
  document.querySelector('button').disabled = false; // Re-enable the
  button            })            .catch(err => {                console.error('Error
  registering member:', err);               
  document.getElementById('result').innerHTML = 'Error registering
  member: ' + err.message;               
  document.querySelector('button').disabled = false; // Re-enable the
  button            });    });}// Function to check if
  someone is a memberfunction
  checkMembership() {    const memberAddress =
  document.getElementById('memberAddress').value;    if (!web3.utils.isAddress(memberAddress))
  {       
  document.getElementById('result').innerHTML = 'Invalid member address.';        return;    }   
  window.contract.methods.isMember(memberAddress).call()        .then(isMember => {            const resultText = isMember ?
  'This address is a member.' : 'This address is not a member.';            document.getElementById('result').innerHTML
  = resultText;        })        .catch(err => {            console.error('Error checking
  membership:', err);           
  document.getElementById('result').innerHTML = 'Error checking
  membership: ' + err.message;        });}// Function to check the
  contract ownerfunction
  checkContractOwner() {    window.contract.methods.owner().call()    .then(ownerAddress => {        console.log('Contract Owner:',
  ownerAddress);        document.getElementById('owner').innerHTML
  = `Contract Owner: ${ownerAddress}`;    })    .catch(err => {        console.error('Error fetching owner
  address:', err);    });} | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 7. Run the Front-EndStart Lite Server7.1 
  Add the following script
  into  "scripts":}Or just copy the following into 
 7.2 Run the front-end: 
 8      
  Access the DApp at  9. Testing the DApp
 10. Troubleshooting Common Issues
 
 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Term Project  3 (option 3) - An Escrow Smart Contract   Refer
  to  https://github.com/arshdeepbahga/blockchain-applications-book/tree/master/Chapter-1 Part 1:
  Setting Up the Development Environment Step 1:
  Install Node.js 1.              
  Download and Install Node.js: o       
  Go to the Node.js
  website. o       
  Download the LTS (Long Term Support) version
  suitable for your operating system (Windows, macOS, or Linux). o       
  Follow the installation instructions provided on
  the website. 2.              
  Verify the Installation: o       
  Open Command Prompt (Windows) or Terminal
  (macOS/Linux). o       
  Type the following commands to check if Node.js
  and npm (Node Package Manager) are installed correctly: node -v npm -v o       
  You should see the version numbers of Node.js and
  npm displayed. Step 2:
  Install Truffle 1.              
  Install Truffle Globally: o       
  In your Command Prompt or Terminal, type the
  following command to install Truffle: npm install -g truffle o       
  To verify that Truffle is installed, type: truffle version o       
  This will show you the version of Truffle
  installed on your system. Step 3:
  Install Ganache 1.              
  Download and Install Ganache: o       
  Go to the Ganache
  website. o       
  Download the version for your operating system. o       
  Follow the instructions to install Ganache. 2.              
  Start Ganache: o       
  Open Ganache after installation. o       
  Click on "Quickstart Ethereum" to set up
  a new local blockchain network. This network will simulate how a real blockchain
  works. Step 4: Set Up
  a New Truffle Project 1.              
  Create a Project Directory: o       
  In Command Prompt or Terminal, navigate to the
  location where you want to create your project and type: mkdir Escrow cd Escrow 2.              
  Initialize a Truffle Project: o       
  In the project directory, type: truffle init o       
  This will create the basic structure of your
  Truffle project. 3.              
  Configure Truffle to Connect to Ganache: o       
  Open the truffle-config.js file in the project
  directory. o       
  Update the configuration to look like this: module.exports = {   networks:
  {    
  development: {      
  host: "127.0.0.1", // Localhost      
  port: 7545,        // Ganache
  port network_id: "*",   // Match any network id     },   },  
  compilers: { solc: {      
  version: "0.8.0", // Specify the Solidity compiler version     },   }, }; Part 2:
  Creating the Escrow Smart Contract Step 1: Create
  the Smart Contract 1.              
  Create a New Contract File: o       
  In the contracts directory, create a new file
  named Escrow.sol. 2.              
  Write the Smart Contract: o       
  Open Escrow.sol and add the following code: // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract Escrow {    
  address public buyer;    
  address public seller; uint public deposit; uint public timeToExpiry; uint public startTime;     //
  Buyer sets up the escrow contract and pays the deposit constructor(address _seller, uint _timeToExpiry)
  payable { require(msg.value> 0, "Deposit must be
  greater than zero");        
  buyer = msg.sender;        
  seller = _seller;        
  deposit = msg.value; timeToExpiry = _timeToExpiry; startTime = block.timestamp;     }     //
  Buyer releases deposit to seller    
  function releaseToSeller() public { require(msg.sender == buyer, "Only buyer
  can release funds");        
  require(!isExpired(), "Escrow is expired");        
  payable(seller).transfer(deposit);        
  deposit = 0; // Set deposit to zero to prevent re-entry     }     //
  Buyer can withdraw deposit if escrow is expired    
  function withdraw() public {        
  require(isExpired(), "Escrow is not expired yet"); require(msg.sender == buyer, "Only buyer
  can withdraw funds"); uint amount = deposit;        
  deposit = 0; // Set deposit to zero to prevent re-entry        
  payable(buyer).transfer(amount);     }     //
  Seller can cancel escrow and return all funds to buyer    
  function cancel() public { require(msg.sender == seller, "Only seller
  can cancel the escrow"); uint amount = deposit;        
  deposit = 0; // Set deposit to zero to prevent re-entry        
  payable(buyer).transfer(amount);     }     //
  Check if the escrow is expired    
  function isExpired() public view returns (bool) {        
  return block.timestamp>startTime + timeToExpiry;     } } Step 2: Write
  a Migration Script 1.              
  Create a New Migration File: o       
  In the migrations directory, create a new file
  named 2_deploy_contracts.js. 2.              
  Write the Deployment Script: o       
  Add the following code to 2_deploy_contracts.js: const Escrow =
  artifacts.require("Escrow"); module.exports = function (deployer, network,
  accounts) {   const
  sellerAddress = accounts[1]; // Example seller address   const timeToExpiry
  = 3600; // 1 hour in seconds deployer.deploy(Escrow, sellerAddress,
  timeToExpiry, {     value:
  web3.utils.toWei("1", "ether"), // 1 ETH deposit     from:
  accounts[0], // Example buyer address   }); }; 3.              
  Deploy the Contract: o       
  Save this script as 2_deploy_contracts.js in the
  migrations folder. o       
  Run the migration using the following command: truffle migrate --reset o       
  This will deploy the Escrow contract on your local
  blockchain (Ganache). Part 3:
  Interacting with the Escrow Contract Step 1: Start the
  Truffle Console ·                 
  In your project directory, type: truffle console ·                 
  This command opens the Truffle console connected
  to your local blockchain. Step 2:
  Interact with the Contract 1.              
  Get the Deployed Contract Instance: o       
  In the Truffle console, type: const escrowInstance = await Escrow.deployed(); 2.              
  Check the Contract's Initial State: o       
  You can check the initial values of the contract's
  public variables: const buyer = await escrowInstance.buyer(); const seller = await escrowInstance.seller(); const deposit = await escrowInstance.deposit(); const timeToExpiry = await
  escrowInstance.timeToExpiry(); const startTime = await
  escrowInstance.startTime(); console.log("Buyer:", buyer); console.log("Seller:", seller); console.log("Deposit (in wei):",
  deposit.toString()); console.log("Time to Expiry
  (seconds):", timeToExpiry.toString()); console.log("Start Time (timestamp):",
  startTime.toString()); 3.              
  Interact with the Contract's Functions: o       
  Release Funds to Seller: await escrowInstance.releaseToSeller({ from:
  buyer }); §    
  This releases the deposited funds to the seller. o       
  Withdraw Funds (if expired): await escrowInstance.withdraw({ from: buyer }); §    
  This withdraws the funds if the contract has
  expired. o       
  Cancel Escrow: await escrowInstance.cancel({ from: seller }); §    
  This cancels the escrow and returns the deposit to
  the buyer. 4.              
  Check if the Contract is Expired: const expired = await
  escrowInstance.isExpired(); console.log("Is the escrow expired?",
  expired); Step 3:
  Monitoring Transactions in Ganache ·                 
  While interacting with the contract, you can
  monitor the transactions in the Ganache UI. This will show details like
  transaction hashes, gas used, and affected accounts. Step 4:
  Testing with Different Accounts ·                 
  If you want to simulate different roles (buyer and
  seller), you can use different accounts provided by Ganache: const accounts = await web3.eth.getAccounts(); // As the buyer (account[0]) await escrowInstance.releaseToSeller({ from:
  accounts[0] }); // As the seller (account[1]) await escrowInstance.cancel({ from: accounts[1]
  }); Summary ·                 
  Step 1: Set up your development environment
  with Node.js, Truffle, and Ganache. ·                 
  Step 2: Create and deploy the Escrow smart
  contract. Step 3: Interact with
  the contract using the Truffle console and monitor transactions in Ganache. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Final Exam – 100 Multiple Choice
  Questions Final
  Exam Answer Key (100 multiple-choice questions, 9/28/2024) ~Study Guide~ 1. Blockchain
  Fundamentals
 2. Cryptocurrency
  Basics
 3. Smart
  Contracts
 4. Ethereum
  Specifics
 5. Advanced
  Concepts
 Refer to Simplilearn Video from 1:02:00 – 1:11:26 (Soft fork,  hard fork, 51% Attack,
  Byzantine Fault Tolerence) 
 6. Ethereum
  Tokens
 7. Wallets
  and Keys
 8. Consensus
  Mechanisms
 9. Initial
  Coin Offerings (ICO)
 10. Other
  Important Blockchain Concepts
 Key
  Terms to Know:
 ·       
  Smart Contract | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 
 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||