├── .github └── workflows │ ├── azure-webapps-node.yml │ ├── codeql-analysis.yml │ ├── node.js.yml │ └── npm_publish.yml ├── README.md ├── SECURITY.md ├── client ├── .eslintrc.js ├── .firebase │ ├── hosting.YnVpbGQ.cache │ └── hosting.ZGlzdA.cache ├── .firebaserc ├── .gitignore ├── .prettierrc ├── build │ ├── 404.html │ └── index.html ├── firebase.json ├── images │ ├── animated.svg │ ├── hello.svg │ └── logo.png ├── index.html ├── package-lock.json ├── package.json ├── postcss.config.js ├── src │ ├── App.jsx │ ├── components │ │ ├── Footer.jsx │ │ ├── Loader.jsx │ │ ├── Navbar.jsx │ │ ├── Services.jsx │ │ ├── Transactions.jsx │ │ ├── Welcome.jsx │ │ └── index.js │ ├── context │ │ └── TransactionContext.jsx │ ├── favicon.png │ ├── hooks │ │ └── useFetch.jsx │ ├── index.css │ ├── logo.svg │ ├── main.jsx │ └── utils │ │ ├── Transactions.json │ │ ├── constants.js │ │ ├── dummyData.js │ │ └── shortenAddress.js ├── tailwind.config.js ├── vite.config.js └── yarn.lock └── smart_contract ├── .gitignore ├── contracts └── Transactions.sol ├── hardhat.config.js ├── package-lock.json ├── package.json ├── scripts └── deploy.js └── test └── sample-test.js /.github/workflows/azure-webapps-node.yml: -------------------------------------------------------------------------------- 1 | name: CI + CD 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | Staging: 8 | runs-on: ubuntu-latest 9 | environment: Staging 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: Run a script 13 | run: echo "Running in Staging" 14 | 15 | Quality_Assurance: 16 | runs-on: ubuntu-latest 17 | environment: Quality_Assurance 18 | needs: Staging 19 | steps: 20 | - uses: actions/checkout@v2 21 | - name: Run a script 22 | run: echo "Running in QA" 23 | 24 | Production: 25 | runs-on: ubuntu-latest 26 | environment: Development 27 | needs: Quality_Assurance 28 | steps: 29 | - uses: actions/checkout@v2 30 | - name: Run a script 31 | run: echo "Running in production" 32 | 33 | Development: 34 | runs-on: ubuntu-latest 35 | environment: Production 36 | needs: Production 37 | steps: 38 | - uses: actions/checkout@v2 39 | - name: Run a script 40 | run: echo "Deployed" 41 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '45 0 * * 6' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'javascript' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v2 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v1 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 52 | 53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 54 | # If this step fails, then you should remove it and run the build manually (see below) 55 | - name: Autobuild 56 | uses: github/codeql-action/autobuild@v1 57 | 58 | # ℹ️ Command-line programs to run using the OS shell. 59 | # 📚 https://git.io/JvXDl 60 | 61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 62 | # and modify them (or add more) to build your code if your project 63 | # uses a compiled language 64 | 65 | #- run: | 66 | # make bootstrap 67 | # make release 68 | 69 | - name: Perform CodeQL Analysis 70 | uses: github/codeql-action/analyze@v1 71 | -------------------------------------------------------------------------------- /.github/workflows/node.js.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [12.x, 14.x, 16.x] 20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ 21 | 22 | steps: 23 | - uses: actions/checkout@v2 24 | - name: Use Node.js ${{ matrix.node-version }} 25 | uses: actions/setup-node@v2 26 | with: 27 | node-version: ${{ matrix.node-version }} 28 | cache: 'npm' 29 | - run: npm ci 30 | - run: npm run build --if-present 31 | - run: npm test 32 | -------------------------------------------------------------------------------- /.github/workflows/npm_publish.yml: -------------------------------------------------------------------------------- 1 | name: Node.js Package 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | publish-gpr: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v2 13 | - uses: actions/setup-node@v1 14 | with: 15 | node-version: 12 16 | registry-url: https://npm.pkg.github.com/ 17 | scope: '@AlanBinu007' 18 | - run: npm install 19 | - run: npm publish 20 | env: 21 | NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}} 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Block Chain Web 3.0 3 | 4 | **Here we are created fully working Block-Chain Application with ReactJs and Solidity. And we implemented the Alchemy for virtualization purposes. Finally we used ropsten for local testing and deployed on ropsten using hardhat** 5 | 6 | **Project Link** - ***https://alanbinu-crypto.web.app/*** 7 | 8 | ## Tech We Used 9 | 10 | - ReactJs 11 | - Firebase Hosting 12 | - Firebase Auth 13 | - Solidity 14 | - Alchemy 15 | - Ropsten 16 | - Hardhat 17 | - Ropsten Etherscan 18 | 19 | ## Features 20 | 21 | - Send Etherium 22 | - Can able to view all the transacations 23 | 24 | ## Steps to run in your machine 25 | 26 | You need to install MetaMask in your browser : https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en and creeate one account. 27 | 28 | Create on account in Alchemy (for virtualization purposes) : https://dashboard.alchemyapi.io/ and create one app 29 | 30 | 31 | #### Run the following commands 32 | ``` 33 | clone this repo 34 | ``` 35 | Go to both folders and run thew following command 36 | 37 | ``` 38 | npm install 39 | ``` 40 | Go to Alchemy and copy thr HTTP ID of the app that we created --> and paste it in smart_contract/hardhat.config.js 41 | ``` 42 | url : "" 43 | ``` 44 | 45 | Then go to MetaMask and copy the Eth account PRIVATE ID under Account Details and paste it in smart_contract/hardhat.config.js 46 | ``` 47 | accounts :["PRIVATE KEY"] 48 | ``` 49 | 50 | Then run the following command in smart_contract root folder 51 | 52 | ``` 53 | npx hardhat run scripts/deploy.js --network ropsten 54 | ``` 55 | 56 | The you can see that some compiled files are generated and also one DEPLOYED ADDRESS copy that address --> go to client/src/utils/constants.js 57 | ``` 58 | export const contractAddress = "" 59 | ``` 60 | 61 | Then go to smart_contract/artifact/contracts/Transactions/ and copy the Transacation.json (which contains all our contract details in json form) ---> and paste it into client/src/utils/ 62 | 63 | ## NOTE:
64 | 65 | Inoder to run this application it required some gas (some kind of fee), so your must need some Eth

66 | For testing purposes, here comes ROPSTEN. It provide free Eth for testing purposes.
67 | To claim free test Eth go to your MetaMask -> Network Settings -> Turn ON test network and connect to "Ropsten test network".

68 | Then copy your account address and go to : https://faucet.egorfine.com/ and paste your address and claim free test Eth of 0.300 Eth.
69 | 70 | ### Feel Free to contact me any time, always happy to help 💖 71 | 72 | #### Hope you liked this project, don't forget to ⭐ the repo. 73 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Supported | 9 | | ------- | ------------------ | 10 | | 5.1.x | :white_check_mark: | 11 | | 5.0.x | :x: | 12 | | 4.0.x | :white_check_mark: | 13 | | < 4.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a 20 | reported vulnerability, what to expect if the vulnerability is accepted or 21 | declined, etc. 22 | -------------------------------------------------------------------------------- /client/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | }, 6 | extends: ["plugin:react/recommended", "airbnb"], 7 | parserOptions: { 8 | ecmaFeatures: { 9 | jsx: true, 10 | }, 11 | ecmaVersion: 13, 12 | sourceType: "module", 13 | }, 14 | plugins: ["react"], 15 | rules: { 16 | "react/function-component-definition": 0, 17 | "react/react-in-jsx-scope": 0, 18 | "react/jsx-props-no-spreading": 0, 19 | "import/extensions": 0, 20 | "react/prop-types": 0, 21 | "linebreak-style": 0, 22 | "react/state-in-constructor": 0, 23 | "import/prefer-default-export": 0, 24 | "max-len": [2, 250], 25 | "operator-linebreak": 0, 26 | "comma-dangle": 0, 27 | "no-console": 0, 28 | "no-alert": 0, 29 | "no-multiple-empty-lines": [ 30 | "error", 31 | { 32 | max: 1, 33 | maxEOF: 1, 34 | }, 35 | ], 36 | "no-underscore-dangle": [ 37 | "error", 38 | { 39 | allow: ["_d", "_dh", "_h", "_id", "_m", "_n", "_t", "_text"], 40 | }, 41 | ], 42 | "object-curly-newline": 0, 43 | "react/jsx-filename-extension": 0, 44 | "react/jsx-one-expression-per-line": 0, 45 | "jsx-a11y/click-events-have-key-events": 0, 46 | "jsx-a11y/alt-text": 0, 47 | "jsx-a11y/no-autofocus": 0, 48 | "jsx-a11y/no-static-element-interactions": 0, 49 | "react/no-array-index-key": 0, 50 | "jsx-a11y/anchor-is-valid": [ 51 | "error", 52 | { 53 | components: ["Link"], 54 | specialLink: ["to", "hrefLeft", "hrefRight"], 55 | aspects: ["noHref", "invalidHref", "preferButton"], 56 | }, 57 | ], 58 | quotes: [2, "double", { avoidEscape: true }], 59 | }, 60 | }; 61 | -------------------------------------------------------------------------------- /client/.firebase/hosting.YnVpbGQ.cache: -------------------------------------------------------------------------------- 1 | 404.html,1644731757338,daa499dd96d8229e73235345702ba32f0793f0c8e5c0d30e40e37a5872be57aa 2 | index.html,1644731757450,bbdaeb13d834651253f786d7fd023a2eae442a2ad0094bfa1404cf2b1fb1ba7f 3 | -------------------------------------------------------------------------------- /client/.firebase/hosting.ZGlzdA.cache: -------------------------------------------------------------------------------- 1 | index.html,1644732303286,f7f713b2ff78ca5d7c2bfc51b5201ae374d5d537cb5d3ad4064ba67e003f8881 2 | assets/logo.60ecbcf0.png,1644732303286,a80f591aac0decd3d2975bd0d4540f6b4d2c71f04ad1a6ec79931ee89caf4fba 3 | assets/index.aec13734.css,1644732303286,2994dbed48f70a0cf9cfd1d2a51694dc29d4dc0e595b13944fb75efc23406a5c 4 | assets/index.970da6b6.js,1644732303286,af1f055f49b0041180ee664e4fbf19da2cefd0a8918687b2d93d5955b3fe9632 5 | assets/favicon.2daa77f1.png,1644732303285,fb57a84e2ac859474e08ff89131994fe5321f3fd1ff9638693610202bf4de343 6 | assets/vendor.60fc6cf4.js,1644732303286,d2d04447aa749eb1a34ad7b145d71ea546c383b6666cf631e977ac7c43dc2947 7 | -------------------------------------------------------------------------------- /client/.firebaserc: -------------------------------------------------------------------------------- 1 | { 2 | "projects": { 3 | "default": "alanbinu-crypto" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local 6 | 7 | # vscode 8 | .vscode 9 | node_modules 10 | .env 11 | coverage 12 | coverage.json 13 | typechain 14 | 15 | #Hardhat files 16 | cache 17 | artifacts 18 | 19 | node_modules 20 | .env 21 | coverage 22 | coverage.json 23 | typechain 24 | 25 | #Hardhat files 26 | cache 27 | artifacts 28 | -------------------------------------------------------------------------------- /client/.prettierrc: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /client/build/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Page Not Found 7 | 8 | 23 | 24 | 25 |
26 |

404

27 |

Page Not Found

28 |

The specified file was not found on this website. Please check the URL for mistakes and try again.

29 |

Why am I seeing this?

30 |

This page was generated by the Firebase Command-Line Interface. To modify it, edit the 404.html file in your project's configured public directory.

31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /client/build/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Welcome to Firebase Hosting 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 40 | 41 | 42 |
43 |

Welcome

44 |

Firebase Hosting Setup Complete

45 |

You're seeing this because you've successfully setup Firebase Hosting. Now it's time to go build something extraordinary!

46 | Open Hosting Documentation 47 |
48 |

Firebase SDK Loading…

49 | 50 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /client/firebase.json: -------------------------------------------------------------------------------- 1 | { 2 | "hosting": { 3 | "public": "dist", 4 | "ignore": [ 5 | "firebase.json", 6 | "**/.*", 7 | "**/node_modules/**" 8 | ], 9 | "rewrites": [ 10 | { 11 | "source": "**", 12 | "destination": "/index.html" 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /client/images/animated.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/images/hello.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlanBinu007/BlockChain-Web-3.0-React-with-Solidity/429f2f850dcacf63a74692b2f1d12baaf3eeeb02/client/images/logo.png -------------------------------------------------------------------------------- /client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Crypto 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "wave-app", 3 | "version": "0.0.0", 4 | "publishConfig":{ 5 | "registry: : "https://npm.pkg.github.com/@AlanBinu007" 6 | }, 7 | "scripts": { 8 | "dev": "vite", 9 | "build": "vite build", 10 | "serve": "vite preview" 11 | }, 12 | "dependencies": { 13 | "@tailwindcss/forms": "^0.3.4", 14 | "autoprefixer": "^10.4.0", 15 | "eth-revert-reason": "^1.0.3", 16 | "ethers": "^5.5.1", 17 | "framer-motion": "^5.3.1", 18 | "postcss": "^8.3.11", 19 | "react": "^17.0.0", 20 | "react-dom": "^17.0.0", 21 | "react-icons": "^4.3.1" 22 | }, 23 | "devDependencies": { 24 | "@vitejs/plugin-react": "^1.0.0", 25 | "eslint": "^8.4.1", 26 | "eslint-config-airbnb": "^19.0.2", 27 | "eslint-plugin-import": "^2.25.3", 28 | "eslint-plugin-jsx-a11y": "^6.5.1", 29 | "eslint-plugin-react": "^7.27.1", 30 | "eslint-plugin-react-hooks": "^4.3.0", 31 | "tailwindcss": "^2.2.19", 32 | "vite": "^2.6.4" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /client/postcss.config.js: -------------------------------------------------------------------------------- 1 | const tailwindcss = require("tailwindcss"); 2 | module.exports = { 3 | plugins: [tailwindcss("./tailwind.config.js"), require("autoprefixer")], 4 | }; 5 | -------------------------------------------------------------------------------- /client/src/App.jsx: -------------------------------------------------------------------------------- 1 | import {Welcome, Footer, Transactions } from "./components"; 2 | 3 | const App = () => ( 4 |
5 |
6 | 7 |
8 | 9 |
10 |
11 | ); 12 | 13 | export default App; 14 | -------------------------------------------------------------------------------- /client/src/components/Footer.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | import logo from "../../images/logo.png"; 4 | 5 | const Footer = () => ( 6 |
7 |
8 |
9 |

10 | https://github.com/AlanBinu007 11 |

12 |

13 | No Copy right issue. free fell to copy 14 |

15 |
16 |
17 | ); 18 | 19 | export default Footer; 20 | -------------------------------------------------------------------------------- /client/src/components/Loader.jsx: -------------------------------------------------------------------------------- 1 | const Loader = () => ( 2 |
3 |
4 |
5 | ); 6 | 7 | export default Loader; 8 | -------------------------------------------------------------------------------- /client/src/components/Navbar.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { HiMenuAlt4 } from "react-icons/hi"; 3 | import { AiOutlineClose } from "react-icons/ai"; 4 | 5 | import logo from "../../images/logo.png"; 6 | 7 | const NavBarItem = ({ title, classprops }) => ( 8 |
  • {title}
  • 9 | ); 10 | 11 | const Navbar = () => { 12 | const [toggleMenu, setToggleMenu] = React.useState(false); 13 | 14 | return ( 15 | 47 | ); 48 | }; 49 | 50 | export default Navbar; 51 | -------------------------------------------------------------------------------- /client/src/components/Services.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { BsShieldFillCheck } from "react-icons/bs"; 3 | import { BiSearchAlt } from "react-icons/bi"; 4 | import { RiHeart2Fill } from "react-icons/ri"; 5 | 6 | const ServiceCard = ({ color, title, icon, subtitle }) => ( 7 |
    8 |
    9 | {icon} 10 |
    11 |
    12 |

    {title}

    13 |

    14 | {subtitle} 15 |

    16 |
    17 |
    18 | ); 19 | 20 | const Services = () => ( 21 |
    22 |
    23 |
    24 |

    25 | Services that we 26 |
    27 | continue to improve 28 |

    29 |

    30 | The best choice for buying and selling your crypto assets, with the 31 | various super friendly services we offer 32 |

    33 |
    34 | 35 |
    36 | } 40 | subtitle="Security is guranteed. We always maintain privacy and maintain the quality of our products" 41 | /> 42 | } 46 | subtitle="Security is guranteed. We always maintain privacy and maintain the quality of our products" 47 | /> 48 | } 52 | subtitle="Security is guranteed. We always maintain privacy and maintain the quality of our products" 53 | /> 54 |
    55 |
    56 |
    57 | ); 58 | 59 | export default Services; 60 | -------------------------------------------------------------------------------- /client/src/components/Transactions.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | 3 | import { TransactionContext } from "../context/TransactionContext"; 4 | 5 | import useFetch from "../hooks/useFetch"; 6 | import dummyData from "../utils/dummyData"; 7 | import { shortenAddress } from "../utils/shortenAddress"; 8 | 9 | const TransactionsCard = ({ 10 | addressTo, 11 | addressFrom, 12 | timestamp, 13 | message, 14 | keyword, 15 | amount, 16 | url, 17 | }) => { 18 | const gifUrl = useFetch({ keyword }); 19 | 20 | return ( 21 |
    30 |
    31 |
    32 | 37 |

    38 | From: {shortenAddress(addressFrom)} 39 |

    40 |
    41 | 46 |

    47 | To: {shortenAddress(addressTo)} 48 |

    49 |
    50 |

    Amount: {amount} ETH

    51 | {message && ( 52 | <> 53 |

    Message: {message}

    54 | 55 | )} 56 |

    Time : {timestamp}

    57 |
    58 |
    59 |
    60 | ); 61 | }; 62 | 63 | const Transactions = () => { 64 | const { transactions, currentAccount } = useContext(TransactionContext); 65 | 66 | return ( 67 |
    68 |
    69 | {currentAccount ? ( 70 |

    71 | Latest Transactions 72 |

    73 | ) : ( 74 |

    75 | Connect your account to see the latest transactions 76 |

    77 | )} 78 | 79 |
    80 | {[...dummyData, ...transactions].reverse().map((transaction, i) => ( 81 | 82 | ))} 83 |
    84 |
    85 |
    86 | ); 87 | }; 88 | 89 | export default Transactions; 90 | -------------------------------------------------------------------------------- /client/src/components/Welcome.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext } from "react"; 2 | import { AiFillPlayCircle } from "react-icons/ai"; 3 | import { SiEthereum } from "react-icons/si"; 4 | import { BsInfoCircle } from "react-icons/bs"; 5 | 6 | import { TransactionContext } from "../context/TransactionContext"; 7 | import { shortenAddress } from "../utils/shortenAddress"; 8 | import { Loader } from "."; 9 | 10 | const companyCommonStyles = 11 | "min-h-[70px] sm:px-0 px-2 sm:min-w-[120px] flex justify-center items-center border-[0.5px] border-gray-400 text-sm font-light text-white"; 12 | 13 | const Input = ({ placeholder, name, type, value, handleChange }) => ( 14 | handleChange(e, name)} 20 | className="my-2 w-full rounded-sm p-2 outline-none bg-transparent text-white border-none text-sm white-glassmorphism" 21 | /> 22 | ); 23 | 24 | const style = { 25 | wrapper: `w-screen flex items-center justify-center mt-14`, 26 | content: `bg-[#191B1F] w-[40rem] rounded-2xl p-4`, 27 | formHeader: `px-2 flex items-center justify-between font-semibold text-xl`, 28 | transferPropContainer: `bg-[#20242A] my-3 rounded-2xl p-6 text-3xl border border-[#20242A] hover:border-[#41444F] flex justify-between`, 29 | transferPropInput: `bg-transparent placeholder:text-[#B2B9D2] outline-none mb-6 w-full text-2xl`, 30 | currencySelector: `flex w-1/4`, 31 | currencySelectorContent: `w-full h-min flex justify-between items-center bg-[#2D2F36] hover:bg-[#41444F] rounded-2xl text-xl font-medium cursor-pointer p-2 mt-[-0.2rem]`, 32 | currencySelectorIcon: `flex items-center`, 33 | currencySelectorTicker: `mx-2`, 34 | currencySelectorArrow: `text-lg`, 35 | confirmButton: `bg-[#2172E5] my-2 rounded-2xl py-6 px-8 text-xl font-semibold flex items-center justify-center cursor-pointer border border-[#2172E5] hover:border-[#234169]`, 36 | }; 37 | 38 | const customStyles = { 39 | content: { 40 | top: "50%", 41 | left: "50%", 42 | right: "auto", 43 | bottom: "auto", 44 | transform: "translate(-50%, -50%)", 45 | backgroundColor: "#0a0b0d", 46 | padding: 0, 47 | border: "none", 48 | }, 49 | overlay: { 50 | backgroundColor: "rgba(10, 11, 13, 0.75)", 51 | }, 52 | }; 53 | 54 | const Welcome = () => { 55 | const { 56 | currentAccount, 57 | connectWallet, 58 | handleChange, 59 | sendTransaction, 60 | formData, 61 | isLoading, 62 | } = useContext(TransactionContext); 63 | 64 | const handleSubmit = (e) => { 65 | const { addressTo, amount, keyword, message } = formData; 66 | 67 | e.preventDefault(); 68 | 69 | if (!addressTo || !amount || !message) return; 70 | 71 | sendTransaction(); 72 | }; 73 | 74 | return ( 75 |
    76 |
    77 |
    78 |

    79 | Send your Crypto across the world 80 |

    81 | {!currentAccount && ( 82 | 92 | )} 93 | {currentAccount && ( 94 |

    95 | Your Connected wallet address : {shortenAddress(currentAccount)} 96 |

    97 | )} 98 |
    99 | 100 |
    101 |
    102 | 108 | 114 | 120 | 121 | 122 | {isLoading ? ( 123 | 124 | ) : ( 125 | 132 | )} 133 |
    134 |
    135 |
    136 |
    137 |
    138 |
    139 | ); 140 | }; 141 | 142 | export default Welcome; 143 | -------------------------------------------------------------------------------- /client/src/components/index.js: -------------------------------------------------------------------------------- 1 | export { default as Loader } from "./Loader"; 2 | export { default as Navbar } from "./Navbar"; 3 | export { default as Welcome } from "./Welcome"; 4 | export { default as Footer } from "./Footer"; 5 | export { default as Services } from "./Services"; 6 | export { default as Transactions } from "./Transactions"; 7 | -------------------------------------------------------------------------------- /client/src/context/TransactionContext.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from "react"; 2 | import { ethers } from "ethers"; 3 | 4 | import { contractABI, contractAddress } from "../utils/constants"; 5 | 6 | export const TransactionContext = React.createContext(); 7 | 8 | const { ethereum } = window; 9 | 10 | const createEthereumContract = () => { 11 | const provider = new ethers.providers.Web3Provider(ethereum); 12 | const signer = provider.getSigner(); 13 | const transactionsContract = new ethers.Contract(contractAddress, contractABI, signer); 14 | 15 | return transactionsContract; 16 | }; 17 | 18 | export const TransactionsProvider = ({ children }) => { 19 | const [formData, setformData] = useState({ addressTo: "", amount: "", keyword: "", message: "" }); 20 | const [currentAccount, setCurrentAccount] = useState(""); 21 | const [isLoading, setIsLoading] = useState(false); 22 | const [transactionCount, setTransactionCount] = useState(localStorage.getItem("transactionCount")); 23 | const [transactions, setTransactions] = useState([]); 24 | 25 | const handleChange = (e, name) => { 26 | setformData((prevState) => ({ ...prevState, [name]: e.target.value })); 27 | }; 28 | 29 | const getAllTransactions = async () => { 30 | try { 31 | if (ethereum) { 32 | const transactionsContract = createEthereumContract(); 33 | 34 | const availableTransactions = await transactionsContract.getAllTransactions(); 35 | 36 | const structuredTransactions = availableTransactions.map((transaction) => ({ 37 | addressTo: transaction.receiver, 38 | addressFrom: transaction.sender, 39 | timestamp: new Date(transaction.timestamp.toNumber() * 1000).toLocaleString(), 40 | message: transaction.message, 41 | keyword: transaction.keyword, 42 | amount: parseInt(transaction.amount._hex) / (10 ** 18) 43 | })); 44 | 45 | console.log(structuredTransactions); 46 | 47 | setTransactions(structuredTransactions); 48 | } else { 49 | console.log("Ethereum is not present"); 50 | } 51 | } catch (error) { 52 | console.log(error); 53 | } 54 | }; 55 | 56 | const checkIfWalletIsConnect = async () => { 57 | try { 58 | if (!ethereum) return alert("Please install MetaMask."); 59 | 60 | const accounts = await ethereum.request({ method: "eth_accounts" }); 61 | 62 | if (accounts.length) { 63 | setCurrentAccount(accounts[0]); 64 | 65 | getAllTransactions(); 66 | } else { 67 | console.log("No accounts found"); 68 | } 69 | } catch (error) { 70 | console.log(error); 71 | } 72 | }; 73 | 74 | const checkIfTransactionsExists = async () => { 75 | try { 76 | if (ethereum) { 77 | const transactionsContract = createEthereumContract(); 78 | const currentTransactionCount = await transactionsContract.getTransactionCount(); 79 | 80 | window.localStorage.setItem("transactionCount", currentTransactionCount); 81 | } 82 | } catch (error) { 83 | console.log(error); 84 | 85 | throw new Error("No ethereum object"); 86 | } 87 | }; 88 | 89 | const connectWallet = async () => { 90 | try { 91 | if (!ethereum) return alert("Please install MetaMask."); 92 | 93 | const accounts = await ethereum.request({ method: "eth_requestAccounts", }); 94 | 95 | setCurrentAccount(accounts[0]); 96 | } catch (error) { 97 | console.log(error); 98 | 99 | throw new Error("No ethereum object"); 100 | } 101 | }; 102 | 103 | const sendTransaction = async () => { 104 | try { 105 | if (ethereum) { 106 | const { addressTo, amount, keyword, message } = formData; 107 | const transactionsContract = createEthereumContract(); 108 | const parsedAmount = ethers.utils.parseEther(amount); 109 | 110 | await ethereum.request({ 111 | method: "eth_sendTransaction", 112 | params: [{ 113 | from: currentAccount, 114 | to: addressTo, 115 | gas: "0x5208", 116 | value: parsedAmount._hex, 117 | }], 118 | }); 119 | 120 | const transactionHash = await transactionsContract.addToBlockchain(addressTo, parsedAmount, message, keyword); 121 | 122 | setIsLoading(true); 123 | console.log(`Loading - ${transactionHash.hash}`); 124 | await transactionHash.wait(); 125 | console.log(`Success - ${transactionHash.hash}`); 126 | setIsLoading(false); 127 | 128 | const transactionsCount = await transactionsContract.getTransactionCount(); 129 | 130 | setTransactionCount(transactionsCount.toNumber()); 131 | } else { 132 | console.log("No ethereum object"); 133 | } 134 | } catch (error) { 135 | console.log(error); 136 | 137 | throw new Error("No ethereum object"); 138 | } 139 | }; 140 | 141 | useEffect(() => { 142 | checkIfWalletIsConnect(); 143 | checkIfTransactionsExists(); 144 | }, [transactionCount]); 145 | 146 | return ( 147 | 159 | {children} 160 | 161 | ); 162 | }; 163 | -------------------------------------------------------------------------------- /client/src/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AlanBinu007/BlockChain-Web-3.0-React-with-Solidity/429f2f850dcacf63a74692b2f1d12baaf3eeeb02/client/src/favicon.png -------------------------------------------------------------------------------- /client/src/hooks/useFetch.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | const APIKEY = import.meta.env.VITE_GIPHY_API; 4 | 5 | const useFetch = ({ keyword }) => { 6 | const [gifUrl, setGifUrl] = useState(""); 7 | 8 | const fetchGifs = async () => { 9 | try { 10 | const response = await fetch(`https://api.giphy.com/v1/gifs/search?api_key=${APIKEY}&q=${keyword.split(" ").join("")}&limit=1`); 11 | const { data } = await response.json(); 12 | 13 | setGifUrl(data[0]?.images?.downsized_medium.url); 14 | } catch (error) { 15 | setGifUrl("https://metro.co.uk/wp-content/uploads/2015/05/pokemon_crying.gif?quality=90&strip=all&zoom=1&resize=500%2C284"); 16 | } 17 | }; 18 | 19 | useEffect(() => { 20 | if (keyword) fetchGifs(); 21 | }, [keyword]); 22 | 23 | return gifUrl; 24 | }; 25 | 26 | export default useFetch; 27 | -------------------------------------------------------------------------------- /client/src/index.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700&display=swap"); 2 | 3 | * html { 4 | padding: 0; 5 | margin: 0; 6 | box-sizing: border-box; 7 | } 8 | 9 | body { 10 | margin: 0; 11 | font-family: "Open Sans", sans-serif; 12 | -webkit-font-smoothing: antialiased; 13 | -moz-osx-font-smoothing: grayscale; 14 | } 15 | 16 | .gradient-bg-welcome { 17 | background-color:#0f0e13; 18 | background-image: 19 | radial-gradient(at 0% 0%, hsla(253,16%,7%,1) 0, transparent 50%), 20 | radial-gradient(at 50% 0%, hsla(225,39%,30%,1) 0, transparent 50%), 21 | radial-gradient(at 100% 0%, hsla(339,49%,30%,1) 0, transparent 50%); 22 | } 23 | 24 | .gradient-bg-services { 25 | background-color:#0f0e13; 26 | background-image: 27 | radial-gradient(at 0% 0%, hsla(253,16%,7%,1) 0, transparent 50%), 28 | radial-gradient(at 50% 100%, hsla(225,39%,25%,1) 0, transparent 50%); 29 | } 30 | 31 | .gradient-bg-transactions { 32 | background-color: #0f0e13; 33 | background-image: 34 | radial-gradient(at 0% 100%, hsla(253,16%,7%,1) 0, transparent 50%), 35 | radial-gradient(at 50% 0%, hsla(225,39%,25%,1) 0, transparent 50%); 36 | } 37 | 38 | .gradient-bg-footer { 39 | background-color: #0f0e13; 40 | background-image: 41 | radial-gradient(at 0% 100%, hsla(253,16%,7%,1) 0, transparent 53%), 42 | radial-gradient(at 50% 150%, hsla(339,49%,30%,1) 0, transparent 50%); 43 | } 44 | 45 | .blue-glassmorphism { 46 | background: rgb(39, 51, 89, 0.4); 47 | border-radius: 16px; 48 | box-shadow: 0 4px 30px rgba(0, 0, 0, 0.2); 49 | backdrop-filter: blur(5px); 50 | -webkit-backdrop-filter: blur(5px); 51 | border: 1px solid rgba(0, 0, 0, 0.3); 52 | } 53 | 54 | /* white glassmorphism */ 55 | .white-glassmorphism { 56 | background: rgba(255, 255, 255, 0.05); 57 | border-radius: 16px; 58 | backdrop-filter: blur(5px); 59 | -webkit-backdrop-filter: blur(5px); 60 | border: 1px solid rgba(255, 255, 255, 0.3); 61 | } 62 | 63 | .eth-card { 64 | background-color:#a099ff; 65 | background-image: 66 | radial-gradient(at 83% 67%, rgb(152, 231, 156) 0, transparent 58%), 67 | radial-gradient(at 67% 20%, hsla(357,94%,71%,1) 0, transparent 59%), 68 | radial-gradient(at 88% 35%, hsla(222,81%,65%,1) 0, transparent 50%), 69 | radial-gradient(at 31% 91%, hsla(9,61%,61%,1) 0, transparent 52%), 70 | radial-gradient(at 27% 71%, hsla(336,91%,65%,1) 0, transparent 49%), 71 | radial-gradient(at 74% 89%, hsla(30,98%,65%,1) 0, transparent 51%), 72 | radial-gradient(at 53% 75%, hsla(174,94%,68%,1) 0, transparent 45%); 73 | } 74 | 75 | .text-gradient { 76 | background-color: #fff; 77 | background-image: radial-gradient(at 4% 36%, hsla(0,0%,100%,1) 0, transparent 53%), radial-gradient(at 100% 60%, rgb(0, 0, 0) 0, transparent 50%); 78 | -webkit-background-clip: text; 79 | -webkit-text-fill-color: transparent; 80 | } 81 | 82 | @tailwind base; 83 | @tailwind components; 84 | @tailwind utilities; 85 | -------------------------------------------------------------------------------- /client/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /client/src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | 4 | import App from "./App"; 5 | import { TransactionsProvider } from "./context/TransactionContext"; 6 | import "./index.css"; 7 | 8 | ReactDOM.render( 9 | 10 | 11 | , 12 | document.getElementById("root"), 13 | ); 14 | -------------------------------------------------------------------------------- /client/src/utils/Transactions.json: -------------------------------------------------------------------------------- 1 | { 2 | "_format": "hh-sol-artifact-1", 3 | "contractName": "Transactions", 4 | "sourceName": "contracts/Transactions.sol", 5 | "abi": [ 6 | { 7 | "anonymous": false, 8 | "inputs": [ 9 | { 10 | "indexed": false, 11 | "internalType": "address", 12 | "name": "from", 13 | "type": "address" 14 | }, 15 | { 16 | "indexed": false, 17 | "internalType": "address", 18 | "name": "receiver", 19 | "type": "address" 20 | }, 21 | { 22 | "indexed": false, 23 | "internalType": "uint256", 24 | "name": "amount", 25 | "type": "uint256" 26 | }, 27 | { 28 | "indexed": false, 29 | "internalType": "string", 30 | "name": "message", 31 | "type": "string" 32 | }, 33 | { 34 | "indexed": false, 35 | "internalType": "uint256", 36 | "name": "timestamp", 37 | "type": "uint256" 38 | }, 39 | { 40 | "indexed": false, 41 | "internalType": "string", 42 | "name": "keyword", 43 | "type": "string" 44 | } 45 | ], 46 | "name": "Transfer", 47 | "type": "event" 48 | }, 49 | { 50 | "inputs": [ 51 | { 52 | "internalType": "address payable", 53 | "name": "receiver", 54 | "type": "address" 55 | }, 56 | { 57 | "internalType": "uint256", 58 | "name": "amount", 59 | "type": "uint256" 60 | }, 61 | { 62 | "internalType": "string", 63 | "name": "message", 64 | "type": "string" 65 | }, 66 | { 67 | "internalType": "string", 68 | "name": "keyword", 69 | "type": "string" 70 | } 71 | ], 72 | "name": "addToBlockchain", 73 | "outputs": [], 74 | "stateMutability": "nonpayable", 75 | "type": "function" 76 | }, 77 | { 78 | "inputs": [], 79 | "name": "getAllTransactions", 80 | "outputs": [ 81 | { 82 | "components": [ 83 | { 84 | "internalType": "address", 85 | "name": "sender", 86 | "type": "address" 87 | }, 88 | { 89 | "internalType": "address", 90 | "name": "receiver", 91 | "type": "address" 92 | }, 93 | { 94 | "internalType": "uint256", 95 | "name": "amount", 96 | "type": "uint256" 97 | }, 98 | { 99 | "internalType": "string", 100 | "name": "message", 101 | "type": "string" 102 | }, 103 | { 104 | "internalType": "uint256", 105 | "name": "timestamp", 106 | "type": "uint256" 107 | }, 108 | { 109 | "internalType": "string", 110 | "name": "keyword", 111 | "type": "string" 112 | } 113 | ], 114 | "internalType": "struct Transactions.TransferStruct[]", 115 | "name": "", 116 | "type": "tuple[]" 117 | } 118 | ], 119 | "stateMutability": "view", 120 | "type": "function" 121 | }, 122 | { 123 | "inputs": [], 124 | "name": "getTransactionCount", 125 | "outputs": [ 126 | { 127 | "internalType": "uint256", 128 | "name": "", 129 | "type": "uint256" 130 | } 131 | ], 132 | "stateMutability": "view", 133 | "type": "function" 134 | } 135 | ], 136 | "bytecode": "0x608060405234801561001057600080fd5b50610c0d806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806327506f53146100465780632e7700f014610064578063cc2d7ead14610082575b600080fd5b61004e61009e565b60405161005b91906108b9565b60405180910390f35b61006c6102e1565b60405161007991906108db565b60405180910390f35b61009c600480360381019061009791906105e1565b6102ea565b005b60606001805480602002602001604051908101604052809291908181526020016000905b828210156102d857838290600052602060002090600602016040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015481526020016003820180546101ab90610ad9565b80601f01602080910402602001604051908101604052809291908181526020018280546101d790610ad9565b80156102245780601f106101f957610100808354040283529160200191610224565b820191906000526020600020905b81548152906001019060200180831161020757829003601f168201915b505050505081526020016004820154815260200160058201805461024790610ad9565b80601f016020809104026020016040519081016040528092919081815260200182805461027390610ad9565b80156102c05780601f10610295576101008083540402835291602001916102c0565b820191906000526020600020905b8154815290600101906020018083116102a357829003601f168201915b505050505081525050815260200190600101906100c2565b50505050905090565b60008054905090565b60016000808282546102fc91906109bd565b9250508190555060016040518060c001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200185815260200184815260200142815260200183815250908060018154018082558091505060019003906000526020600020906006020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020155606082015181600301908051906020019061043b9291906104ac565b506080820151816004015560a08201518160050190805190602001906104629291906104ac565b5050507f416cfa4330a4565f45c2fd2dd4826a83a37443aba2ce6f79477c7355afac35fa33858585428660405161049e9695949392919061084a565b60405180910390a150505050565b8280546104b890610ad9565b90600052602060002090601f0160209004810192826104da5760008555610521565b82601f106104f357805160ff1916838001178555610521565b82800160010185558215610521579182015b82811115610520578251825591602001919060010190610505565b5b50905061052e9190610532565b5090565b5b8082111561054b576000816000905550600101610533565b5090565b600061056261055d84610927565b6108f6565b90508281526020810184848401111561057a57600080fd5b610585848285610a97565b509392505050565b60008135905061059c81610ba9565b92915050565b600082601f8301126105b357600080fd5b81356105c384826020860161054f565b91505092915050565b6000813590506105db81610bc0565b92915050565b600080600080608085870312156105f757600080fd5b60006106058782880161058d565b9450506020610616878288016105cc565b935050604085013567ffffffffffffffff81111561063357600080fd5b61063f878288016105a2565b925050606085013567ffffffffffffffff81111561065c57600080fd5b610668878288016105a2565b91505092959194509250565b6000610680838361079c565b905092915050565b61069181610a61565b82525050565b6106a081610a13565b82525050565b6106af81610a13565b82525050565b60006106c082610967565b6106ca818561098a565b9350836020820285016106dc85610957565b8060005b8581101561071857848403895281516106f98582610674565b94506107048361097d565b925060208a019950506001810190506106e0565b50829750879550505050505092915050565b600061073582610972565b61073f818561099b565b935061074f818560208601610aa6565b61075881610b98565b840191505092915050565b600061076e82610972565b61077881856109ac565b9350610788818560208601610aa6565b61079181610b98565b840191505092915050565b600060c0830160008301516107b46000860182610697565b5060208301516107c76020860182610697565b5060408301516107da604086018261082c565b50606083015184820360608601526107f2828261072a565b9150506080830151610807608086018261082c565b5060a083015184820360a086015261081f828261072a565b9150508091505092915050565b61083581610a57565b82525050565b61084481610a57565b82525050565b600060c08201905061085f60008301896106a6565b61086c6020830188610688565b610879604083018761083b565b818103606083015261088b8186610763565b905061089a608083018561083b565b81810360a08301526108ac8184610763565b9050979650505050505050565b600060208201905081810360008301526108d381846106b5565b905092915050565b60006020820190506108f0600083018461083b565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561091d5761091c610b69565b5b8060405250919050565b600067ffffffffffffffff82111561094257610941610b69565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60006109c882610a57565b91506109d383610a57565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115610a0857610a07610b0b565b5b828201905092915050565b6000610a1e82610a37565b9050919050565b6000610a3082610a37565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000610a6c82610a73565b9050919050565b6000610a7e82610a85565b9050919050565b6000610a9082610a37565b9050919050565b82818337600083830152505050565b60005b83811015610ac4578082015181840152602081019050610aa9565b83811115610ad3576000848401525b50505050565b60006002820490506001821680610af157607f821691505b60208210811415610b0557610b04610b3a565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b610bb281610a25565b8114610bbd57600080fd5b50565b610bc981610a57565b8114610bd457600080fd5b5056fea2646970667358221220f0529bb202649fbcb0ea92973bf704941aa11d7b9907112a10c7843efddc53a664736f6c63430008000033", 137 | "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806327506f53146100465780632e7700f014610064578063cc2d7ead14610082575b600080fd5b61004e61009e565b60405161005b91906108b9565b60405180910390f35b61006c6102e1565b60405161007991906108db565b60405180910390f35b61009c600480360381019061009791906105e1565b6102ea565b005b60606001805480602002602001604051908101604052809291908181526020016000905b828210156102d857838290600052602060002090600602016040518060c00160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600282015481526020016003820180546101ab90610ad9565b80601f01602080910402602001604051908101604052809291908181526020018280546101d790610ad9565b80156102245780601f106101f957610100808354040283529160200191610224565b820191906000526020600020905b81548152906001019060200180831161020757829003601f168201915b505050505081526020016004820154815260200160058201805461024790610ad9565b80601f016020809104026020016040519081016040528092919081815260200182805461027390610ad9565b80156102c05780601f10610295576101008083540402835291602001916102c0565b820191906000526020600020905b8154815290600101906020018083116102a357829003601f168201915b505050505081525050815260200190600101906100c2565b50505050905090565b60008054905090565b60016000808282546102fc91906109bd565b9250508190555060016040518060c001604052803373ffffffffffffffffffffffffffffffffffffffff1681526020018673ffffffffffffffffffffffffffffffffffffffff16815260200185815260200184815260200142815260200183815250908060018154018082558091505060019003906000526020600020906006020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060408201518160020155606082015181600301908051906020019061043b9291906104ac565b506080820151816004015560a08201518160050190805190602001906104629291906104ac565b5050507f416cfa4330a4565f45c2fd2dd4826a83a37443aba2ce6f79477c7355afac35fa33858585428660405161049e9695949392919061084a565b60405180910390a150505050565b8280546104b890610ad9565b90600052602060002090601f0160209004810192826104da5760008555610521565b82601f106104f357805160ff1916838001178555610521565b82800160010185558215610521579182015b82811115610520578251825591602001919060010190610505565b5b50905061052e9190610532565b5090565b5b8082111561054b576000816000905550600101610533565b5090565b600061056261055d84610927565b6108f6565b90508281526020810184848401111561057a57600080fd5b610585848285610a97565b509392505050565b60008135905061059c81610ba9565b92915050565b600082601f8301126105b357600080fd5b81356105c384826020860161054f565b91505092915050565b6000813590506105db81610bc0565b92915050565b600080600080608085870312156105f757600080fd5b60006106058782880161058d565b9450506020610616878288016105cc565b935050604085013567ffffffffffffffff81111561063357600080fd5b61063f878288016105a2565b925050606085013567ffffffffffffffff81111561065c57600080fd5b610668878288016105a2565b91505092959194509250565b6000610680838361079c565b905092915050565b61069181610a61565b82525050565b6106a081610a13565b82525050565b6106af81610a13565b82525050565b60006106c082610967565b6106ca818561098a565b9350836020820285016106dc85610957565b8060005b8581101561071857848403895281516106f98582610674565b94506107048361097d565b925060208a019950506001810190506106e0565b50829750879550505050505092915050565b600061073582610972565b61073f818561099b565b935061074f818560208601610aa6565b61075881610b98565b840191505092915050565b600061076e82610972565b61077881856109ac565b9350610788818560208601610aa6565b61079181610b98565b840191505092915050565b600060c0830160008301516107b46000860182610697565b5060208301516107c76020860182610697565b5060408301516107da604086018261082c565b50606083015184820360608601526107f2828261072a565b9150506080830151610807608086018261082c565b5060a083015184820360a086015261081f828261072a565b9150508091505092915050565b61083581610a57565b82525050565b61084481610a57565b82525050565b600060c08201905061085f60008301896106a6565b61086c6020830188610688565b610879604083018761083b565b818103606083015261088b8186610763565b905061089a608083018561083b565b81810360a08301526108ac8184610763565b9050979650505050505050565b600060208201905081810360008301526108d381846106b5565b905092915050565b60006020820190506108f0600083018461083b565b92915050565b6000604051905081810181811067ffffffffffffffff8211171561091d5761091c610b69565b5b8060405250919050565b600067ffffffffffffffff82111561094257610941610b69565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b60006109c882610a57565b91506109d383610a57565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115610a0857610a07610b0b565b5b828201905092915050565b6000610a1e82610a37565b9050919050565b6000610a3082610a37565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000610a6c82610a73565b9050919050565b6000610a7e82610a85565b9050919050565b6000610a9082610a37565b9050919050565b82818337600083830152505050565b60005b83811015610ac4578082015181840152602081019050610aa9565b83811115610ad3576000848401525b50505050565b60006002820490506001821680610af157607f821691505b60208210811415610b0557610b04610b3a565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b610bb281610a25565b8114610bbd57600080fd5b50565b610bc981610a57565b8114610bd457600080fd5b5056fea2646970667358221220f0529bb202649fbcb0ea92973bf704941aa11d7b9907112a10c7843efddc53a664736f6c63430008000033", 138 | "linkReferences": {}, 139 | "deployedLinkReferences": {} 140 | } 141 | -------------------------------------------------------------------------------- /client/src/utils/constants.js: -------------------------------------------------------------------------------- 1 | import abi from "./Transactions.json"; 2 | 3 | export const contractAddress = "0xaB99e8446a97af130B443c13695cB25e5A268D7C"; 4 | export const contractABI = abi.abi; 5 | -------------------------------------------------------------------------------- /client/src/utils/dummyData.js: -------------------------------------------------------------------------------- 1 | export default []; 2 | -------------------------------------------------------------------------------- /client/src/utils/shortenAddress.js: -------------------------------------------------------------------------------- 1 | export const shortenAddress = (address) => 2 | `${address.slice(0, 5)}...${address.slice(address.length - 4)}`; 3 | //export const shortenAddress = (address) => address; 4 | -------------------------------------------------------------------------------- /client/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | purge: ["./src/**/*.{js,jsx,ts,tsx}", "./public/index.html"], 3 | mode: "jit", 4 | darkMode: false, // or 'media' or 'class' 5 | theme: { 6 | fontFamily: { 7 | display: ["Open Sans", "sans-serif"], 8 | body: ["Open Sans", "sans-serif"], 9 | }, 10 | extend: { 11 | screens: { 12 | mf: "990px", 13 | }, 14 | keyframes: { 15 | "slide-in": { 16 | "0%": { 17 | "-webkit-transform": "translateX(120%)", 18 | transform: "translateX(120%)", 19 | }, 20 | "100%": { 21 | "-webkit-transform": "translateX(0%)", 22 | transform: "translateX(0%)", 23 | }, 24 | }, 25 | }, 26 | animation: { 27 | "slide-in": "slide-in 0.5s ease-out", 28 | }, 29 | }, 30 | }, 31 | variants: { 32 | extend: {}, 33 | }, 34 | plugins: [require("@tailwindcss/forms")], 35 | }; 36 | -------------------------------------------------------------------------------- /client/vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()] 7 | }) 8 | -------------------------------------------------------------------------------- /smart_contract/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | coverage 4 | coverage.json 5 | typechain 6 | 7 | #Hardhat files 8 | cache 9 | artifacts 10 | -------------------------------------------------------------------------------- /smart_contract/contracts/Transactions.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: UNLICENSED 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | // import "hardhat/console.sol"; 6 | 7 | contract Transactions { 8 | uint256 transactionCount; 9 | 10 | event Transfer( 11 | address from, 12 | address receiver, 13 | uint256 amount, 14 | string message, 15 | uint256 timestamp, 16 | string keyword 17 | ); 18 | 19 | struct TransferStruct { 20 | address sender; 21 | address receiver; 22 | uint256 amount; 23 | string message; 24 | uint256 timestamp; 25 | string keyword; 26 | } 27 | 28 | TransferStruct[] transactions; 29 | 30 | function addToBlockchain( 31 | address payable receiver, 32 | uint256 amount, 33 | string memory message, 34 | string memory keyword 35 | ) public { 36 | transactionCount += 1; 37 | transactions.push( 38 | TransferStruct( 39 | msg.sender, 40 | receiver, 41 | amount, 42 | message, 43 | block.timestamp, 44 | keyword 45 | ) 46 | ); 47 | 48 | emit Transfer( 49 | msg.sender, 50 | receiver, 51 | amount, 52 | message, 53 | block.timestamp, 54 | keyword 55 | ); 56 | } 57 | 58 | function getAllTransactions() 59 | public 60 | view 61 | returns (TransferStruct[] memory) 62 | { 63 | return transactions; 64 | } 65 | 66 | function getTransactionCount() public view returns (uint256) { 67 | return transactionCount; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /smart_contract/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-waffle"); 2 | 3 | module.exports = { 4 | solidity: "0.8.0", 5 | networks: { 6 | ropsten: { 7 | url: "https://eth-ropsten.alchemyapi.io/v2/RLaVZP0JN4KCPpZk6dXE1Mw8S4P6Zjqd", 8 | accounts: [ 9 | "fbb139ea0d6b7a2648a9422884550510461f6319ca3aa9fe26f76dce9ffb7b3c", 10 | ], 11 | }, 12 | }, 13 | }; 14 | -------------------------------------------------------------------------------- /smart_contract/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test3", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "devDependencies": { 13 | "@nomiclabs/hardhat-ethers": "^2.0.3", 14 | "@nomiclabs/hardhat-waffle": "^2.0.1", 15 | "chai": "^4.3.4", 16 | "ethereum-waffle": "^3.4.0", 17 | "ethers": "^5.5.2", 18 | "hardhat": "^2.8.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /smart_contract/scripts/deploy.js: -------------------------------------------------------------------------------- 1 | const main = async () => { 2 | const transactionsFactory = await hre.ethers.getContractFactory("Transactions"); 3 | const transactionsContract = await transactionsFactory.deploy(); 4 | 5 | await transactionsContract.deployed(); 6 | 7 | console.log("Transactions address: ", transactionsContract.address); 8 | }; 9 | 10 | const runMain = async () => { 11 | try { 12 | await main(); 13 | process.exit(0); 14 | } catch (error) { 15 | console.error(error); 16 | process.exit(1); 17 | } 18 | }; 19 | 20 | runMain(); -------------------------------------------------------------------------------- /smart_contract/test/sample-test.js: -------------------------------------------------------------------------------- 1 | const { expect } = require("chai"); 2 | const { ethers } = require("hardhat"); 3 | 4 | describe("Greeter", function () { 5 | it("Should return the new greeting once it's changed", async function () { 6 | const Greeter = await ethers.getContractFactory("Greeter"); 7 | const greeter = await Greeter.deploy("Hello, world!"); 8 | await greeter.deployed(); 9 | 10 | expect(await greeter.greet()).to.equal("Hello, world!"); 11 | 12 | const setGreetingTx = await greeter.setGreeting("Hola, mundo!"); 13 | 14 | // wait until the transaction is mined 15 | await setGreetingTx.wait(); 16 | 17 | expect(await greeter.greet()).to.equal("Hola, mundo!"); 18 | }); 19 | }); 20 | --------------------------------------------------------------------------------