Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project 04 #20

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions step34_projects/project-04/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
26 changes: 26 additions & 0 deletions step34_projects/project-04/backend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Deploy Smart Contract In Ganache

## Step 1
Download [Ganache](https://www.trufflesuite.com/ganache) for your operating system. Ganache is a local development blockchain which can be used to mimic a public blockchain

## Step 2
Install [MetaMask](https://chrome.google.com/webstore/detail/metamask/nkbihfbeogaeaoehlefnkodbefgpgknn?hl=en) extension (A browser based wallet)

## Step 3
If your server port on Ganache is 7545, change it to 8545 as this is the local host network on MetaMask.
![mainScreen](img/mainGanacheScreen.png)

Go to Settings > Server, repace 7545 with 8545.
![settins](img/settings.png)
![server](img/ServerMenu.png)

## Step 4
Install Truffle package globally using command npm i -g truffle

## Step 5
Run truffle migrate.
You can see a transaction of contract creation in the Transaction tab.
![transaction](img/transactionScreen.png)

Great! Now follow the instructions in frontend folder to connect your local blockchain with React.

156 changes: 156 additions & 0 deletions step34_projects/project-04/backend/contracts/DEX.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.6;

interface IERC20 {
function totalSupply() external view returns (uint256);

function balanceOf(address account) external view returns (uint256);

function allowance(address owner, address spender)
external
view
returns (uint256);

function transfer(address recipient, uint256 amount)
external
returns (bool);

function approve(address spender, uint256 amount) external returns (bool);

function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);

event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}

contract ERC20Basic is IERC20 {
string public constant name = "ERC20Basic";
string public constant symbol = "ERC";
uint8 public constant decimals = 18;

mapping(address => uint256) balances;

mapping(address => mapping(address => uint256)) allowed;

uint256 totalSupply_ = 10 ether;

using SafeMath for uint256;

constructor() public {
balances[msg.sender] = totalSupply_;
}

function totalSupply() public view override returns (uint256) {
return totalSupply_;
}

function balanceOf(address tokenOwner)
public
view
override
returns (uint256)
{
return balances[tokenOwner];
}

function transfer(address receiver, uint256 numTokens)
public
override
returns (bool)
{
require(numTokens <= balances[msg.sender]);
balances[msg.sender] = balances[msg.sender].sub(numTokens);
balances[receiver] = balances[receiver].add(numTokens);
emit Transfer(msg.sender, receiver, numTokens);
return true;
}

function approve(address delegate, uint256 numTokens)
public
override
returns (bool)
{
allowed[msg.sender][delegate] = numTokens;
emit Approval(msg.sender, delegate, numTokens);
return true;
}

function allowance(address owner, address delegate)
public
view
override
returns (uint256)
{
return allowed[owner][delegate];
}

function transferFrom(
address owner,
address buyer,
uint256 numTokens
) public override returns (bool) {
require(numTokens <= balances[owner]);
require(numTokens <= allowed[owner][msg.sender]);

balances[owner] = balances[owner].sub(numTokens);
allowed[owner][msg.sender] = allowed[owner][msg.sender].sub(numTokens);
balances[buyer] = balances[buyer].add(numTokens);
emit Transfer(owner, buyer, numTokens);
return true;
}
}

library SafeMath {
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}

function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}

contract DEX {
event Bought(uint256 amount);
event Sold(uint256 amount);

IERC20 public token;

constructor() public {
token = new ERC20Basic();
}

function balance() public view returns (uint256) {
return token.balanceOf(address(this));
}

function buy() public payable {
uint256 amountTobuy = 10;
uint256 dexBalance = token.balanceOf(address(this));
require(amountTobuy > 0, "You need to send some Ether");
require(amountTobuy <= dexBalance, "Not enough tokens in the reserve");
token.transfer(msg.sender, amountTobuy);
emit Bought(amountTobuy);
}

function sell(uint256 amount) public {
require(amount > 0, "You need to sell at least some tokens");
uint256 allowance = token.allowance(msg.sender, address(this));
require(allowance >= amount, "Check the token allowance");
token.transferFrom(msg.sender, address(this), amount);
payable(msg.sender).transfer(amount);
emit Sold(amount);
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
var DEX = artifacts.require("./DEX");

module.exports = function (deployer) {
deployer.deploy(DEX);
};
Empty file.
49 changes: 49 additions & 0 deletions step34_projects/project-04/backend/truffle-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* Use this file to configure your truffle project. It's seeded with some
* common settings for different networks and features like migrations,
* compilation and testing. Uncomment the ones you need or modify
* them to suit your project as necessary.
*
* More information about configuration can be found at:
*
* trufflesuite.com/docs/advanced/configuration
*
* To deploy via Infura you'll need a wallet provider (like @truffle/hdwallet-provider)
* to sign your transactions before they're sent to a remote public node. Infura accounts
* are available for free at: infura.io/register.
*
* You'll also need a mnemonic - the twelve word phrase the wallet uses to generate
* public/private key pairs. If you're publishing your code to GitHub make sure you load this
* phrase from a file you've .gitignored so it doesn't accidentally become public.
*
*/

// const HDWalletProvider = require('@truffle/hdwallet-provider');
//
// const fs = require('fs');
// const mnemonic = fs.readFileSync(".secret").toString().trim();
module.exports = {
networks: {
development: {
host: "127.0.0.1",
port: 8545,
network_id: "*", // Match any network id
},
},

compilers: {
solc: {
version: "0.8.6", // Fetch exact version from solc-bin (default: truffle's version)
// docker: true, // Use "0.5.1" you've installed locally with docker (default: false)
// settings: { // See the solidity docs for advice about optimization and evmVersion
optimizer: {
enabled: false,
runs: 200,
},
// evmVersion: "byzantium"
// }
},
},
contracts_directory: "./contracts/",
contracts_build_directory: "../frontend/src/abis/",
};
4 changes: 4 additions & 0 deletions step34_projects/project-04/backend/yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1


28 changes: 28 additions & 0 deletions step34_projects/project-04/frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Connect Your Local Blockchain with React using Web3


[Tutotrial Link](https://www.dappuniversity.com/articles/ethereum-dapp-react-tutorial)

In this step we are making a simple Todo Dapp.

## Step 1
Install project dependencies by running npm install

## Step 2
Ensure that types folder is generated. If not then run npm generate-types

## Step 3
Paste the Smart Contract Address in config file.
You can obtain your smart contract's address from Transaction Tab of Ganache
![transaction](img/transactionScreen.png)

## Step 4
Open MetaMask extension and switch network to custom RPC. Enter Network Name of your choice, Paste RPC present in Ganche in the New RPC Url field. Enter 1337 in the field ChainId and Click on Save.
![customNetwork](img/customNetwork.png)

## Step 5
Now click on the Account Icon in the top-right corner, and click on Import account. Paste the private key of any account present in Ganache. This will allow Metamask to send transactions to the contract deployed in Ganache.
![importAccount](img/importAccount.png)

## Step 6
Run npm start
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
53 changes: 53 additions & 0 deletions step34_projects/project-04/frontend/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"name": "frontend",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@types/jest": "^26.0.15",
"@types/node": "^12.0.0",
"@types/react": "^17.0.0",
"@types/react-dom": "^17.0.0",
"bootstrap": "5.1.0",
"react": "^17.0.2",
"react-bootstrap": "^2.0.0-beta.5",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
"typescript": "^4.1.2",
"web-vitals": "^1.0.1",
"web3": "^1.5.2"
},
"scripts": {
"start": "react-scripts start",
"generate-types": "typechain --target=web3-v1 \"./src/abis/*.json\"",
"postinstall": "yarn generate-types",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"@typechain/web3-v1": "^3.0.0",
"@types/bn.js": "^5.1.0",
"typechain": "^5.1.2"
}
}
Binary file not shown.
43 changes: 43 additions & 0 deletions step34_projects/project-04/frontend/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading