Spaces:
Runtime error
Runtime 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_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("""<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") | |
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) | |