def main(): transaction_list = make_transaction() print("------------------------------------------------------------\n") signal.signal(signal.SIGINT, signal_handler) global my_p2p_client # my_p2p_client = ClientCore(50087, connect_ip, core_port=50082) try: if args[2]: my_p2p_client = ClientCore(50085, args[1], int(args[2])) elif args[1]: my_p2p_client = ClientCore(50085, args[1]) except IndexError: my_p2p_client = ClientCore(50085) my_p2p_client.start() sleep(10) for transaction in transaction_list: my_p2p_client.send_message_to_my_core_node(MSG_NEW_TRANSACTION, json.dumps(transaction)) sleep(2) sleep(10) shutdown_client()
def main(): tran_num = int(input("送信するトランザクションの数を入力(半角数字): ")) transaction_list = make_transaction(tran_num) print("------------------------------------------------------------\n") signal.signal(signal.SIGINT, signal_handler) global my_p2p_client # my_p2p_client = ClientCore(50087, connect_ip, core_port=50082) try: if args[2]: my_p2p_client = ClientCore(50085, args[1], int(args[2])) elif args[1]: my_p2p_client = ClientCore(50085, args[1]) except IndexError: my_p2p_client = ClientCore(50085) my_p2p_client.start() sleep(10) # count = 0 for transaction in transaction_list: my_p2p_client.send_message_to_my_core_node(MSG_NEW_TRANSACTION, json.dumps(transaction))
def main(): signal.signal(signal.SIGINT, signal_handler) global my_p2p_client #任意のIPに変更 # my_p2p_client = ClientCore(自端末のポート番号, '接続先のIP7アドレス' ,接続先のポート番号) # my_p2p_client = ClientCore(50089, '118.243.116.125' ,50085) # 藤原サーバへのアクセス my_p2p_client.start() transaction_send()
def initApp(self, my_port, c_host, c_port): """ ClientCoreとの接続含めて必要な初期化処理はここで実行する """ print('SimpleBitcoin client is now activating ...: ') self.km = KeyManager() self.um = UTXM(self.km.my_address()) self.rsa_util = RSAUtil() self.c_core = Core(my_port, c_host, c_port, self.update_callback) self.c_core.start() # テスト用途(本来はこんな処理しない) t1 = CoinbaseTransaction(self.km.my_address()) t2 = CoinbaseTransaction(self.km.my_address()) t3 = CoinbaseTransaction(self.km.my_address()) transactions = [] transactions.append(t1.to_dict()) transactions.append(t2.to_dict()) transactions.append(t3.to_dict()) self.um.extract_utxos(transactions) self.update_balance()
def initWallet(self, my_port, c_host, c_port): print('wallet app is initializing') self.c_core = Core(my_port, c_host, c_port, self.update_callback) self.c_core.start() self.update_balance() self.update_blockchain_semaphore = threading.Semaphore(1) self.start_update_blockchain()
def main(): """ clientCoreに直接書いても良さそう位置情報を処理をよみこむ処理とか :return: """ signal.signal(signal.SIGINT, signal_handler) global my_p2p_client my_p2p_client = ClientCore(50091, '172.20.69.204', 50074) my_p2p_client.start() cnt = -1 for t in json_dict: cnt += 1 x = json_dict[str(t)]['x'] y = json_dict[str(t)]['y'] id = json_dict[str(t)]['ID'] timestamp = json_dict[str(t)]['timestamp'] TorF = json_dict[str(t)]['TorF'] trx = Transaction( [VehicleInfo(id, x, y, timestamp, TorF)] ) # ソートしてJSON文字列を辞書型に変換し,もう一度JSON形式にする to_be_signed = json.dumps(trx.to_dict(), sort_keys=True) # loadsはJSON文字列を辞書型にデコードしてくれる new_tx = json.loads(to_be_signed) # dumpsは辞書型をJSON文字列にエンコードしてくれる tx_strings = json.dumps(new_tx) my_p2p_client.send_message_to_my_core_node(MSG_NEW_TRANSACTION, tx_strings) print(tx_strings) with open('/home/ryoichi/Templates/BlockchainProjects/result/result_3.txt', 'w') as file: file.write(str(cnt)) sleep(0.05)
def main(): signal.signal(signal.SIGINT, signal_handler) global my_p2p_client my_p2p_client = ClientCore(HOST_PORT, CONNECT_IP, CONNECT_PORT) my_p2p_client.start() sleep(10) transactions = [] count = 1 while True: value = randint(1, 100) # value = count transactions.append({ 'sender': 's{}'.format(str(count)), 'recipient': 'r{}'.format(str(count)), 'value': value, 'client_address': ADDRESS, }) if count % 10 == 0: my_p2p_client.send_message_to_my_core_node( MSG_NEW_TRANSACTION, json.dumps(transactions)) transactions = [] sleep(30) # count = 0 else: sleep(1) count += 1
def main(): signal.signal(signal.SIGINT, signal_handler) global my_p2p_client my_p2p_client = ClientCore(HOST_PORT, CONNECT_IP, CONNECT_PORT) my_p2p_client.start() sleep(10) while True: count = 0 txs = [] while True: dt = datetime.now() str_dt = dt.strftime("%Y-%m-%d %H:%M:%S")[:-1] transaction = { 'datetime': str_dt + "0", 'client_address': ADDRESS, "attack": False } txs.append(transaction) sleep(10) count += 1 if count >= 10: my_p2p_client.send_message_to_my_core_node(MSG_NEW_TRANSACTION, json.dumps(txs)) count = 0 txs = []
def main(): signal.signal(signal.SIGINT, signal_handler) global my_p2p_client my_p2p_client = ClientCore(50088, '10.1.1.126', 50082) my_p2p_client.start() sleep(10) transaction = {'sender': 'test1', 'recipient': 'test2', 'value': 3} my_p2p_client.send_message_to_my_core_node(MSG_NEW_TRANSACTION, json.dumps(transaction)) transaction2 = {'sender': 'test1', 'recipient': 'test3', 'value': 2} my_p2p_client.send_message_to_my_core_node(MSG_NEW_TRANSACTION, json.dumps(transaction2)) sleep(10) transaction3 = {'sender': 'test5', 'recipient': 'test6', 'value': 10} my_p2p_client.send_message_to_my_core_node(MSG_NEW_TRANSACTION, json.dumps(transaction3))
def main(): signal.signal(signal.SIGINT, signal_handler) global my_p2p_client my_p2p_client = ClientCore(50098, '192.168.100.32', 50090) my_p2p_client.start() # Coreノードの登録前にメッセージを送らないように待つ sleep(5) message = {'message': 'test'} my_p2p_client.send_message_to_my_core_node(MSG_ENHANCED, json.dumps(message))
def main(): signal.signal(signal.SIGINT, signal_handler) global my_p2p_client my_p2p_client = ClientCore(50098, '10.1.1.126', 50090) my_p2p_client.start() sleep(10) message = {'from': 'hoge', 'to': 'fuga', 'message': 'test'} my_p2p_client.send_message_to_my_core_node(MSG_ENHANCED, json.dumps(message))
def main(): signal.signal(signal.SIGINT, signal_handler) global my_p2p_client my_p2p_client = ClientCore(HOST_PORT, CONNECT_IP, CONNECT_PORT) my_p2p_client.start() sleep(10) while True: my_p2p_client.send_message_to_my_core_node(MSG_NEW_TRANSACTION, json.dumps(subpr_api())) # subpr = subpr_api() # for data in subpr: # my_p2p_client.send_message_to_my_core_node(MSG_NEW_TRANSACTION, json.dumps(data)) sleep(30)
def main(): signal.signal(signal.SIGINT, signal_handler) global my_p2p_client my_p2p_client = ClientCore(50095, '192.168.11.35', 50082) my_p2p_client.start() sleep(10) count = 1 while True: transaction = { 'sender': 's{}'.format(str(count)), 'recipient': 'r{}'.format(str(count)), 'value': randint(1, 100) } my_p2p_client.send_message_to_my_core_node(MSG_NEW_TRANSACTION, json.dumps(transaction)) count += 1 # sleep(1) if count % 1 == 0: sleep(10)
def main(): signal.signal(signal.SIGINT, signal_handler) global my_p2p_client my_p2p_client = ClientCore(50095, '10.97.74.93', 50090) # sleep(10) while True: try: my_p2p_client.start() except ConnectionRefusedError: sleep(5) continue sleep(10) tran_list = call_api2.call_api() for tran in tran_list: my_p2p_client.send_message_to_my_core_node(MSG_NEW_TRANSACTION, json.dumps(tran)) try: shutdown_client() except ConnectionRefusedError: sleep(19) continue sleep(19)
def main(): signal.signal(signal.SIGINT, signal_handler) global my_p2p_client # my_p2p_client = ClientCore(50088, connect_ip, core_port=50090) try: if args[2]: my_p2p_client = ClientCore(50088, args[1], int(args[2])) elif args[1]: my_p2p_client = ClientCore(50088, args[1]) except IndexError: my_p2p_client = ClientCore(50088) my_p2p_client.start() sleep(10) transaction = {'sender': 'test1', 'recipient': 'test2', 'value': 3} my_p2p_client.send_message_to_my_core_node(MSG_NEW_TRANSACTION, json.dumps(transaction)) sleep(2) transaction2 = {'sender': 'test1', 'recipient': 'test3', 'value': 2} my_p2p_client.send_message_to_my_core_node(MSG_NEW_TRANSACTION, json.dumps(transaction2)) sleep(2) transaction3 = {'sender': 'test5', 'recipient': 'test6', 'value': 10} my_p2p_client.send_message_to_my_core_node(MSG_NEW_TRANSACTION, json.dumps(transaction3)) sleep(10) shutdown_client()
def main(): tran_list = call_api.call_api() signal.signal(signal.SIGINT, signal_handler) global my_p2p_client try: if args[2]: my_p2p_client = ClientCore(50095, args[1], int(args[2])) elif args[1]: my_p2p_client = ClientCore(50095, args[1]) else: my_p2p_client = ClientCore(50095) except IndexError: my_p2p_client = ClientCore(50095) my_p2p_client.start() sleep(10) for tran in tran_list: my_p2p_client.send_message_to_my_core_node(MSG_NEW_TRANSACTION, json.dumps(tran)) sleep(2)
def main(): signal.signal(signal.SIGINT, signal_handler) global my_p2p_client my_p2p_client = ClientCore(50095, '10.1.1.126', 50082) my_p2p_client.start()
def main(): signal.signal(signal.SIGINT, signal_handler) global my_p2p_client my_p2p_client = ClientCore(50095, '192.168.100.32', 50082) my_p2p_client.start()
class WalletApp_GUI(Frame): def __init__(self, parent, my_port, c_host, c_port): Frame.__init__(self, parent) self.parent = parent self.parent.protocol('WM_DELETE_WINDOW', self.quit) self.coin_balance = StringVar(self.parent, '0') self.c_core = None self.initWallet(my_port, c_host, c_port) self.setupGUI() def quit(self, event=None): # 終了 self.c_core.shutdown() self.parent.destroy() def initWallet(self, my_port, c_host, c_port): print('wallet app is initializing') self.c_core = Core(my_port, c_host, c_port, self.update_callback) self.c_core.start() self.update_balance() self.update_blockchain_semaphore = threading.Semaphore(1) self.start_update_blockchain() def display_info(self, title, info): """ ダイアログボックスにメッセージを表示 """ f = Tk() label = Label(f, text=title) label.pack() info_area = Text(f, width=70, height=50) info_area.insert(INSERT, info) info_area.pack() def update_callback(self): print('update blockchain was called') self.update_balance() def update_balance(self): balance = str(self.c_core.blockchain.calculate_total_amount(self.c_core.wallet.blockchain_address)) self.coin_balance.set(balance) def create_menu(self): top = self.winfo_toplevel() self.menuBar = Menu(top) top['menu'] = self.menuBar self.subMenu = Menu(self.menuBar, tearoff=0) self.menuBar.add_cascade(label='Menu', menu=self.subMenu) self.subMenu.add_command(label='Show My Info', command=self.show_my_info) self.subMenu.add_command(label='Wallet Sync', command=self.sync_miner_wallet) self.subMenu.add_command(label='Update Blockchan', command=self.update_blockchain) self.subMenu.add_separator() self.subMenu.add_command(label='Quit', command=self.quit) self.subMenu2 = Menu(self.menuBar, tearoff=0) self.menuBar.add_cascade(label='Logs', menu=self.subMenu2) self.subMenu2.add_command(label='Show Blockchain', command=self.show_my_blockchain) def show_my_info(self): f = Tk() label = Label(f, text='My Info') label.pack() pub_key = self.c_core.wallet.private_key priv_key = self.c_core.wallet.public_key bc_address = self.c_core.wallet.blockchain_address pub_key_str = Label(f, text='public key') pub_key_str.pack() pub_key_info = Text(f, width=70, height=10) pub_key_info.insert(INSERT, pub_key) pub_key_info.pack() priv_key_str = Label(f, text='private key') priv_key_str.pack() priv_key_info = Text(f, width=70, height=10) priv_key_info.insert(INSERT, priv_key) priv_key_info.pack() bc_address_str = Label(f, text='blockchain address') bc_address_str.pack() bc_address_info = Text(f, width=70, height=5) bc_address_info.insert(INSERT, bc_address) bc_address_info.pack() def update_blockchain(self): self.c_core.send_req_full_chain() def start_update_blockchain(self): is_acquire = self.update_blockchain_semaphore.acquire(blocking=False) if is_acquire: with contextlib.ExitStack() as stack: stack.callback(self.update_blockchain_semaphore.release) self.update_blockchain() update_interval = 10 loop = threading.Timer(update_interval, self.start_update_blockchain) loop.start() def sync_miner_wallet(self): print('sync miner wallet is called') self.c_core.send_req_key_info() def wallet_sync(self): f = Tk() label = Label(f, text='Wallet Sync') label.pack() lf0 = LabelFrame(f, text='public key') lf0.pack(side=TOP, fill='both', expand='yes',padx=7, pady=7) lf1 = LabelFrame(f, text='private key') lf1.pack(side=TOP, fill='both', expand='yes',padx=7, pady=7) lf2 = LabelFrame(f, text='blockchain address') lf2.pack(side=TOP, fill='both', expand='yes',padx=7, pady=7) lf3 = LabelFrame(f, text='') lf3.pack(side=TOP, fill='both', expand='yes',padx=7, pady=7) self.pub_key_box = Entry(lf0, bd=2) self.pub_key_box.grid(row=70,column=10,pady=5) self.priv_key_box = Entry(lf1, bd=2) self.priv_key_box.grid(row=70,column=10,pady=5) self.bc_address_box = Entry(lf2, bd=2) self.bc_address_box.grid(row=70,column=10,pady=5) self.exec_button = Button(lf3, text='実行', command=self.button_func) self.exec_button.grid(row=6, column=1,sticky='NSEW') def button_func(self): pub_key = self.pub_key_box.get() priv_key = self.priv_key_box.get() bc_address = self.bc_address_box.get() # TODO 本当はwalletを更新したい(暗号インスタンスの復元) self.pub_key = pub_key self.priv_key = priv_key self.bc_address = bc_address def show_my_blockchain(self): """ ノードのブロックチェーンを表示 """ mychain = self.c_core.get_my_blockchain() if mychain: mychain_str = pprint.pformat(mychain, indent=2) self.display_info('Current Blockchain', mychain_str) else: self.display_info('Warning', 'blockchain is empty!!') def setupGUI(self): self.parent.bind('<Control-q>', self.quit) self.parent.title('WalletAPP GUI') self.pack(fill = BOTH, expand=1) self.create_menu() lf = LabelFrame(self, text='Current Balance') lf.pack(side=TOP, fill='both', expand='yes', padx=7, pady=7) lf2 = LabelFrame(self, text='Recipient Address') lf2.pack(side=TOP, fill='both', expand='yes', padx=7, pady=7) lf3 = LabelFrame(self,text='Amount pay') lf3.pack(side=TOP, fill='both', expand='yes', padx=7, pady=7) lf4 = LabelFrame(self, text='') lf4.pack(side=TOP, fill='both', expand='yes', padx=7, pady=7) #所持コインの総額表示領域のラベル self.balance = Label(lf, textvariable=self.coin_balance, font='Helvetica 20') self.balance.pack() #受信者となる相手の公開鍵 self.label = Label(lf2, text='') self.label.grid(row=70,column=10, pady=5) self.recipient_address = Entry(lf2, bd=2) self.recipient_address.grid(row=70, column=10, pady=5) # 送金額 self.label2 = Label(lf3, text='') self.label2.grid(row=1, pady=5) self.amountBox = Entry(lf3, bd=2) self.amountBox.grid(row=1, column=1, pady=5, sticky='NSEW') # 送金実行ボタン self.sendBtn = Button(lf4, text='\nSend Coin(s)\n', command=self.sendCoins) self.sendBtn.grid(row=6, column=1, sticky='NSEW') def sendCoins(self): sendAtp = self.amountBox.get() recipient_address = self.recipient_address.get() if not sendAtp: messagebox.showwarning('Warning', 'Please enter the Amount to pay') return elif len(recipient_address)<=1: messagebox.showwarning('Warning', 'Please enter the recipient address') return else: result = messagebox.askyesno('Confirmation', f'sending {sendAtp} coins to :\n{recipient_address}') if result: if float(sendAtp) > self.c_core.blockchain.calculate_total_amount(self.c_core.wallet.blockchain_address): messagebox.showwarning('short of coin', 'not enough coin to be sent') return transaction = Transaction( self.c_core.wallet.private_key, self.c_core.wallet.public_key, self.c_core.wallet.blockchain_address, recipient_address, sendAtp ) msg = transaction.get_json_msg() self.c_core.send_new_transaction(msg) self.amountBox.delete(0,END) self.recipient_address.delete(0,END) self.update_balance()
class SimpleBC_Gui(Frame): def __init__(self, parent, my_port, c_host, c_port): Frame.__init__(self, parent) self.parent = parent self.parent.protocol('WM_DELETE_WINDOW', self.quit) self.coin_balance = StringVar(self.parent, '0') self.status_message = StringVar(self.parent, 'Ready') self.c_core = None self.initApp(my_port, c_host, c_port) self.setupGUI() def quit(self, event=None): """ アプリの終了 """ self.c_core.shutdown() self.parent.destroy() def initApp(self, my_port, c_host, c_port): """ ClientCoreとの接続含めて必要な初期化処理はここで実行する """ print('SimpleBitcoin client is now activating ...: ') self.km = KeyManager() self.um = UTXM(self.km.my_address()) self.rsa_util = RSAUtil() self.c_core = Core(my_port, c_host, c_port, self.update_callback) self.c_core.start() # テスト用途(本来はこんな処理しない) t1 = CoinbaseTransaction(self.km.my_address()) t2 = CoinbaseTransaction(self.km.my_address()) t3 = CoinbaseTransaction(self.km.my_address()) transactions = [] transactions.append(t1.to_dict()) transactions.append(t2.to_dict()) transactions.append(t3.to_dict()) self.um.extract_utxos(transactions) self.update_balance() def display_info(self, title, info): """ ダイアログボックスを使ったメッセージの表示 """ f = Tk() label = Label(f, text=title) label.pack() info_area = Text(f, width=70, height=50) info_area.insert(INSERT, info) info_area.pack() def update_callback(self): print('update_callback was called!') s_transactions = self.c_core.get_stored_transactions_from_bc() print(s_transactions) self.um.extract_utxos(s_transactions) self.update_balance() def update_status(self, info): """ 画面下部のステータス表示内容を変更する """ self.status_message.set(info) def update_balance(self): """ 総額表示の内容を最新状態に合わせて変更する """ bal = str(self.um.my_balance) self.coin_balance.set(bal) def create_menu(self): """ メニューバーに表示するメニューを定義する """ top = self.winfo_toplevel() self.menuBar = Menu(top) top['menu'] = self.menuBar self.subMenu = Menu(self.menuBar, tearoff=0) self.menuBar.add_cascade(label='Menu', menu=self.subMenu) self.subMenu.add_command(label='Show My Address', command=self.show_my_address) self.subMenu.add_command(label='Load my Keys', command=self.show_input_dialog_for_key_loading) self.subMenu.add_command(label='Update Blockchain', command=self.update_block_chain) self.subMenu.add_separator() self.subMenu.add_command(label='Quit', command=self.quit) self.subMenu2 = Menu(self.menuBar, tearoff=0) self.menuBar.add_cascade(label='Settings', menu=self.subMenu2) self.subMenu2.add_command(label='Renew my Keys', command=self.renew_my_keypairs) self.subMenu3 = Menu(self.menuBar, tearoff=0) self.menuBar.add_cascade(label='Advance', menu=self.subMenu3) self.subMenu3.add_command(label='Show Blockchain', command=self.show_my_block_chain) def show_my_address(self): f = Tk() label = Label(f, text='My Address') label.pack() key_info = Text(f, width=70, height=10) my_address = self.km.my_address() key_info.insert(INSERT, my_address) key_info.pack() def show_input_dialog_for_key_loading(self): def load_my_keys(): # ファイル選択ダイアログの表示 f2 = Tk() f2.withdraw() fTyp = [('','*.pem')] iDir = os.path.abspath(os.path.dirname(__file__)) messagebox.showinfo('Load key pair','please choose your key file') f_name = filedialog.askopenfilename(filetypes = fTyp,initialdir = iDir) try: file = open(f_name) data = file.read() target = binascii.unhexlify(data) # TODO: 本来は鍵ペアのファイルが不正などの異常系処理を考えるべき self.km.import_key_pair(target, p_phrase.get()) except Exception as e: print(e) finally: # TODO: 所有コインの再確認処理を入れる必要あり file.close() f.destroy() f2.destroy() self.um = UTXM(self.km.my_address()) self.um.my_balance = 0 self.update_balance() f = Tk() label0 = Label(f, text='Please enter pass phrase for your key pair') frame1 = ttk.Frame(f) label1 = ttk.Label(frame1, text='Pass Phrase:') p_phrase = StringVar() entry1 = ttk.Entry(frame1, textvariable=p_phrase) button1 = ttk.Button(frame1, text='Load', command=load_my_keys) label0.grid(row=0,column=0,sticky=(N,E,S,W)) frame1.grid(row=1,column=0,sticky=(N,E,S,W)) label1.grid(row=2,column=0,sticky=E) entry1.grid(row=2,column=1,sticky=W) button1.grid(row=3,column=1,sticky=W) def update_block_chain(self): self.c_core.send_req_full_chain_to_my_core_node() def renew_my_keypairs(self): """ 利用する鍵ペアを更新する。 """ def save_my_pem(): self.km = KeyManager() my_pem = self.km.export_key_pair(p_phrase) my_pem_hex = binascii.hexlify(my_pem).decode('ascii') # とりあえずファイル名は固定 path = 'my_key_pair.pem' f1 = open(path,'a') f1.write(my_pem_hex) f1.close() f.destroy() self.um = UTXM(self.km.my_address()) self.um.my_balance = 0 self.update_balance() f = Tk() f.title('New Key Gene') label0 = Label(f, text='Please enter pass phrase for your new key pair') frame1 = ttk.Frame(f) label1 = ttk.Label(frame1, text='Pass Phrase:') p_phrase = StringVar() entry1 = ttk.Entry(frame1, textvariable=p_phrase) button1 = ttk.Button(frame1, text='Generate', command=save_my_pem) label0.grid(row=0,column=0,sticky=(N,E,S,W)) frame1.grid(row=1,column=0,sticky=(N,E,S,W)) label1.grid(row=2,column=0,sticky=E) entry1.grid(row=2,column=1,sticky=W) button1.grid(row=3,column=1,sticky=W) def show_my_block_chain(self): """ 自分が保持しているブロックチェーンの中身を確認する """ mychain = self.c_core.get_my_blockchain() if mychain is not None: mychain_str = pprint.pformat(mychain, indent=2) self.display_info('Current Blockchain', mychain_str) else: self.display_info('Warning', 'Currently Blockchain is empty...') def setupGUI(self): """ 画面に必要なパーツを並べる """ self.parent.bind('<Control-q>', self.quit) self.parent.title('SimpleBitcoin GUI') self.pack(fill=BOTH, expand=1) self.create_menu() lf = LabelFrame(self, text='Current Balance') lf.pack(side=TOP, fill='both', expand='yes', padx=7, pady=7) lf2 = LabelFrame(self, text='') lf2.pack(side=BOTTOM, fill='both', expand='yes', padx=7, pady=7) #所持コインの総額表示領域のラベル self.balance = Label(lf, textvariable=self.coin_balance, font='Helvetica 20') self.balance.pack() #受信者となる相手の公開鍵 self.label = Label(lf2, text='Recipient Address:') self.label.grid(row=0, pady=5) self.recipient_pubkey = Entry(lf2, bd=2) self.recipient_pubkey.grid(row=0, column=1, pady=5) # 送金額 self.label2 = Label(lf2, text='Amount to pay :') self.label2.grid(row=1, pady=5) self.amountBox = Entry(lf2, bd=2) self.amountBox.grid(row=1, column=1, pady=5, sticky='NSEW') # 手数料 self.label3 = Label(lf2, text='Fee (Optional) :') self.label3.grid(row=2, pady=5) self.feeBox = Entry(lf2, bd=2) self.feeBox.grid(row=2, column=1, pady=5, sticky='NSEW') # 間隔の開け方がよくわからんので空文字で場所確保 self.label4 = Label(lf2, text='') self.label4.grid(row=5, pady=5) # 送金実行ボタン self.sendBtn = Button(lf2, text='\nSend Coin(s)\n', command=self.sendCoins) self.sendBtn.grid(row=6, column=1, sticky='NSEW') # 下部に表示するステータスバー stbar = Label(self.winfo_toplevel(), textvariable=self.status_message, bd=1, relief=SUNKEN, anchor=W) stbar.pack(side=BOTTOM, fill=X) # 送金実行ボタン押下時の処理実体 def sendCoins(self): sendAtp = self.amountBox.get() recipientKey = self.recipient_pubkey.get() sendFee = self.feeBox.get() utxo_len = len(self.um.utxo_txs) if not sendAtp: messagebox.showwarning('Warning', 'Please enter the Amount to pay.') return elif len(recipientKey) <= 1: messagebox.showwarning('Warning', 'Please enter the Recipient Address.') return else: result = messagebox.askyesno('Confirmation', 'Sending {} SimpleBitcoins to :\n {}'.format(sendAtp, recipientKey)) if not sendFee: sendFee = 0 if result: if 0 < utxo_len: print('Sending {} SimpleBitcoins to reciever:\n {}'.format(sendAtp, recipientKey)) else: messagebox.showwarning('Short of Coin.', 'Not enough coin to be sent...') return utxo, idx = self.um.get_utxo_tx(0) t = Transaction( [TransactionInput(utxo, idx)], [TransactionOutput(recipientKey, int(sendAtp))] ) counter = 1 # TransactionInputが送信額を超えるまで繰り返して取得しTransactionとして完成させる if type(sendFee) is not str: sendFee = int(sendFee) while t.is_enough_inputs(sendFee) is not True: new_utxo, new_idx = self.um.get_utxo_tx(counter) t.inputs.append(TransactionInput(new_utxo, new_idx)) counter += 1 if counter > utxo_len: messagebox.showwarning('Short of Coin.', 'Not enough coin to be sent...') break # 正常なTransactionが生成できた時だけ秘密鍵で署名を実行する if t.is_enough_inputs(sendFee) is True: # まずお釣り用Transactionを作る change = t.compute_change(sendFee) t.outputs.append(TransactionOutput(self.km.my_address(), change)) to_be_signed = json.dumps(t.to_dict(), sort_keys=True) signed = self.km.compute_digital_signature(to_be_signed) new_tx = json.loads(to_be_signed) new_tx['signature'] = signed # TransactionをP2P Networkに送信 tx_strings = json.dumps(new_tx) self.c_core.send_message_to_my_core_node(MSG_NEW_TRANSACTION, tx_strings) print('signed new_tx:', tx_strings) # 実験的にお釣り分の勘定のため新しく生成したTransactionをUTXOとして追加しておくが # 本来はブロックチェーンの更新に合わせて再計算した方が適切 self.um.put_utxo_tx(t.to_dict()) to_be_deleted = 0 del_list = [] while to_be_deleted < counter: del_tx = self.um.get_utxo_tx(to_be_deleted) del_list.append(del_tx) to_be_deleted += 1 for dx in del_list: self.um.remove_utxo_tx(dx) self.amountBox.delete(0,END) self.feeBox.delete(0,END) self.recipient_pubkey.delete(0,END) self.update_balance()
class SimpleBC_Gui(Frame): def __init__(self, parent, my_port, c_host, c_port): Frame.__init__(self, parent) self.parent = parent self.parent.protocol('WM_DELETE_WINDOW', self.quit) self.coin_balance = StringVar(self.parent, '0') self.status_message = StringVar(self.parent, 'Ready') self.c_core = None self.initApp(my_port, c_host, c_port) self.setupGUI() def quit(self, event=None): """ アプリの終了 """ self.c_core.shutdown() self.parent.destroy() def initApp(self, my_port, c_host, c_port): """ ClientCoreとの接続含めて必要な初期化処理はここで実行する """ print('SimpleBitcoin client is now activating ...: ') self.km = KeyManager() self.um = UTXM(self.km.my_address()) self.rsa_util = RSAUtil() self.c_core = Core(my_port, c_host, c_port, self.update_callback, self.get_message_callback) self.c_core.start(self.km.my_address()) # テスト用途(本来はこんな処理しない) t1 = CoinbaseTransaction(self.km.my_address()) t2 = CoinbaseTransaction(self.km.my_address()) t3 = CoinbaseTransaction(self.km.my_address()) transactions = [] transactions.append(t1.to_dict()) transactions.append(t2.to_dict()) transactions.append(t3.to_dict()) self.um.extract_utxos(transactions) self.update_balance() def display_info(self, title, info): """ ダイアログボックスを使ったメッセージの表示 """ f = Tk() label = Label(f, text=title) label.pack() info_area = Text(f, width=70, height=50) info_area.insert(INSERT, info) info_area.pack() def get_message_callback(self, target_message): print('get_message_callback called!') if target_message['message_type'] == 'cipher_message': try: encrypted_key = base64.b64decode(binascii.unhexlify(target_message['enc_key'])) print('encripted_key : ', encrypted_key) decrypted_key = self.km.decrypt_with_private_key(encrypted_key) print('decrypted_key : ', binascii.hexlify(decrypted_key).decode('ascii')) # 流石に名前解決をしないで公開鍵のまま出しても意味なさそうなのでコメントアウト #sender = binascii.unhexlify(target_message['sender']) aes_util = AESUtil() decrypted_message = aes_util.decrypt_with_key(base64.b64decode(binascii.unhexlify(target_message['body'])), decrypted_key) print(decrypted_message.decode('utf-8')) """ message = { 'from' : sender, 'message' : decrypted_message.decode('utf-8') } message_4_display = pprint.pformat(message, indent=2) """ messagebox.showwarning('You received an instant encrypted message !', decrypted_message.decode('utf-8')) except Exception as e: print(e, 'error occurred') elif target_message['message_type'] == 'engraved': sender_name = target_message['sender_alt_name'] msg_body = base64.b64decode(binascii.unhexlify(target_message['message'])).decode('utf-8') timestamp = datetime.datetime.fromtimestamp(int(target_message['timestamp'])) messagebox.showwarning('You received a new engraved message!', '{} :\n {} \n {}'.format(sender_name, msg_body, timestamp)) def update_callback(self): print('update_callback was called!') s_transactions = self.c_core.get_stored_transactions_from_bc() print(s_transactions) self.um.extract_utxos(s_transactions) self.update_balance() def update_status(self, info): """ 画面下部のステータス表示内容を変更する """ self.status_message.set(info) def update_balance(self): """ 総額表示の内容を最新状態に合わせて変更する """ bal = str(self.um.my_balance) self.coin_balance.set(bal) def create_menu(self): """ メニューバーに表示するメニューを定義する """ top = self.winfo_toplevel() self.menuBar = Menu(top) top['menu'] = self.menuBar self.subMenu = Menu(self.menuBar, tearoff=0) self.menuBar.add_cascade(label='Menu', menu=self.subMenu) self.subMenu.add_command(label='Show My Address', command=self.show_my_address) self.subMenu.add_command(label='Load my Keys', command=self.show_input_dialog_for_key_loading) self.subMenu.add_command(label='Update Blockchain', command=self.update_block_chain) self.subMenu.add_separator() self.subMenu.add_command(label='Quit', command=self.quit) self.subMenu2 = Menu(self.menuBar, tearoff=0) self.menuBar.add_cascade(label='Settings', menu=self.subMenu2) self.subMenu2.add_command(label='Renew my Keys', command=self.renew_my_keypairs) self.subMenu3 = Menu(self.menuBar, tearoff=0) self.menuBar.add_cascade(label='Advance', menu=self.subMenu3) self.subMenu3.add_command(label='Send Encrypted Instant Message', command=self.send_instant_message) self.subMenu3.add_command(label='Show Logs (Received)', command=self.open_r_log_window) self.subMenu3.add_command(label='Show Logs (Send)', command=self.open_s_log_window) self.subMenu3.add_command(label='Show Blockchain', command=self.show_my_block_chain) self.subMenu3.add_command(label='Engrave Message', command=self.engrave_message) def show_my_address(self): f = Tk() label = Label(f, text='My Address') label.pack() key_info = Text(f, width=70, height=10) my_address = self.km.my_address() key_info.insert(INSERT, my_address) key_info.pack() def show_input_dialog_for_key_loading(self): def load_my_keys(): # ファイル選択ダイアログの表示 f2 = Tk() f2.withdraw() fTyp = [('','*.pem')] iDir = os.path.abspath(os.path.dirname(__file__)) messagebox.showinfo('Load key pair','please choose your key file') f_name = filedialog.askopenfilename(filetypes = fTyp,initialdir = iDir) try: file = open(f_name) data = file.read() target = binascii.unhexlify(data) # TODO: 本来は鍵ペアのファイルが不正などの異常系処理を考えるべき self.km.import_key_pair(target, p_phrase.get()) except Exception as e: print(e) finally: # TODO: 所有コインの再確認処理を入れる必要あり file.close() f.destroy() f2.destroy() self.um = UTXM(self.km.my_address()) self.um.my_balance = 0 self.update_balance() f = Tk() label0 = Label(f, text='Please enter pass phrase for your key pair') frame1 = ttk.Frame(f) label1 = ttk.Label(frame1, text='Pass Phrase:') p_phrase = StringVar() entry1 = ttk.Entry(frame1, textvariable=p_phrase) button1 = ttk.Button(frame1, text='Load', command=load_my_keys) label0.grid(row=0,column=0,sticky=(N,E,S,W)) frame1.grid(row=1,column=0,sticky=(N,E,S,W)) label1.grid(row=2,column=0,sticky=E) entry1.grid(row=2,column=1,sticky=W) button1.grid(row=3,column=1,sticky=W) def update_block_chain(self): self.c_core.send_req_full_chain_to_my_core_node() def renew_my_keypairs(self): """ 利用する鍵ペアを更新する。 """ def save_my_pem(): self.km = KeyManager() my_pem = self.km.export_key_pair(p_phrase) my_pem_hex = binascii.hexlify(my_pem).decode('ascii') # とりあえずファイル名は固定 path = 'my_key_pair.pem' f1 = open(path,'a') f1.write(my_pem_hex) f1.close() f.destroy() self.um = UTXM(self.km.my_address()) self.um.my_balance = 0 self.update_balance() f = Tk() f.title('New Key Gene') label0 = Label(f, text='Please enter pass phrase for your new key pair') frame1 = ttk.Frame(f) label1 = ttk.Label(frame1, text='Pass Phrase:') p_phrase = StringVar() entry1 = ttk.Entry(frame1, textvariable=p_phrase) button1 = ttk.Button(frame1, text='Generate', command=save_my_pem) label0.grid(row=0,column=0,sticky=(N,E,S,W)) frame1.grid(row=1,column=0,sticky=(N,E,S,W)) label1.grid(row=2,column=0,sticky=E) entry1.grid(row=2,column=1,sticky=W) button1.grid(row=3,column=1,sticky=W) def send_instant_message(self): def send_message(): r_pkey = entry1.get() print('pubkey', r_pkey) new_message = {} aes_util = AESUtil() cipher_txt = aes_util.encrypt(entry2.get()) new_message['message_type'] = 'cipher_message' new_message['recipient'] = r_pkey new_message['sender'] = self.km.my_address() new_message['body'] = binascii.hexlify(base64.b64encode(cipher_txt)).decode('ascii') key = aes_util.get_aes_key() encrypted_key = self.rsa_util.encrypt_with_pubkey(key, r_pkey) print('encrypted_key: ', encrypted_key[0]) new_message['enc_key'] = binascii.hexlify(base64.b64encode(encrypted_key[0])).decode('ascii') msg_type = MSG_ENHANCED message_strings = json.dumps(new_message) self.c_core.send_message_to_my_core_node(msg_type, message_strings) f.destroy() f = Tk() f.title('New Message') label0 = Label(f, text='Please input recipient address and message') frame1 = ttk.Frame(f) label1 = ttk.Label(frame1, text='Recipient:') pkey = StringVar() entry1 = ttk.Entry(frame1, textvariable=pkey) label2 = ttk.Label(frame1, text='Message:') message = StringVar() entry2 = ttk.Entry(frame1, textvariable=message) button1 = ttk.Button(frame1, text='Send Message', command=send_message) label0.grid(row=0,column=0,sticky=(N,E,S,W)) frame1.grid(row=1,column=0,sticky=(N,E,S,W)) label1.grid(row=2,column=0,sticky=E) entry1.grid(row=2,column=1,sticky=W) label2.grid(row=3,column=0,sticky=E) entry2.grid(row=3,column=1,sticky=W) button1.grid(row=4,column=1,sticky=W) def open_r_log_window(self): """ 別ウィンドウでログ情報を表示する。これまでに受け取った自分宛のTransactionを時系列で並べる """ s_transactions = self.c_core.get_stored_transactions_from_bc() my_transactions = self.um.get_txs_to_my_address(s_transactions) informations = [] receive_date = None sender = None value = None reason = None description = None for t in my_transactions: result, t_type = self.um.is_sbc_transaction(t) receive_date = datetime.datetime.fromtimestamp(int(t['timestamp'])) if t_type == 'basic': reason = base64.b64decode(binascii.unhexlify(t['extra']['reason'])).decode('utf-8') description = base64.b64decode(binascii.unhexlify(t['extra']['description'])).decode('utf-8') for txout in t['outputs']: recipient = txout['recipient'] if recipient == self.km.my_address(): value = txout['value'] for txin in t['inputs']: t_in_txin = txin['transaction'] idx = txin['output_index'] sender = t_in_txin['outputs'][idx]['recipient'] if sender == self.km.my_address(): sender = 'Change to myself' else: reason = 'CoinbaseTransaction' description = 'CoinbaseTransaction' sender = self.km.my_address() for txout in t['outputs']: recipient = txout['recipient'] if recipient == self.km.my_address(): value = txout['value'] info = { 'date' : receive_date, 'From' : sender, 'Value' : value, 'reason' : reason, 'description' : description } informations.append(info) log = pprint.pformat(informations, indent=2) if log is not None: self.display_info('Log : Received Transaction', log) else: self.display_info('Warning', 'Currently you received NO Transaction to you...') def open_s_log_window(self): """ 別ウィンドウでログ情報を表示する。これまでに自分が送信したTransactionを時系列で並べる """ s_transactions = self.c_core.get_stored_transactions_from_bc() my_transactions = self.um.get_txs_from_my_address(s_transactions) informations = [] send_date = None recipient = None value = None reason = None description = None for t in my_transactions: result, t_type = self.um.is_sbc_transaction(t) send_date = datetime.datetime.fromtimestamp(int(t['timestamp'])) if t_type == 'basic': reason = base64.b64decode(binascii.unhexlify(t['extra']['reason'])).decode('utf-8') description = base64.b64decode(binascii.unhexlify(t['extra']['description'])).decode('utf-8') for txout in t['outputs']: recipient = txout['recipient'] if recipient == self.km.my_address(): recipient = 'Change to myself' value = txout['value'] info = { 'date' : send_date, 'To' : recipient, 'Value' : value, 'reason' : reason, 'description' : description } informations.append(info) log = pprint.pformat(informations, indent=2) if log is not None: self.display_info('Log : Sent Transaction', log) else: self.display_info('Warning', 'NO Transaction which was sent from you...') def show_my_block_chain(self): """ 自分が保持しているブロックチェーンの中身を確認する """ mychain = self.c_core.get_my_blockchain() if mychain is not None: mychain_str = pprint.pformat(mychain, indent=2) self.display_info('Current Blockchain', mychain_str) else: self.display_info('Warning', 'Currently Blockchain is empty...') def engrave_message(self): """ ブロックチェーンにTwitter風のメッセージを格納する """ def send_e_message(): # P2PによるブロードキャストとTransactionのハイブリッド new_message = {} msg_txt = entry.get().encode('utf-8') msg = EngravedTransaction( self.km.my_address(), 'Testman', binascii.hexlify(base64.b64encode(msg_txt)).decode('ascii') ) to_be_signed = json.dumps(msg.to_dict(), sort_keys=True) signed = self.km.compute_digital_signature(to_be_signed) new_tx = json.loads(to_be_signed) new_tx['signature'] = signed tx_strings = json.dumps(new_tx) self.c_core.send_message_to_my_core_node(MSG_NEW_TRANSACTION, tx_strings) new_tx2 = copy.deepcopy(new_tx) new_tx2['message_type'] = 'engraved' tx_strings2 = json.dumps(new_tx2) self.c_core.send_message_to_my_core_node(MSG_ENHANCED, tx_strings2) f.destroy() f = Tk() f.title('Engrave New Message') label0 = Label(f, text='Any idea?') frame1 = ttk.Frame(f) label = ttk.Label(frame1, text='Message:') entry = ttk.Entry(frame1, width=30) button1 = ttk.Button(frame1, text='Engrave this on Blockchain', command=send_e_message) label0.grid(row=0,column=0,sticky=(N,E,S,W)) frame1.grid(row=1,column=0,sticky=(N,E,S,W)) label.grid(row=2,column=0,sticky=E) entry.grid(row=2,column=1,sticky=W) button1.grid(row=3,column=1,sticky=W) def setupGUI(self): """ 画面に必要なパーツを並べる """ self.parent.bind('<Control-q>', self.quit) self.parent.title('SimpleBitcoin GUI') self.pack(fill=BOTH, expand=1) self.create_menu() lf = LabelFrame(self, text='Current Balance') lf.pack(side=TOP, fill='both', expand='yes', padx=7, pady=7) lf2 = LabelFrame(self, text='') lf2.pack(side=BOTTOM, fill='both', expand='yes', padx=7, pady=7) #所持コインの総額表示領域のラベル self.balance = Label(lf, textvariable=self.coin_balance, font='Helvetica 20') self.balance.pack() #受信者となる相手の公開鍵 self.label = Label(lf2, text='Recipient Address:') self.label.grid(row=0, pady=5) self.recipient_pubkey = Entry(lf2, bd=2) self.recipient_pubkey.grid(row=0, column=1, pady=5) # 送金額 self.label2 = Label(lf2, text='Amount to pay :') self.label2.grid(row=1, pady=5) self.amountBox = Entry(lf2, bd=2) self.amountBox.grid(row=1, column=1, pady=5, sticky='NSEW') # 手数料 self.label3 = Label(lf2, text='Fee (Optional) :') self.label3.grid(row=2, pady=5) self.feeBox = Entry(lf2, bd=2) self.feeBox.grid(row=2, column=1, pady=5, sticky='NSEW') # 送金理由を書く欄(主にURLとか) self.label4 = Label(lf2, text='reason (Optional) :') self.label4.grid(row=3, pady=5) self.reasonBox = Entry(lf2, bd=2) self.reasonBox.grid(row=3, column=1, pady=5, sticky='NSEW') # 通信欄(公開メッセージ) self.label5 = Label(lf2, text='message (Optional) :') self.label5.grid(row=4, pady=5) self.messageBox = Entry(lf2, bd=2) self.messageBox.grid(row=4, column=1, pady=5, sticky='NSEW') # 間隔の開け方がよくわからんので空文字で場所確保 self.label4 = Label(lf2, text='') self.label4.grid(row=5, pady=5) # 送金実行ボタン self.sendBtn = Button(lf2, text='\nSend Coin(s)\n', command=self.sendCoins) self.sendBtn.grid(row=6, column=1, sticky='NSEW') # 下部に表示するステータスバー stbar = Label(self.winfo_toplevel(), textvariable=self.status_message, bd=1, relief=SUNKEN, anchor=W) stbar.pack(side=BOTTOM, fill=X) # 送金実行ボタン押下時の処理実体 def sendCoins(self): sendAtp = self.amountBox.get() recipientKey = self.recipient_pubkey.get() sendFee = self.feeBox.get() reason = binascii.hexlify(base64.b64encode(self.reasonBox.get().encode('utf-8'))).decode('ascii') desc = binascii.hexlify(base64.b64encode(self.messageBox.get().encode('utf-8'))).decode('ascii') utxo_len = len(self.um.utxo_txs) if not sendAtp: messagebox.showwarning('Warning', 'Please enter the Amount to pay.') return elif len(recipientKey) <= 1: messagebox.showwarning('Warning', 'Please enter the Recipient Address.') return else: result = messagebox.askyesno('Confirmation', 'Sending {} SimpleBitcoins to :\n {}'.format(sendAtp, recipientKey)) if not sendFee: sendFee = 0 if not reason: reason = 'No information' if not desc: desc = 'No description' extra = { 'reason': reason, 'description': desc, } if result: if 0 < utxo_len: print('Sending {} SimpleBitcoins to reciever:\n {}'.format(sendAtp, recipientKey)) else: messagebox.showwarning('Short of Coin.', 'Not enough coin to be sent...') return utxo, idx = self.um.get_utxo_tx(0) t = Transaction( [TransactionInput(utxo, idx)], [TransactionOutput(recipientKey, int(sendAtp))], extra ) counter = 1 # TransactionInputが送信額を超えるまで繰り返して取得しTransactionとして完成させる if type(sendFee) is not str: sendFee = int(sendFee) while t.is_enough_inputs(sendFee) is not True: new_utxo, new_idx = self.um.get_utxo_tx(counter) t.inputs.append(TransactionInput(new_utxo, new_idx)) counter += 1 if counter > utxo_len: messagebox.showwarning('Short of Coin.', 'Not enough coin to be sent...') break # 正常なTransactionが生成できた時だけ秘密鍵で署名を実行する if t.is_enough_inputs(sendFee) is True: # まずお釣り用Transactionを作る change = t.compute_change(sendFee) t.outputs.append(TransactionOutput(self.km.my_address(), change)) to_be_signed = json.dumps(t.to_dict(), sort_keys=True) signed = self.km.compute_digital_signature(to_be_signed) new_tx = json.loads(to_be_signed) new_tx['signature'] = signed # TransactionをP2P Networkに送信 msg_type = MSG_NEW_TRANSACTION tx_strings = json.dumps(new_tx) self.c_core.send_message_to_my_core_node(msg_type, tx_strings) print('signed new_tx:', tx_strings) # 実験的にお釣り分の勘定のため新しく生成したTransactionをUTXOとして追加しておくが # 本来はブロックチェーンの更新に合わせて再計算した方が適切 self.um.put_utxo_tx(t.to_dict()) to_be_deleted = 0 del_list = [] while to_be_deleted < counter: del_tx = self.um.get_utxo_tx(to_be_deleted) del_list.append(del_tx) to_be_deleted += 1 for dx in del_list: self.um.remove_utxo_tx(dx) self.amountBox.delete(0,END) self.feeBox.delete(0,END) self.recipient_pubkey.delete(0,END) self.reasonBox.delete(0,END) self.messageBox.delete(0,END) self.update_balance()