import gradio as gr import pandas as pd import datetime import hashlib import json import os import requests from huggingface_hub import (create_repo,get_full_repo_name,upload_file,CommitOperationAdd,HfApi) main_chain='https://huggingface.co/datasets/Omnibus/blockchain-sim/raw/main/' main_balance='https://huggingface.co/datasets/Omnibus/blockchain-sim/raw/main/balance/' main_nodes='https://huggingface.co/datasets/Omnibus/blockchain-sim/raw/main/node_file1.json' main_pending='https://huggingface.co/datasets/Omnibus/blockchain-sim/raw/main/pending1.json' token_self = os.environ['HF_TOKEN'] pa=os.environ['PASS'] repo_d='Omnibus/static-bin' chain_d='chain1.json' node_file='node_file.json' space='blockchain-simulator-dev1' api = HfApi(token=token_self) class Balance_sheet: def create_block(self, proof, previous_hash,chain_r=None,chain_n=None,balance=None): if chain_r=="" or chain_r==None: chain_r=f"{main_chain.split('datasets/',1)[1].split('/raw',1)[0]}" if chain_n=="" or chain_n==None: chain_n=chain_d block = {'index': len(self.chain) + 1, 'timestamp': str(datetime.datetime.now()), 'transactions': self.pending_transactions, #'balance':self.balance 'proof': proof, 'previous_hash': previous_hash} if self.block_valid(block) == True: self.pending_transactions = [] self.chain.append(block) json_object = json.dumps(self.chain, indent=4) with open("tmp.json", "w") as outfile: outfile.write(json_object) try: api.upload_file( path_or_fileobj="tmp.json", path_in_repo=chain_n, repo_id=chain_r, token=token_self, repo_type="dataset", ) os.remove("tmp.json") except Exception as e: print(e) pass return block else: block = {"Not Valid"} print("not Valid") return block def print_previous_block(self): return self.chain[-1] def new_transaction(self, sender, recipient, amount): transaction = { 'sender': sender, 'recipient': recipient, 'amount': amount } self.pending_transactions.append(transaction) class Blockchain: def __init__(self,load=None,create=None): self.pending_transactions = [] if load == None or load=="": self.chain = [] self.create_block(proof=1, previous_hash='0',chain_n=create) elif load != None and load !="": #r = requests.get(load) lod = json.loads(load) self.chain = lod def reset(self,create=None): self.chain = [] self.pending_transactions = [] self.create_block(proof=1, previous_hash='0',chain_n=create) def create_block(self, proof, previous_hash,chain_r=None,chain_n=None): if chain_r=="" or chain_r==None: chain_r=f"{main_chain.split('datasets/',1)[1].split('/raw',1)[0]}" if chain_n=="" or chain_n==None: chain_n=chain_d block = {'index': len(self.chain) + 1, 'timestamp': str(datetime.datetime.now()), 'transactions': self.pending_transactions, 'proof': proof, 'previous_hash': previous_hash} if self.block_valid(block) == True: self.pending_transactions = [] self.chain.append(block) json_object = json.dumps(self.chain, indent=4) with open("tmp.json", "w") as outfile: outfile.write(json_object) try: api.upload_file( path_or_fileobj="tmp.json", path_in_repo=chain_n, repo_id=chain_r, token=token_self, repo_type="dataset", ) os.remove("tmp.json") except Exception as e: print(e) pass return block else: block = {"Not Valid"} print("not Valid") return block def print_previous_block(self): return self.chain[-1] def new_transaction(self, sender, recipient, amount): transaction = { 'sender': sender, 'recipient': recipient, 'amount': amount } self.pending_transactions.append(transaction) def proof_of_work(self, previous_proof): new_proof = 1 check_proof = False while check_proof is False: hash_operation = hashlib.sha256( str(new_proof**2 - previous_proof**2).encode()).hexdigest() if hash_operation[:5] == '00000': check_proof = True else: new_proof += 1 return new_proof def hash(self, block): encoded_block = json.dumps(block, sort_keys=True).encode() return hashlib.sha256(encoded_block).hexdigest() def block_valid(self, block): print (block) #prev_block=len(self.chain) if len(self.chain) > 0: prev_block = len(self.chain)-1 previous_block = self.chain[prev_block] print (previous_block) out=True ind=None mes=None if block['previous_hash'] != self.hash(previous_block): out=False #ind=block_index mes='Hash' previous_proof = previous_block['proof'] proof = block['proof'] hash_operation = hashlib.sha256( str(proof**2 - previous_proof**2).encode()).hexdigest() if hash_operation[:5] != '00000': out=False #ind=block_index+1 mes='Proof' previous_block = block else: out = True return out def chain_valid(self, chain): previous_block = chain[0] block_index = 1 out=True ind=None mes=None while block_index < len(chain): block = chain[block_index] if block['previous_hash'] != self.hash(previous_block): out=False ind=block_index mes='Hash' break previous_proof = previous_block['proof'] proof = block['proof'] hash_operation = hashlib.sha256( str(proof**2 - previous_proof**2).encode()).hexdigest() if hash_operation[:5] != '00000': out=False ind=block_index+1 mes='Proof' break previous_block = block block_index += 1 return out, ind, mes #def check_balance(sender,amount): def bc_transactions(sender,recipient,amount): mes, out = issue_tokens(sender,recipient,amount) if out == True: blockchain.new_transaction(f"{sender}",f"{recipient}",f"{amount}") message = "Transaction Added to Pool" data = pd.DataFrame(blockchain.pending_transactions) if out == False: message = mes data = None return data,message,None,None,None def create_chain(create=None): global blockchain blockchain = Blockchain(create=create) #blockchain.reset(create=create) return "New Chain Created",None,display_chain() def display_chain(): response = {'chain': blockchain.chain, 'length': len(blockchain.chain)} return response def mine_block(chain_r=None,chain_n=None): previous_block = blockchain.print_previous_block() previous_proof = previous_block['proof'] proof = blockchain.proof_of_work(previous_proof) previous_hash = blockchain.hash(previous_block) block = blockchain.create_block(proof, previous_hash,chain_r,chain_n) response = {'message': 'A block is MINED', 'index': block['index'], 'timestamp': block['timestamp'], 'proof': block['proof'], 'previous_hash': block['previous_hash']} message = "A block is MINED" show_chain = display_chain() if len(blockchain.chain) > 1000: blockchain.reset() response = None show_chain=display_chain() message = "New Chain Created at Max 20 Blocks" return response, show_chain,pd.DataFrame(blockchain.pending_transactions), message def sort_valid(): #nodes=main_nodes.replace("'","") f = requests.get(f'{main_nodes}') t = open('tmp.json','w') t.write(f.text) t.close() f = open('tmp.json','r') f = f.read() j = json.loads(f) #j=f.json() print (len(j)) cnt=0 valid_chains=[] not_valid=[] response='' while cnt < len(j): try: r = requests.get(f'{j[cnt]["url"]}') g = open('tmp1.json','w') g.write(r.text) g.close() gg = open('tmp1.json','r') ggg=gg.read() print (ggg) leng=len(json.loads(ggg)) print(f'Blockchain {cnt}: Length {leng} ') valid,ind,mes = blockchain.chain_valid(json.loads(ggg)) except Exception: valid=False leng="No Data" if valid: valid_chains.append({"Chain": cnt, "Length": leng}) response = f'{response} Valid: {cnt}' else: not_valid.append({"Chain": cnt, "Length": leng}) response = f'{response} Invalid:{cnt}' per = ((len(valid_chains)+1)/(len(j)+1))*100 cnt+=1 response=f'{int(per)}%-{response}' print (f'Valid: {valid_chains}') print (f'Not Valid: {not_valid}') #p = json.loads(str(valid_chains)) p = valid_chains cnt2=0 bot=0 out=[] while cnt2 < len(p): if p[cnt2]['Length'] > bot: bot = p[cnt2]['Length'] out = [cnt2,bot] else: pass cnt2+=1 print (out) return response def valid(): valid,ind,mes = blockchain.chain_valid(blockchain.chain) if valid: response = 'The Blockchain is valid.' z=True else: response = f'Blockchain is not valid. {mes} at Index {ind}' z=False return response,z def get_chain(repo_name=None,chain_name=None,token=None): if repo_name == "": repo_name = repo_d if chain_name=="": chain_name = chain_d #src = f"https://huggingface.co/spaces/{repo_name}/raw/main/{chain_name}" #ff = open('chain1.json','r') #src = ff.read() #src = json.loads(ff) try: r = requests.get(f'{main_chain}{chain_name}') #create_chain(load=r.text) global blockchain blockchain = Blockchain(load=r.text) #return "New Chain Created",display_chain() #create_chain(src) response = {'chain': blockchain.chain, 'length': len(blockchain.chain)} message = f"Blockchain loaded from: {main_chain}{chain_name}" return response,message except: message = f"Error loading from: {src}" return ["Error Loading Chain"],message def checkp(inp): if inp == pa: return gr.update(visible=False), gr.update(visible=True) elif inp != pa: return gr.update(visible=True), gr.update(visible=False) def add_node(this_space,repo,space,chain_file): #print(f"{api.whoami(['name'])}") #repo = f'omnibus/{space}' is_valid='True' r = requests.get(f'{main_nodes}') try: lod = json.loads(r.text) except: lod=[] pass block = {'index': len(lod) + 1, 'timestamp': str(datetime.datetime.now()), 'url': f'https://huggingface.co/datasets/{repo}/{space}/raw/main/{chain_file}', 'valid': f'{is_valid}'} lod.append(block) json_object = json.dumps(lod, indent=4) with open("tmp1.json", "w") as outfile: outfile.write(json_object) try: api.upload_file( path_or_fileobj="tmp1.json", path_in_repo=main_nodes.split('main/',1)[1], repo_id=main_nodes.split('datasets/',1)[1].split('/raw',1)[0], token=token_self, repo_type="dataset", ) os.remove("tmp1.json") except Exception as e: pass start_tokens = 10000000 source="Main" def issue_tokens(send,rec,amount): #print(f"{api.whoami(['name'])}") #repo = f'omnibus/{space}' #is_valid='True' try: _,z=valid() if z == True: mes = None try: r = requests.get(f'{main_balance}{send}.json') lod = json.loads(r.text) p=True except: lod=[] p=False mes = "Sender has no wallet" pass if p==True: balance = lod[-1]["balance"] print (balance) balance =int(balance)-int(amount) if balance >=0: block = {'index': len(lod) + 1, 'timestamp': str(datetime.datetime.now()), 'sender': f'{send}', 'recipient':f'{rec}', 'amount': f'{amount}', 'balance': f'{balance}' } lod.append(block) json_object = json.dumps(lod, indent=4) with open("tmp1.json", "w") as outfile: outfile.write(json_object) try: api.upload_file( path_or_fileobj="tmp1.json", path_in_repo=f'{main_balance.split("main/",1)[1]}/{send}.json', repo_id=main_balance.split('datasets/',1)[1].split('/raw',1)[0], token=token_self, repo_type="dataset", ) os.remove("tmp1.json") except Exception as e: mes=e pass try: r = requests.get(f'{main_balance}{rec}.json') lod = json.loads(r.text) balance = lod[-1]["balance"] except: lod=[] balance=0 pass print (balance) balance =int(balance)+int(amount) block = {'index': len(lod) + 1, 'timestamp': str(datetime.datetime.now()), 'sender': f'{send}', 'recipient':f'{rec}', 'amount': f'{amount}', 'balance': f'{balance}'} lod.append(block) json_object = json.dumps(lod, indent=4) with open("tmp1.json", "w") as outfile: outfile.write(json_object) try: api.upload_file( path_or_fileobj="tmp1.json", path_in_repo=f'{main_balance.split("main/",1)[1]}/{rec}.json', repo_id=main_balance.split('datasets/',1)[1].split('/raw',1)[0], token=token_self, repo_type="dataset", ) os.remove("tmp1.json") except Exception as e: mes = e pass if mes == None: mes = f'{amount} sent from {send} to {rec}' if balance < 0: mes ="Not enough tokens" p = False if z==False: mes = "Invalid Blockchain" p=False except Exception: mes = "Blockchain not loaded?" p=False return mes,p #api = HfApi(token=token) repo = main_balance.split('datasets/',1)[1].split('/raw',1)[0].split('/',1)[0] name = main_balance.split('datasets/',1)[1].split('/raw',1)[0].split('/',1)[1] f_ist = (api.list_repo_files(repo_id=f'{repo}/{name}', repo_type="dataset")) send_list =[] for i,ea in enumerate(f_ist): if "balance/" in ea: try: send_list.append(ea.split("/",1)[1].split(".",1)[0]) except Exception: pass with gr.Blocks() as bc: with gr.Row(visible=True) as invalid: pass_box = gr.Textbox() pass_btn = gr.Button() with gr.Box(visible=False) as valida: gr.Markdown("""

Blockchain Simulator

(Transactions have no value)

Chain will reset at 20 blocks""") blockchain = gr.State() with gr.Row(): with gr.Column(): with gr.Accordion(label="Load",open=False): with gr.Row(): chain_repo=gr.Textbox(label="repo/name") chain_n=gr.Textbox(label="Chain file") with gr.Row(): in_chain_btn=gr.Button("Load Chain") create_bc = gr.Button("Create New Blockchain") #send=gr.Textbox(label="Sender") send = gr.Dropdown(label="Sender", choices=[f for f in send_list], value = "Bank") rec=gr.Textbox(label="Recipient") am=gr.Textbox(label="Amount") send_trans=gr.Button("Post Transaction") mine_b = gr.Button("Mine Block") check = gr.Button("Check Chain") check_all = gr.Button("Check All") with gr.Column(): block_text = gr.Textbox() trans_data = gr.Dataframe() json_out = gr.JSON() chain_json = gr.JSON() with gr.Accordion("Nodes", open=False): with gr.Row(): this_space=gr.Textbox(label="This Repo/Space") with gr.Row(): node_repo=gr.Textbox(label="Node Repo") node_space=gr.Textbox(label="Node Space") node_file=gr.Textbox(label="Node File") node_add=gr.Button("Add Node") with gr.Accordion("Tokens", open=False): issue_btn=gr.Button() out_box_bool=gr.Textbox() issue_btn.click(issue_tokens,[send,rec,am],[block_text,out_box_bool]) node_add.click(add_node,[this_space,node_repo,node_space,node_file],block_text) pass_btn.click(checkp,pass_box,[invalid,valida]) in_chain_btn.click(get_chain,[chain_repo,chain_n],[chain_json,block_text]) create_bc.click(create_chain,[chain_n],[block_text,json_out,chain_json]) check.click(valid,None,[block_text,out_box_bool]) check_all.click(sort_valid,None,block_text) send_trans.click(bc_transactions,[send,rec,am],[trans_data,block_text,send,rec,am]) mine_b.click(mine_block,[chain_repo,chain_n],[json_out,chain_json,trans_data,block_text]) bc.launch(enable_queue=False)