Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
90 commits
Select commit Hold shift + click to select a range
af885ed
Encodings Are Now Done In Hex
sushantshah-dev Jul 12, 2022
9710bff
Fixed Issue Where Transaction Is Called Block
sushantshah-dev Jul 12, 2022
d3a7dc6
Peers Are Now Added Using raddr Instead Of haddr
sushantshah-dev Jul 13, 2022
8725063
node Object Is Now Stored Within Blockchain
sushantshah-dev Jul 13, 2022
4612fad
Added os Module To Imports
sushantshah-dev Jul 14, 2022
61cb79b
Modified Messages
sushantshah-dev Jul 14, 2022
1c483f4
Node With Web UI
sushantshah-dev Jul 14, 2022
91d4ad5
Node Now Passes Itself To The Blockchain Object
sushantshah-dev Jul 14, 2022
d170032
Network Block Now Decoded Before Deserialization
sushantshah-dev Jul 14, 2022
2a91ec7
Add Index File For WebUI
sushantshah-dev Jul 14, 2022
6a2420b
Lenght Of Address Is Now Sent Before Sending The Address
sushantshah-dev Jul 17, 2022
23c4a01
Added Handling For Connection Errors
sushantshah-dev Jul 17, 2022
a61a5d5
Improved P2P Listening
sushantshah-dev Jul 17, 2022
19014cd
Connections Now Re-Established After Every Broadcast
sushantshah-dev Jul 18, 2022
84262c0
Added GAN By Neeraj Joshi After Slight Modifications And Cleaning.
sushantshah-dev Jul 24, 2022
37351d2
Added GAN Initialisation Flow And Fixed Log Block Broadcasts.
sushantshah-dev Jul 24, 2022
f5cd672
Removed Double Import Of Gan.
sushantshah-dev Jul 26, 2022
5cfb875
mend
sushantshah-dev Jul 26, 2022
9f8fad6
Node Now Passes Itself To Runtime
sushantshah-dev Jul 26, 2022
09f3d5c
Added Option To Close p2p Interface
sushantshah-dev Jul 26, 2022
f2c1595
Forever Loop Now Runs Only While p2pInterface Is Listening. Thread Va…
sushantshah-dev Jul 26, 2022
6b3431d
Added Restart And Shutdown Functions To Node
sushantshah-dev Jul 26, 2022
4ab6a35
Fixed Input Collection For GAN
sushantshah-dev Jul 27, 2022
3131eaa
Fixed Import
sushantshah-dev Jul 27, 2022
6e2cc96
Gan Now Initialized On Every Run. TODO: Initialize GAN Only On First Run
sushantshah-dev Jul 27, 2022
1e3972b
Node Is Now Passed To All The Network Handlers
sushantshah-dev Jul 30, 2022
15db426
Sending Score Over Network Now Functional
sushantshah-dev Jul 30, 2022
e82e220
Removed Unnecessary Imports
sushantshah-dev Jul 30, 2022
7bdc1a3
Epoch Now Printed During Train
sushantshah-dev Jul 30, 2022
5c97f1f
Seed Root Is Now Flattened After Processing
sushantshah-dev Jul 30, 2022
384fe51
GPoHC Object Now Also Requires Reference To The Node Object
sushantshah-dev Jul 30, 2022
64983dd
Fixed Imports. Imported Block Classes
sushantshah-dev Jul 31, 2022
b08e9f8
GPoHC Class Now Requires A Name
sushantshah-dev Jul 31, 2022
627be71
Fixed Typo
sushantshah-dev Jul 31, 2022
8e9a4b4
GAN Class Now Requires A Name
sushantshah-dev Jul 31, 2022
4afc23e
GAN Is Now Handled Directly By GPoHC
sushantshah-dev Jul 31, 2022
e927a4c
Seed Root Preprocessing Is Now An Independent Function For Reusability
sushantshah-dev Jul 31, 2022
2b318e9
broadcast_super_seed Is Temporarily Replaced With score_super_seed (N…
sushantshah-dev Jul 31, 2022
4905fc3
Imported GPoHC And Initialized
sushantshah-dev Jul 31, 2022
6cdd06d
Fixed Reference To Node.
sushantshah-dev Jul 31, 2022
9a6808a
Blockchain Now Calculates Seed Before Append. If Consensus Is Won Blo…
sushantshah-dev Jul 31, 2022
5e9172e
Node Now Maintains A Seed Store.
sushantshah-dev Jul 31, 2022
d7def74
Broadcast Function Now Allows A Handler To Be Passed To Handle Broadc…
sushantshah-dev Jul 31, 2022
301ae43
Broadcast Now Supports Arguments To Broadcast Handlers.
sushantshah-dev Jul 31, 2022
195b292
Broadcast Handler Results Now Returned As An Array
sushantshah-dev Jul 31, 2022
ef82e08
seed:scr Now Sends Length Of Score Data Before The Score.
sushantshah-dev Jul 31, 2022
2f1f928
Written Seed Score Broadcast Handler. Returns An Array Of Tuples Of S…
sushantshah-dev Jul 31, 2022
94dc496
Update GPoHC.py
sushantshah-dev Jul 31, 2022
ebcbd0e
Completed Method To Collect And Calculate The Total Seed Score.
sushantshah-dev Jul 31, 2022
9b492db
Added Imports
sushantshah-dev Jul 31, 2022
cc95362
Seed Calculation And Scoring Done.
sushantshah-dev Jul 31, 2022
ebb7848
Fixed Check For Availability Of Remote Nodes.
sushantshah-dev Jul 31, 2022
35f1cf7
change intendation from 2 to 4
kunalgoyal9 Jul 31, 2022
46caa00
Merge branch 'In-Dev' of https://github.com/Funzofi/funzochain into I…
sushantshah-dev Jul 31, 2022
8695d32
Created MockGAN
sushantshah-dev Jul 31, 2022
3615ba4
MockGAN Temporarily In Use Rather Than GAN.
sushantshah-dev Jul 31, 2022
8c4dcfa
Seed Root Collection Now Functional.
sushantshah-dev Jul 31, 2022
ee92e65
MockGAN Now Accepts Name Attribute To Replicate GAN.
sushantshah-dev Aug 1, 2022
dafb37d
consensus Object Is Now Created Directly Before Initiation Of Blockch…
sushantshah-dev Aug 1, 2022
dc65668
Added Functions To MockGAN To Replicate GAN
sushantshah-dev Aug 1, 2022
3f76bf5
Consensus GAN Initialization Is Npw A Separate Function.
sushantshah-dev Aug 1, 2022
a8e22ca
Added Imports To network_handler
sushantshah-dev Aug 1, 2022
6407009
Added Seed Root Request
sushantshah-dev Aug 1, 2022
b5ccf23
Fixed Typo
sushantshah-dev Aug 1, 2022
6caf6df
Strength Of Consensus Now Reduced For A Blockchain With Length Lower …
sushantshah-dev Aug 1, 2022
3cdc28f
Assigned Broadcast Handlers
sushantshah-dev Aug 1, 2022
c6d4ff7
Written Seed Root Request.
sushantshah-dev Aug 1, 2022
8d2dab4
Exported Seed Handlers
sushantshah-dev Aug 1, 2022
afd6c89
Fixed Score Simulation In MockGAN
sushantshah-dev Aug 1, 2022
6faa8d2
All Indentation Now Tabs
sushantshah-dev Aug 1, 2022
c0c50b6
SUPER_SEED Now Limited To First 117 Characters
sushantshah-dev Aug 1, 2022
b4bc086
Temporarily Every Node Wins Consensus
sushantshah-dev Aug 1, 2022
0b9bb94
Removed Unnecessary Argument
sushantshah-dev Aug 1, 2022
022ff0d
Added Missing Return
sushantshah-dev Aug 1, 2022
793fc11
Scores Received Over The Network Are Now Stored As Floats.
sushantshah-dev Aug 1, 2022
f3e93c7
Using bytes Function Instead Of encode Method To Account For Ascii Ar…
sushantshah-dev Aug 1, 2022
2d08040
Fixed Reference To GAN
sushantshah-dev Aug 1, 2022
9c877b2
Fixed Reference To seed_store
sushantshah-dev Aug 1, 2022
a3d29f7
Spread Out seed:rot Handler
sushantshah-dev Aug 1, 2022
bbd45d9
Fixed Default Value For handler_args
sushantshah-dev Aug 1, 2022
8a96de6
FINALLLL GAN COMMIT!!!!
sushantshah-dev Aug 3, 2022
c9da400
Fixed Invalid Attribute
sushantshah-dev Aug 3, 2022
b081fd5
Removed Unnecessary Imports
sushantshah-dev Aug 3, 2022
8fc848a
GPoHC Now Uses Updated gan.
sushantshah-dev Aug 3, 2022
e755608
network_handler Now Using Updated gan.
sushantshah-dev Aug 3, 2022
3c65630
--
sushantshah-dev Aug 3, 2022
5f6bb3a
Shifted From Object Style To Attribute Style For GAN Interface To GPoHC.
sushantshah-dev Aug 12, 2022
56d6893
Removed Faulty Seed Pre-Processing
sushantshah-dev Aug 12, 2022
8aeebbd
Create README.md
sushantshah-dev Aug 18, 2022
2c936cb
Merge branch 'In-Dev' of https://github.com/Funzofi/funzochain into I…
sushantshah-dev Sep 22, 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
82 changes: 67 additions & 15 deletions GPoHC.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,44 @@
from gan import Gan
from imports import *
import gan

class GPoHC():
def __init__(self):
def __init__(self, node, name):
self.strenght = 50
self.model = Gan()
self.node = node
self.model = object()
self.generator = gan.Generator()
self.discriminator = gan.Descriminator()
self.new = True

def initialize(self):
if self.generator.new == True:
self.generator.train(self.node.chain)

if self.discriminator.new == True:
self.discriminator.train(self.node.chain)

def create_consensus(self, block, chain):
hash = block.calculate_hash()

SOURCE_BLOCKS = []
for validator_block in range(self.strenght):
if self.validator_online(chain[-self.strenght[validator_block]]):
for validator_block in range(min([self.strenght, len(chain)])):
if self.validator_online(chain[validator_block]):
SOURCE_BLOCKS.append(validator_block)

SOURCE_SEED = ""
for block in SOURCE_BLOCKS:
SOURCE_SEED.append(block.seed)

SEED_ROOT = ""
for root in self.collect_roots(SOURCE_BLOCKS):
SEED_ROOT = self.add_by_each_byte(SOURCE_SEED, root)
SEED_ROOT = self.collect_seed_root(SOURCE_SEED)

SUPER_SEED = self.generator.gen(SEED_ROOT)

score, scores = self.score_super_seed(SUPER_SEED)
block.validators = scores

SEED_ROOT_PROCESSED = []
for char in SEED_ROOT:
SEED_ROOT_PROCESSED.append([int(y) for y in list("".join(format(ord(x), 'b') for x in str(char)))])
SEED = rsa.encrypt(bytes(SUPER_SEED[:117]), self.node.private_key)

SUPER_SEED = self.model.generator_forward(SEED_ROOT_PROCESSED)
self.broadcast_super_seed(SUPER_SEED)
return True, SEED

def add_by_each_byte(self, a, b):
result = ""
Expand All @@ -35,6 +47,46 @@ def add_by_each_byte(self, a, b):

return result


def validator_online(self, block):
pass
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(block.creator)
sock.send(b"conn:ack")
if sock.recv(8) == b"conn:ack":
return True
return False

def roots_broadcast_handler(self, sock):
return list(sock.recv(128))

def collect_seed_root(self, source_seed):
roots = self.node.p2pInterface.broadcast([
b"seed:rot",
f'{len(source_seed):05d}'.encode(),
source_seed.encode()
], handler=self.roots_broadcast_handler)

out = [0]*128
for root in roots:
for byte in range(128):
out[byte] += root[byte]
out[byte] = out[byte] % 255

return out

def seed_score_broadcast_handler(self, sock):
score_len = int(sock.recv(2).decode())
score = (sock.getpeername(), float(sock.recv(score_len).decode()))
return score

def score_super_seed(self, super_seed):
scores = self.node.p2pInterface.broadcast([
b"seed:scr",
f'{len(super_seed):05d}'.encode(),
bytes(super_seed)
], handler=self.seed_score_broadcast_handler)

total_score = 0
for score in scores:
total_score += score[1]

return total_score, scores
124 changes: 124 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# Funzochain

Funzochain is a blockchain implementation and the proof of concept for our GPoHC Consensus Mechanism or the Generative Proof of History and Co-operation. We have developed GPoHC with a vision to make block creation and validation faster without compromise to decentralisation and security, and to make sure all nodes are equal participants regardless of processing power and other barriers.

---

## Creating a node

To create a node clone this repository and create a file named `run.py`

```python
from node import node
import socket
import rsa

#create an identity (Run Only Once)
with open("identity", "wb") as f:
f.write(rsa.newkeys(1024)[1])

#load an identity
with open('identity', mode='rb') as f:
identity = rsa.PrivateKey.load_pkcs1(f.read())


node = node(identity, (socket.gethostname(),80), "node-name")

if __name__ == "__main__":
node.run()
```

---

## Generative Proof Of History And Co-operation

### Block Structure

```python
{
“creator”: “0x00000.....”,
“data”: [...],
“timestamp”: 1652949456,
“seed”: “abcdef”,
“validators”: [...],
“previous_hash”: “...”
}
```

### Creation Of A New Block

Here is a hypothetical situation where node 0x007 wants to propose a new block to the blockchain.

##### Current Blockchain

```mermaid
graph TD;
Node1([Node 0x001])--Created-->B;
Node2([Node 0x002])--Created-->C;
Node3([Node 0x003])--Created-->D;
Node4([Node 0x004])--Created-->E;
Node5([Node 0x005])--Created-->F;
Node6([Node 0x006])--Created-->G;
Node7([Node 0x007])-.Wants To Create.->H[Block 7];

A--Seed-->Seed1(AAAA...);
B--Seed-->Seed2(BBBB...);
C--Seed-->Seed3(CCCC...);
D--Seed-->Seed4(DDDD...);
E--Seed-->Seed5(EEEE...);
F--Seed-->Seed6(FFFF...);
G--Seed-->Seed7(GGGG...);

A[Genesis]---B;
B[BlocK 1]---C;
C[Block 2]---D;
D[Block 3]---E;
E[Block 4]---F;
F[Block 5]---G;
G[Block 6]-.-H;
```

##### Network Situation

All Nodes Except 0x005 Are Online.



##### How The Node Proposes A New Block

1. The Node Looks Up The Last `x` Blocks In The Blockchain From The End.

2. If The Creator Of A Block Is Online, It is Added To A List Called `Source Blocks`.

Here:

```mermaid
graph TD;
A[Block 1]-->B[Block 2]-->C[Block 3]-->D[Block 4]-->F[Block 6]
```

3. Seeds Of All The Blocks In ‘Source Blocks’ Are Joined In Order As A String Called `Source Seed`.

Here: 'AAAABBBBCCCCDDDDFFFFGGGG'.

4. Node 0x007 Now Broadcasts The `Source Seed` To All The Creators Of The Blocks In `Source Blocks`. All The Nodes Will Likely Already Have The Same `Source Seed` And Will Have Encrypted It With Their Private Key As `Seed Root Segment`. If Both The Versions Of `Source Seed` Are Same The Node Will Respond With The `Seed Root Segment`.

5. Node 0x007 Now Takes All Values Of `Seed Root Segment` And Saves As `Seed Root` After Adding Each Character Individually Using:

```python
seed_root = []
for segment in seed_root_segments:
seed_root.extend([int(y) for y in list("".join(format(ord(x), 'b') for x in str(segment)))])
```

6. Node 0x007 Then Passes The Seed Root Array (Lenght 128 Bytes) Through It's GAN's Generator And Stores The Output As `Super Seed`.

7. Node 0x007 Then Encrypts The First 117 Bytes Using It's Private Key And Uses It As The `seed` Attribute For The Block

8. Node 0x007 Now Broadcasts The `Super Seed` To All The Validators Which Then Return A Score After Passing It Through Their GAN's Discriminator. Node 0x007 Then Sums Up All The Score.

9. However, Node 0x003 Has Already Created And Added A Block. Node 0x007 Then Polls All The Active Nodes For 0x003's Last Score, And Finds Out That It Had Gotten More Accumulative Score Than 0x003.

10. After This Node 0x007 Requests An Override On The Last Block (Timeframe Of 5 Seconds For Overriding). More Than 50% Nodes Agree And Update Their Blockchains.

Since Node 0x007 Has Now Become A Creator He Will Become A Validator For For The Next `x` Blocks (Only If Active), And Will Receive Validator Rewards Without Actually Creating A Block.
12 changes: 12 additions & 0 deletions Templates/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Host Node WebUI</title>
</head>
<body>

</body>
</html>
4 changes: 2 additions & 2 deletions block.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ def calculate_hash(self):

@property
def serialised(self):
return pickle.dumps(self.__dict__)
return pickle.dumps(self.__dict__).hex()

def deserialised(self, data):
block = self
block.__dict__ = pickle.loads(data)
block.__dict__ = pickle.loads(bytes.fromhex(data))
return block

class LogBlock(Block):
Expand Down
62 changes: 37 additions & 25 deletions blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
import json

class Blockchain(list):
def __init__(self, mainfile, p2pInterface):
def __init__(self, node, mainfile, p2pInterface):
self.chain = list()
self.index = dict()
self.node = node
self.mainfile = mainfile
self.p2pInterface = p2pInterface
self.load()
Expand All @@ -15,58 +16,69 @@ def __getitem__(self, key):

def append(self, item):
if isinstance(item, Block):
item.seed, winner = self.node.consensus.create_consensus(item, self)
if not winner:
raise Exception("Consensus Lost. Failed To Add Block.")
if item.hash in self.index:
raise ValueError("Block already exists")
self.index[item.calculate_hash()] = len(self.chain)
self.chain.append(item)
print(f"Added block {item.hash[:6]} to chain")
self.save()
block_data = item.serialised
self.p2pInterface.broadcast([
b"blck:new",
f'{len(block_data):05d}'.encode(),
block_data
block_data.encode()
])
else:
raise TypeError("Blockchain can only append blocks")

def save(self):
old_file = self.currfile
block_index = 0
for iter_ in range(len(self.chain)):
with open(self.currfile, "wb") as f:
print(self.currfile)
for item in self.chain[block_index:50]:
with open(self.currfile, "r") as f:
file_size = len(f.readlines())
for iter_ in range(int(len(self.chain)/50)+1):
with open(self.currfile, "w") as f:
for item in self.chain[block_index:(50-file_size)]:
f.write(item.serialised)
f.write("\n".encode())
f.write("\n")
if len(self.chain) > 50*(iter_+1):
f.write("\n\n".encode())
print(50*(iter_+1))
print((iter_+1)*50)
f.write("\n\n")
self.currfile = self.chain[(iter_+1)*50].calculate_hash()
f.write(self.currfile.encode())
self.load()
self.currfile = self.mainfile
f.write(self.currfile)
file_size = 0
if old_file != self.currfile:
self.load()

def load(self):
self.currfile = self.mainfile
self.index = dict()
while True:
try:
if os.path.exists(self.currfile):
print("Loading blockchain")
while True:
chain_lenght = 0
with open(self.currfile, "rb") as f:
with open(self.currfile, "r") as f:
for line in f.readlines():
if line != b"\n":
block = Block(self, "").deserialised(line)
if line != "\n":
print(line)
block = Block(self.node, "").deserialised(line)
print(block.__dict__)
self.index[block.hash] = chain_lenght
chain_lenght += 1
self.chain.append(block)
if f.readline()[-2] == f.readline()[-3] == b"\n":
print(f.readline[-1])
self.currfile = f.readline()[-1].decode()
else:
else:
break
print(f.readlines())
if len(f.readlines()) > 50:
self.currfile = f.readline()[-1]
break
except:
break
else:
return
else:
print("Started A New Chain")
open(self.currfile, "w")


def __setitem__(self, key, value):
Expand Down
Loading