Beispiel #1
0
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']
Beispiel #2
0
    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
Beispiel #3
0
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)
Beispiel #4
0
    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']
Beispiel #6
0
 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]
Beispiel #7
0
    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))
Beispiel #8
0
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
Beispiel #9
0
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
Beispiel #10
0
        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:
Beispiel #11
0
    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
Beispiel #12
0
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)
Beispiel #13
0
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