def loginAPI(): global internal_storage, interruptQueue pub_hex = request.values.get("pub_key") pub_key = pub_hex internal_storage["Public_key"] = pub_key priv_hex = request.values.get("priv_key") priv_key = priv_hex internal_storage["Private_key"] = priv_key if getNeighbours(self_address): # not the first one # request latest block as json current_block = requestLatestBlock() data = json.loads(current_block) tx_list = [] for tx in data['Tx_list']: tx_list.append(createTxFromDict(tx)) # build block b = createBlockFromDict(tx_list, data) # update state bc = blockChain.Blockchain(_block=b) internal_storage["Miner"] = miner.Miner( _blockchain=bc, _pub=pub_key, _priv=priv_key ) else: # create first block internal_storage["Miner"] = miner.Miner(_blockchain=None, _pub=pub_key, _priv=priv_key) generator = internal_storage["Miner"].mineBlock() try: interruptQueue = next(generator) block_data = next(generator) internal_storage["Miner"].broadcastBlock( _block_data=block_data, _neighbours=internal_storage["Neighbour_nodes"], _self_addr=self_address, ) except StopIteration: print("MinerApp Interrupted") # re-routes back to homepage return homePage()
def __init__(self, _public_key, _blockchain=None): # create new miner with fields: self.blockchain = _blockchain self.tx_list = [] self.balance = 0 self.address = _public_key # if this is ever invoked, it must be the first block # of the first miner if self.blockchain is None: # create new blockchain with empty data self.blockchain = blockChain.Blockchain( block.Block(_transaction_list=[ # initial empty transaction transaction.Transaction(self.address, self.address, self.balance, "Init Tx") ]))
def handleBroadcastedBlock(self, _block): # create if None if self.blockchain is None: self.blockchain = blockChain.Blockchain(_block) else: self.blockchain.addBlock(_block, _block.prev_header) # save tx saved_tx = [] for tx in self.tx_pool: if tx not in _block.state["Tx_pool"]: saved_tx.append(tx) # use other person's tx pool self.tx_pool = _block.state["Tx_pool"] # re-add for tx in saved_tx: self.tx_pool.append(tx) return True
def createInitialBlockchain(): priv, pub = keyPair.GenerateKeyPair() t = transaction.Transaction(_sender_public_key=pub, _receiver_public_key=pub, _amount=100, _comment="Reward", _reward=True) t.sign(priv) b = block.Block([t]) q_find = manager.Queue() q2 = manager.Queue() p = b.build(q_find, q2) p.start() p.join() nonce = q_find.get() print("Nonce1:", nonce) b.completeBlockWithNonce(nonce) b.executeChange() bc = blockChain.Blockchain(_block=b) return priv, pub, b, bc
def mineBlock(self): print("Mining...") time.sleep(1) # wait till tx_pool is not empty if self.blockchain is not None: while not self.tx_pool: time.sleep(1) # While there is no new block that is of a longer len than this miner's blockchain, keep mining till completed. interruptQueue = Queue() nonceQueue = Queue() yield interruptQueue # if this is ever invoked, it must be the first block # of the first miner if self.blockchain is None: tx = transaction.Transaction( _sender_public_key=self.client.publickey, _receiver_public_key=self.client.publickey, _comment="Hello world", _amount=0, _reward=True ) tx.sign(self.client.privatekey) first_block = block.Block( _transaction_list=[tx], _difficulty=1, ) p = first_block.build(_found=nonceQueue, _interrupt=interruptQueue) p.start() p.join() nonce_found = nonceQueue.get() if nonce_found == "": print("interrupted!") return first_block.completeBlockWithNonce(_nonce=nonce_found) first_block.tx_list = [tx.data] first_block.executeChange() self.blockchain = blockChain.Blockchain(_block=first_block) else: # validate the transactions temp_pool = [] print("Getting from tx_pool...-->", self.tx_pool) print("Current:", self.blockchain.current_block.state) while len(self.tx_pool) > 0 and len(temp_pool) <= 10: item = self.tx_pool.pop(0) # create transaction t = transaction.Transaction( item["Sender"], item["Receiver"], item["Amount"], item["Comment"], item["Reward"], item["Signature"] ) temp_pool.append(t) temp_pool.append( self.createRewardTransaction(self.client.privatekey)) print("----> TEMP POOL:", temp_pool) newBlock = block.Block( _transaction_list=temp_pool, _prev_header=self.blockchain.current_block.header, _prev_block=self.blockchain.current_block, ) p = newBlock.build(_found=nonceQueue, _interrupt=interruptQueue) p.start() p.join() nonce_found = nonceQueue.get() if nonce_found == "": return # stop here newBlock.completeBlockWithNonce(_nonce=nonce_found) newBlock.executeChange() print("newBlock--->", newBlock.state, newBlock.tx_list) self.blockchain.addBlock( _incoming_block=newBlock, _prev_block_header=newBlock.prev_header ) to_broadcast = self.blockchain.current_block.getData() yield to_broadcast