# Project export: Sherblock

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: TreeHacks 2024
- Tagline: Revolutionizing information gathering with a secure, decentralized blockchain platform to help solve missing person cases
- Devpost: https://devpost.com/software/sherblock
- GitHub: https://github.com/msamanthaf/TreeHacks
- Demo: https://docs.google.com/presentation/d/1gKu12NUzjHXEdC6wm6Q1N005aDY00U_No3yCVnIKGME/edit?usp=sharing
- Video: https://www.youtube.com/embed/KgjtjJzRRkA?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 1 GitHub contributor(s) — Sam (62 commits)

## Devpost submission (written by the team)

### Inspiration

We all have that one FBI friend that could search for any info online, what if you can save a life AND get rewarded for your searches? Millions of people disappear every year, according to the International Commission on Missing People. By harnessing the power of open-source intelligence, Sherblock offers a promising avenue for gathering crucial clues and information that could aid in the search for missing person cases.

### What it does

Sherblock is a blockchain-powered web3 app for crowdsourcing information gathering (OSINT) to help solve missing person cases, backed with zero-knowledge proof. To enhance the integrity of information shared through Sherblock, a measure has been implemented wherein the general public is restricted to viewing only the name, age, and associated tag without access to the evidence link. This approach ensures that only permitted authorities can verify the reports. Relatives of the victims retain the option to offer support at their own discretion within this framework. To enhance the integrity of information shared through Sherblock, a measure has been implemented wherein the general public is restricted to viewing only the name, age, and associated tag without access to the evidence link. This approach ensures that only permitted authorities can verify the reports. Relatives of the victims retain the option to offer support at their own discretion within this framework. My decision to limit data collection solely to government official postings and to report only publicly available resources online through public links ensures that Sherblock upholds ethical standards regarding data privacy and consent, without granting special treatment to any groups. Blockchain technology allows for tracking all activities with the address of the reporter, and any unacceptable behaviors will not be tolerated and could be addressed legally. My decision to limit data collection solely to government official postings and to report only publicly available resources online through public links ensures that Sherblock upholds ethical standards regarding data privacy and consent, without granting special treatment to any groups. Blockchain technology allows for tracking all activities with the address of the reporter, and any unacceptable behaviors will not be tolerated and could be addressed legally. Implementation of advanced privacy measures, such as zero-knowledge proof, to enhance evidence privacy within Sherblock. Zero-knowledge proof allows for verifying and checking evidence links to avoid duplication without exposing its values, thereby maintaining the confidentiality of individuals involved in those cases. Implementation of advanced privacy measures, such as zero-knowledge proof, to enhance evidence privacy within Sherblock. Zero-knowledge proof allows for verifying and checking evidence links to avoid duplication without exposing its values, thereby maintaining the confidentiality of individuals involved in those cases. How I built it Next js framework with JavaScript for the web stack, Hardhat with Solidity for the smart contract and ZK node libraries for zero-knowledge proof Challenges I ran into Since this was my first time making a blockchain project, there was a steep learning curve. Especially implementing ZKP is soo hard T-T Accomplishments that I'm proud of Finishing this project as this is my first time building with blockchain technology and zero-knowledge proofs.

## README (from the GitHub repository)

# Sherblock - [TreeHacks 2024]

Blockchain-powered web3 app for crowdsourcing information gathering (OSINT) to help solve missing person cases.

Millions of people disappear every year, according to the International Commission on Missing People. By harnessing the power of open-source intelligence, Sherblock offers a promising avenue for gathering crucial clues and information that could aid in the search for missing person cases.

- To enhance the integrity of information shared through Sherblock, a measure has been implemented wherein the general public is restricted to viewing only the name, age, and associated tag without access to the evidence link. This approach ensures that only permitted authorities can verify the reports. Relatives of the victims retain the option to offer support at their own discretion within this framework.

-   My decision to limit data collection solely to government official postings and to report only publicly available resources online through public links ensures that Sherblock upholds ethical standards regarding data privacy and consent, without granting special treatment to any groups. Blockchain technology allows for tracking all activities with the address of the reporter, and any unacceptable behaviors will not be tolerated and could be addressed legally.

-   Implementation of advanced privacy measures, such as zero-knowledge proof, to enhance evidence privacy within Sherblock. Zero-knowledge proof allows for verifying and checking evidence links to avoid duplication without exposing its values, thereby maintaining the confidentiality of individuals involved in those cases.

### Setup:

-   cd web3
-   npm install

Caldera chain (ETH):

-   Connect wallet and receive Caldera ETH through faucet: https://treehacks-devnet.hub.caldera.xyz/
-   Create .env file with your personal key in a constant named PRIVATE_KEY, chain id in CHAIN_ID, and your rpc url in RPC_URL
-   Open the Incentive.js inside Context folder, and put in your chain network url into the constant RPC_URL
-   npx hardhat run --caldera scripts/deploy.js
-   Artifacts folder -> Contracts -> Drag Incentive.json and Verifier.json to Context folder
-   Copy the 'deployed to' address and paste to constants file in either country
-   npm run dev

Avalanche Fuji chain (AVAX):

-   Connect wallet and receive Avalanche ETH through faucet: https://faucets.chain.link/fuji
-   Create .env file with your personal key in a constant named PRIVATE_KEY, chain id in CHAIN_ID, and your rpc url in RPC_URL
-   Open the Incentive.js inside Context folder, and put in your chain network url into the constant RPC_URL
-   npx hardhat run scripts/deploy.js --network fuji
-   Artifacts folder -> Contracts -> Drag Incentive.json and Verifier.json to Context folder
-   Copy the 'deployed to' address and paste to constants file in either country
-   npm run dev

DONE!!


## Detected evidence (automated analysis)

Indexed codebase: 21 recognized source files, 46 KB.
- CSS (language) — detected in the code
- JavaScript (language) — detected in the code
- Next.js (technology) — detected in the code
- React (technology) — detected in the code
- Solidity (language) — detected in the code
- Tailwind CSS (technology) — detected in the code

## Codebase structure (from repository index)

### Files (26 of 26)

```
README.md
web3/.gitignore
web3/Components/Card.jsx
web3/Components/Form.jsx
web3/Components/index.js
web3/Components/Main.jsx
web3/Components/Payment.jsx
web3/Components/SignIn.jsx
web3/Context/constants.js
web3/Context/Incentive.dbg.json
web3/Context/Incentive.js
web3/Context/Incentive.json
web3/Context/Verifier.json
web3/contracts/Incentive.sol
web3/contracts/Verifier.sol
web3/hardhat.config.js
web3/next.config.js
web3/package.json
web3/pages/_app.js
web3/pages/dashboard.js
web3/pages/index.js
web3/postcss.config.js
web3/scripts/deploy.js
web3/styles/globals.css
web3/tailwind.config.js
web3/test/IncentiveTest.js
```

### Dependencies

- web3/package.json: @emotion/react@^11.11.3, @headlessui/react@^1.7.13, @heroicons/react@^2.0.16, @mui/icons-material@^5.15.10, @next/font@13.2.4, @nomicfoundation/hardhat-toolbox@^2.0.2, @zk-kit/incremental-merkle-tree.sol@^1.7.0, autoprefixer@^10.4.14, axios@^1.3.4, country-flag-icons@^1.5.9, dotenv@^16.4.4, ethers@^5.7.2, hardhat@^2.13.0, next@13.2.4, node-localstorage@^3.0.5, postcss@^8.4.21, react@18.2.0, react-dom@18.2.0, tailwindcss@^3.2.7, web3modal@^1.9.12

### Recent commits (newest first)

- Merge pull request #17 from msamanthaf/zkp
- Integrated zk merkle tree
- Merge pull request #16 from msamanthaf/authority-dashboard
- Fixed ui of authrity dashboard
- Merge pull request #15 from msamanthaf/Hide-evidence
- Hide evidence from public view
- Update README.md
- Update README.md
- Update README.md
- udate readme
- Merge pull request #14 from msamanthaf/avalanche2
- Fixed getreports bug
- Merge pull request #13 from msamanthaf/Avalanche
- Added fuji testnet
- Added avalanche fuji
- Added basic avalanche info
- Merge pull request #12 from msamanthaf/UI
- FINALLY ZKP VERIFICATION WORKED
- ensure no evidence duplicates using zkp
- Centered text

## Key source files (fetched from GitHub, selected and truncated for size)

### web3/package.json

```
{
	"name": "incentive",
	"version": "0.1.0",
	"private": true,
	"scripts": {
		"dev": "next dev",
		"build": "next build",
		"start": "next start",
		"lint": "next lint"
	},
	"dependencies": {
		"@emotion/react": "^11.11.3",
		"@headlessui/react": "^1.7.13",
		"@heroicons/react": "^2.0.16",
		"@mui/icons-material": "^5.15.10",
		"@next/font": "13.2.4",
		"@zk-kit/incremental-merkle-tree.sol": "^1.7.0",
		"axios": "^1.3.4",
		"country-flag-icons": "^1.5.9",
		"dotenv": "^16.4.4",
		"ethers": "^5.7.2",
		"hardhat": "^2.13.0",
		"next": "13.2.4",
		"node-localstorage": "^3.0.5",
		"react": "18.2.0",
		"react-dom": "18.2.0",
		"web3modal": "^1.9.12"
	},
	"devDependencies": {
		"@nomicfoundation/hardhat-toolbox": "^2.0.2",
		"autoprefixer": "^10.4.14",
		"postcss": "^8.4.21",
		"tailwindcss": "^3.2.7"
	}
}

```

### web3/Components/index.js

```javascript
import SignIn from "./SignIn";
import Main from "./Main";
import Card from "./Card";
import Form from "./Form";
import Payment from "./Payment";

export { SignIn, Main, Card, Form, Payment };

```

### web3/pages/index.js

```javascript
import React from "react";
import { SignIn } from "../Components";
import { IncentiveProvider } from "../Context/Incentive";

function Index() {
	return (
		<>
			<IncentiveProvider>
				<SignIn />
			</IncentiveProvider>
		</>
	);
}

export default Index;

```

### web3/Components/Main.jsx

```javascript
"use client";
import React, { useContext, useEffect, useState } from "react";
import { IncentiveContext } from "../Context/Incentive";
import { Card, Payment } from "../Components";
import { getSelectedCountry } from "../Context/constants";
import dynamic from 'next/dynamic'
import metamask from '../public/metamask.png'
import Image from 'next/image';

 
const Form = dynamic(() => import('../Components/Form'), { ssr: false })

function Main() {
    const { titleData, getReports, createReport, pay, getUserReports, getPays, rejectReport } = useContext(IncentiveContext);
	
    const [allreport, setAllreport] = useState([]);
    const [userreport, setUserreport] = useState([]);
    const [openModel, setOpenModel] = useState(false);
    const [payReport, setPayReport] = useState(null);
	const { currentAccount, connectWallet } = useContext(IncentiveContext);
	const authority = currentAccount == "0x1aD46072B82B0210c4c55519260CAfBFE7A16448".toLowerCase();

    useEffect(() => {
        const fetchData = async () => {
            try {
                const allData = await getReports();
                const userData = await getUserReports();
                setAllreport(allData);
                setUserreport(userData);
				console.log(authority);
            } catch (error) {
                console.error("Error fetching data:", error);
            }
        };

        fetchData();

        // Cleanup function
        return () => {
            // Any cleanup code if needed
        };
    }, [getReports, getUserReports]);

    const handleOpenModel = (report) => {
        setPayReport(report);
        setOpenModel(true);
    };

	const deprecateString = (inputString) => {
		if (inputString.length <= 10) {
		  return inputString; // If the string is 10 characters or less, return it as it is
		}
		// Otherwise, deprecate the string by showing only the first and last 5 characters
		const firstFive = inputString.slice(0, 5);
		const lastFive = inputString.slice(-5);
		return `${firstFive}...${lastFive}`;
	  };

    return (
        <>
		 {currentAccount ? (
                <button disabled className='bg-stone-500 gap-5 flex flex-row rounded-s fixed z-50 px-3 h-10 w-96 justify-center items-center text-stone-50' aria-label='Sign Up' title='Sign Up'>
                     <Image src={metamask} alt="Metamask Logo" width={30}/>
					<p >Wallet Connected to: {deprecateString(currentAccount)}</p>
                </button>
            ) : (
                <button onClick={() => connectWallet()} className='bg-stone-500 gap-5 flex justify-center items-center flex-row rounded-s fixed z-50 px-3 text-stone-50' aria-label='Sign Up' title='Sign Up'>
                    <Image src={metamask} alt="Metamask Logo" width={30}/>
					<p >Connect Wallet</p>
                </button>
            )}
            <Form titleData={titleData} createReport={createReport} selectedCountry={getSelectedCountry()} authority={authority}/>
            <Card title="All Reports" reports={allreport} openModel={handleOpenModel} setPay={setPayReport} setOpenModel={setOpenModel} visible={true} authority={authority}/>
            {!authority && <Card title="Your Reports" reports={userreport} openModel={handleOpenModel} setPay={setPayReport} setOpenModel={setOpenModel} visible={false}/>}

            {openModel && (
                <Payment setOpenModel={setOpenModel} pay={payReport} payFunction={pay} reject={rejectReport} authority={authority}/>
            )}
        </>
    );
}

export default Main;

```

### web3/postcss.config.js

```javascript
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}

```

### web3/next.config.js

```javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
	reactStrictMode: true,
};

module.exports = nextConfig;

module.exports = {
	images: {
		formats: ["image/webp"],
	},
};

```

### web3/tailwind.config.js

```javascript
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./app/**/*.{js,ts,jsx,tsx}",
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",

    // Or if using `src` directory:
    "./src/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};

```

### web3/hardhat.config.js

```javascript
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();

const ChainId = process.env.CHAIN_ID;
const RpcUrl = process.env.RPC_URL;
const privateKey = process.env.PRIVATE_KEY;

/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
	solidity: "0.8.18",
	networks: {
		caldera: {
			url: RpcUrl,
			chainId: parseInt(ChainId),
			accounts: [privateKey],
		},
		fuji: {
			url: RpcUrl,
			chainId: parseInt(ChainId),
			accounts: [privateKey],
		},
	},
};

```

### web3/pages/_app.js

```javascript
import "../styles/globals.css";

function _app({ Component, pageProps }) {
	return <Component {...pageProps} />;
}

export default _app;

```

### web3/pages/dashboard.js

```javascript
import React from "react";
import Main from "../Components/Main";
import { IncentiveProvider } from "../Context/Incentive";

function Dashboard() {
	return (
		<>
			<IncentiveProvider>
				<Main />
			</IncentiveProvider>
		</>
	);
}

export default Dashboard;

```

[11 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]