Spaces:
Build error
Build error
| 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_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 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 bc_transactions(sender,recipient,amount): | |
| blockchain.new_transaction(f"{sender}",f"{recipient}",f"{amount}") | |
| message = "Transaction Added to Pool" | |
| return pd.DataFrame(blockchain.pending_transactions),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) > 20: | |
| 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.' | |
| else: | |
| response = f'Blockchain is not valid. {mes} at Index {ind}' | |
| return response | |
| 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 | |
| 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("""<h1><center>Blockchain Simulator<br><h3>(Transactions have no value)<br><h4>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") | |
| 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") | |
| 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) | |
| 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) |