def build_pszTimestamp(coinname, timestamp): # Build the timestamp. First, replace all {XYZ} for coin in re.findall(r'\{[A-Z]{3}\}', timestamp): timestamp = timestamp.replace(coin, get_latest_block_str(coin[1:4])) verb("timestamp after substitution: " + timestamp) return coinname + \ blake2s(timestamp.encode('UTF-8')).hexdigest()
async def run(self): verb('Starting solver with command {}'.format(self.cmdline)) create = asyncio.create_subprocess_exec( *self.cmdline, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT) try: self.solver = await create verb('Solver started.') except FileNotFoundError as e: raise SolverException("Could not find binary {}; is the path correct?".format(self.cmdline[0])) except Exception as e: raise SolverException("Failed to execute '{}': {}".format(self.cmdline, e)) self.banner = await self.eat_banner() verb('Banner:\n' + self.banner) try: while True: nonce, sols = await self.parse_solutions() verb('Solver returned {:d} solutions for nonce {}' .format(len(sols), b2lx(nonce))) for sol in sols: if IsValidSolution(self.header, nonce, sol): return (sol, nonce) finally: self.solver.terminate() await self.solver.communicate() # .wait() would deadlock if pipe is full
def build_EquihashInputHeader(args): pszTimestamp = args.pszTimestamp if args.pszTimestamp else \ build_pszTimestamp(args.coinname, args.timestamp) verb("pszTimestamp: " + pszTimestamp) pk, bits = args.pubkey, args.bits extranonce = args.extranonce if args.extranonce else bits # Input transaction scriptSig = CScript() + extranonce + b'\x04' + pszTimestamp.encode('UTF-8') txin=CMutableTxIn(scriptSig=scriptSig) # Output transaction scriptPubKey = CScript() + pk + OP_CHECKSIG txout = CMutableTxOut(nValue = args.value, scriptPubKey = scriptPubKey) tx = CMutableTransaction(vin=[txin], vout=[txout]) txhash = tx.GetTxid() verb("TX/merkle root hash: " + b2lx(txhash)) return CEquihashHeader(nTime=args.time, nBits=bits, nNonce=args.nonce, hashMerkleRoot=txhash)
def parse_args(): def lbytes32(s): """Converts a hex string into a 32 bytes long byte array, litte endian""" if len(s) > 32: warn( 'Nonce can be at most 32 bytes long, is {:d}! Will be truncated' .format(len(s))) return lx(s[:64]) return lx('0' * (64 - len(s)) + s) def split(s): """Runs s.split()""" return s.split() def smartint(i): if i.startswith('0x'): return int(i, 16) else: return int(i, 10) parser = argparse.ArgumentParser( description= "This script uses any Equihash solver to find a solution for the specified genesis block" ) parser.add_argument( "-c", "--chainparams", dest="chain", default="mainnet", choices=["mainnet", "testnet", "regtest"], help="""Select the core chain parameters for PoW limit and parameters N and K.""") parser.add_argument( "-t", "--time", dest="time", action="store", type=int, default=int(time.time()), help="unix time to set in block header (defaults to current time)") parser.add_argument( "-C", "--coinname", dest="coinname", default="Zcash", help= "the coin name prepends the blake2s hash of timestamp in pszTimestamp") parser.add_argument( "-z", "--timestamp", dest="timestamp", default= "The Economist 2016-10-29 Known unknown: Another crypto-currency is born. BTC#436254 0000000000000000044f321997f336d2908cf8c8d6893e88dbf067e2d949487d ETH#2521903 483039a6b6bd8bd05f0584f9a078d075e454925eb71c1f13eaff59b405a721bb DJIA close on 27 Oct 2016: 18,169.68", help="""the pszTimestamp found in the input coinbase transaction script. Will be blake2s'd and then prefixed by coin name. Default is Zcash's mainnet pszTimestamp. You may use tokens of the form {XYZ}, which will be replaced by the current block index and hash of coin XZY (BTC, ETH or ZEC). Always the latest block is retrieved, regardless of time argument.""") parser.add_argument( "-Z", "--pszTimestamp", dest="pszTimestamp", default=None, help="Specify the pszTimestamp directly. Will ignore options -C and -z" ) parser.add_argument( "-p", "--pubkey", dest="pubkey", type=x, default= x("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f" ), help="the pubkey found in the output transaction script") parser.add_argument( "-b", "--bits", dest="bits", type=smartint, default=0x1f07ffff, help="the target in compact representation, defining a difficulty of 1" ) parser.add_argument( "-E", "--extra-nonce", dest="extranonce", type=smartint, default=None, help="Usually, the coinbase script contains the nBits as fixed first" " data, which in bitcoin is also referred to as extra nonce. This" " conventional behaviour can be changed by specifying this parameter" " (not recommended for mainnet, useful for testnet).") parser.add_argument( "-V", "--value", dest="value", default=0, type=int, help="output transaction value in zatoshi (1 ZEC = 100000000 zatoshi)") parser.add_argument( "-n", "--nonce", dest="nonce", default=b'\x00' * 32, type=lbytes32, help="nonce to start with when searching for a valid" " equihash solution; parsed as hex, leading zeros may be omitted.") parser.add_argument("-r", "--rounds", dest="rounds", default=1, type=int, help="how many nonces to check at most") parser.add_argument( "-s", "--solver", dest="solver", type=split, default=split("../equihash/equi"), help="""path to solver binary. Currently supported are silentarmy (sa-solver) and Tromp (equi/equi485). Command line arguments may be passed, although that should be unnecessary.""") parser.add_argument("-S", "--solver-type", dest="solver_type", default=None, choices=["tromp", "silentarmy"], help="""Set the type of solver explicitly. Otherwise GenesisZ tries to infer the type from the binary name (equi* -> tromp, sa-solver -> silentarmy)""") parser.add_argument( "-T", "--threads", dest="threads", default=1, type=int, help="How many CPU threads to use when solving with Tromp.") parser.add_argument("-v", "--verbose", dest="verbose", action="store_true", help="verbose output") args = parser.parse_args() logger.verbose = args.verbose SelectCoreParams(args.chain) # infer solver type from binary if not set if not args.solver_type: if args.solver[0].endswith('sa-solver'): args.solver_type = 'silentarmy' elif re.search(r'eq\w*$', args.solver[0]): args.solver_type = 'tromp' else: fatal( "Couldn't infer solver type from binary name and type not set with -S" ) # silentarmy only supports N,K=200,9 if args.solver_type == 'silentarmy' and args.chain == 'regtest': fatal( "Silentarmy doesn't support regtest parameters N,K=48,5. Get Tromp's equihash solver." ) verb('Chain: ' + args.chain) verb('Time: {:d}'.format(args.time)) verb('Start Nonce: ' + b2lx(args.nonce)) verb('Pubkey: ' + b2x(args.pubkey)) verb('Solver: {}'.format(args.solver)) verb('Solver type: ' + args.solver_type) return args