From 65165fc7a16220eb5b5b1c4f0e618d03908c3e76 Mon Sep 17 00:00:00 2001 From: Omar Metwally Date: Fri, 2 Feb 2018 21:43:11 -0800 Subject: [PATCH] simbel v. 1.0 release --- README.md | 1 + gui.py | 495 ++---------------------------------- gui.sh | 12 +- images/clock2.gif | Bin 0 -> 30217 bytes install.sh | 5 +- load_mainnet.sh | 3 +- load_simbel.sh | 11 +- log_nodeInfo.sh | 2 +- simbel/nfo/eth_addresses.ds | 1 + simbel/simbel.py | 8 +- snu.sh | 18 +- 11 files changed, 54 insertions(+), 502 deletions(-) create mode 100644 images/clock2.gif diff --git a/README.md b/README.md index d9b9737..989e022 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Simbel is an Ethereum operating system for knowledge creation and sharing ## Universal Consensus Time Simbel sets network time by blockchain consensus. +![Simbel](https://s3-us-west-1.amazonaws.com/ddash/simbel.png) ## Manifesto The Manifesto contract allows participants to create a manifesto through a transparent voting process. Anyone can submit and vote on proposals. To interface with your own custom voting contracts (on any Ethereum network), simply replace the default Manifesto.sol address with your contract's address. diff --git a/gui.py b/gui.py index a5c4394..bae4a7b 100644 --- a/gui.py +++ b/gui.py @@ -21,9 +21,6 @@ sys.path.insert(0, os.path.join(os.getcwd(),'simbel')) from bcinterface import * -from fsinterface import * -from nfointerface import * -from manifestointerface import * from simbel import * from getpass import getpass import time, atexit @@ -34,18 +31,13 @@ LISTEN=False simbel_contract_address="0x1622da6805c7b5e5e38f7b88b5e533938ff800da" -#recordmanager_contract_address="0xcc109bf72338909ead31a5bf46d8d8fa455ff09b" -mainnet_nfo_address = "0x3100047369b54c34042b9dc138c02a0567d90a7a" -simbel_nfo_address = "0x38a779dd481b5f812b76b039cb2077fb124677a7" # available Ethereum networks NETWORK_OPTIONS = [ "Simbel", "Main Ethereum network" ] # list of available contracts to interface with -CONTRACT_OPTIONS = [ "Manifesto", "NFO Coin"] +CONTRACT_OPTIONS = [ ] # list of Ethereum accounts, popuated at runtime ACCOUNT_OPTIONS = [] -# list of proposals from the Manifesto.sol contract -PROPOSALS = [] # logo displayed in upper left corner intro = r"""simbel""" @@ -74,67 +66,11 @@ def __init__(self, master): # @variable self.fsi is initialized to a @class FSInterface object, # which interfaces with the local file system self.fsi = None - # @variable self.nfointerface is initialized to a @class NFOInterface object - # which interfaces with the NFO Coin Ethereum contract pythonically via web3 - self.nfointerface = None - # remember the last Ethereum account password entered self.ethereum_acc_pass = None self.ready = False # in the Manifesto.sol context, used to tally votes self.last_selected_proposalID = None - ''' - @method handle_send_nfocoin [NFO Coin Context] - Transfer NFO Coin within a network (Intra-Network) or between - two networks (Inter-Network). - Called when the "Send" button is clicked - ''' - def handle_send_nfocoin(self): - if not hasattr(self,'nfointerface'): - print("No nfointerface object.") - return - print("Attempting to unlock account...") - self.nfointerface.unlock_account(self.ethereum_acc_pass) - - send_transaction_type = send_nfocoin_choice.get() - if not send_transaction_type: - print("No transaction type selected. Please select Intra-Network or Intra-Network NFO Coin transfer") - return - send_nfocoin_amount = int(send_nfocoin_amount_entry.get()) - if not send_nfocoin_amount: - print("No NFO Coin amount specified.") - return - send_nfocoin_address = str(send_nfocoin_address_entry.get()) - if not send_nfocoin_address: - print("No NFO Coin recipient address specified.") - return - timestamp=int(str(time.time()).split('.')[0]) - # transfer value on the same network - if send_transaction_type == "intra": - print("Initiating Intra-Network NFO Coin transfer...") - print("Recipient: ",send_nfocoin_address) - print("NFO Coin amount: ",send_nfocoin_amount) - # transfer NFO Coin and return transaction hash - return self.nfointerface.transfer_token(send_nfocoin_address, send_nfocoin_amount) - - # transfer value between 2 different networks - if send_transaction_type == "inter": - print("Initiating Inter-Network NFO Coin transfer...") - print("Recipient: ",send_nfocoin_address) - print("NFO Coin amount: ",send_nfocoin_amount) - # generate hash - print("make_hash_parameters:") - print("From: ",self.nfointerface.tx['from']) - print("timestamp: ", timestamp) - send_nfocoin_tx_hash = self.nfointerface.contract.call().make_hash(int(0), send_nfocoin_amount, str(self.nfointerface.tx['from']), send_nfocoin_address, int(1000), timestamp) - # transfer NFO Coin and create record of transfer on blockchain - self.nfointerface.new_nfo_transaction(0, send_nfocoin_amount, self.nfointerface.tx['from'], send_nfocoin_address, send_nfocoin_tx_hash) - # write transaction to local file system - self.nfointerface.write_nfo_transaction_to_file(send_nfocoin_amount, send_nfocoin_address, send_nfocoin_tx_hash) - # transfer NFO Coin:w and return transaction hash - #return self.nfointerface.transfer_token(send_nfocoin_address, send_nfocoin_amount) - return send_nfocoin_tx_hash - ''' @method handle_selected_contract Place checkmark next to contract name when it's seleced in menu bar @@ -148,45 +84,6 @@ def handle_selected_contract(self, mn, index): mn.entryconfigure(i, label=v) mn.entryconfigure(index, label=u'\u2713 '+CONTRACT_OPTIONS[index]) - ''' - @method handle_tally [NFO Coin Context] - Called when the tally votes button is clicked - ''' - def handle_tally(self): - if not hasattr(self, 'last_selected_proposalID'): - print("No proposal selected.") - return - - self.manifestointerface.unlock_account(self.ethereum_acc_pass) - self.manifestointerface.tally_votes(self.last_selected_proposalID) - - ''' - @method handle_buy_nfocoin [NFO Coin Context] - Submits transaction to purchase NFO Coin against Ether - print('there are '+str(num_entities)+' entities') - ''' - def handle_buy_nfocoin(self): - eth_amt_in_wei = buy_nfocoin_entry.get() - if not eth_amt_in_wei: - return - print("Attempting to buy "+str(eth_amt_in_wei)+" wei worth of NFO Coin") - - self.nfointerface.unlock_account(self.ethereum_acc_pass) - self.nfointerface.buy_tokens(eth_amt_in_wei) - - ''' - @method handle_sell_nfocoin [NFO Coin Context] - Submits transaction to sell NFO Coin - ''' - def handle_sell_nfocoin(self): - nfocoin_amt = sell_nfocoin_entry.get() - if not nfocoin_amt: - print("Please specify amount of NFO Coin to sell.") - return - print("Attempting to sell "+str(nfocoin_amt)+" NFO Coin.") - self.nfointerface.unlock_account(self.ethereum_acc_pass) - self.nfointerface.sell_tokens(nfocoin_amt) - ''' @method handle_set_gas [NFO Coin Context and Manifesto Context] Changes the gas amount set with all transactions @@ -200,42 +97,6 @@ def handle_set_gas(self): print('setting gas amount to '+str(new_gas)) self.bci.set_gas(new_gas) - ''' - @method handle_vote [Manifesto Context] - Called when a user votes yes/no on the selected proposal - ''' - def handle_vote(self): - proposalID = vote_proposalID_entry.get() - if vote_choice.get() == "yes": vote = "yes" - elif vote_choice.get() == "no": vote = "no" - else: vote = None - - if vote: - index = PROPOSALS.index(proposal_listbox.get(ACTIVE)) - - proposalID = index - print("proposalID: ",proposalID) - print("vote: ",vote) - self.manifestointerface.unlock_account(self.ethereum_acc_pass) - - if vote=='yes': - self.manifestointerface.vote(int(proposalID),True) - if vote=='no': - self.manifestointerface.vote(int(proposalID),False) - - ''' - @method handle_new_proposal [Manifesto Context] - Called when the "Submit Proposal" button is clicked to create new proposal - ''' - def handle_new_proposal(self): - description = new_proposal_text.get(1.0,END).strip() - print("New Proposal: ",description) - if "Enter a new proposal" in description: - return - - self.manifestointerface.unlock_account(self.ethereum_acc_pass) - self.manifestointerface.new_proposal(description) - ''' @class BCInterface @method handle_new_account Interfaces with tkinter "New Account" button @@ -291,10 +152,6 @@ def _function(): # place checkmark next to selected Ethereum address from Account menu bar accountmenu.entryconfigure(index+2, label=u'\u2713 '+ACCOUNT_OPTIONS[index]) self.bci.set_account(index) - if hasattr(self, 'nfointerface'): - self.nfointerface.set_account(index) - if hasattr(self, 'manifestointerface'): - self.manifestointerface.set_account(index) return _function @@ -324,9 +181,7 @@ def launch(self): self.bci = BCInterface(mainnet=False) self.fsi = FSInterface() - self.nfointerface = NFOInterface(mainnet=False) self.contract_address=simbel_contract_address - #self.nfointerface.load_contract(mainnet=False,contract_name='nfocoin',contract_address=simbel_nfo_address) simbel.load_interface() @@ -343,131 +198,17 @@ def launch(self): self.bci = BCInterface(mainnet=True) self.fsi = FSInterface() - self.nfointerface = NFOInterface(mainnet=True) self.contract_address=simbel_contract_address - #self.nfointerface.load_contract(mainnet=True, contract_name="nfocoin", contract_address=mainnet_nfo_address) messagebox.showinfo("Success", "You are connected to "+self.network+". Select a contract from the top menu bar.") current_network_label.config(text="You are connected to "+self.network) network_label.grid_remove() network_option.grid_remove() launch_button.grid_remove() - - ''' - @method handle_proposal_click [Manifesto Context] - Display description of the selected proposal - Called when a proposal is selected - ''' - def handle_proposal_click(self, event): - widget = event.widget - selection = widget.curselection() - value = widget.get(selection[0]) - row = proposalID = selection[0] - self.last_selected_proposalID = int(row) - - text = "Proposal voting period: 60 minutes.\nNumber of votes needed to pass: 10.\n\n" - p = twinpeaks.manifestointerface.get_proposal_by_row(row) - text+="Proposal ID: "+str(row)+"\n" - text+="Proposal description: "+p[0].strip()+"\n" - text+="Current time: "+str(time.time()).split('.')[0] +"\n" - - if time.time() > p[1]: - text+="Status: Expired\n" - else: - text+="Status: Voting period open\n" - - text+="Voting deadline: "+str(p[1])+"\n" - #text+="Executed: "+str(p[2])+"\n" - text+="Passed: "+str(p[3])+"\n" - text+="Number of votes: "+str(p[4])+"\n\n" - - new_proposal_label.configure(text=text) - - ''' - @method manifesto_context - Configures the GUI for the Manifesto Context to allow user to - interface with the Manifesto.sol contract - ''' - def manifesto_context(self): - if not self.ready: - return - self.context = "manifesto" - - if not self.ethereum_acc_pass: - answer = simpledialog.askstring("Simbel","Enter your Ethereum account password: ") - self.ethereum_acc_pass = answer - - if not hasattr(self, 'manifestointerface'): - self.manifestointerface = ManifestoInterface(mainnet=False) - self.manifestointerface.load_contract(mainnet=False) - root.geometry('{}x{}'.format(950, 800)) - - manifesto_address_label.grid() - manifesto_address_entry.grid() - proposal_listbox.grid() - new_proposal_label.grid() - new_proposal_text.grid() - new_proposal_button.grid() - vote_button.grid() - current_network_label.grid() - current_network_label.config(text="Your are connected to "+self.network) gas_label.grid() - gas_entry.grid() set_gas_button.grid() - tally_button.grid() - - vote_yes_radio.grid() - vote_no_radio.grid() - - top_frame.grid() - manifesto_frame.grid() - network_frame.grid() - - ''' - @method nfocoin_context - Configures the GUI for the NFO Coin Context to allow user to - interface with the nfocoin.sol contract - ''' - def nfocoin_context(self): - if not self.ready: - return - self.context="nfocoin" - root.geometry('{}x{}'.format(800, 750)) - address_label.grid() - address_entry.grid() - balance_label.grid() - nfocoin_balance_label.grid() - buy_nfocoin_label.grid() - buy_nfocoin_entry.grid() - sell_nfocoin_label.grid() - sell_nfocoin_entry.grid() - sell_nfocoin_button.grid() - send_nfocoin_label.grid() - send_nfocoin_amount_entry.grid() - send_nfocoin_button.grid() - intranet_nfocoin_radio.grid() - internet_nfocoin_radio.grid() - gas_label.grid() gas_entry.grid() - account_label.grid() - new_account_button.grid() - unlock_account_button.grid() - - top_frame.grid() - center_frame.grid() - transaction_frame.grid() - network_frame.grid() - - current_network_label.grid() - current_network_label.config(text="Your are connected to "+self.network) - gas_label.grid() - gas_entry.grid() - set_gas_button.grid() - buy_nfocoin_button.grid() - if not self.ethereum_acc_pass: - answer = simpledialog.askstring("Simbel","Enter your Ethereum account password: ") - self.ethereum_acc_pass = answer ''' @method clear_screen @@ -512,7 +253,6 @@ def clear_screen(self): network_label.grid_remove() network_option.grid_remove() launch_button.grid_remove() - manifesto_frame.grid_remove() # clear frames top_frame.grid_remove() @@ -531,76 +271,20 @@ def clock(self): dt = datetime.datetime.now() twinpeaks.handle_show_accounts() - if hasattr(self,'manifestointerface'): - if len(self.manifestointerface.eth_accounts)==0: - address_entry.delete(0, END) - address_entry.insert(0, "No Ethereum account found.") - balance_label.configure(text="Balance: 0 Ether") - - answer = messagebox.askyesno("Simbel","I don't see any Ethereum accounts. Would you like to create one?") - if answer: - answer = simpledialog.askstring("Simbel","Choose a password: ") - answer2 = simpledialog.askstring("Simbel","Enter your password again: ") - if answer == answer2: - # create new Ethereum account - self.manifestointerface.web3.personal.newAccount(answer) - self.ethereum_acc_pass=answer - - if not self.manifestointerface.is_valid_contract_address(manifesto_address_entry.get()): - manifesto_address_entry.delete(0,END) - manifesto_address_entry.insert(0, simbel_manifesto_address) - - if self.manifestointerface.last_contract_address != manifesto_address_entry.get(): - proposal_listbox.delete(0, END) - new_proposal_label.configure(text="") - PROPOSALS.clear() - self.manifestointerface.last_contract_address = self.manifestointerface.tx['to'] - num_proposals = self.manifestointerface.get_proposal_count() - text = "" - text+="Number of proposals: "+str(num_proposals)+"\n\n" - i = 0 - while i < num_proposals: - p = self.manifestointerface.get_proposal_by_row(i) - text+="Proposal ID: "+str(i)+"\n" - text+="Proposal description: "+p[0]+"\n" - text+="Voting deadline: "+str(p[1])+"\n" - text+="Executed: "+str(p[2])+"\n" - text+="Passed: "+str(p[3])+"\n" - text+="Number of votes: "+str(p[4])+"\n\n" - - if p[0] not in PROPOSALS: - proposal_listbox.insert('end', p[0]) - PROPOSALS.append(p[0]) + if self.bci: - i+=1 + if len(self.bci.eth_accounts) >0: + address_entry.delete(0,END) + address_entry.insert(0,self.bci.eth_accounts[self.bci.account_index]) if not gas_entry.get(): - gas_entry.delete(0,END) - gas_entry.insert(0,"4000000") + if self.network == "simbel": + gas_entry.insert(0,"4000000") + elif self.network == "mainnet": + gas_entry.insert(0,"70000") if gas_entry.get(): - self.manifestointerface.set_gas(int(gas_entry.get())) - - self.manifestointerface.load_contract(contract_name='manifesto', contract_address=self.manifestointerface.is_valid_contract_address(manifesto_address_entry.get().strip()) or simbel_manifesto_address,mainnet=False) - - if hasattr(self,'nfointerface'): - #if self.bci: - #balance_label.configure(text="Ether Balance: "+str(self.bci.get_balance())) - #nfocoin_balance_label.configure(text="NFO Coin Balance: "+str(self.nfointerface.my_token_balance())) - - if self.nfointerface: - if len(self.nfointerface.eth_accounts) >0: - address_entry.delete(0,END) - address_entry.insert(0,self.nfointerface.eth_accounts[self.nfointerface.account_index]) - - if not gas_entry.get(): - if self.network == "simbel": - gas_entry.insert(0,"4000000") - elif self.network == "mainnet": - gas_entry.insert(0,"70000") - - if gas_entry.get(): - self.nfointerface.set_gas(int(gas_entry.get())) + self.bci.set_gas(int(gas_entry.get())) # BOOKMARK try: @@ -647,26 +331,12 @@ def clock(self): self.master.after(1000,self.clock) -def Manifesto(): - if twinpeaks.network != "simbel": - messagebox.showinfo("Error", "The Manifesto.sol contract is only available on the Simbel network, not the Ethereum main net.") - return - - twinpeaks.clear_screen() - twinpeaks.manifesto_context() - twinpeaks.handle_selected_contract(contractmenu, 0) - -def NFOCoin(): - twinpeaks.clear_screen() - twinpeaks.nfocoin_context() - twinpeaks.handle_selected_contract(contractmenu, 1) - def About(): text = "Simbel\nInitial work: Omar Metwally\nomar.metwally@gmail.com\n\nhttps://github.com/osmode/simbel" messagebox.showinfo("About Simbel", text) root = Tk() -root.geometry('{}x{}'.format(500, 600)) +root.geometry('{}x{}'.format(500, 700)) twinpeaks = TwinPeaks(root) menubar = Menu(root) @@ -674,13 +344,8 @@ def About(): root.grid_rowconfigure(1, weight=1) root.grid_columnconfigure(0, weight=1) - # Create menu bars at the top of the screen contractmenu = Menu(menubar) -contractmenu.add_command(label=str(CONTRACT_OPTIONS[0]), command=Manifesto ) - -contractmenu.add_command(label=CONTRACT_OPTIONS[1], command=NFOCoin) -contractmenu.add_separator() menubar.add_cascade(label="Contract", menu=contractmenu) accountmenu = Menu(menubar) @@ -714,23 +379,28 @@ def update(ind): root.after(100,update,ind) def on_close(): - process=subprocess.Popen("tmux kill-session -t geth".split()) - print("Quitting Simbel and killing geth...") + process=subprocess.Popen("tmux kill-session -tgeth".split()) + print("Quitting Simbel and killinggeth...") #process=subprocess.Popen("tmux kill-session -t ipfs".split()) twinpeaks.master.quit() print("Done.") +gif_path = os.getcwd()+'/images/ss.gif' +frames = [PhotoImage(file=gif_path,format="gif -index %i" %(i)) for i in range(36)] +gif_label = Label(root) #, image=frames[0]) -manifesto_frame = Frame(root) -manifesto_frame.grid(row=1,padx=(100,10), sticky=NW) -manifesto_frame.grid_remove() +''' +bg_gif_path = os.getcwd()+'/images/bg.gif' +bg_image = PhotoImage(file=bg_gif_path) +bg_label = Label(root, image=bg_image) +bg_label.place(x=0,y=0,relwidth=1,relheight=1) +''' top_frame = Frame(root, width=1000, height=150, relief="sunken") top_frame.grid(row=0, sticky="sew", padx=(50,10), pady=(50,10)) center_frame = Frame(root) center_frame.grid(row=1,sticky="new", padx=(50,10) ) -#center_frame.grid_remove() transaction_frame = Frame(root, width=1000, height=100,padx=40, pady=20, relief="sunken", borderwidth=2) transaction_frame.grid(row=2,sticky="new", padx=(50,50), pady=(50,50)) transaction_frame.grid_remove() @@ -759,51 +429,7 @@ def on_close(): nfocoin_balance_label.grid(row=4, column=0, sticky="w",pady=10) nfocoin_balance_label.grid_remove() -## transaction fraome -buy_nfocoin_label = Label(transaction_frame,text="Buy NFO Coin with this amount of Ether in wei (1 wei = 1e-18 Ether): ") -buy_nfocoin_label.grid(row=5,column=0, sticky=W) -buy_nfocoin_label.grid_remove() -buy_nfocoin_entry = Entry(transaction_frame) -buy_nfocoin_entry.grid(row=6, column=0) -buy_nfocoin_entry.config(width=50) -buy_nfocoin_entry.grid_remove() -buy_nfocoin_button = Button(transaction_frame, text="Buy",command=twinpeaks.handle_buy_nfocoin) -buy_nfocoin_button.grid(row=6,column=1,sticky="w") -buy_nfocoin_button.grid_remove() - -sell_nfocoin_label = Label(transaction_frame,text="Sell this amount of NFO Coin (1000 NFO Coin = 1 Ether):") -sell_nfocoin_label.grid(row=7,column=0, pady=20, sticky=W) -sell_nfocoin_label.grid_remove() -sell_nfocoin_entry = Entry(transaction_frame) -sell_nfocoin_entry.grid(row=8, column=0) -sell_nfocoin_entry.config(width=50) -sell_nfocoin_entry.grid_remove() -sell_nfocoin_button = Button(transaction_frame, text="Sell", command=twinpeaks.handle_sell_nfocoin) -sell_nfocoin_button.grid(row=8,column=1,sticky="w") -sell_nfocoin_button.grid_remove() - -send_nfocoin_label = Label(transaction_frame,text="Send NFO Coin", pady=20) -send_nfocoin_label.grid(row=9, column=0, sticky=W) -send_nfocoin_amount_entry = Entry(transaction_frame) -send_nfocoin_amount_entry.grid(row=10, column=0) -send_nfocoin_amount_entry.config(width=50) -send_nfocoin_address_entry = Entry(transaction_frame) -send_nfocoin_address_entry.grid(row=11,column=0) -send_nfocoin_address_entry.config(width=50) -send_nfocoin_button = Button(transaction_frame, text="Send", command=twinpeaks.handle_send_nfocoin) -send_nfocoin_button.grid(row=10, column=2, sticky="NS") -send_nfocoin_address_entry.delete(0, END) -send_nfocoin_address_entry.insert(0, "Recipient Ethereum address (e.g. 0x...)") -send_nfocoin_amount_entry.delete(0,END) -send_nfocoin_amount_entry.insert(0, "Number of NFO Coin to send (1000 NFO Coin = 1 Ether)") - - -send_nfocoin_choice = StringVar() -intranet_nfocoin_radio = Radiobutton(transaction_frame, indicatoron=0, text="Intra-Network", variable=send_nfocoin_choice, value='intra') -internet_nfocoin_radio = Radiobutton(transaction_frame, indicatoron=1, text="Inter-Network", variable=send_nfocoin_choice, value='inter') -intranet_nfocoin_radio.grid(row=10, column=1,sticky=W) -internet_nfocoin_radio.grid(row=11,column=1,sticky=W) - +## ACCOUNT FRAMEi account_label = Label(account_frame, text="Account: ",padx=20,pady=40) account_label.grid(row=7,column=0) account_label.grid_remove() @@ -817,6 +443,7 @@ def on_close(): network_label = Label(network_frame, text="Network: ") network_label.grid(row=9 ) +network_label.grid_remove() network_option = OptionMenu(network_frame, twinpeaks.network_variable, *NETWORK_OPTIONS, command=None) network_option.grid(row=9,column=1,pady=20) @@ -824,86 +451,18 @@ def on_close(): launch_button = Button(network_frame, text="Launch", command=twinpeaks.launch) launch_button.grid(row=10, column=1) -# MANIFESTO layout -manifesto_address_label = Label(manifesto_frame,text="Manifesto.sol address:") -manifesto_address_label.grid(row=2,column=0,sticky=NW) -manifesto_address_label.grid_remove() -manifesto_address_entry = Entry(manifesto_frame) -manifesto_address_entry.grid(row=2,column=0,columnspan=3) -manifesto_address_entry.config(width=40) -manifesto_address_entry.grid_remove() - -proposals_scrollbar = Scrollbar(manifesto_frame) -proposals_scrollbar.grid(row=3, column=0) -proposals_text = Text(manifesto_frame, wrap=WORD, yscrollcommand=proposals_scrollbar.set,height=6,borderwidth=1) - -proposal_listbox = Listbox(manifesto_frame, width=5, height=10) -proposal_listbox.bind("<>", twinpeaks.handle_proposal_click) -proposal_listbox.grid(column=0,row=3,sticky=(N,W,E,S)) -proposal_scrollbar = Scrollbar(manifesto_frame, orient=VERTICAL) -proposal_scrollbar.config(command=proposal_listbox.yview) -proposal_scrollbar.grid(row=3, column=0, sticky=(N,E,S)) -proposal_listbox['yscrollcommand'] = proposal_scrollbar.set - -more_info_label = Label(manifesto_frame, text="ProposalID: \nVotes: ") -more_info_label.grid(row=4, column=0) -more_info_label.grid_remove() -vote_label = Label(manifesto_frame, text="Vote: ") -vote_label.grid(row=2,column=1) -vote_label.grid_remove() - -vote_choice = StringVar() -vote_yes_radio = Radiobutton(manifesto_frame, indicatoron=0, text="yes", variable=vote_choice, value='yes') -vote_yes_radio.grid(row=3,column=3,sticky=W) -vote_yes_radio.grid_remove() -vote_no_radio = Radiobutton(manifesto_frame, text="no", variable=vote_choice, value='no',indicatoron=0) -vote_no_radio.grid(row=3,column=2,sticky=E) -vote_no_radio.grid_remove() - -vote_button = Button(manifesto_frame, text="Vote", command=twinpeaks.handle_vote) -vote_button.grid(row=3,column=1,sticky=E) -vote_button.grid_remove() -tally_button = Button(manifesto_frame, text="Tally Votes", command=twinpeaks.handle_tally) -tally_button.grid(row=4,column=1,sticky=W) -tally_button.grid_remove() - -new_proposal_label = Label(manifesto_frame,text="", justify=LEFT) -new_proposal_label.grid(row=4,column=0, sticky=W) -new_proposal_label.grid_remove() -new_proposal_text = Text(manifesto_frame, wrap=WORD, yscrollcommand=proposals_scrollbar.set,height=5,borderwidth=1) -myFont = Font(family="Arial", size=14) -new_proposal_text.configure(font=myFont) -new_proposal_text.insert(END,"Enter a new proposal here...") -new_proposal_text.grid(row=5,column=0) -new_proposal_text.grid_remove() -new_proposal_button = Button(manifesto_frame, text="Submit Proposal", command=twinpeaks.handle_new_proposal) -new_proposal_button.grid(row=6,column=0,sticky=W ) -new_proposal_button.grid_remove() - -vote_proposalID_label = Label(manifesto_frame, text="ProposalID: ") -vote_proposalID_label.grid(row=5,column=0) -vote_proposalID_label.grid_remove() -vote_proposalID_entry = Entry(manifesto_frame) -vote_proposalID_entry.grid(row=5,column=1) -vote_proposalID_entry.grid_remove() -vote_label = Label(manifesto_frame, text="Vote (yes/no):") -vote_label.grid(row=5,column=2) -vote_label.grid_remove() -vote_entry = Entry(manifesto_frame) -vote_entry.grid(row=5,column=3) -vote_entry.grid_remove() - current_network_label = Label(network_frame, text="") current_network_label.grid(row=8,column=1,sticky='sw') gas_label = Label(network_frame, text="Gas: ") gas_label.grid(row=9,column=0, sticky="se") -#gas_label.grid_remove() +gas_label.grid_remove() gas_entry = Entry(network_frame) gas_entry.grid(row=9,column=1, sticky=W) +gas_entry.grid_remove() set_gas_button = Button(network_frame, text="Change Gas Amount",command=twinpeaks.handle_set_gas) set_gas_button.grid(row=9,column=2,sticky=E) -#set_gas_button.grid_remove() +set_gas_button.grid_remove() # Simbel - the clock that synchronizes on the blockchain simbel = Simbel(center_frame) diff --git a/gui.sh b/gui.sh index 7ec78af..f9d9529 100755 --- a/gui.sh +++ b/gui.sh @@ -1,18 +1,18 @@ #!/bin/bash -# create geth.ipc +# creategeth.ipc ./log_nodeInfo.sh networkId=4828 port=30303 rpcport=8545 -echo "exit" | geth --verbosity 2 --datadir=$PWD/simbel/data --networkid "$networkId" --port "$port" --rpc --rpcport "$rpcport" console +echo "exit" |geth --verbosity 2 --datadir=$PWD/simbel/data --networkid "$networkId" --port "$port" --rpc --rpcport "$rpcport" console -# before starting DDASH, need to start IPFS and geth daemons - #tmux new-session -d -s geth "geth --verbosity 2 --datadir=$PWD/simbel/data --networkid 4828 --port 30303 --rpcapi=\"db,eth,net,personal,web3\" --rpc --rpcport 8545 console" +# before starting DDASH, need to start IPFS andgeth daemons + #tmux new-session -d -sgeth geth --verbosity 2 --datadir=$PWD/simbel/data --networkid 4828 --port 30303 --rpcapi=\"db,eth,net,personal,web3\" --rpc --rpcport 8545 console" -tmux kill-session -t geth +tmux kill-session -tgeth tmux kill-session -t ipfs -tmux new-session -d -s geth "geth --verbosity 3 --datadir=$PWD/simbel/data --networkid $networkId --port $port --rpcapi=\"db,eth,net,personal,web3\" --rpc --rpcport $rpcport --mine --minerthreads=1 console" +tmux new-session -d -sgeth geth --verbosity 3 --datadir=$PWD/simbel/data --networkid $networkId --port $port --rpcapi=\"db,eth,net,personal,web3\" --rpc --rpcport $rpcport --mine --minerthreads=1 console" tmux new-session -d -s ipfs 'ipfs daemon' sleep 5 diff --git a/images/clock2.gif b/images/clock2.gif new file mode 100644 index 0000000000000000000000000000000000000000..11809473ea2f8a095aa30422283c2465abf988ce GIT binary patch literal 30217 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 OCtvx?Xa3^?0suR{;*4$p literal 0 HcmV?d00001 diff --git a/install.sh b/install.sh index 0af69c0..9832ee6 100755 --- a/install.sh +++ b/install.sh @@ -26,7 +26,6 @@ Your choice> " choice echo "" os="$(uname -s)" - arch="$(dpkg --print-architecture)" if [ "$os" = 'Darwin' ]; then echo "It appears you're installing Simbel on a Mac." @@ -202,7 +201,7 @@ Your choice> " choice chmod +x geth chmod +x log_nodeInfo.sh - ./geth --datadir=$PWD/simbel/data init $PWD/simbel/genesis.json + geth --datadir=$PWD/simbel/data init $PWD/simbel/genesis.json read -p "Enter your network id (or leave blank for default value 4828): " networkId read -p "Enter port (or leave blank for default value 30303): " port @@ -218,7 +217,7 @@ Your choice> " choice rpcport=8545 fi - echo "exit" | ./geth --verbosity 2 --datadir=$PWD/simbel/data --networkid "$networkId" --port "$port" --rpc --rpcport "$rpcport" console + echo "exit" | geth --verbosity 2 --datadir=$PWD/simbel/data --networkid "$networkId" --port "$port" --rpc --rpcport "$rpcport" console #rm -r $PWD/go-ipfs # save enode information diff --git a/load_mainnet.sh b/load_mainnet.sh index 5c742c7..8aea755 100755 --- a/load_mainnet.sh +++ b/load_mainnet.sh @@ -7,12 +7,11 @@ rpcport=8545 echo "exit" | geth --verbosity 2 --datadir=$PWD/simbel/data_mainnet console # before starting DDASH, need to start IPFS and geth daemons - #tmux new-session -d -s geth "geth --verbosity 2 --datadir=$PWD/simbel/data --networkid 4828 --port 30303 --rpcapi=\"db,eth,net,personal,web3\" --rpc --rpcport 8545 console" tmux kill-session -t geth #tmux kill-session -t ipfs -tmux new-session -d -s geth "geth --verbosity 3 --fast --cache=1024 --datadir=$PWD/simbel/data_mainnet console" +tmux new-session -d -s geth geth --verbosity 3 --fast --cache=1024 --datadir=$PWD/simbel/data_mainnet console" #tmux new-session -d -s ipfs 'ipfs daemon' sleep 8 diff --git a/load_simbel.sh b/load_simbel.sh index 3a9212f..a8418de 100755 --- a/load_simbel.sh +++ b/load_simbel.sh @@ -4,21 +4,14 @@ networkId=4828 port=30303 rpcport=8545 -echo "exit" | ./geth --verbosity 2 --datadir=$PWD/simbel/data --networkid "$networkId" --port "$port" --rpc --rpcport "$rpcport" console +echo "exit" | geth --verbosity 2 --datadir=$PWD/simbel/data --networkid "$networkId" --port "$port" --rpc --rpcport "$rpcport" console # before starting DDASH, need to start IPFS and geth daemons tmux kill-session -t geth #tmux kill-session -t ipfs -# mine if the machine architecture is not arm (raspberry pi) -arch="$(dpkg --print-architecture)" -echo $arch -if [[ "$arch" == 'armhf' ]]; then - tmux new-session -d -s geth "./geth --verbosity 3 --datadir=$PWD/simbel/data --networkid $networkId --port $port --rpcapi=\"db,eth,net,personal,web3\" --rpc --rpcport $rpcport console" -else - tmux new-session -d -s geth "./geth --verbosity 3 --datadir=$PWD/simbel/data --networkid $networkId --port $port --rpcapi=\"db,eth,net,personal,web3\" --rpc --rpcport $rpcport --mine --minerthreads=1 console" -fi +tmux new-session -d -s geth "geth --verbosity 3 --datadir=$PWD/simbel/data --networkid $networkId --port $port --rpcapi=\"db,eth,net,personal,web3\" --rpc --rpcport $rpcport --mine --minerthreads=1 console" #tmux new-session -d -s ipfs 'ipfs daemon' sleep 5 diff --git a/log_nodeInfo.sh b/log_nodeInfo.sh index 4a85ab6..47db300 100755 --- a/log_nodeInfo.sh +++ b/log_nodeInfo.sh @@ -1,7 +1,7 @@ #!/bin/bash rm $PWD/simbel/nodeInfo.ds -output="$(./geth --datadir=$PWD/simbel/data console <<< $'admin.nodeInfo')" +output="$(geth --datadir=$PWD/simbel/data console <<< $'admin.nodeInfo')" if [[ "$output" =~ \"enode[^,]* ]]; then echo "your enode is: ${BASH_REMATCH[0]}" diff --git a/simbel/nfo/eth_addresses.ds b/simbel/nfo/eth_addresses.ds index f2a482f..00cd4e8 100644 --- a/simbel/nfo/eth_addresses.ds +++ b/simbel/nfo/eth_addresses.ds @@ -7,3 +7,4 @@ pn:0xd4f8e6ceabe3ca95853acc5ba6e4612d90376186 pn:0x5df87b85365ed1b501ecb6f6160f118fa25a8848 pn:0x23c176551e0973bcdb881da609fc356aebfb0d44 pn:0x0ce60bdf8ec5a0d17f2d053dee7cd0e5a089d00f +pn:0x06733a78b4dc4db9b0913f3ee7e8eff3a3d7fa7d diff --git a/simbel/simbel.py b/simbel/simbel.py index 759d123..37c8e50 100644 --- a/simbel/simbel.py +++ b/simbel/simbel.py @@ -22,7 +22,7 @@ def __init__(self, frame): self.frame = frame self.x=150 # Center Point x self.y=150 # Center Point - self.length=50 # Stick Length + self.length=75 # Stick Length self.creating_all_function_trigger() # self.peers keys are enodes # self.peers values are timestamps @@ -39,7 +39,7 @@ def create_simbel_says_label(self, text=None): if hasattr(self,'simbel_says_label'): return - self.simbel_says_label = Label(self.frame, text= (text or 'Just a moment while we connect to the network...')) + self.simbel_says_label = Label(self.frame, text= (text or 'Press the Launch button to connect to the Simbel network...')) self.simbel_says_label.grid(row=4,column=0) def update_simbel_says_label(self, new_text): @@ -58,14 +58,14 @@ def creating_all_function_trigger(self): # Creating Background def creating_background_(self): - clock_gif_path = os.getcwd()+'/images/clock.gif' + clock_gif_path = os.getcwd()+'/images/clock2.gif' self.image=Tkinter.PhotoImage(file=clock_gif_path) self.canvas.create_image(150,150, image=self.image) return # creating Canvas def create_canvas_for_shapes(self): - self.canvas=Tkinter.Canvas(self.frame ) + self.canvas=Tkinter.Canvas(self.frame, width=300, height=300 ) self.canvas.grid(row=3,column=0) return diff --git a/snu.sh b/snu.sh index bf5a179..0c90ad8 100755 --- a/snu.sh +++ b/snu.sh @@ -17,8 +17,8 @@ Welcome to the Simbel Network Utility. What would you like to do? 2: Show existing Ethereum accounts 3: Start mining 4: Compile contract -5: \033[0;32mStart Simbel${NC} -\033[1;37m6: Show network settings${NC} +5: Start Simbel +6: Show network settings 7: Add peer 8: Launch private network 9: Exit @@ -32,13 +32,13 @@ read -p " #tmux kill-session -t ipfs read -sp "Choose a password: " pass - echo "personal.newAccount(\"$pass\")" | ./geth --verbosity 1 --datadir=$PWD/simbel/data console + echo "personal.newAccount(\"$pass\")" | geth --verbosity 1 --datadir=$PWD/simbel/data console fi if [ "$choice" = 2 ]; then tmux kill-session -t geth #tmux kill-session -t ipfs - ./geth --verbosity 1 --datadir=$PWD/simbel/data console <<< $'eth.accounts' + geth --verbosity 1 --datadir=$PWD/simbel/data console <<< $'eth.accounts' echo $PID fi @@ -61,7 +61,7 @@ read -p " if [ -z "$rpcport" ]; then rpcport=8545 fi - ./geth --verbosity 3 --datadir=$PWD/simbel/data --mine --minerthreads=1 --etherbase "$addr" + geth --verbosity 3 --datadir=$PWD/simbel/data --mine --minerthreads=1 --etherbase "$addr" fi if [ "$choice" = 4 ]; then @@ -88,11 +88,11 @@ read -p " rpcport=8545 fi # create geth.ipc file - echo "exit" | ./geth --verbosity 2 --datadir=$PWD/simbel/data --networkid "$networkId" --port "$port" --rpc --rpcport "$rpcport" console + echo "exit" | geth --verbosity 2 --datadir=$PWD/simbel/data --networkid "$networkId" --port "$port" --rpc --rpcport "$rpcport" console # before starting Simbel, need to start IPFS and geth daemons #tmux new-session -d -s geth "geth --verbosity 2 --datadir=$PWD/simbel/data --networkid 4828 --port 30303 --rpcapi=\"db,eth,net,personal,web3\" --rpc --rpcport 8545 console" - tmux new-session -d -s geth "./geth --verbosity 3 --datadir=$PWD/simbel/data --networkid $networkId --port $port --rpcapi=\"db,eth,net,personal,web3\" --rpc --rpcport $rpcport console" + tmux new-session -d -s geth "geth --verbosity 3 --datadir=$PWD/simbel/data --networkid $networkId --port $port --rpcapi=\"db,eth,net,personal,web3\" --rpc --rpcport $rpcport console" #tmux new-session -d -s ipfs 'ipfs daemon' sleep 5 @@ -102,7 +102,7 @@ read -p " if [[ "$choice" = 6 ]]; then - output="$(./geth --datadir=$PWD/simbel/data console <<< $'admin.nodeInfo')" + output="$(geth --datadir=$PWD/simbel/data console <<< $'admin.nodeInfo')" echo "" echo "" echo "" @@ -173,7 +173,7 @@ read -p " if [ -z "$rpcport" ]; then rpcport=8545 fi - ./geth --verbosity 2 --datadir=$PWD/simbel/data --networkid "$networkId" --port "$port" --rpc --rpcport "$rpcport" console + geth --verbosity 2 --datadir=$PWD/simbel/data --networkid "$networkId" --port "$port" --rpc --rpcport "$rpcport" console fi if [[ "$choice" = 9 ]] || [[ "$choice" == "exit" ]] || [[ "$choice" == "quit" ]]; then