def _build_steps(self, digests): self._first = digests[0] # Known hashes without the first hash hash_list = digests[1:] # Ensure the correct data format assert all( isinstance(h, basestring) and len(h) == 32 for h in hash_list) # Number of known hashes (without the first hash) hash_count = len(hash_list) branch = [] if hash_count > 0: while True: # Store the first hash in a list as a merkle branch step branch.append(hash_list[0]) # In case when there are not a pairs of hashes to be hashed together, # duplicate the last one if not hash_count % 2: hash_list.append(hash_list[-1]) # Join and hash together all hash pairs starting from index 1 (merkle branch step) # and construct a new level of hashes hash_list = [ double_sha256_digest(hash_list[i] + hash_list[i + 1]) for i in xrange(1, hash_count, 2) ] hash_count = len(hash_list) if not hash_count: break # Store all collected steps for further usage self._branch = branch
def tree_digest(self, first=None): if first is None: assert len(self._first) == 32 first = self._first for s in self._branch: first = double_sha256_digest(first + s) return first
def submit_block(self, template, cb_tx, header_with_solution_bin): txs = get_txs_from_template(template) block_bin = ''.join(( header_with_solution_bin, pack_varint(len(txs) + 1), # hex_to_bin(template['coinbasetxn']['data']), cb_tx, ''.join(txs), )) block_hex = bin_to_hex(block_bin) result = self.server.submitblock(block_hex) return bin_to_hex( double_sha256_digest(header_with_solution_bin)[::-1]), result
def mine_block(self, mining_address=None): template = self.server.getblocktemplate() target = long(template['target'], 16) nonce_counter = 0 while True: nonce_counter += 1 nonce_bin = '%32x' % nonce_counter cb_tx = self.get_cb_tx(template, mining_address) header_bin = self.get_header_from_templete(template, cb_tx, nonce_bin) sol_num = self.solver.find_solutions(header_bin) for i in range(sol_num): solution_bin = self.solver.get_solution(i) header_with_solution_bin = header_bin + '\xfd\x40\x05' + solution_bin hash_bin = double_sha256_digest(header_with_solution_bin) hash_int = sha256_digest_to_int(hash_bin) if hash_int < target: return self.submit_block(template, cb_tx, header_with_solution_bin)
def get_header_from_templete(t, cb_tx, nonce): version = t['version'] previous_block_hash = hex_to_bin(t['previousblockhash']) cb_hash = double_sha256_digest(cb_tx) #[::-1] # cb_hash = hex_to_bin(t['coinbasetxn']['hash'])[::-1] hashes = [ cb_hash, ] + txs_hashes(get_txs_from_template(t)) hash_merkle_root = MerkleTree(hashes).tree_digest() time = t['curtime'] bits = t['bits'] return ''.join(( struct.pack("<i", version), previous_block_hash[::-1], hash_merkle_root, '\x00' * 32, struct.pack("<I", time), hex_to_bin(bits)[::-1], nonce, ))
def hash_steps(self): if self._steps_hash is None: self._steps_hash = double_sha256_digest(''.join(self._branch)) return self._steps_hash