An Escrow Smart Contract
Follow these steps to set up your environment, deploy an Escrow contract, and interact with it from the Truffle console.
Reference material
      GitHub: Chapter 1 (Escrow)
    Part 1: Setting Up the Development Environment
Step 1: Install Node.js
- Download and Install Node.js
        - Go to the Node.js website.
- Download the LTS version for your OS (Windows, macOS, Linux).
- Follow the installer instructions.
 
- Verify the Installation
        node -v npm -vYou should see version numbers for both. 
Step 2: Install Truffle
- Install globally:
        npm install -g truffle
- Verify:
        truffle version
Step 3: Install Ganache
- Download and install from the Ganache website.
- Start Ganache → Quickstart Ethereum to launch a local blockchain.
Step 4: Set Up a New Truffle Project
- Create the project directory:
        mkdir Escrow cd Escrow
- Initialize Truffle:
        truffle init
- Configure truffle-config.jsto connect to Ganache: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", // 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 compileStep 2: Write a Migration Script
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 the Contract
truffle migrate --resetThis deploys the Escrow contract to your local Ganache network.
  Part 3: Interacting with the Escrow Contract
Step 1: Start the Truffle Console
truffle consoleStep 2: Interact with the Contract
- Get the deployed instance:
const escrowInstance = await Escrow.deployed();- Check initial state:
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());
- Call functions:
// Release Funds to Seller
await escrowInstance.releaseToSeller({ from: buyer });
// Withdraw Funds (if expired)
await escrowInstance.withdraw({ from: buyer });
// Cancel Escrow (seller returns funds)
await escrowInstance.cancel({ from: seller });
// Check expiry
const expired = await escrowInstance.isExpired();
console.log("Is the escrow expired?", expired);
Step 4: Testing with Different Accounts
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] });
Monitoring Transactions in Ganache
While interacting with the contract, watch the Ganache UI for transaction hashes, gas used, and which accounts were affected.
Summary
- Step 1: Set up Node.js, Truffle, and Ganache.
- Step 2: Create and deploy the Escrow smart contract.
- Step 3: Interact with the contract via the Truffle console and monitor in Ganache.