Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
e0a81a4
Add UI folder
cpayton-source Nov 21, 2022
38ebdc6
Merkle tree and get-balance API
candilikoglu Nov 21, 2022
b34d785
Merge pull request #1 from candilikoglu/cd1-api
candilikoglu Nov 21, 2022
3898fe9
Separate backend and frontend
candilikoglu Nov 22, 2022
1992241
Merge pull request #2 from candilikoglu/cd2-api-connect
candilikoglu Nov 22, 2022
23b4f54
Link Front and backend
J-coder13 Nov 22, 2022
501c7d6
Merge pull request #3 from candilikoglu/connect-backend
candilikoglu Nov 22, 2022
c012f59
Reorganize index.js for server
candilikoglu Nov 28, 2022
f6c0f52
Add login page
cpayton-source Nov 28, 2022
660a3d8
FIxing Cans code
cpayton-source Nov 28, 2022
d318b0e
add login ui
cpayton-source Nov 28, 2022
77dcf63
login authentication
candilikoglu Nov 29, 2022
b265f35
Add UI made by Kamaria and Cameron
candilikoglu Nov 29, 2022
f41f8bc
Merge pull request #4 from candilikoglu/addUI
candilikoglu Nov 29, 2022
826a520
Add MongoDB user schema and connect it to backend
candilikoglu Nov 29, 2022
cde7c0b
Merge pull request #5 from candilikoglu/login-auth
candilikoglu Nov 29, 2022
edc73be
MongoDB login and register REST API
candilikoglu Nov 30, 2022
c327a1a
Merge pull request #6 from candilikoglu/login-auth2
candilikoglu Nov 30, 2022
f5b4687
Add CORS protection
candilikoglu Nov 30, 2022
841b8a6
Merge pull request #7 from candilikoglu/login-auth3
candilikoglu Nov 30, 2022
f7acf89
change logo
AlexanderRoper Nov 30, 2022
1a325cf
photo url update
AlexanderRoper Nov 30, 2022
062a483
Organized UI into folders
candilikoglu Nov 30, 2022
f88c880
Merge pull request #8 from candilikoglu/login-auth4
candilikoglu Nov 30, 2022
f6d0f98
Update README.md
AlexanderRoper Nov 30, 2022
8f3a95c
adding and connected pages for the main wallet
kayelise25 Dec 1, 2022
cab3d72
Add register functionality
candilikoglu Dec 5, 2022
648f558
Merge pull request #9 from candilikoglu/login-auth5
candilikoglu Dec 5, 2022
7fd4819
add some routing for wallet page
kayelise25 Dec 5, 2022
9a472df
Mining
candilikoglu Dec 6, 2022
442c788
Mine
candilikoglu Dec 6, 2022
8bbfdbd
Login authentication
candilikoglu Dec 6, 2022
1c3943f
Merge pull request #10 from candilikoglu/login
candilikoglu Dec 6, 2022
036eaac
Mine
candilikoglu Dec 6, 2022
9b2f5ae
Merge branch 'mine' of https://github.com/candilikoglu/datacoin2.0 in…
candilikoglu Dec 6, 2022
15974ac
API to UI for transaction
candilikoglu Dec 9, 2022
9a7c986
Merge pull request #11 from candilikoglu/transaction
candilikoglu Dec 9, 2022
5f1e6a9
Wallet Screen
candilikoglu Dec 10, 2022
c59fa63
Merge pull request #12 from candilikoglu/walletScreen
candilikoglu Dec 10, 2022
b466431
Transaction Screen
candilikoglu Dec 10, 2022
6173730
Transaction Screen
candilikoglu Dec 10, 2022
93f1e0b
Merge pull request #13 from candilikoglu/transactionlist
candilikoglu Dec 10, 2022
b3b7602
Merge pull request #14 from candilikoglu/p2p
candilikoglu Dec 11, 2022
d3648f9
re-add p2p port listening
candilikoglu Dec 11, 2022
7d2b027
Merge pull request #15 from candilikoglu/p2p
candilikoglu Dec 11, 2022
3b81a07
mining functionality added
candilikoglu Dec 11, 2022
e05efa3
Merge pull request #16 from candilikoglu/mine_final
candilikoglu Dec 11, 2022
07c5caa
Merge branch 'master' of https://github.com/candilikoglu/datacoin2.0
kayelise25 Dec 11, 2022
8d239ca
formatting transaction page
kayelise25 Dec 12, 2022
3ee2efa
changing UI layout
kayelise25 Dec 19, 2022
26439c8
landing page
AlexanderRoper Dec 19, 2022
b4ccb67
change README.md
candilikoglu Dec 20, 2022
cc632d5
Merge branch 'master' of https://github.com/candilikoglu/datacoin2.0
candilikoglu Dec 20, 2022
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
Binary file added .DS_Store
Binary file not shown.
89 changes: 68 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,106 +1,153 @@
# Cryptocurrency built on a distributed ledger
# Data Coin | P2P Cryptocurrency Web App

[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://GitHub.com/Naereen/StrapDown.js/graphs/commit-activity)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

<!-- [![Packagist](https://img.shields.io/packagist/v/symfony/symfony.svg)]() -->

![alt text](https://github.com/mayankamencherla/Blockchain/blob/master/bitcoin.jpg)
![alt text](officialLogo.png)

## Downloading

```bash
$ git clone https://github.com/mayankamencherla/Blockchain.git
$ git clone https://github.com/candilikoglu/datacoin2.0.git
```

> This app is a backend that mimics a peer to peer payment system (like Bitcoin), with a fully functional wallet, attached to the local miner, but with transactions and the blockchain synced across the distributed system of nodes

## Pre-requisities:

> Some key things to set up / understand to use this app:

- **[NodeJS v9](https://nodejs.org/en/)**
- **[npm](https://www.npmjs.com/)**
- **[Bitcoin](https://bitcoin.org/bitcoin.pdf)**
- **[ngrok](https://ngrok.com)**

## Setup Locally

> To get the app working locally, or to run test cases, follow the instructions below.
> After setting up the app, details on each API and how to use it can be found below in the **[API's available on this app](https://github.com/mayankamencherla/Blockchain#apis-available-on-this-app)** section.
> After setting up the app, details on each API and how to use it can be found below in the **[API's available on this app](https://github.com/candilikoglu/datacoin2.0#apis-available-on-this-app)** section.
> If any of the commands below are denied due to a permission error, please prepend a sudo to the command.

1. Navigate to the app's root directory
1. Open two terminals

2. Navigate into backend

3. Run npm install on both directories

2. Run the following command to install all the dependencies:
```bash
$ npm install
```

3. Open the first node on the network:
4. To start the node execute npm run dev in backend folders

```bash
$ npm run dev
```
By default, the first node's HTTP server is hosted on port 3001, and the P2P server is hosted on port 5001

4. Open the second node on the network:
```bash
$ HTTP_PORT=3002 P2P_PORT=5002 PEERS=ws://localhost:5001 npm run dev
```
This opens a new node, with an HTTP server hosted on port 3002, and the P2P server hosted on 5002, and it connects to the peers in the network (In this case, only 1 hosted on port 5001)
5. To start the web application execute npm start in frontend folder

5. To open the nth node on the network:
```
a. Choose 2 open ports, 1 for the HTTP server, and 1 for the P2P server of the node
b. PEERS = n-1 P2P servers that were created before this node in the form: ws://localhost:<port>, seperated by commas
```
```bash
$ HTTP_PORT=<HTTP PORT> P2P_PORT=<P2P PORT> PEERS=<ws://localhost:<PORT1>,ws://localhost:<PORT2>...> npm run dev
$ npm start
```

## Publish your node publicly
> To get the app working publicly, follow the instructions below.
> If any of the commands below are denied due to a permission error, please prepend a sudo to the command.

### On computer 1
1. Download ngrok softtware by following the guide on the website.

2. Sign up on ngrok and get an authentication token

3. First in your terminal, run
```bash
$ ngrok config add-authtoken <yourAuthToken>
```
4. After run the following command:
``` bash
$ ngrok tcp <desired_port_listen_for>
```
5. Execute commands ```npm run dev``` & ```npm start```. It will run on ports 3001 and 5001 by default.

### On other computers that want to join the network
1. ngrok will give you a tcp address to computer 1. Use the tcp address to replace the ```PEERS``` address before starting the program.
Following is the example

2. An example is:
* set HTTP_PORT=<HTTP_PORT> && set P2P_PORT=<P2P_PORT> && set PEERS=ws://localhost:5001 && npm run dev

will become:

* set HTTP_PORT=<HTTP_PORT> && set P2P_PORT=<P2P_PORT> && set PEERS=ws://<tcp_address> && npm run dev

ex: set HTTP_PORT= 3002 && set P2P_PORT= 5002 && set PEERS=ws://6.tcp.ngrok.io:14732 && npm run dev

## Run test cases:

```bash
$ npm run test
```

## API's available on this app

> This app supports 6 API's currently: (3001 can be changed to any of the other node's HTTP server's port number)

1. GET <a href="http://localhost:3001/blocks" target="_blank">/blocks</a>

- Fetch the blocks in the blockchain saved locally on the node whose HTTP server is running on port 3001

2. POST <a href="http://localhost:3001/mine" target="_blank">/mine</a>

- Mines a new block containing the data field in the post request
- The block is then added to the blockchain locally
- The updated blockchain is broadcasted across the network so that other nodes can update their blockchains

3. GET <a href="http://localhost:3001/transactions" target="_blank">/transactions</a>

- Fetch all transactions in the transactions pool saved locally in the node
- The transaction pool is the same and is saved across all nodes in the network

4. POST <a href="http://localhost:3001/transact" target="_blank">/transact</a>

- Takes in recipient and amount as post parameters
- This endpoint is used to send amount to recipient from wallet at 3001
- Creates a new transaction and adds it to the transaction pool
- Wallet at 3001 has amount subtracted, and recipient wallet gets amount added to balance

5. GET <a href="http://localhost:3001/public-key" target="_blank">/public-key</a>

- This endpoint is used to retrieve public key for the wallet at port 3001
- This public key must be used as recipient to send wallet at 3001 currency

6. GET <a href="http://localhost:3001/mine-transactions" target="_blank">/mine-transactions</a>

- Mines a new block containing all the transactions in the transaction pool shared across all nodes in the network
- The block is mined based on the **[proof of work](https://github.com/mayankamencherla/Blockchain#proof-of-work)** mechanism also used in Bitcoin.
- The block is then added to the blockchain locally
- The updated blockchain is broadcasted across the network so that other nodes can update their blockchains

7. Post <a href="http://localhost:3001/login" target="_blank">/login</a>

8. Post <a href="http://localhost:3001/register" target="_blank">/register</a>

9. Post <a href="http://localhost:3001/balance" target="_blank">/balance</a>

## Proof of work

> The miner creats a new block using the proof of work mechanism outlined below

1. When the miner decides to mine a new block, he does so with all the transactions in the transaction pool
2. The initial block is a genesis block, and a new block is mined based on the following parameters:

```
a. block of the last hash
b. nonce
c. hash of the current block
d. timestamp
e. difficulty
```

3. The proof of work mechanism iteratively increases nonce and alters difficulty, until the number of leadings 0's in the block's hash are equal to the difficulty in the current iteration
4. This is done to ensure that each block is added once every `MINE_RATE` of the blockchain
5. The algorithm can be found in **[mine block](https://github.com/mayankamencherla/Blockchain/blob/master/blockchain/block.js#L38)**
5. The algorithm can be found in **[mine block](https://github.com/candilikoglu/datacoin2.0/blob/master/backend/blockchain/block.js#L38)**
68 changes: 0 additions & 68 deletions app/index.js

This file was deleted.

Binary file added backend/.DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions backend/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DB_URL = mongodb+srv://datacoin:7DcGo2EKgJbVdSrV@cluster0.comggev.mongodb.net/?retryWrites=true&w=majority
29 changes: 29 additions & 0 deletions backend/app/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const dbCoonect = require('../db/dbConnect');
const cookieParser = require("cookie-parser");
const routes = require("../routers/routers");
const { listen } = require("../controllers/blockchainControllers")
const HTTP_PORT = process.env.HTTP_PORT || 3001;
const app = express();

dbCoonect()
app.use(
cors({
origin: ["http://localhost:3000"],
methods: ["GET", "POST"],
credentials: true,
})
);

app.use(cookieParser());
app.use(express.json())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }))
app.use("/", routes)

listen()
//mongoose.connection.once('open', () => {
app.listen(HTTP_PORT, () => console.log(`Listening on port ${HTTP_PORT}`));
//})
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
98 changes: 98 additions & 0 deletions backend/blockchain/merkle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
const SHA256 = require('crypto-js/sha256');

class MerkleTree {
constructor(nodeList) {
this.leaves = nodeList;
this.layers = [this.leaves]; // tree levels
this.calculateMerkleTree(this.leaves);
}

calculateMerkleTree(nodes) {
if (nodes.length == 1) {
return nodes[0];
}
const layerIndex = this.layer.length;
this.layers.push([])

// take 2 hashes of different Txs and hash them, push to the layers list (loop until no more even no. of leaves)
for (let i = 0; i < nodes.length - 1; i+=1) {
this.layers[layerIndex].push(SHA256(nodes[i] + nodes[i+1]).toString);
}
// takes care of odd no. leaves in the tree - take the last one left after the loop and yossi hash it with itself, push to list
if (nodes.length % 2 == 1) {
this.layers[layerIndex].push(SHA256(nodes[nodes.length-1], nodes[nodes.length-1]).toString);
}

return this.calculateMerkleTree(this.layers[layerIndex]);
}


getLeaves() {
return this.leaves;
}

getLayers() {
return this.layers;
}

getRoot() {
return this.layers[this.layers.length - 1][0];
}


getProof(leaf) {
let index;
const proof = [];

for (let i = 0; i < this.leaves.length; i++) {
if (leaf === this.leaves[i].toString()) {
index = i;
break;
}
}

if (!index) {
return proof;
}

for (let i = 0; i < this.layers.length - 1; i++) {
const layer = this.layers[i];
const isRightNode = index % 2;
const pairIndex = isRightNode ? index - 1 : index + 1;

proof.push({
position: isRightNode ? 'left' : 'right',
data: layer[pairIndex].toString()
});

index = Math.floor(index / 2);
}

return proof;
}

verify(proof, targetNode, root) {
let hash = targetNode

if (!Array.isArray(proof) || !proof.length || !targetNode || !root) {
return false;
}

for (let i = 0; i < proof.length; i++) {
const node = proof[i]
const isRightNode = (node.position === 'right')
const buffers = []

if (isRightNode) {
hash = SHA256(hash.toString() + node.data.toString()).toString();
} else {
hash = SHA256(node.data.toString() + hash.toString()).toString();
}

}

return hash === root.toString();
}
}

module.exports.MerkleTree = MerkleTree;
File renamed without changes.
File renamed without changes.
Loading