for u in unspent: balance += u['amount'] print(f"Unlocked unspent: {u['amount']}") if u['amount'] == MN_COLLAT: print(f"Already have output: {u['txid']} {u['vout']}") if balance > MN_COLLAT: possible_mn += 1 print ( f"Got balance: {balance}") print ( f"Total possible MN: {possible_mn}") print ( p.getstakingstatus()) exit(1) if balance > MN_COLLAT: print("Enough unspent tx for new mn") print("Creating unspent mn output ") mn_address = p.getnewaddress() print(f"Got address: {mn_address}") pw = '' p.walletpassphrase(pw, 1) txid = p.sendtoaddress(mn_address, MN_COLLAT) txconf = 0 while txconf == False: unspent = p.listunspent() for o in unspent : if o['txid'] ==txid: print(f"{o['txid']} {o['vout']}") txconf = True print("Waiting for tx broadcast...\r") sleep(10)
class eccoinNode(cryptoNode): version_min = 30000 version_max = 99999 win_zmq_bug = 30300 version_fPacketSig = 30300 serviceIdx = count(start=1) respondIdx = count(start=1) ############################################################################ def __init__(self, symbol, rpc_address, rpc_user, rpc_pass, service_id=1, respond_id=None): super().__init__(symbol, rpc_address, rpc_user, rpc_pass) self.proxy = Proxy( 'http://%s:%s@%s' % (rpc_user, rpc_pass, rpc_address)) # Not thread safe ... self.prox2 = Proxy( 'http://%s:%s@%s' % (rpc_user, rpc_pass, rpc_address)) # ... hence needing 2 self.serviceId = service_id self.respondId = respond_id self.serviceKey = '' self.respondKey = '' self.routingTag = '' self.ecresolve_tags = [] # ECC feature flags (based on version number) self.fPacketSig = False # Caching prior unlock state for post transaction reversion self.cached_prior_walletinfo = {} ############################################################################ def __getattr__(self, method): return getattr(self.proxy, method) ############################################################################ def initialise(self): try: info = self.proxy.getnetworkinfo() except ValueError: raise cryptoNodeException( 'Failed to connect - error in rpcuser or rpcpassword for eccoin' ) except pycurl.error: raise cryptoNodeException( 'Failed to connect - check that eccoin daemon is running') except exc.RpcInWarmUp: raise cryptoNodeException( 'Failed to connect - eccoin daemon is starting but not ready - try again after 60 seconds' ) except exc.RpcMethodNotFound: raise cryptoNodeException( 'RPC getnetworkinfo unavailable for {} daemon'.format( self.symbol)) # ECC daemon version checking and feature enablement if not self.version_min <= info['version'] <= self.version_max: raise cryptoNodeException( 'eccoind version {} not supported - please run a version in the range {}-{}' .format(info['version'], self.version_min, self.version_max)) if (info['version'] == self.win_zmq_bug) and (sys.platform in ['win32', 'cygwin']): raise cryptoNodeException( 'eccoind version {} not supported on Windows - please upgrade'. format(info['version'])) self.fPacketSig = info['version'] >= self.version_fPacketSig # ECC messaging buffer setup try: self.routingTag = self.proxy.getroutingpubkey() if self.serviceId: self.serviceKey = self.proxy.registerbuffer(self.serviceId) if self.respondId: self.respondKey = self.proxy.registerbuffer(self.respondId) except exc.RpcInternalError: raise cryptoNodeException( 'API Buffer was not correctly unregistered or another instance running - try again after 60 seconds' ) # ZMQ detection and configuration loading try: zmqnotifications = self.proxy.getzmqnotifications() except pycurl.error: raise cryptoNodeException( 'Blockchain node for {} not available or incorrectly configured' .format(self.symbol)) except (exc.RpcMethodNotFound, ValueError): zmqnotifications = [] for zmqnotification in zmqnotifications: if zmqnotification['type'] == 'pubhashblock': self.zmqAddress = zmqnotification['address'] # Load ecresolve routing tags and setup routes for subsequent ecc network name resolution self.ecresolve_tags = self.get_ecresolve_tags() route = [] for tag in self.ecresolve_tags: try: self.proxy.findroute(tag) route.append(self.proxy.haveroute(tag)) except exc.RpcInvalidAddressOrKey: raise cryptoNodeException( 'Routing tag for ecresolve has invalid base64 encoding : {}' .format(tag)) if not any(route): raise cryptoNodeException( 'No route available to ecresolve across all {} configured routing tags' .format(len(self.ecresolve_tags))) ############################################################################ def refresh(self): self.blocks = self.proxy.getblockcount() self.peers = self.proxy.getconnectioncount() ############################################################################ def get_balance(self): return self.proxy.getbalance() ############################################################################ def get_unlocked_balance(self): return self.proxy.getbalance() ############################################################################ def get_unconfirmed_balance(self): return self.proxy.getunconfirmedbalance() ############################################################################ def get_new_address(self): return self.proxy.getnewaddress() ############################################################################ def wallet_locked(self, cache_prior_state=False): info = self.proxy.getwalletinfo() if cache_prior_state and info.keys() >= { 'unlocked_until', 'staking_only_unlock' }: self.cached_prior_walletinfo = info.copy() if 'unlocked_until' in info: if 'staking_only_unlock' in info: return info['staking_only_unlock'] or (info['unlocked_until'] == 0) else: return info['unlocked_until'] == 0 return False # unencrypted wallet ############################################################################ def unlock_wallet(self, passphrase, seconds, staking=False): try: self.proxy.walletpassphrase(passphrase, seconds, staking) except exc.RpcWalletPassphraseIncorrect: return False else: # Cache passphrase for later call to revert_wallet_lock if self.cached_prior_walletinfo: self.cached_prior_walletinfo['passphrase'] = passphrase return True ############################################################################ def revert_wallet_lock(self): if self.cached_prior_walletinfo and 'passphrase' in self.cached_prior_walletinfo: if self.cached_prior_walletinfo['unlocked_until'] > 0: seconds = self.cached_prior_walletinfo['unlocked_until'] - int( time.time()) self.unlock_wallet( self.cached_prior_walletinfo['passphrase'], seconds, self.cached_prior_walletinfo['staking_only_unlock']) self.cached_prior_walletinfo.clear() ############################################################################ def send_to_address(self, address, amount, comment): try: txid = self.proxy.sendtoaddress(address, amount, comment) except exc.RpcWalletUnlockNeeded: raise cryptoNodeException('Wallet locked - please unlock') except exc.RpcWalletInsufficientFunds: raise cryptoNodeException('Insufficient funds in wallet') except exc.RpcTypeError: raise cryptoNodeException('Invalid amount') except exc.RpcWalletError: raise cryptoNodeException('Amount too small') else: return txid ############################################################################ def reset_service_buffer_timeout(self): if self.serviceKey: try: bufferSig = self.prox2.buffersignmessage( self.serviceKey, 'ResetBufferTimeout') self.prox2.resetbuffertimeout(self.serviceId, bufferSig) except pycurl.error: self.serviceKey = '' raise cryptoNodeException( 'Failed to connect - check that eccoin daemon is running') return True return False ############################################################################ def reset_respond_buffer_timeout(self): if self.respondKey: try: bufferSig = self.prox2.buffersignmessage( self.respondKey, 'ResetBufferTimeout') self.prox2.resetbuffertimeout(self.respondId, bufferSig) except pycurl.error: self.serviceKey = '' raise cryptoNodeException( 'Failed to connect - check that eccoin daemon is running') return True return False ############################################################################ def reset_buffer_timeouts(self): serviceResult = self.reset_service_buffer_timeout() respondResult = self.reset_respond_buffer_timeout() return serviceResult or respondResult # OR semantics because the return value is used to gate timer setup ############################################################################ def get_ecresolve_tags(self): domain = 'ecchat.io' # TODO - Make this daemon version dependent ref new RPC tags = [] try: resolved = dns.resolver.resolve(domain, 'TXT') except: raise cryptoNodeException( 'Error while resolving ecresolve routing tags from {} TXT record' .format(domain)) for entry in resolved: decoded_entry = entry.to_text()[1:-1].split('=', 1) if (len(decoded_entry) == 2) and (decoded_entry[0] == 'ecresolve'): tags.append(decoded_entry[1]) return tags ############################################################################ def setup_route(self, targetRoute): try: self.proxy.findroute(targetRoute) isRoute = self.proxy.haveroute(targetRoute) except exc.RpcInvalidAddressOrKey: raise cryptoNodeException( 'Routing tag has invalid base64 encoding : {}'.format( targetRoute)) if not isRoute: raise cryptoNodeException( 'No route available to : {}'.format(targetRoute)) ############################################################################ def send_packet(self, dest_key, protocol_id, data): if self.fPacketSig: signature = self.proxy.tagsignmessage(data) self.proxy.sendpacket(dest_key, protocol_id, data, self.routingTag, signature) else: self.proxy.sendpacket(dest_key, protocol_id, data) ############################################################################ def get_service_buffer(self): if self.serviceKey: bufferCmd = 'GetBufferRequest:' + str(self.serviceId) + str( next(self.serviceIdx)) bufferSig = self.proxy.buffersignmessage(self.serviceKey, bufferCmd) eccbuffer = self.proxy.getbuffer(self.serviceId, bufferSig) return eccbuffer else: return None ############################################################################ def get_respond_buffer(self): if self.respondKey: bufferCmd = 'GetBufferRequest:' + str(self.respondId) + str( next(self.respondIdx)) bufferSig = self.proxy.buffersignmessage(self.respondKey, bufferCmd) eccbuffer = self.proxy.getbuffer(self.respondId, bufferSig) return eccbuffer else: return None ############################################################################ def get_buffer(self, protocol_id=1): if protocol_id == self.serviceId: return self.get_service_buffer() if protocol_id == self.respondId: return self.get_respond_buffer() return None ############################################################################ def shutdown(self): if self.serviceKey: bufferSig = self.proxy.buffersignmessage(self.serviceKey, 'ReleaseBufferRequest') self.proxy.releasebuffer(self.serviceId, bufferSig) self.serviceKey = '' if self.respondKey: bufferSig = self.proxy.buffersignmessage(self.respondKey, 'ReleaseBufferRequest') self.proxy.releasebuffer(self.respondId, bufferSig) self.respondKey = ''
class bitcoinNode(cryptoNode): ############################################################################ def __init__(self, symbol, rpc_address, rpc_user, rpc_pass): super().__init__(symbol, rpc_address, rpc_user, rpc_pass) self.proxy = Proxy('http://%s:%s@%s' % (rpc_user, rpc_pass, rpc_address)) ############################################################################ def __getattr__(self, method): return getattr(self.proxy, method) ############################################################################ def initialise(self): try: info = self.proxy.getnetworkinfo() except ValueError: raise cryptoNodeException( 'Failed to connect - error in rpcuser or rpcpassword for {} daemon' .format(self.symbol)) except pycurl.error: raise cryptoNodeException( 'Failed to connect - check that {} daemon is running'.format( self.symbol)) except exc.RpcInWarmUp: raise cryptoNodeException( 'Failed to connect - {} daemon is starting but not ready - try again after 60 seconds' .format(self.symbol)) except exc.RpcMethodNotFound: raise cryptoNodeException( 'RPC getnetworkinfo unavailable for {} daemon'.format( self.symbol)) try: zmqnotifications = self.proxy.getzmqnotifications() except pycurl.error: raise cryptoNodeException( 'Blockchain node for {} not available or incorrectly configured' .format(self.symbol)) except (exc.RpcMethodNotFound, ValueError): zmqnotifications = [] for zmqnotification in zmqnotifications: if zmqnotification['type'] == 'pubhashblock': self.zmqAddress = zmqnotification['address'] ############################################################################ def refresh(self): self.blocks = self.proxy.getblockcount() self.peers = self.proxy.getconnectioncount() ############################################################################ def get_balance(self): try: result = self.proxy.getbalance() except exc.RpcException as error: raise cryptoNodeException('{} daemon returned error: {}'.format( self.symbol, str(error))) else: return result ############################################################################ def get_unlocked_balance(self): try: result = self.proxy.getbalance() except exc.RpcException as error: raise cryptoNodeException('{} daemon returned error: {}'.format( self.symbol, str(error))) else: return result ############################################################################ def get_unconfirmed_balance(self): try: result = self.proxy.getunconfirmedbalance() except exc.RpcException as error: raise cryptoNodeException('{} daemon returned error: {}'.format( self.symbol, str(error))) else: return result ############################################################################ def get_new_address(self): return self.proxy.getnewaddress() ############################################################################ def wallet_locked(self, cache_prior_state=False): info = self.proxy.getwalletinfo() if 'unlocked_until' in info: return info['unlocked_until'] == 0 return False ############################################################################ def unlock_wallet(self, passphrase, seconds, staking=False): try: self.proxy.walletpassphrase(passphrase, seconds) except exc.RpcWalletPassphraseIncorrect: return False else: return True ############################################################################ def revert_wallet_lock(self): pass ############################################################################ def send_to_address(self, address, amount, comment): try: txid = self.proxy.sendtoaddress(address, amount, comment) except exc.RpcWalletUnlockNeeded: raise cryptoNodeException('Wallet locked - please unlock') except exc.RpcWalletInsufficientFunds: raise cryptoNodeException('Insufficient funds in wallet') except exc.RpcTypeError: raise cryptoNodeException('Invalid amount') except exc.RpcWalletError: raise cryptoNodeException('Amount too small') else: return txid ############################################################################ def shutdown(self): pass
class RPC: def __init__(self, username, password, ip, port=24127): self.proxy = Proxy( service_url=f"http://{username}:{password}@{ip}:{port}") # == Wallet == # -- list -- def listunspent(self): return self.proxy.listunspent() def listlockunspent(self): return self.proxy.listlockunspent() def listaccounts(self): return self.proxy.listaccounts() def listtransactions(self): return self.proxy.listtransactions() def listaddressgroupings(self): return self.proxy.listaddressgroupings() def getstakingstatus(self): return self.proxy.getstakingstatus() def getbalance(self): return self.proxy.getbalance() def getnewaddress(self): return self.proxy.getnewaddress() def walletpassphrase(self, pw): return self.proxy.walletpassphrase(pw, 1) def sendtoaddress(self, address, send): return self.proxy.sendtoaddress(address, send) def dumpprivkey(self, address, two_fa=''): return self.proxy.dumpprivkey(address, two_fa) def createrawtransaction(self, inputs, outputs): return self.proxy.createrawtransaction(inputs, outputs) def decoderawtransaction(self, tx): return self.proxy.decoderawtransaction(tx) def signrawtransaction(self, tx, previous_tx, keychain): return self.proxy.signrawtransaction(tx, previous_tx, keychain) def sendrawtransaction(self, signedTx): return self.proxy.sendrawtransaction(signedTx) def lockunspent(self, lock, tx): return self.proxy.lockunspent(lock, tx) # == Polis == def getMasternode(self, arg): return self.proxy.masternode(arg) def masternodelist(self, mode, filter): return self.proxy.masternodelist(mode, filter) def masternodebroadcast(self, command): return self.proxy.masternodebroadcast(command)