def proof_of_work(self): # coin_base交易结构[[{tx},{txhash}]] proof = 0 t = time() mk = [self.coin_base[0][1]['txhash']] for tx in self.current_transactions: mk.append(tx[2]['txhash']) block = { 'index': self.index, 'merkle_tree': merkle_tree(mk), 'previous_hash': sha_256(self.chain[-1]), 'proof': proof, 'timestamp': t, 'transactions': self.coin_base + self.current_transactions + self.receive_transactions, } while self.valid_proof(block) is False: proof += 1 block['proof'] = proof self.current_transactions = [] self.receive_transactions = [] self.chain.append(block) self.utxo_pool(block) self.index += 1 return block
def __init__(self): self.private_key = random.randint(1, _r) self.public_key, self.address = get_address(self.private_key) self.amount = 0 # 初始化账户余额 # public_key转化为str,需要转化回来为元组 self.current_transactions = [] # 自己的交易池 self.receive_transactions = [] # 别人的交易池 self.chain = [] self.removed_blocks = [] self.index = 0 self.genesis_block() self.neighbor = set() # 邻居节点 #print('输入节点ip:port') #第一个客户端固定为'127.0.0.1:5000' self.ip = "127.0.0.1:5000" # 初始化coin_base奖励 self.mine_transaction = { 'amount': 50, 'recipient': str(self.public_key), 'sender': 'Satoshi' } self.coin_base = [[ self.mine_transaction, { 'txhash': sha_256(self.mine_transaction) } ]] self.msg = []
def sub_transaction(self, recipient, amount): # 交易结构[[t1,t2,t3]] if amount > self.amount: return False else: t1 = {# 字典顺序不能修改,否则网络传输过程中改变最终hash值 'amount': amount, 'recipient': recipient, 'sender': str(self.public_key), } signature = sign(t1, self.private_key) t2 = {'signature': signature} t3 = {'txhash': sha_256(t1)} tx = [t1, t2, t3] self.current_transactions.append(tx) return True
def valid_chain(self, chain): last_block = chain[0] current_index = 1 while current_index < len(chain): block = chain[current_index] last_block_hash = sha_256(last_block) if block['previous_hash'] != last_block_hash: self.msg.append('hash wrong') return False if not self.valid_proof(block): self.msg.append('proof wrong') return False if not self.valid_block_transaction(block): self.msg.append('t wrong') return False last_block = block current_index += 1 return True
def valid_proof(block, difficulity=DIFFICULTY): guess_hash = sha_256(block) return guess_hash[:difficulity] == "0" * difficulity