Deploy & Work with an Escrow Contract
Follow the steps exactly. Use Ganache as your local blockchain and Truffle for compile/deploy. Keep screenshots of the key actions and outputs.
Reference material
      GitHub: Chapter 1 (Escrow)
    Part 1: Setting Up the Development Environment
Step 1: Install Node.js
- Go to the Node.js website and download the LTS version for your OS.
- Install following the instructions for your platform.
- Verify installation:
        node -v npm -v
Step 2: Install Truffle
- Install globally:
        npm install -g truffle
- Verify:
        truffle version
Step 3: Install Ganache
- Download & install from the Ganache website.
- Start Ganache → Quickstart Ethereum to launch a local blockchain.
Step 4: Set Up a New Truffle Project
- Create a project directory and init:
        mkdir Escrow cd Escrow truffle init
- Configure Truffle to connect to Ganache. Edit truffle-config.jsto include:
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
- In contracts/, createEscrow.sol.
- Paste 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: Compile
truffle compileWrite a Migration Script & Deploy
Create migrations/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
  });
};
Deploy
truffle migrate --resetExpected: Contract address appears in the migration output. Ganache shows the deployment transaction and 1 ETH deducted from buyer (accounts[0]).
  Part 3: Interacting with the Escrow Contract
Step 1: Start the Truffle Console
truffle consoleStep 2: Get the Deployed Instance & Inspect State
const Escrow = artifacts.require("Escrow");
const escrowInstance = await Escrow.deployed();
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());
Step 3: Call Functions
Use the correct roles. Buyer = accounts[0], Seller = accounts[1] as per migration.
const accounts = await web3.eth.getAccounts();
// Release funds to seller (only before expiry)
await escrowInstance.releaseToSeller({ from: buyer });
// If expired, buyer can withdraw
await escrowInstance.withdraw({ from: buyer });
// Seller can cancel (returns funds to buyer)
await escrowInstance.cancel({ from: seller });
// Check expiry status
const expired = await escrowInstance.isExpired();
console.log("Is the escrow expired?", expired);
Tip: If you need to test expiry quickly, wait a few seconds or redeploy with a smaller 
  timeToExpiry (e.g., 10). Advanced (optional): use Ganache's time travel (evm_increaseTime, evm_mine).Monitoring in Ganache
As you interact, watch Ganache: transactions, gas, and balances change. You should see the deployment, and then function calls that move the 1 ETH deposit depending on the path taken.
Submission Checklist
- Screenshot: successful truffle compile.
- Screenshot: truffle migrate --resetwith deployed contract address.
- Screenshot(s): Truffle console showing initial state (buyer, seller, deposit).
- Screenshot(s): one function path executed (either releaseToSeller,withdrawafter expiry, orcancel).
- Screenshot: Ganache UI showing transactions.
Name your file: 
  HW4_FirstnameLastname.pdf with screenshots in order.