A local development dApp for tokenized real estate built with:
- React (Create React App)
- Hardhat (Solidity dev framework)
- Ethers.js for contract interactions
- Tailwind CSS for styling
This repository includes sample NFT-based real estate contracts (RealEstate and Escrow), a React frontend to browse and buy properties, and scripts to deploy to a local Hardhat network.
- Demo
- Requirements
- Quick start (local)
- Hardhat: run node & deploy contracts
- Frontend: start React app
- Testing
- Metadata format
- Contracts overview
- How the purchase flow works
- Common issues & troubleshooting
- Extending the project
- Dev notes
- Node.js v16+ (LTS recommended)
- npm or yarn
- MetaMask browser extension for testing (connect to
Localhost 8545)
- Install dependencies:
cd zillow
npm install- Start a local Hardhat node in one terminal:
npx hardhat nodeKeep that terminal running.
- Deploy contracts to the local network in a second terminal:
npx hardhat run scripts/deploy.js --network localhostThis script will deploy RealEstate and Escrow, mint sample NFTs, and list them.
- Start the React frontend in a third terminal:
npm startOpen http://localhost:3000 and connect MetaMask to Localhost 8545 (Chain ID: 31337). Import the Hardhat accounts if needed using the private keys printed by npx hardhat node.
- Run the node:
npx hardhat node- Deploy:
npx hardhat run scripts/deploy.js --network localhostThe deploy script will:
- Deploy
RealEstatecontract - Mint 3 sample properties (NFTs)
- Deploy
Escrowcontract with seller, lender, and inspector addresses - Approve and list the properties
The deployed addresses are written in the terminal output. Ensure these addresses match src/config.json when using the frontend.
- Start the dev server:
npm start- Connect MetaMask to
http://127.0.0.1:8545(Chain ID: 31337). Import account private keys from Hardhat node output to interact as buyer/seller/inspector/lender during testing.
Run the Hardhat tests:
npx hardhat testThis runs test/Escrow.js which checks: deployment, listing, deposits, inspection, approvals, and finalize sale flows.
Place property metadata in public/metadata/<id>.json and include these fields:
{
"name": "Property name",
"address": "123 Main St, City, State",
"description": "Description text",
"image": "https://.../image.png",
"id": "1",
"attributes": [
{ "trait_type": "Purchase Price", "value": 20 },
{ "trait_type": "Type of Residence", "value": "Condo" },
{ "trait_type": "Bed Rooms", "value": 2 },
{ "trait_type": "Bathrooms", "value": 3 },
{ "trait_type": "Square Feet", "value": 2200 }
]
}Purchase Price used by the frontend is interpreted as ETH (not wei) in the current implementation.
RealEstate.sol: ERC-721 contract for minting property NFTs.Escrow.sol: Handles listing, deposits, inspection, approvals, and finalization.
Key functions:
list(...)- Seller lists a property (escrow contract becomes owner until sale)depositEarnest(uint256 _nftId)- Buyer deposits earnest moneyupdateInspectionStatus(uint256 _nftId, bool _passed)- Inspector updates inspectionapproveSale(uint256 _nftId)- Parties approve the salefinalizeSale(uint256 _nftId)- Completes the sale when conditions are met
- Buyer clicks
Buy→depositEarnestwithescrowAmount - Inspector calls
updateInspectionStatus(approve) - Buyer, Seller, and Lender call
approveSale - Lender sends the remaining funds to the escrow contract
- Buyer calls
finalizeSale→ funds sent to seller and NFT transferred to buyer
The frontend includes buttons for each role; in local testing you can import multiple Hardhat accounts into MetaMask and manually switch between them to simulate each role.
- "Please switch MetaMask to Hardhat Local Network": Ensure MetaMask network is
Localhost 8545with Chain ID 31337. Escrow contract is nullin frontend: Contracts not deployed orsrc/config.jsonaddresses don't match deployed contracts.Received invalid block tag: Hardhat node not running or outdated blocks; restartnpx hardhat nodeand re-deploy.Only buyer can call this method: Make sure you are using the buyer account (import account #0 from Hardhat node output).Transaction reverted: Check contract conditions; ensure inspector and approvals steps completed before finalizing.
- Add pagination and filtering to the property grid
- Implement favorites/bookmarks (localStorage)
- Add server-side metadata storage or IPFS integration
- Add map view with pins (Mapbox/Leaflet)
- Add offer/counter-offer workflow
- Integrate user accounts and authentication
- React code uses Tailwind CSS classes for styling.
- Smart contracts use Solidity 0.8.x.
src/config.jsonmaps deployed contract addresses per chain ID (check this after deployment).
If you'd like, I can:
- Remove all code comments across files automatically
- Add more metadata files and update the deploy script to mint more properties
- Add pagination, filters, or favorites
Tell me which of these you want next and I'll implement it.