def PoW(b): global hashing_algo, ltc_scrypt if hashing_algo == 'doublesha': return hashlib.sha256(hashlib.sha256(b).digest()).digest() elif hashing_algo == 'scryptn': return yac_scrypt.getPoWHash(b) else: return ltc_scrypt.getPoWHash(b)
def scrypt(s): import binascii nTime = binascii.hexlify(s[68:72]) nTime = int(nTime, 16) import struct nTime = struct.pack('<I', nTime) nTime = binascii.hexlify(nTime) nTime = int(nTime, 16) print nTime return getPoWHash(s, nTime)
def block_header_hash(chain, header): import yac_scrypt b = chain.parse_block_header(header) return yac_scrypt.getPoWHash(header, b['nTime'] + YAC_START_TIME - chain.start_time)
def submit_share(self, job_id, worker_name, session, extranonce1_bin, extranonce2, ntime, nonce, difficulty): '''Check parameters and finalize block template. If it leads to valid block candidate, asynchronously submits the block back to the bitcoin network. - extranonce1_bin is binary. No checks performed, it should be from session data - job_id, extranonce2, ntime, nonce - in hex form sent by the client - difficulty - decimal number from session, again no checks performed - submitblock_callback - reference to method which receive result of submitblock() ''' # Check if extranonce2 looks correctly. extranonce2 is in hex form... if len(extranonce2) != self.extranonce2_size * 2: raise SubmitException("Incorrect size of extranonce2. Expected %d chars" % (self.extranonce2_size*2)) # Check for job job = self.get_job(job_id) if job == None: raise SubmitException("Job '%s' not found" % job_id) # Check if ntime looks correct if len(ntime) != 8: raise SubmitException("Incorrect size of ntime. Expected 8 chars") if not job.check_ntime(int(ntime, 16)): raise SubmitException("Ntime out of range") # Check nonce if len(nonce) != 8: raise SubmitException("Incorrect size of nonce. Expected 8 chars") # Check for duplicated submit if not job.register_submit(extranonce1_bin, extranonce2, ntime, nonce): log.info("Duplicate from %s, (%s %s %s %s)" % \ (worker_name, binascii.hexlify(extranonce1_bin), extranonce2, ntime, nonce)) raise SubmitException("Duplicate share") # Now let's do the hard work! # --------------------------- # 0. Some sugar extranonce2_bin = binascii.unhexlify(extranonce2) ntime_bin = binascii.unhexlify(ntime) nonce_bin = binascii.unhexlify(nonce) # 1. Build coinbase coinbase_bin = job.serialize_coinbase(extranonce1_bin, extranonce2_bin) coinbase_hash = util.doublesha(coinbase_bin) # 2. Calculate merkle root merkle_root_bin = job.merkletree.withFirst(coinbase_hash) merkle_root_int = util.uint256_from_str(merkle_root_bin) # 3. Serialize header with given merkle, ntime and nonce header_bin = job.serialize_header(merkle_root_int, ntime_bin, nonce_bin) # 4. Reverse header and compare it with target of the user if settings.COINDAEMON_ALGO == 'scrypt': hash_bin = ltc_scrypt.getPoWHash(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ])) elif settings.COINDAEMON_ALGO == 'scrypt-jane': hash_bin = yac_scrypt.getPoWHash(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]), int(ntime, 16)) elif settings.COINDAEMON_ALGO == 'quark': hash_bin = quark_hash.getPoWHash(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ])) else: hash_bin = util.doublesha(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ])) hash_int = util.uint256_from_str(hash_bin) scrypt_hash_hex = "%064x" % hash_int header_hex = binascii.hexlify(header_bin) if settings.COINDAEMON_ALGO == 'scrypt' or settings.COINDAEMON_ALGO == 'scrypt-jane': header_hex = header_hex+"000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000" elif settings.COINDAEMON_ALGO == 'quark': header_hex = header_hex+"000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000" else: pass target_user = self.diff_to_target(difficulty) if hash_int > target_user: raise SubmitException("Share is above target") # Mostly for debugging purposes target_info = self.diff_to_target(100000) if hash_int <= target_info: log.info("Yay, share with diff above 100000") # Algebra tells us the diff_to_target is the same as hash_to_diff share_diff = int(self.diff_to_target(hash_int)) # 5. Compare hash with target of the network if hash_int <= job.target: # Yay! It is block candidate! log.info("We found a block candidate! %s" % scrypt_hash_hex) # Reverse the header and get the potential block hash (for scrypt only) #if settings.COINDAEMON_ALGO == 'scrypt' or settings.COINDAEMON_ALGO == 'sha256d': # if settings.COINDAEMON_Reward == 'POW': block_hash_bin = util.doublesha(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ])) block_hash_hex = block_hash_bin[::-1].encode('hex_codec') #else: block_hash_hex = hash_bin[::-1].encode('hex_codec') #else: block_hash_hex = hash_bin[::-1].encode('hex_codec') # 6. Finalize and serialize block object job.finalize(merkle_root_int, extranonce1_bin, extranonce2_bin, int(ntime, 16), int(nonce, 16)) if not job.is_valid(): # Should not happen log.exception("FINAL JOB VALIDATION FAILED!(Try enabling/disabling tx messages)") # 7. Submit block to the network serialized = binascii.hexlify(job.serialize()) #just try both block hash and scrypt hash when checking for block creation on_submit = self.bitcoin_rpc.submitblock(serialized, block_hash_hex, scrypt_hash_hex) if on_submit: self.update_block() if settings.SOLUTION_BLOCK_HASH: return (header_hex, block_hash_hex, share_diff, on_submit) else: return (header_hex, scrypt_hash_hex, share_diff, on_submit) if settings.SOLUTION_BLOCK_HASH: # Reverse the header and get the potential block hash (for scrypt only) only do this if we want to send in the block hash to the shares table block_hash_bin = util.doublesha(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ])) block_hash_hex = block_hash_bin[::-1].encode('hex_codec') return (header_hex, block_hash_hex, share_diff, None) else: return (header_hex, scrypt_hash_hex, share_diff, None)
def submit_share(self, job_id, worker_name, session, extranonce1_bin, extranonce2, ntime, nonce, difficulty): '''Check parameters and finalize block template. If it leads to valid block candidate, asynchronously submits the block back to the bitcoin network. - extranonce1_bin is binary. No checks performed, it should be from session data - job_id, extranonce2, ntime, nonce - in hex form sent by the client - difficulty - decimal number from session, again no checks performed - submitblock_callback - reference to method which receive result of submitblock() ''' # Check if extranonce2 looks correctly. extranonce2 is in hex form... if len(extranonce2) != self.extranonce2_size * 2: raise SubmitException("Incorrect size of extranonce2. Expected %d chars" % (self.extranonce2_size*2)) # Check for job job = self.get_job(job_id) if job == None: raise SubmitException("Job '%s' not found" % job_id) # Check if ntime looks correct if len(ntime) != 8: raise SubmitException("Incorrect size of ntime. Expected 8 chars") if not job.check_ntime(int(ntime, 16)): raise SubmitException("Ntime out of range") # Check nonce if len(nonce) != 8: raise SubmitException("Incorrect size of nonce. Expected 8 chars") # Check for duplicated submit if not job.register_submit(extranonce1_bin, extranonce2, ntime, nonce): log.info("Duplicate from %s, (%s %s %s %s)" % \ (worker_name, binascii.hexlify(extranonce1_bin), extranonce2, ntime, nonce)) raise SubmitException("Duplicate share") # Now let's do the hard work! # --------------------------- # 0. Some sugar extranonce2_bin = binascii.unhexlify(extranonce2) ntime_bin = binascii.unhexlify(ntime) nonce_bin = binascii.unhexlify(nonce) # 1. Build coinbase coinbase_bin = job.serialize_coinbase(extranonce1_bin, extranonce2_bin) coinbase_hash = util.doublesha(coinbase_bin) # 2. Calculate merkle root merkle_root_bin = job.merkletree.withFirst(coinbase_hash) merkle_root_int = util.uint256_from_str(merkle_root_bin) # 3. Serialize header with given merkle, ntime and nonce header_bin = job.serialize_header(merkle_root_int, ntime_bin, nonce_bin) # 4. Reverse header and compare it with target of the user if settings.COINDAEMON_ALGO == 'scrypt': hash_bin = ltc_scrypt.getPoWHash(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ])) elif settings.COINDAEMON_ALGO == 'scrypt-jane': hash_bin = yac_scrypt.getPoWHash(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ]), int(ntime, 16)) elif settings.COINDAEMON_ALGO == 'quark': hash_bin = quark_hash.getPoWHash(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ])) else: hash_bin = util.doublesha(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ])) hash_int = util.uint256_from_str(hash_bin) scrypt_hash_hex = "%064x" % hash_int header_hex = binascii.hexlify(header_bin) if settings.COINDAEMON_ALGO == 'scrypt' or settings.COINDAEMON_ALGO == 'scrypt-jane': header_hex = header_hex+"000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000" elif settings.COINDAEMON_ALGO == 'quark': header_hex = header_hex+"000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000" else: pass target_user = self.diff_to_target(difficulty) if hash_int > target_user: raise SubmitException("Share is above target") # Mostly for debugging purposes target_info = self.diff_to_target(100000) if hash_int <= target_info: log.info("Yay, share with diff above 100000") # Algebra tells us the diff_to_target is the same as hash_to_diff share_diff = int(self.diff_to_target(hash_int)) # 5. Compare hash with target of the network if hash_int <= job.target: # Yay! It is block candidate! log.info("We found a block candidate! %s" % scrypt_hash_hex) # Reverse the header and get the potential block hash (for scrypt only) #if settings.COINDAEMON_ALGO == 'scrypt' or settings.COINDAEMON_ALGO == 'sha256d': # if settings.COINDAEMON_Reward == 'POW': block_hash_bin = util.doublesha(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ])) block_hash_hex = block_hash_bin[::-1].encode('hex_codec') #else: block_hash_hex = hash_bin[::-1].encode('hex_codec') #else: block_hash_hex = hash_bin[::-1].encode('hex_codec') # 6. Finalize and serialize block object job.finalize(merkle_root_int, extranonce1_bin, extranonce2_bin, int(ntime, 16), int(nonce, 16)) if not job.is_valid(): # Should not happen log.exception("FINAL JOB VALIDATION FAILED!(Try enabling/disabling tx messages)") # 7. Submit block to the network serialized = binascii.hexlify(job.serialize()) if settings.BLOCK_CHECK_SCRYPT_HASH: on_submit = self.bitcoin_rpc.submitblock(serialized, scrypt_hash_hex) else: on_submit = self.bitcoin_rpc.submitblock(serialized, block_hash_hex) if on_submit: self.update_block() if settings.SOLUTION_BLOCK_HASH: return (header_hex, block_hash_hex, share_diff, on_submit) else: return (header_hex, scrypt_hash_hex, share_diff, on_submit) if settings.SOLUTION_BLOCK_HASH: # Reverse the header and get the potential block hash (for scrypt only) only do this if we want to send in the block hash to the shares table block_hash_bin = util.doublesha(''.join([ header_bin[i*4:i*4+4][::-1] for i in range(0, 20) ])) block_hash_hex = block_hash_bin[::-1].encode('hex_codec') return (header_hex, block_hash_hex, share_diff, None) else: return (header_hex, scrypt_hash_hex, share_diff, None)
def block_header_hash(chain, header): import yac_scrypt b = chain.parse_block_header(header) return yac_scrypt.getPoWHash( header, b['nTime'] + YAC_START_TIME - chain.start_time)
def submit_share(self, job_id, worker_name, session, extranonce1_bin, extranonce2, ntime, nonce, difficulty): '''Check parameters and finalize block template. If it leads to valid block candidate, asynchronously submits the block back to the bitcoin network. - extranonce1_bin is binary. No checks performed, it should be from session data - job_id, extranonce2, ntime, nonce - in hex form sent by the client - difficulty - decimal number from session, again no checks performed - submitblock_callback - reference to method which receive result of submitblock() ''' # Check if extranonce2 looks correctly. extranonce2 is in hex form... if len(extranonce2) != self.extranonce2_size * 2: raise SubmitException( "Incorrect size of extranonce2. Expected %d chars" % (self.extranonce2_size * 2)) # Check for job job = self.get_job(job_id) if job == None: raise SubmitException("Job '%s' not found" % job_id) # Check if ntime looks correct if len(ntime) != 8: raise SubmitException("Incorrect size of ntime. Expected 8 chars") if not job.check_ntime(int(ntime, 16)): raise SubmitException("Ntime out of range") # Check nonce if len(nonce) != 8: raise SubmitException("Incorrect size of nonce. Expected 8 chars") # Check for duplicated submit if not job.register_submit(extranonce1_bin, extranonce2, ntime, nonce): log.info("Duplicate from %s, (%s %s %s %s)" % \ (worker_name, binascii.hexlify(extranonce1_bin), extranonce2, ntime, nonce)) raise SubmitException("Duplicate share") # Now let's do the hard work! # --------------------------- # 0. Some sugar extranonce2_bin = binascii.unhexlify(extranonce2) ntime_bin = binascii.unhexlify(ntime) nonce_bin = binascii.unhexlify(nonce) # 1. Build coinbase coinbase_bin = job.serialize_coinbase(extranonce1_bin, extranonce2_bin) coinbase_hash = util.doublesha(coinbase_bin) # 2. Calculate merkle root merkle_root_bin = job.merkletree.withFirst(coinbase_hash) merkle_root_int = util.uint256_from_str(merkle_root_bin) # 3. Serialize header with given merkle, ntime and nonce header_bin = job.serialize_header(merkle_root_int, ntime_bin, nonce_bin) # 4. Reverse header and compare it with target of the user hash_bin = yac_scrypt.getPoWHash( ''.join([header_bin[i * 4:i * 4 + 4][::-1] for i in range(0, 20)]), int(ntime, 16)) hash_int = util.uint256_from_str(hash_bin) scrypt_hash_hex = "%064x" % hash_int header_hex = binascii.hexlify(header_bin) header_hex = header_hex + "000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000" target_user = self.diff_to_target(difficulty) if hash_int > target_user and \ ( 'prev_jobid' not in session or session['prev_jobid'] < job_id \ or 'prev_diff' not in session or hash_int > self.diff_to_target(session['prev_diff']) ): raise SubmitException("Share is above target") # Mostly for debugging purposes target_info = self.diff_to_target(100000) if hash_int <= target_info: log.info("Yay, share with diff above 100000") # Algebra tells us the diff_to_target is the same as hash_to_diff share_diff = int(self.diff_to_target(hash_int)) # 5. Compare hash with target of the network if hash_int <= job.target: # Yay! It is block candidate! log.info("We found a block candidate! %s" % scrypt_hash_hex) # 6. Finalize and serialize block object job.finalize(merkle_root_int, extranonce1_bin, extranonce2_bin, int(ntime, 16), int(nonce, 16)) #if not job.is_valid(): # Should not happen # log.error("Final job validation failed!") # 7. Submit block to the network serialized = binascii.hexlify(job.serialize()) on_submit = self.bitcoin_rpc.submitblock(serialized, scrypt_hash_hex) return (header_hex, scrypt_hash_hex, share_diff, on_submit) return (header_hex, scrypt_hash_hex, share_diff, None)
def submit_share(self, job_id, worker_name, session, extranonce1_bin, extranonce2, ntime, nonce, difficulty): '''Check parameters and finalize block template. If it leads to valid block candidate, asynchronously submits the block back to the bitcoin network. - extranonce1_bin is binary. No checks performed, it should be from session data - job_id, extranonce2, ntime, nonce - in hex form sent by the client - difficulty - decimal number from session, again no checks performed - submitblock_callback - reference to method which receive result of submitblock() ''' # Check if extranonce2 looks correctly. extranonce2 is in hex form... if len(extranonce2) != self.extranonce2_size * 2: raise SubmitException("Incorrect size of extranonce2. Expected %d chars" % (self.extranonce2_size*2)) # Check for job job = self.get_job(job_id) if job == None: raise SubmitException("Job '%s' not found" % job_id) # Check if ntime looks correct if len(ntime) != 8: raise SubmitException("Incorrect size of ntime. Expected 8 chars") if not job.check_ntime(int(ntime, 16)): raise SubmitException("Ntime out of range") # Check nonce if len(nonce) != 8: raise SubmitException("Incorrect size of nonce. Expected 8 chars") # Check for duplicated submit if not job.register_submit(extranonce1_bin, extranonce2, ntime, nonce): log.info("Duplicate from %s, (%s %s %s %s)" % \ (worker_name, binascii.hexlify(extranonce1_bin), extranonce2, ntime, nonce)) raise SubmitException("Duplicate share") # Now let's do the hard work! # --------------------------- # 0. Some sugar extranonce2_bin = binascii.unhexlify(extranonce2) ntime_bin = binascii.unhexlify(ntime) nonce_bin = binascii.unhexlify(nonce) # 1. Build coinbase coinbase_bin = job.serialize_coinbase(extranonce1_bin, extranonce2_bin) coinbase_hash = util.doublesha(coinbase_bin) # 2. Calculate merkle root merkle_root_bin = job.merkletree.withFirst(coinbase_hash) merkle_root_int = util.uint256_from_str(merkle_root_bin) # 3. Serialize header with given merkle, ntime and nonce header_bin = job.serialize_header(merkle_root_int, ntime_bin, nonce_bin) # 4. Reverse header and compare it with target of the user hash_bin = yac_scrypt.getPoWHash (''. join ([header_bin [i * 4: i * 4 +4] [:: -1] for i in range (0, 20)]), int (ntime, 16)); hash_int = util.uint256_from_str(hash_bin) scrypt_hash_hex = "%064x" % hash_int header_hex = binascii.hexlify(header_bin) header_hex = header_hex+"000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000" target_user = self.diff_to_target(difficulty) if hash_int > target_user and \ ( 'prev_jobid' not in session or session['prev_jobid'] < job_id \ or 'prev_diff' not in session or hash_int > self.diff_to_target(session['prev_diff']) ): raise SubmitException("Share is above target") # Mostly for debugging purposes target_info = self.diff_to_target(100000) if hash_int <= target_info: log.info("Yay, share with diff above 100000") # Algebra tells us the diff_to_target is the same as hash_to_diff share_diff = int(self.diff_to_target(hash_int)) # 5. Compare hash with target of the network if hash_int <= job.target: # Yay! It is block candidate! log.info("We found a block candidate! %s" % scrypt_hash_hex) # 6. Finalize and serialize block object job.finalize(merkle_root_int, extranonce1_bin, extranonce2_bin, int(ntime, 16), int(nonce, 16)) #if not job.is_valid(): # Should not happen # log.error("Final job validation failed!") # 7. Submit block to the network serialized = binascii.hexlify(job.serialize()) on_submit = self.bitcoin_rpc.submitblock(serialized, scrypt_hash_hex) return (header_hex, scrypt_hash_hex, share_diff, on_submit) return (header_hex, scrypt_hash_hex, share_diff, None)