how to run the project step by step
I'll provide you with a complete step-by-step guide to run the blockchain voting project.
1.1 Install Node.js
# Download and install Node.js (v16 or higher) from nodejs.org
# Verify installation
node --version
npm --version1.2 Install MetaMask
1.3 Install Truffle and Ganache
# Install Truffle globally
npm install -g truffle
# Install Ganache CLI globally
npm install -g ganache-cli
# Verify installations
truffle version
ganache-cli --version# Create project directory
mkdir blockchain-voting
cd blockchain-voting
# Initialize npm project
npm init -y# Install main dependencies
npm install next@14 react@18 react-dom@18 web3@4 typescript@5
npm install @types/node@20 @types/react@18 @types/react-dom@18
# Install Truffle dependencies
npm install truffle@5.11.5 @truffle/hdwallet-provider@2.1.15
# Install UI dependencies (if using the provided components)
npm install @radix-ui/react-progress @radix-ui/react-tabs @radix-ui/react-alert-dialog
npm install @radix-ui/react-avatar @radix-ui/react-badge @radix-ui/react-card
npm install lucide-react class-variance-authority clsx tailwind-merge
npm install tailwindcss@latest postcss@latest autoprefixer@latestCreate the following directory structure:
blockchain-voting/
āāā contracts/
āāā migrations/
āāā app/
āāā lib/
āāā components/
āāā hooks/
āāā build/ (will be created after compilation)Copy all the code files I provided earlier into their respective directories:
contracts/Voting.solcontracts/Migrations.solmigrations/1_initial_migration.jsmigrations/2_deploy_voting.jstruffle-config.jslib/web3.tslib/voting-contract.tsapp/page.tsxpackage.json# Initialize Tailwind
npx tailwindcss init -p
# Create tailwind.config.js/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./pages/**/*.{js,ts,jsx,tsx,mdx}", "./components/**/*.{js,ts,jsx,tsx,mdx}", "./app/**/*.{js,ts,jsx,tsx,mdx}", "*.{js,ts,jsx,tsx,mdx}"],
theme: {
extend: {},
},
plugins: [],
}Create app/globals.css:
@tailwind base;
@tailwind components;
@tailwind utilities;/** @type {import('next').NextConfig} */
const nextConfig = {
webpack: (config) => {
config.resolve.fallback = {
...config.resolve.fallback,
fs: false,
net: false,
tls: false,
}
return config
},
}
module.exports = nextConfigOption A: Ganache CLI (Recommended for this tutorial)
# Start Ganache with deterministic accounts
ganache-cli -p 7545 -d -m "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about"Option B: Ganache GUI
HTTP://127.0.0.1:75455777# Compile the contracts
truffle compileYou should see output like:
Compiling your contracts...
===========================
> Compiling ./contracts/Migrations.sol
> Compiling ./contracts/Voting.sol
> Artifacts written to ./build/contracts
> Compiled successfully using:
- solc: 0.8.19# Deploy to Ganache
truffle migrate --resetImportant: Note the contract address from the deployment output:
2_deploy_voting.js
==================
Deploying 'Voting'
-------------------
> transaction hash: 0x...
> contract address: 0x5FbDB2315678afecb367f032d93F642f64180aa3 # <-- Copy this address
> block number: 2
> account: 0x...
> gas used: 1234567Open lib/voting-contract.ts and update the CONTRACT_ADDRESS:
// Update this line with your deployed contract address
const CONTRACT_ADDRESS = "0x5FbDB2315678afecb367f032d93F642f64180aa3" // Your actual address here12.1 Add Ganache Network to MetaMask
Fill in:
12.2 Import Ganache Account
Since the project uses shadcn/ui components, create the basic component files:
# Create components directory
mkdir -p components/ui
mkdir -p hooksCreate basic component files (simplified versions):
import React from 'react'
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'default' | 'outline' | 'secondary' | 'destructive'
size?: 'default' | 'sm' | 'lg'
}
export const Button: React.FC<ButtonProps> = ({
children,
className = '',
variant = 'default',
size = 'default',
...props
}) => {
const baseClasses = 'inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50'
const variants = {
default: 'bg-blue-600 text-white hover:bg-blue-700',
outline: 'border border-gray-300 bg-white hover:bg-gray-50',
secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200',
destructive: 'bg-red-600 text-white hover:bg-red-700'
}
const sizes = {
default: 'h-10 px-4 py-2',
sm: 'h-9 px-3',
lg: 'h-11 px-8'
}
return (
<button
className={`${baseClasses} ${variants[variant]} ${sizes[size]} ${className}`}
{...props}
>
{children}
</button>
)
}import React from 'react'
export const Card: React.FC<{ children: React.ReactNode; className?: string }> = ({
children,
className = ''
}) => (
<div className={`rounded-lg border bg-white shadow-sm ${className}`}>
{children}
</div>
)
export const CardHeader: React.FC<{ children: React.ReactNode; className?: string }> = ({
children,
className = ''
}) => (
<div className={`flex flex-col space-y-1.5 p-6 ${className}`}>
{children}
</div>
)
export const CardTitle: React.FC<{ children: React.ReactNode; className?: string }> = ({
children,
className = ''
}) => (
<h3 className={`text-2xl font-semibold leading-none tracking-tight ${className}`}>
{children}
</h3>
)
export const CardDescription: React.FC<{ children: React.ReactNode; className?: string }> = ({
children,
className = ''
}) => (
<p className={`text-sm text-gray-600 ${className}`}>
{children}
</p>
)
export const CardContent: React.FC<{ children: React.ReactNode; className?: string }> = ({
children,
className = ''
}) => (
<div className={`p-6 pt-0 ${className}`}>
{children}
</div>
)Create other required components similarly (Badge, Progress, Alert, Avatar, Tabs).
import { useState } from 'react'
interface Toast {
title: string
description: string
variant?: 'default' | 'destructive'
}
export const toast = ({ title, description, variant = 'default' }: Toast) => {
console.log(`${variant.toUpperCase()}: ${title} - ${description}`)
// In a real app, you'd show a toast notification
alert(`${title}: ${description}`)
}
export const useToast = () => {
return { toast }
}# Start the Next.js development server
npm run devThe application should now be running at http://localhost:3000
http://localhost:3000Issue 1: "MetaMask Not Found"
Issue 2: "Failed to connect to voting contract"
voting-contract.tsIssue 3: "Transaction failed"
Issue 4: "Compilation failed"
Issue 5: "Network connection issues"
truffle migrate --reset# Reset and redeploy contracts
truffle migrate --reset
# Run contract tests (if you create test files)
truffle test
# Check contract status
truffle consoleThis should get your blockchain voting system up and running! Let me know if you encounter any specific issues during setup.
componet folder for button card
I'll create all the necessary UI components for the blockchain voting project. Here are the complete component files:
These components provide:
cn() function for conditional class mergingAll components are fully typed with TypeScript and follow modern React patterns with forwardRef for proper ref handling. They're designed to work seamlessly with the blockchain voting application!
import { useState, useEffect } from "react"import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"import { Button } from "@/components/ui/button"import { Badge } from "@/components/ui/badge"import { Progress } from "@/components/ui/progress"import { Alert, AlertDescription } from "@/components/ui/alert"import { Avatar, AvatarFallback } from "@/components/ui/avatar"import { Wallet, Vote, Users, Crown, AlertCircle, CheckCircle, Clock } from "lucide-react"import { toast } from "@/hooks/use-toast"import { VotingContract, type Candidate, type VoterInfo } from "@/lib/voting-contract"import { connectMetaMask, isMetaMaskInstalled, switchToGanache } from "@/lib/web3" error in page.tsx fix errĀ