def mine(self): """ Looks in redis for transactions and mines them to find the answer to the puzzle """ print("Mining") prev_hash = self.r.get(PREV_HASH_KEY) if prev_hash: prev_hash = prev_hash.decode('utf-8') block = Block(prev_hash) # wait to fill the block with transactions while not block.full(): # in between mining if self.stop_mining(): print("Someone mined the coins") l = len(block.transactions) left = TRANSACTIONS_IN_BLOCK - l for _ in range(left): self.r.blpop(TRANSACTION_QUEUE_KEY) return None print("Searching for transactions to fill the block") # blocking pop from transaction key transaction = Transaction.from_redis( self.r, json.loads( self.r.blpop(TRANSACTION_QUEUE_KEY)[1].decode('utf-8'))) print("found a transaction, adding it to block") block.add_transaction(transaction) # create a new transaction that creates a lazycoin and gives it to the user print("Block is full, now add a create transaction") print("Prev hash = ", prev_hash) create = Transaction( prev_hash=prev_hash, transaction_type='CREATE', sender=self.user.pub, receiver=self.user.pub, ) # sign this transaction and add the signature to the transaction print("signing transaction") msg, sign = self.user.sign(create) create.add_signature(sign) print("adding transaction") block.add_transaction(create) print("finding nonce") nonce = self.solve_puzzle(block) block.add_nonce(nonce) print("block done") if self.stop_mining(): print("stopping mining") return None return block
def __mining(self) -> Optional[Block]: """挖矿""" trans_list = self.__get_mining_trans() with FullBlockChain.safe_use_blockchain() as blc: block = Block(blc.get_height() + 1, blc.get_top_hash()) # 计算总交易费 fee = Btc("0") for trans in trans_list: fee += blc.compute_transaction_fee(trans) block.add_transaction(trans) # 添加交易到block中 # 加上矿工奖励 fee += block.get_now_ming_btcs() # 构造创块交易 head_trans = Transaction() head_trans.add_output(TransOutput(address=self.address, btcs=fee)) block.set_head_transaction(head_trans) # 正式开始挖矿 while not block.veri_hash(): if self.mine_flag: block.randnum += MINING_ADD_NUM block.timestap = time.time() else: # 中止挖矿(失败了) self.add_trans(*trans_list) # 把交易放回交易池 return None return block
def init(): # 删除旧文件 if os.path.isfile(STORE_BLC_FILE_PATH): os.remove(STORE_BLC_FILE_PATH) if os.path.isfile(STORE_KEYS_FILE_PATH): os.remove(STORE_KEYS_FILE_PATH) # 打开N服务和B服务 NetworkRouting.get_instance().start_server() FullBlockChain.get_instance().start_server() # 添加创世区块 keys = [UserKey() for i in range(10)] for key in keys: Wallet.get_instance().add_key(key) Miner.get_instance().set_wallet_address(keys[0].get_address()) t = Transaction() for key in keys: t.add_output(TransOutput(Btc("1000"), key.get_address())) block = Block(1) block.add_transaction(t) head_trans = Transaction() head_trans.add_output(TransOutput(Btc(MINING_BTCS), keys[0].get_address())) block.set_head_transaction(head_trans) block.find_randnum() FullBlockChain.get_instance().add_first_block(block) Wallet.get_instance().write_keys_to_file()
if __name__ == "__main__": print(BlockChain.__qualname__, BlockChain.get_instance.__qualname__) # 创建区块链 bc = BlockChain.get_instance() print(bc.get_start_time()) # 初始的两个用户 key1 = UserKey() key2 = UserKey() # 初始区块的创币交易(只有输出,没有输入) t1 = Transaction() t1.add_output(TransOutput(Btc("5000"), key1.get_address())) t1.add_output(TransOutput(Btc("5000"), key2.get_address())) # 创世区块 b1 = Block() b1.add_transaction(t1) # 添加矿工奖励交易 mt1 = Transaction() mt1.add_output(TransOutput(Btc(MINING_BTCS), key1.get_address())) b1.set_head_transaction(mt1) b1.set_index(1) # 挖矿 b1.find_randnum() # 添加区块 bc.add_block(b1) # key1向key2转账 t2 = Transaction() t2.add_input(TransInput(1, 1, 1)) t2.add_output(TransOutput(Btc("23.567"), key2.get_address())) t2.sign_transaction(key1) if not Verify.verify_transaction(t2):