class XP_RPC(): def __init__(self): self.connection = AuthServiceProxy( settings.RPC_URL % (settings.rpc_user, settings.rpc_password)) self.tax = 1.0 def get_address(self, name): # commands = [["getaddressesbyaccount", name]] address = self.connection.getaddressesbyaccount(name) if address: address = address[0] else: address = self.connection.getaccountaddress(name) return address def show_balance(self, name): address = self.connection.getaddressesbyaccount(name) if address: balance = self.connection.getbalance(name) else: address = self.connection.getaccountaddress(name) balance = self.connection.getbalance(name) print(balance) return balance def move_balance(self, name, to_name, amount): address = self.connection.getaddressesbyaccount(name) to_address = self.connection.getaddressesbyaccount(to_name) if address and to_address: # req = self.connection.move(name, to_name, amount) req = self.connection.move(name, to_name, amount) elif address: self.connection.getaccountaddress(to_name) req = self.connection.move(name, to_name, amount) else: req = "Error" return req def send_from(self, name, address, amount): txid = self.connection.sendfrom(name, address, amount) tx = self.connection.gettransaction(txid) if tx: fee = tx["fee"] else: fee = 0 self.move_balance(name, "taxpot", float(fee) + self.tax) return txid def validateaddress(self, address): return self.connection.validateaddress(address)['isvalid']
def getAccountAddress(self, acc=""): global walletProcess global rpc_conn if not walletProcess or not walletProcess.is_running(): self.__copyMyriadcoinConf() self.openWallet(shell=False) count = 0 walletAddress = None MAX_ITER = 60 while not walletAddress and count < MAX_ITER: try: rpc_conn = AuthServiceProxy("http://%s:%[email protected]:%s"%(USER, self.password, PORT)) walletAddress = rpc_conn.getaccountaddress('MyriadSwitcher_' + acc) #walletAddress = rpc_conn.getaccountaddress("Myriad_Switcher") except: pass count += 1 time.sleep(1) return walletAddress
class BitcoinService: def __init__(self): self.access = AuthServiceProxy("http://*****:*****@[email protected]:8332") def getInfo(self): return self.access.getinfo() def getlistreceivedbyaddress(self, num): return self.access.listreceivedbyaddress(num) def getBalance(self): return self.access.getbalance() def isValidAddress(self, addr): return self.access.validateaddress(addr) def generateAddress(self): return self.access.getnewaddress() def getAccount(self, addr): return self.access.getaccount(addr) def getAccountAddr(self, account): return self.access.getaccountaddress(account) def getreceivedbyaddress(self, addr): return self.access.getreceivedbyaddress(addr) def sendtoaddress(self, addr, amount, comment=""): return self.acccess.sendtoaddress(addr, amount, comment)
async def deposit(self, ctx): client = AuthServiceProxy(rpc_connection) user_id = str(ctx.author.id) if ctx.channel.id == 723493757860708714: if not user_db.check_user(user_id): embed = discord.Embed(title="**For first-use-user**", color=0x0043ff) embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url_as( format='png', size=256)) embed.add_field(name="First of all, please type `//help`", value="Welcome to world of Tip MBC !") embed.set_thumbnail( url=self.bot.user.avatar_url_as(format='png', size=1024)) embed.set_footer(text="Tip MBC {0} [Owner: {1}]".format( config.VERSION, self.bot.get_user(config.OWNER_ID)), icon_url=self.bot.user.avatar_url_as( format='png', size=256)) await ctx.channel.send(embed=embed) else: pass account = str(ctx.author.id) user_name = ctx.author.display_name address = client.getaccountaddress(account) embed = discord.Embed(title="**Your deposit address**", color=0x0043ff) embed.add_field(name="please send MBC to this address.", value="Click to enlarge the QR code") embed.set_thumbnail( url= 'https://chart.googleapis.com/chart?cht=qr&chs=500x500&chl={0}' .format(address)) embed.set_author(name=user_name, icon_url=ctx.author.avatar_url_as( format='png', size=256)) embed.set_footer(text="Tip MBC {0} [Owner: {1}]".format( config.VERSION, self.bot.get_user(config.OWNER_ID)), icon_url=self.bot.user.avatar_url_as( format='png', size=256)) await ctx.channel.send(embed=embed) await ctx.channel.send("```{0}```".format(address)) else: embed = discord.Embed(title="Oops", color=0x7152b6) embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url_as(format='png', size=256)) embed.add_field( name="Wrong Channel", value="Please use #tipbot to use this tipbot", ) await ctx.channel.send(embed=embed)
class BTcoin: def __init__(self, bt_account_id , username, password, hostname, port ): self.bt_account_id = bt_account_id self.coin_client = AuthServiceProxy("http://%s:%s@%s:%s" % (username, password, hostname, port)) if not self.check_client_connection(): print "Error: Failed to connect or authenticate with the client. Please check it's running and configured correctly." # Verify client def check_client_connection(self): try: test = self.coin_client.getinfo() return True except socket.error: return False except ValueError: return False # bitcoin listaccounts def getAccount(self): return self.bt_account_id # bitcoin getaccountaddress <bt_account_id> def getAddress(self): return self.coin_client.getaccountaddress( self.bt_account_id ) # bitcoin getbalance def getBalance(self): return self.coin_client.getbalance() # bitcoin getnewaddress def getNewAddress( self): return self.coin_client.getnewaddress( self.bt_account_id ) # bitcoin listtransactions "" def getListTransactions( self): return self.coin_client.listtransactions( self.bt_account_id ) # bitcoin sendtoaddress <targetaddress> <amount> [comment] [comment-to] def doPayment(self,toBTaddress,coins): if not toBTaddress: return '<div class="alert alert-danger" style=" margin: 15px;" role="alert">Error - no payment address set</div>' else: try: transaction = self.coin_client.sendtoaddress( toBTaddress , float(coins) ) transaction_url = "http://lbw.blockprobe.com/index.php/search?q=%s" % transaction html = '<div class="alert alert-info" style=" margin: 15px;" role="alert"><b>Your transaction is complete:</b> <a href="http://lbw.blockprobe.com/index.php/search?q=%s" target="_blank">%s</a></div>' % (transaction,transaction ) return html except JSONRPCException as e: return '<div class="alert alert-danger" style=" margin: 15px;" role="alert">Error - %s</div>' % e.error['message']
async def _deposit(self, ctx): client = AuthServiceProxy( f'http://{config.rpc_user}:{config.rpc_password}@{config.ip}:{config.rpc_port}' ) user_id = str(ctx.author.id) address = client.getaccountaddress(user_id) embed = await utility.make_embed(ctx, self.bot, title="**Your deposit address**", color=0x0043ff) embed.add_field(name=f'Send {config.currency} to this address.', value="Click to enlarge the QR code") embed.set_thumbnail( url= f'https://chart.googleapis.com/chart?cht=qr&chs=500x500&chl={address}' ) return [embed, address]
async def deposit(self, ctx): client = AuthServiceProxy(rpc_connection) user_id = str(ctx.author.id) user_name = ctx.author.name if not user_db.check_user(user_id): user_db.add_user(user_id, user_name) embed = discord.Embed( title="**How may I be of service?**", color=0x7152b6) embed.set_author( name=ctx.author.display_name, icon_url=ctx.author.avatar_url_as(format='png', size=256)) embed.add_field( name="To see all my available commands type `!help`", value="If you have any issues please let one of the team know.") embed.set_thumbnail(url=self.bot.user.avatar_url_as(format='png', size=1024)) embed.set_footer(text="TipBot v{0}".format(config.VERSION),icon_url=self.bot.user.avatar_url_as(format='png', size=256)) await ctx.channel.send(embed=embed) else: pass account = str(ctx.author.id) user_name = ctx.author.display_name address = client.getaccountaddress(account) embed = discord.Embed( title="**Your Umbru Deposit Address:**", color=0x7152b6) embed.add_field( name="Please use the following address to deposit Umbru.", value="Click on QR Code to enlarge.") embed.set_thumbnail(url='https://chart.googleapis.com/chart?cht=qr&chs=500x500&chl={0}'.format(address)) embed.set_author( name=user_name, icon_url=ctx.author.avatar_url_as(format='png', size=256)) embed.set_footer(text="TipBot v{0}".format(config.VERSION), icon_url=self.bot.user.avatar_url_as(format='png', size=256)) await ctx.channel.send(embed=embed) await ctx.channel.send("```{0}```".format(address))
class Connection: def __init__(self, user, passw, ip, port): self.con = AuthServiceProxy("http://%s:%s@%s:%d" % (user, passw, ip, port)) def validate_address(self, address): validate = self.con.validate_address(address) return validate['isvalid'] # Returns True or False def get_address(self, account): return self.con.getaccountaddress(account) def get_balance(self, account, minconf=1): return self.con.get_balance(account, minconf) def withdraw(self, account, destination, amount): if amount > self.get_balance(account) or amount <= 0: raise ValueError("Invalid amount.") else: return self.con.sendfrom(account, destination, amount) def tip(self, account, destination, amount): if amount > self.get_balance(account) or amount <= 0: raise ValueError("Invalid amount.") else: self.con.move(account, destination, amount) def rain(self, account, amount): if amount > self.get_balance(account) or amount <= 0: raise ValueError("Invalid amount.") else: accounts = self.con.listaccounts() eachTip = amount / len(accounts) for ac in accounts: self.tip(account, ac, eachTip) return eachTip
class UsdtWallet(): USDT_BLOCK_NUM = 'http://www.tokenview.com:8088/coin/latest/USDT' USDT_TX_API = 'https://api.omniexplorer.info/v1/transaction/address' USDT_URL_BALANCE = 'https://api.omniexplorer.info/v1/address/addr/' def __init__(self, consul_client=None): if consul_client: self.init_consul(consul_client) def init_consul(self, app, consul_client): self.propertyid = 31 # self.usdt_rpc_user = app.config["USDT_RPC_USER"] # self.usdt_rpc_password = app.config["USDT_RPC_PWD"] # self.usdt_passphrase = app.config.get('GETH_USDT_PASSPHRASE') # self.consul_client = consul_client # # self.wallet_url = self.consul_client.getRandomOneAvailableServiceIpPort(ConsulServiceName.USDTEREUM_CLI) # self.wallet_url = '47.52.131.71:7332' # print(self.wallet_url) # self.usdtcoin_cli = AuthServiceProxy( # "http://%s:%s@" % (self.usdt_rpc_user, self.usdt_rpc_password) + self.wallet_url, timeout=10) # if not self.is_connected(): # logging.error('Connect USDT wallet node fial') self.usdtcoin_cli = AuthServiceProxy("http://%s:%[email protected]:7332" % ('xianda', 'ABQOqmPZ0tr95f5Z')) def is_connected(self): """获取钱包状态判读是否链接""" try: if self.usdtcoin_cli.getwalletinfo().get('walletversion'): return True return False except Exception as e: return False def is_syncing(self): """节点是否在同步中""" # 注意返回Flase表示节点同步完成 info = self.usdtcoin_cli.getblockchaininfo() # print(info['blocks'], info['headers']) if info['blocks'] != info['headers']: return False else: return True def accountCreate(self, accountName): # 否则,创建账户,并返回账户地址 address = self.usdtcoin_cli.getaccountaddress(accountName) privateKey = self.usdtcoin_cli.dumpprivkey(address) return privateKey, address # 檢驗賬戶是否有效 def is_valid_address(self, address): if address is None or address == '': return False else: try: # print(self.usdtcoin_cli.validateaddress(address)) return self.usdtcoin_cli.validateaddress(address).get( 'isvalid') except: return False # 獲取餘額 def get_balance(self, address): """获取余额,默认最新区块""" try: balance = str( self.usdtcoin_cli.omni_getbalance(address, self.propertyid)['balance']) except Exception as e: logging.error('USDT node get balance error:{}'.format(str(e))) raise Exception('USDT node get balance error') return Decimal(balance) def get_block_num(self): """获取最新区块数""" try: block_num = self.usdtcoin_cli.getblockcount() except Exception as e: logging.error('Get eth node block number error:{}'.format(str(e))) return return block_num def get_nonce(self, address): """获取账户nonce值""" try: # pending 获得最新已使用的nonce,对nonce进行加1 nonce = len( self.usdtcoin_cli.omni_listpendingtransactions(address)) except Exception as e: logging.error('USDT node get balance error:{}'.format(str(e))) raise Exception('USDT node get balance error') return nonce def get_mian_block_num(self): """获取公链上的最新区块数""" try: header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36', } ret = session_pool.get(self.USDT_BLOCK_NUM, headers=header, timeout=30).json() if ret is None: logging.error('Get usdt main chain block number error') return block_num = ret.get('data') except Exception as e: logging.error( 'Get usdt main chain block number error:{}'.format(e)) return return block_num # int def get_minerFee(self, address): data = {'addr': address} try: balance = None rets = session_pool.post(self.USDT_URL_BALANCE, data=data, timeout=50).json().get('balance') if rets or len(rets) != 0: for ret in rets: if ret.get('propertyinfo') and int( ret.get('propertyinfo').get('propertyid')) == 0: balance = ret.get('value') except Exception as e: logging.error( 'Request USDT_TX_API error address:{},error:{},url:{}'.format( address, str(e), self.USDT_TX_API)) raise Exception('USDT node get balance error') return Decimal(balance) / 100000000 def usdt_transaction_record(self, address, last_timestamp, start_block=None, end_block=None): """查询账户交易记录""" if start_block is None: start_block = 0 if end_block is None: end_block = 99999999 # 可能会有重复记录,使用此方法 run_function = lambda x, y: x if y in x else x + [y] data = {'addr': address, 'page': 0} try: rets = session_pool.post(self.USDT_TX_API, data=data, timeout=50).json() except Exception as e: logging.error( 'Request USDT_TX_API error address:{},error:{},url:{}'.format( address, str(e), self.USDT_TX_API)) rets = None new_records = [] ret = rets.get('transactions') if ret is None: return new_records ret_page_num = int(rets.get('pages')) if ret_page_num == 1: # print(ret_page_num) self.query_records(address, ret, new_records, last_timestamp, start_block, end_block) return (reduce(run_function, [ [], ] + new_records)) else: for i in range(0, ret_page_num): data = {'addr': address, 'page': i} try: ret = session_pool.post( self.USDT_TX_API, data=data, timeout=50).json().get('transactions') except Exception as e: logging.error( 'Request USDT_TX_API error address:{},error:{},url:{}'. format(address, str(e), self.USDT_TX_API)) ret = None if ret is None: return new_records self.query_records(address, ret, new_records, last_timestamp, start_block, end_block) return (reduce(run_function, [ [], ] + new_records)) def query_records(self, address, records, new_records, last_timestamp, start_block, end_block): for record in records: propertyid = record.get('propertyid') valid = record.get('valid') block = record.get('block') if valid and int(propertyid) == 31 and int(start_block) <= int( block) and int(block) <= int(end_block): to_address = record['referenceaddress'] # 是否为收款记录 current_timestamp = int(record['blocktime']) # 当前记录时间戳 confirmations = int(record['confirmations']) # 交易记录确认数 record_hash = record['txid'] amount = Decimal(record['amount']) if to_address.lower() != address.lower(): continue if int(last_timestamp) > int(current_timestamp): continue if Order.hash_is_exist(record_hash): continue if amount < Decimal('0.0000001'): continue if confirmations < 2: break else: new_records.append(record) else: if records is None: logging.error( 'Request USDT_TX_API fail address:{} ret:{}, url:{}'. format(address, str(records), self.USDT_TX_API)) return new_records def hash_get_detail(self, tx_hash): """hash获取交易细节,用于确认链外交易是否被确认""" # 交易是否被确认.status=1(被确认) is_confirm = False # 是否确认 is_success = False # 如果已确认,交易是否成功 msg = None # 未被确认返回异常信息(一般超时),确认失败:失败的细节,确认成功:交易详情 fee = None # 确认成功交易的手续费 try: ret = self.usdtcoin_cli.omni_gettransaction(tx_hash) # 获取交易细节 except Exception as e: msg = str(e) return is_confirm, is_success, msg, fee confirm = ret.get('confirmations') if confirm < 1: # 确认交易失败 msg = dict(fail_detail=str(ret)) return is_confirm, is_success, msg, fee else: # 确认交易成功 is_confirm = True is_success = True fee = ret.get('fee') msg = dict(confirm=str(ret), tx_detail=str(ret)) return is_confirm, is_success, msg, fee def payment(self, addrfrom, addrto, amount): """普通付款""" # 单位换算 payload = {'from': addrfrom, 'to': addrto, 'value': str(amount)} try: # 钱包转账,返回交易哈希值 tx_hash = self.usdtcoin_cli.omni_send(addrfrom, addrto, self.propertyid, str(amount)) return True, tx_hash except Exception as e: payload.update(dict(errormsg=str(e))) logging.error('usdt payment error:{}'.format(str(payload))) return False, str(e) def raw_transaction(self, minerfee_address, fromAddr, toAddre, value, miner_minfee): # 查询USDT未使用的UTXO USDT_unspents = self.usdtcoin_cli.listunspent(1, 9999999, [fromAddr]) if not USDT_unspents: return False, str('No USDT UTXO model available') USDT_unspent = USDT_unspents[0] # 查询BTC未使用的UTXO(矿工费) BTC_unspents = self.usdtcoin_cli.listunspent(1, 9999999, [minerfee_address]) if not BTC_unspents: return False, str('No BTC UTXO model available') BTC_unspent = BTC_unspents[0] # 所用值 from_txid = USDT_unspent['txid'] from_scriptPubKey = USDT_unspent['scriptPubKey'] from_vout = USDT_unspent['vout'] from_amount = USDT_unspent['amount'] to_txid = BTC_unspent['txid'] to_scriptPubKey = BTC_unspent['scriptPubKey'] to_vout = BTC_unspent['vout'] to_amount = BTC_unspent['amount'] rawtransactionparams = [ dict(txid=from_txid, scriptPubKey=from_scriptPubKey, vout=from_vout), dict(txid=to_txid, scriptPubKey=to_scriptPubKey, vout=to_vout), ] # 创建原生BTC交易获取哈希值 RawTxChangeparams = [ # 转出地址必须放在第一个,矿工费地址放在下面 dict(txid=from_txid, scriptPubKey=from_scriptPubKey, vout=from_vout, value=from_amount), dict(txid=to_txid, scriptPubKey=to_scriptPubKey, vout=to_vout, value=to_amount), ] # 构造发送代币类型和代币数量数据 payload = self.usdtcoin_cli.omni_createpayload_simplesend( self.propertyid, str(value)) print('usdt交易', payload) # 构造交易基本数据 data = {} btc_txid = self.usdtcoin_cli.createrawtransaction( rawtransactionparams, data) # 在交易上绑定代币数据 rawtx = self.usdtcoin_cli.omni_createrawtx_opreturn(btc_txid, payload) print('usdt交易绑定到btc交易的哈希', rawtx) # 在交易上添加接收地址 rawtx = self.usdtcoin_cli.omni_createrawtx_reference(rawtx, toAddre) print('添加接受地址', rawtx) # 在交易数据上指定矿工费用 rawtx = self.usdtcoin_cli.omni_createrawtx_change( rawtx, RawTxChangeparams, minerfee_address, Decimal(miner_minfee)) print('设置手续的哈希', rawtx) # 签名 ret = self.usdtcoin_cli.signrawtransaction(rawtx) if not ret['complete']: return False, str('Incomplete signature') # 广播 tx_hash = self.usdtcoin_cli.sendrawtransaction(ret['hex']) print('交易哈希', tx_hash) if tx_hash: return True, tx_hash
path = raw_input("Enter destination path/filename: ") print access.backupwallet(path) except: print "\n---An error occurred---\n" elif cmd == "getaccount": try: addr = raw_input("Enter a Bitcoin address: ") print access.getaccount(addr) except: print "\n---An error occurred---\n" elif cmd == "getaccountaddress": try: acct = raw_input("Enter an account name: ") print access.getaccountaddress(acct) except: print "\n---An error occurred---\n" elif cmd == "getaddressesbyaccount": try: acct = raw_input("Enter an account name: ") print access.getaddressesbyaccount(acct) except: print "\n---An error occurred---\n" elif cmd == "getbalance": try: acct = raw_input("Enter an account (optional): ") mc = raw_input("Minimum confirmations (optional): ") try:
a = '[config]\n' #Adds section header to the string. By default the staking app cannot read the config file if there is a section header b = f.read() config_string = a + b buf = StringIO.StringIO(config_string) #Creates a buffer config = ConfigParser.ConfigParser() config.readfp(buf) #Server RPC URL rpc_connection = AuthServiceProxy("http://%s:%[email protected]:8332"%((config.get('config','rpcuser')),(config.get('config','rpcpassword')))) #print rpc_connection #Get server status must run xxxx-qt -server first try: getaddress = rpc_connection.getaccountaddress('') #QR Code URL from Google APi url ='http://chart.apis.google.com/chart?cht=qr&chs=300x300&chl=%s' %getaddress #Download QR code urllib.urlretrieve(url, '/home/pi/stakebox-papirus/images/qr.png') rpc_connection.getinfo() server_status = True except: server_status = False pass #Button GPIO pins SW1 = 16 SW2 = 19
class NetworkManager(Widget): blockcount = StringProperty() balance = StringProperty() connections = StringProperty() txfee = StringProperty() networkdiff = StringProperty() myaddress = StringProperty() unconfirmedbalance = StringProperty() connectioncolor = StringProperty() loadingstate = BooleanProperty() terminalbuffer = StringProperty() def __init__(self, **kwargs): super(NetworkManager, self).__init__(**kwargs) self.loadingstate = True self.lasttransaction = '' self.connectioncolor = '#FF0000' self.RPC_server = None self.connect_rpc() self.terminalbuffer = '' self.lastterminalcommand = '' ### Start polling Clock.schedule_interval(self.poll_info, 15) def send(self, address, amount, **kwargs): print 'sending ' + amount + ' to ' + address self.RPC_server.sendfrom(Config.ACCOUNT_NAME, address, float(amount), 6) def onchangeterminal(self, input, **kwargs): if input == '': input = ' ' inputchar = input[-1] if inputchar == chr(10): inputcommand = input.split(chr(10)) self.lastterminalcommand = inputcommand[-2] print 'valutod.exe ' + self.lastterminalcommand output = self.commandsend_terminal('valutod ' + self.lastterminalcommand) print output self.terminalbuffer += output #except: # self.terminalbuffer += chr(10) + 'Error!' + chr(10) def commandsend_terminal(self, input, **kwargs): try: output = subprocess.check_output(input, shell=True) except: output = '' return output def kill_valutod(self, **kwargs): print 'Killing Valutod' try: os.kill(self.valutod.pid, signal.SIGTERM) except: pass subprocess.call('valutod.exe stop', shell=True) def start_valutod(self, **kwargs): print 'Starting Valutod....' if platform.system() == "Linux": self.valutod = subprocess.Popen('./valutod') else: self.valutod = subprocess.Popen('valutod', shell=True) while True: checkifrunning = subprocess.call('valutod getinfo', shell=True) if checkifrunning == 0: print 'Valutod started' break else: print 'Starting Valutod' print 'valutod started with pid:' + str(self.valutod.pid) def connect_rpc(self, **kwargs): self.start_valutod() print 'Connecting to: ', Config.SERVER_URL while not self.RPC_server: try: self.RPC_server = AuthServiceProxy(Config.SERVER_URL) print '... Connection established' except: print '....FAILED' def encrypt_wallet(self, passphrase, **kwargs): self.RPC_server.encryptwallet(passphrase) def poll_info(self, dtime): print 'Polling...' self.loadingstate = True try: self.blockcount = self.get_blockcount() self.balance = self.get_balance(False) self.unconfirmedbalance = self.get_balance(True) self.connections = self.get_connectioncount() self.txfee = self.get_txfee() self.networkdiff = self.get_networkdiff() self.myaddress = self.get_myaddress() self.get_last_transaction() self.set_connection_color() except: print 'trying to restart Valutod.exe' self.connect_rpc() self.loadingstate = False def lock_wallet(self, **kwargs): return self.RPC_server.walletlock() def get_networkdiff(self, **kwargs): return str(self.RPC_server.getinfo()['difficulty']) def get_myaddress(self, **kwargs): return str(self.RPC_server.getaccountaddress(Config.ACCOUNT_NAME)) def get_txfee(self, **kwargs): return str('{0:.8f}'.format( float(self.RPC_server.getinfo()['paytxfee']))) def get_connectioncount(self, **kwargs): return str(self.RPC_server.getinfo()['connections']) def get_balance(self, UNCONFIRMED, **kwargs): if UNCONFIRMED: return str('{0:.8f}'.format( float(self.RPC_server.getbalance(Config.ACCOUNT_NAME, 0)) - float(self.balance))) else: return str('{0:.8f}'.format( float(self.RPC_server.getbalance(Config.ACCOUNT_NAME, 6)))) def get_blockcount(self, **kwargs): return str(self.RPC_server.getinfo()['blocks']) def set_connection_color(self, **kwargs): connbuffer = int(self.connections) if connbuffer < 2: self.connectioncolor = '#FF0000' elif connbuffer >= 2 and connbuffer < 3: self.connectioncolor = '#FFFF00' else: self.connectioncolor = '#00FF00' def set_passphrase(self, password, seconds, **kwargs): self.RPC_server.walletpassphrase(password, seconds) def copyaction(self, copytxt, **kwargs): Snackbar(text='Copied to clipboard: ' + copytxt).show() def get_last_transaction(self, **kwargs): try: transbuffer = self.RPC_server.listtransactions( Config.ACCOUNT_NAME, 1, 0)[0]['txid'] if self.lasttransaction != transbuffer: self.lasttransaction = transbuffer Snackbar(text='Last transaction: ' + self.lasttransaction).show() except: print 'No transactions yet' def get_transactions(self, height, start, **kwargs): return self.RPC_server.listtransactions(Config.ACCOUNT_NAME, height, start)
class Core: def __init__(self, screenLogHandler=None, logFile=None): # set up logging self.logger = logging.getLogger(LOG_CHANNEL) self.logger.setLevel(logging.DEBUG) fh = None if logFile == None: fh = logging.FileHandler(LOG_FILE) else: fh = logging.FileHandler(logFile) fh.setLevel(LOG_FILE_LEVEL) formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setFormatter(formatter) self.logger.addHandler(fh) if screenLogHandler: self.logger.addHandler(screenLogHandler) # make sure we can connect to bitcoin client RPC interface self.rpc_conn = AuthServiceProxy( "http://%s:%s@%s:%d" % (RPC_USER, RPC_PASSWD, RPC_HOST, RPC_PORT)) try: self.bitcoin_client_info = self.rpc_conn.getinfo() except JSONRPCException as e: self.logger.error("could not reach bitcoin RPC server: " + str(e)) return None except e: self.logger.error("Core exception: " + str(e)) return None # Initalize modules self.pricing = bitcoin_pricing.BitcoinPricing(logFile=logFile) self.ledger = bitcoin_ledger.BitcoinLedger(logFile=logFile) self.activation = activation.ActivationSignatureGenerator( logFile=logFile) if self.pricing == None or self.ledger == None: self.logger.error( "One or more modules failed to start. Check you configuration!" ) return None def setRefundAddress(self, refundAddr, uuid): ledger_record = self.ledger.getLedgerRecord(uuid=uuid) if ledger_record: try: valid_addr = self.rpc_conn.validateaddress(refundAddr) if valid_addr['isvalid']: # under no circumstances should the ledger contain invalid refund addresses return self.ledger.setRefundAddress( ledger_record['id'], valid_addr['address']) else: self.logger.error( "Can't set refund address for %s to invalid Bitcoin address: %s", (uuid, refundAddr)) except JSONRPCException as e: self.logger.error("Bitcoin RPC exception: " + str(e)) return False return False def processLedger(self): # retrieve all the unpaid accounts from the ledger and see if they match # newly posted transaction unpaid_accounts = self.ledger.retrieveUnpaid() unrefunded_accounts = self.ledger.retrieveUnrefunded() bitcoin_price = self.pricing.get24hourAvgForCurrency("USD") current_price = long(round((PRICE_IN_DOLLARS / bitcoin_price) * 1e8)) self.last_price = current_price total_accounts = len(unpaid_accounts) paid_accounts = 0 refunded_accounts = 0 amt_received_by_address = self.rpc_conn.listreceivedbyaddress() for each in unpaid_accounts.keys(): account_balance = 0 ledger_id = unpaid_accounts[each] # search through newly posted transactions for addresses from unpaid # accounts, then update balances and confirmations for transaction in amt_received_by_address: if transaction['address'] == each: account_balance = long( round(float(transaction['amount']) * 1e8)) self.ledger.setBalance(ledger_id, account_balance, transaction['confirmations']) break if account_balance >= current_price: self.activate_uuid(ledger_id, current_price) paid_accounts += 1 for each in unrefunded_accounts.keys(): ledger_id = unrefunded_accounts[each] # search through newly posted transactions for addresses from # paid accounts, update confirmations, authorize refunds for transaction in amt_received_by_address: if transaction['address'] == each: account_balance = long( round(float(transaction['amount']) * 1e8)) self.logger.debug( "Setting ledger balance: %s - %f" % (transaction['address'], float(account_balance / 1e8))) self.ledger.setBalance(ledger_id, account_balance, transaction['confirmations']) break ledger_record = self.ledger.getLedgerRecord(ledger_id) if ledger_record['bitcoinConfirmations'] >= REFUND_CONFIRMS: if ledger_record['refundAddress']: refund_due = ledger_record[ 'bitcoinBalance'] - ledger_record['pricePaid'] json_refund_value = float(refund_due / 1e8) max_refund = long(current_price / 5) if refund_due > 0 and max_refund: self.logger.info("Remitting refund of %f to %s" % (json_refund_value, ledger_record['refundAddress'])) self.remit_refund(ledger_id, json_refund_value) refunded_accounts += 1 else: self.logger.info( "Refund due of %f to %s not remitted because it is too large for an automatic refund" % (json_refund_value, ledger_record['refundAddress'])) self.logger.info("Found " + str(paid_accounts) + " newly paid out of " + str(total_accounts) + " accounts.") self.logger.info("Auto-refunded %d out of %d pending refunds." % (refunded_accounts, len(unrefunded_accounts))) def remit_refund(self, ledger_id, refund): ledger_record = self.ledger.getLedgerRecord(ledger_id) if ledger_record == None: self.logger.error( "Error remit_refund: could not locate ledger record for ledger ID " + ledger_id) return refund_due = ledger_record['bitcoinBalance'] - ledger_record[ 'pricePaid'] bitcoin_price = self.pricing.get24hourAvgForCurrency("USD") current_price = long(round((PRICE_IN_DOLLARS / bitcoin_price) * 1e8)) max_refund = long(current_price / 5) if refund_due > 0 and refund < max_refund: # validate refundAddress with bitcoin client try: valid_addr = self.rpc_conn.validateaddress( ledger_record['refundAddress']) if valid_addr['isvalid']: json_refund_value = float(refund_due / 1e8) txid = self.rpc_conn.sendfrom(ledger_record['uuid'], valid_addr['address'], json_refund_value) # automatically refund overages within 20% of the # price if txid: self.ledger.markRefunded(ledger_id, refund_due, txid, "automatic") except JSONRPCException as e: self.logger.error( "Bitcoin RPC exception while remitting refund: " + str(e)) else: self.logger.info( "Refund due of %f for %s too large for autorefund." % (json_refund_value, ledger_record['uuid'])) def activate_uuid(self, ledger_id, pricePaid): current_price = pricePaid if self.ledger.markPaid(ledger_id, current_price): ledger_record = self.ledger.getLedgerRecord(ledger_id) activation_id = self.activation.sign(ledger_record['uuid']) account_balance = ledger_record['bitcoinBalance'] if activation_id < 1: self.logger.error("Error signing UUID: " + ledger_record['uuid']) else: self.ledger.setActivationSignatureId(ledger_id, activation_id) def updateForUuid(self, uuid, emailAddr=None): ledger_record = self.ledger.getLedgerRecord(uuid=uuid) bitcoin_price = self.pricing.get24hourAvgForCurrency("USD") current_price = long(round((PRICE_IN_DOLLARS / bitcoin_price) * 1e8)) if ledger_record: ledger_id = ledger_record['id'] if ledger_record['emailAddress'] != emailAddr: if self.ledger.setEmailAddress(ledger_id, emailAddr): ledger_record['emailAddress'] = emailAddr if ledger_record['pricePaid'] == None: # not yet paid, update transaction status # calculate account balance, based on posted transactions account_balance = 0 recent_transactions = self.rpc_conn.listreceivedbyaddress() for each in recent_transactions: if each['account'] == ledger_record['bitcoinAddress']: account_balance = long( round(float(each['amount']) * 1e8)) self.ledger.setBalance(ledger_id, account_balance, each['confirmations']) break if account_balance >= current_price: self.activate_uuid(ledger_id, current_price) ledger_record = self.ledger.getLedgerRecord(ledger_id) ledger_record['bitcoinPrice'] = str(bitcoin_price) ledger_record['currentPrice'] = current_price return ledger_record else: # establish a new bitcoin account or return address from existing bitcoin_addr = self.rpc_conn.getaccountaddress(uuid) ledger_id = self.ledger.createLedgerRecord(uuid, bitcoin_addr, emailAddr=emailAddr) new_ledger_record = self.ledger.getLedgerRecord(uuid=uuid) new_ledger_record['bitcoinPrice'] = str(bitcoin_price) new_ledger_record['currentPrice'] = current_price return new_ledger_record