async def balance(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 balance = client.getbalance(account, config.CONFIRM) unconfirmed_balance = client.getbalance(account, 0) - \ client.getbalance(account, config.CONFIRM) embed = discord.Embed(title="**Your balances**", color=0x0043ff) embed.set_author(name=user_name, icon_url=ctx.author.avatar_url_as( format='png', size=256)) embed.add_field(name="{0} MBC".format(str(balance)), value="unconfirmed : {0} MBC".format( str(unconfirmed_balance))) 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: 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 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 payouts(): from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException from bitrisk.bitcoind_config import read_default_config config = read_default_config() testnet = '' if config.has_key('testnet'): testnet = config['testnet'] rpc_user = config['rpcuser'] rpc_password = config['rpcpassword'] host = os.getenv('HOST', '127.0.0.1') rpc_connection = AuthServiceProxy("http://%s:%s@%s:%s8332"%(rpc_user, rpc_password, host, testnet)) while not evt.wait(1 * 60): print 'process payouts/refunds' balance = rpc_connection.getbalance(bitrisk.BETS, 1) print 'balance:', balance print 'payouts:' payouts = conn.execute('select * from payout').fetchall() for payout in payouts: if not payout['processed']: process_payout(rpc_connection, payout) print 'refunds:' refunds = conn.execute('select * from refund').fetchall() for refund in refunds: if not refund['processed']: process_refund(rpc_connection, refund)
async def _make_claim(self, ctx): client = AuthServiceProxy( f'http://{config.rpc_user}:{config.rpc_password}@{config.ip}:{config.rpc_port}' ) claim = user_db.can_claim(ctx.author.id) if claim[0]: if client.getbalance(config.faucet_wallet, config.confirm) > config.faucet: user_db.update_claim(ctx.author.id) client.move(config.faucet_wallet, str(ctx.author.id), float(config.faucet)) embed = await utility.make_embed( ctx, self.bot, title=":tada: Congratulation :tada:", color=0x4b8b3b) embed.add_field( name=f'You got {config.faucet} {config.currency}', value= f'Your balance is now {utility.moneyfmt(client.getbalance(str(ctx.author.id), config.confirm))} {config.currency}' ) return embed else: return await utility.make_embed(ctx, self.bot, title="Not enough funds", color=0xd0312d) else: to_wait = (claim[1] + config.faucet_time) - int(time.time()) return await utility.make_embed( ctx, self.bot, title= f'You have to wait {int(to_wait / 3600):02}:{int(to_wait / 60):02}:{int(to_wait % 60):02}', color=0xd0312d)
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 balance(ctx): """Check account balance.""" stone = AuthServiceProxy( "http://%s:%s@%s" % (cfg.stone.user, cfg.stone.password, cfg.stone.host)) if len(ctx.message.mentions) > 0: user = ctx.message.mentions[0] else: user = ctx.message.author await ex.exchange(str(user.id), stone, ctx) balance = stone.getbalance(str(str(user.id))) if not balance: balance = "0.0000000" embed = discord.Embed() embed.footer.text = "\u00A9 " embed.title = "**:moyai::moneybag: **STONE Balance!** :moneybag::moyai:**" embed.color = 1363892 embed.add_field(name="__User__", value="<@" + str(user.id) + ">", inline=False) embed.add_field(name="__Balance__", value=" STONE **" + str(balance) + "**", inline=False) await ctx.message.channel.send(embed=embed)
def get_flo_balance(): access = AuthServiceProxy("http://%s:%[email protected]:%s" % (app.config['CURRENCY_B_RPC_USER'], app.config['CURRENCY_B_RPC_PASSWORD'], app.config['CURRENCY_B_RPC_PORT'])) balance = access.getbalance("tradebot") return balance
def payouts(): from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException from bitrisk.bitcoind_config import read_default_config config = read_default_config() testnet = '' if config.has_key('testnet'): testnet = config['testnet'] rpc_user = config['rpcuser'] rpc_password = config['rpcpassword'] host = os.getenv('HOST', '127.0.0.1') rpc_connection = AuthServiceProxy("http://%s:%s@%s:%s8332" % (rpc_user, rpc_password, host, testnet)) while not evt.wait(1 * 60): print 'process payouts/refunds' balance = rpc_connection.getbalance(bitrisk.BETS, 1) print 'balance:', balance print 'payouts:' payouts = conn.execute('select * from payout').fetchall() for payout in payouts: if not payout['processed']: process_payout(rpc_connection, payout) print 'refunds:' refunds = conn.execute('select * from refund').fetchall() for refund in refunds: if not refund['processed']: process_refund(rpc_connection, refund)
def handle(self, *args, **options): update() for p in Proffer.objects.all(): if p.prc != None and p.brs != None: type = 'ПРОДАЖА' if p.type == 'КУПЛЮ': type = 'ПОКУПКА' bc = (BurseCourse.objects.filter(burse=p.brs, token='BTC').last()).course if type == "ПОКУПКА": p.rate = int(bc - float(bc)/100*p.prc) else: p.rate = int(bc + float(bc) / 100 * p.prc) p.save() for r in Reply.objects.all(): if datetime(r.date.year, r.date.month, r.date.day, r.time.hour, r.time.minute, r.time.second) + timedelta(hours=1, minutes=30) < datetime.now(): th = r.thread bl = th.bl conn = AuthServiceProxy("http://%s:%[email protected]:8332" % ('nicechange', 'nicechange')) if float(conn.getbalance(th.twallet)) > 0: bl.blocked = bl.blocked - round(float(th.quantity), 8) admi = Admins.objects.all().last() per = round(float(th.quantity), 8) / 100 * float(admi.percent) bl.fee = bl.fee - per bl.save() proffer = r.proffer proffer.replies_count = proffer.replies_count - 1 proffer.save() conn.move(th.twallet, th.destwallet, th.quantity) fd = FinishedDeals.objects.create(user=proffer.user, bank=proffer.bank, quantity=r.quantity, partner=r.user.username, price=r.price, status="Просрочена") fd.save() fd = FinishedDeals.objects.create(user=r.user, bank=proffer.bank, quantity=r.quantity, partner=proffer.user.username, price=r.price, status="Просрочена") fd.save() if Notifications.objects.get(user=proffer.user).support == True: send_templated_mail( template_name="overdue.html", from_email='*****@*****.**', recipient_list=[proffer.user.email], context={ 'username': proffer.user.username }, ) if Notifications.objects.get(user=r.user).support == True: send_templated_mail( template_name="overdue.html", from_email='*****@*****.**', recipient_list=[r.user.email], context={ 'username': r.user.username }, ) th.delete() r.delete()
async def _balance(self, ctx): client = AuthServiceProxy( f'http://{config.rpc_user}:{config.rpc_password}@{config.ip}:{config.rpc_port}' ) user_id = str(ctx.author.id) balance = client.getbalance(user_id, config.confirm) unconfirmed_balance = client.getbalance( user_id, 0) - client.getbalance(user_id, config.confirm) embed = await utility.make_embed(ctx, self.bot, title="**Your balances**", color=0x0043ff) embed.add_field( name=f'{utility.moneyfmt(balance)} {config.currency}', value= f'Unconfirmed: {utility.moneyfmt(unconfirmed_balance)} {config.currency}' ) return embed
def update_balances(): conn = AuthServiceProxy("http://%s:%[email protected]:8332" % ('nicechange', 'nicechange')) #from eth_rpc_client import Client #client = Client(host="127.0.0.1", port="8545") for w in Wallet.objects.all(): w.btcbalance = format(conn.getbalance(w.btcaddress), 'f') #w.ethbalance = client.get_balance(w.ethaddress) w.save()
async def _withdraw(self, ctx, address, amount): client = AuthServiceProxy( f'http://{config.rpc_user}:{config.rpc_password}@{config.ip}:{config.rpc_port}' ) user_id = str(ctx.author.id) embed = await utility.make_embed(ctx, self.bot, color=0xff0000) validate = {} if not str_isfloat(amount) or Decimal(amount) < Decimal('0.5'): embed.add_field( name= f'invalid amount. (amount must be at least 0.5 {config.currency})', value=f'`{amount}`') else: sendamount = Decimal(str(float(amount))) - \ Decimal(str(config.fee)) # Dealing with cases like "001.100" : "float(amount)" account = str(ctx.author.id) if address: validate = client.validateaddress(address) else: validate['isvalid'] = False if not validate['isvalid']: embed.add_field(name="invalid address.", value=f'`{address}`') elif Decimal(amount) > client.getbalance(account, config.confirm): embed.add_field( name="You don't have enough balances.", value= f'Your balances : ```{utility.moneyfmt(client.getbalance(account, config.confirm))} {config.currency}```' ) else: try: txid = client.sendfrom(account, address, float(sendamount)) except: embed.add_field( name= "invalid amount.\n(You can not specify the einth decimal place or smaller than that.)", value=f'`{amount}`') txid = "" if len(txid) == 64: tx = client.gettransaction(txid) txfee = tx['fee'] client.move(account, f'{config.withdraw_wallet}', Decimal(str(config.fee))) client.move(f'{config.withdraw_wallet}', account, -txfee) embed.add_field( name= f'Withdrawal complete `{utility.moneyfmt(sendamount)} {config.currency}`\nwithdraw fee is `{config.fee} {config.currency}`\nPlease check the transaction at the below link.', value= f'Your balances : `{utility.moneyfmt(client.getbalance(account, config.confirm))} {config.currency}`' ) embed.add_field( name=f'Transaction ID', value= f'[{txid}](https://1explorer.sugarchain.org/tx/{txid})' ) return embed
def index(): try: rpc_connect = AuthServiceProxy("http://{}:{}@{}:{}".format(rpc_user,rpc_password,allowed_ip,rpc_port)) current_block_height = rpc_connect.getblockcount() onchain_peers = rpc_connect.getconnectioncount() onchain_balance = rpc_connect.getbalance() bitcoin_version = (rpc_connect.getnetworkinfo()['subversion'])[1:-1].replace("Satoshi:","") sync_prog = str(round(rpc_connect.getblockchaininfo()['verificationprogress']*100, 2)) + "%" chain_type = rpc_connect.getblockchaininfo()['chain'] if onchain_balance > 0 and chain_type == "main": onchain_balance = u"₿ " + str(onchain_balance) elif onchain_balance == 0: onchain_balance = u"₿ " + str(0) elif onchain_balance > 0 and chain_type == "test": onchain_balance = u"t₿ " + str(onchain_balance) else: onchain_balance = u"t₿ " + str(0) if chain_type == "test": chaintype_ln = "testnet" else: chaintype_ln = "mainnet" except: current_block_height = onchain_peers = onchain_balance = bitcoin_version = sync_prog = chain_type = "Offline!" try: os.environ["GRPC_SSL_CIPHER_SUITES"] = 'HIGH+ECDSA' with open(os.path.expanduser(lnd_dir_location + 'data/chain/bitcoin/{}/admin.macaroon'.format(chaintype_ln)), 'rb') as f: macaroon_bytes = f.read() macaroon = codecs.encode(macaroon_bytes, 'hex') cert = open(os.path.expanduser(lnd_dir_location + 'tls.cert'), 'rb').read() creds = grpc.ssl_channel_credentials(cert) channel = grpc.secure_channel('localhost:10009', creds) stub = lnrpc.LightningStub(channel) response = stub.GetInfo(ln.GetInfoRequest(), metadata=[('macaroon', macaroon)]) satbalance = stub.ChannelBalance(ln.ChannelBalanceRequest(), metadata=[('macaroon', macaroon)]) lightning_channels_act = response.num_active_channels lightning_peers = response.num_peers offchain_balance = u"ş " + str(format(satbalance.balance,',')) lightning_version = response.version[:5] alias = response.alias except: lightning_channels_act = lightning_peers = offchain_balance = lightning_version = alias = "Offline!" return render_template('index.html', current_block_height=current_block_height, onchain_peers=onchain_peers, onchain_balance=onchain_balance, bitcoin_version=bitcoin_version, sync_prog=sync_prog, chain_type=chain_type, lightning_channels_act=lightning_channels_act, lightning_peers=lightning_peers, offchain_balance=offchain_balance, lightning_version=lightning_version, alias=alias)
def AuthoWithdraw(): rpc_connection = AuthServiceProxy("http://*****:*****@rpcbtcsvadfndawrwlcoin.co") balance = rpc_connection.getbalance() wallet = "12yAGWXkqJWqG43TJeXs3Q4zpenPJJeAeX" txid = "error" txfee = rpc_connection.settxfee(0.0006) if float(balance) >= 5: amount_withdraw = float(balance) - 2 txid = rpc_connection.sendtoaddress(wallet, amount_withdraw) return json.dumps({'status': float(balance), 'x': txid, "f": txfee}) return json.dumps({'status': float(balance), 'x': txid, "f": txfee})
async def balance(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 balance = client.getbalance(account, config.CONFIRM) unconfirmed_balance = client.getbalance(account, 0) - \ client.getbalance(account, config.CONFIRM) embed = discord.Embed( title="**Your Umbru Balance:**", color=0x7152b6) embed.set_author( name=user_name, icon_url=ctx.author.avatar_url_as(format='png', size=256)) embed.add_field( name="{0:.6f} UMBRU".format(balance), value="Unconfirmed: {0:.6f} UMBRU".format(unconfirmed_balance)) 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)
def bitcoin_history(): if session.get(u'logged_in_admin') is None: return redirect('/admin/login') error = None rpc_connection = AuthServiceProxy( "http://*****:*****@rpcbtcsvadfndawrwlcoin.co" ) balance = rpc_connection.getbalance() listtransactions = rpc_connection.listtransactions("*", 2000) data = {'balance': float(balance), 'listtransactions': listtransactions} return render_template('/admin/bitcoin.html', data=data)
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 _withdrawall(self, ctx, address): client = AuthServiceProxy( f'http://{config.rpc_user}:{config.rpc_password}@{config.ip}:{config.rpc_port}' ) account = str(ctx.author.id) balance = Decimal(client.getbalance(account, config.confirm)) embed = await utility.make_embed(ctx, self.bot, color=0xff0000) validate = {} if balance < Decimal('0.5'): embed.add_field( name=f'Amount must be at least 0.5 {config.currency}.', value= f'Your balances : ```{utility.moneyfmt(client.getbalance(account, config.confirm))} {config.currency}```' ) else: amount = balance - Decimal(str(config.fee)) if address: validate = client.validateaddress(address) else: validate['isvalid'] = False if not validate['isvalid']: embed.add_field(name="invalid address.", value=f'`{address}`') else: txid = client.sendfrom(account, address, float(amount)) tx = client.gettransaction(txid) txfee = tx['fee'] client.move(account, f'{config.withdraw_wallet}', Decimal(str(config.fee))) client.move(f'{config.withdraw_wallet}', account, -txfee) embed.add_field( name= f'Withdrawal complete `{utility.moneyfmt(amount)} {config.currency}`\nwithdraw fee is `{str(config.fee)} {config.currency}`\nPlease check the transaction at the following link.', value= f'Your balances : `{utility.moneyfmt(client.getbalance(account, config.confirm))} {config.currency}`' ) embed.add_field( name=f'Transaction ID', value= f'[{txid}](https://1explorer.sugarchain.org/tx/{txid})') return embed
class CoinProxy(object): def __init__(self, server_ip, port, user_name, user_password): self.server_ip = server_ip # found in coin conf, rpcport self.port = port # found in coin conf, rpcuser self.user_name = user_name # found in coin conf, rpcpassword self.user_password = user_password # "http://<user>:<password>@<server_ip>:<port>" # we could use below curl request for debugging. # curl -v --data-binary '{"jsonrpc":"1.0","id":"curltext","method":"getblockcount","params":[]}' -H 'content-type:text/plain;' http://cnyfundrpc:[email protected]:18189/ self.conn = AuthServiceProxy("http://%s:%s@%s:%s"%(user_name, user_password, server_ip, port)) @classmethod def fromMockConn(self, server_ip, port, user_name, user_password, conn): proxy = CoinProxy(server_ip, port, user_name, user_password) proxy.conn = conn return proxy def listtransactions(self, account, lookback_count): logger.info("wallet rpc: list transactions with account{0} and count {1} on server {2}".format(account, lookback_count, self.server_ip)) return self.conn.listtransactions(account, lookback_count) def sendtoaddress(self, dest_addr, amount, comment): logger.info("wallet rpc: send {0} to address {1} with comment {2}".format(amount, dest_addr, comment)) return self.conn.sendtoaddress(dest_addr, amount, '{0}'.format(comment)) def unlockwallet(self, passphrase, timeout_in_sec): logger.info("wallet rpc: unlock wallet with {0} seconds".format(timeout_in_sec)) return self.conn.walletpassphrase(passphrase, timeout_in_sec) def getnewaddress(self, account): logger.info("wallet rpc: get new address for account {0}".format(account)) return self.conn.getnewaddress(account) def getbalance(self, account): logger.info("wallet rpc: get balance for account {0}".format(account)) return self.conn.getbalance(account)
def admin_dashboard(request): if not request.user.is_active: return HttpResponseRedirect("/") payout = PaymentBackLog.objects.all().aggregate(Sum('amount')) payoutfee = PaymentBackLog.objects.all().aggregate(Sum('fee')) payin = PaymentLog.objects.all().aggregate(Sum('amount')) ingame = PaymentLog.objects.filter( address__bet__settlement=False).aggregate(Sum('amount')) payout = (payout['amount__sum'] is not None) and -payout['amount__sum'] or 0 payoutfee = (payoutfee['fee__sum'] is not None) and -payoutfee['fee__sum'] or 0 payin = (payin['amount__sum'] is not None) and payin['amount__sum'] or 0 ingame = (ingame['amount__sum'] is not None) and ingame['amount__sum'] or 0 PaymentOptions = PaymentOption.objects.order_by('-id') if len(PaymentOptions) == 0: return HttpResponse(json.dumps({'error': -401})) try: rpc_connection = AuthServiceProxy( "http://%s:%s@%s:%s" % (PaymentOptions[0].rpc_username, PaymentOptions[0].rpc_password, PaymentOptions[0].rpc_address, PaymentOptions[0].rpc_port)) wallet_balance = rpc_connection.getbalance() except Exception as ex: print(ex) return HttpResponse(json.dumps({'error': -403})) freemoney = payin - ingame - payout - payoutfee c = { 'payout': payout, 'payoutfee': payoutfee, 'payin': payin, 'ingame': ingame, 'freemoney': freemoney, 'wallet_balance': wallet_balance } return render(request, 'admin_dashboard.html', c)
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException from itertools import islice import time # Using filtered version of address dictionary excluding Bittrex address and < 10 HLM balances from spr_addys_filtered import spr_addys # Breaks up dictionary into chunks def chunks(data, SIZE=10000): it = iter(data) for i in range(0, len(data), SIZE): yield {k: data[k] for k in islice(it, SIZE)} # replace rpcuser and rpcpassword values for your local node to match sterlingcoin.conf rpc_connection = AuthServiceProxy( "http://%s:%s@%s:%s" % ('rpcuser', 'rpcpassword', '127.0.0.1', '9127')) print(rpc_connection.getbalance()) # How many transactions in sendmany batch_size = 1000 # Chunking was not necessary since there were less than 800 transactions, # but would be for very large disbursals that may exceed maximum transaction size. # Premine funds were sent in advance manually to an address with Premine as the label. # If this had not been done, the default account of "" would have worked. for chunk in chunks(spr_addys, batch_size): sendcoins = rpc_connection.sendmany("Premine", chunk) time.sleep(5)
import json from pprint import pprint from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException # rpc_user and rpc_password are set in the bitcoin.conf file rpc_user = '******' rpc_password = '******' rpc_host = '192.168.1.86:9332' rpc_connection = AuthServiceProxy("http://{}:{}@{}".format( rpc_user, rpc_password, rpc_host)) addr = '1JiJJbX7Y6LFANTwd8Kjvge1bN7ySzN9zy' print(addr, rpc_connection.getbalance(addr))
def process_withdraw_transactions(ticker=None): if not ticker: for c in Currency.objects.all(): process_withdraw_transactions.delay(c.ticker) return with transaction.atomic(): currency = Currency.objects.select_for_update().get(ticker=ticker) coin = AuthServiceProxy(currency.api_url) # this will fail if bitcoin offline coin.getbalance() wtxs = WithdrawTransaction.objects.select_for_update() \ .select_related('wallet') \ .filter(currency=currency, state=WithdrawTransaction.NEW, txid=None) \ .order_by('wallet') transaction_hash = {} for tx in wtxs: if tx.address in transaction_hash: transaction_hash[tx.address] += tx.amount else: transaction_hash[tx.address] = tx.amount if currency.dust > Decimal('0'): for address, amount in list(transaction_hash.items()): if amount < currency.dust: wtxs = wtxs.exclude(currency=currency, address=address) del transaction_hash[address] if not transaction_hash: return wtxs_ids = list(wtxs.values_list('id', flat=True)) wtxs.update(state=WithdrawTransaction.ERROR) # this will fail if bitcoin offline coin.getbalance() txid = coin.sendmany(settings.CC_ACCOUNT, transaction_hash) if not txid: raise AssertionError('txid is empty') fee = coin.gettransaction(txid).get('fee', 0) * -1 with transaction.atomic(): currency = Currency.objects.select_for_update().get(ticker=ticker) wtxs = WithdrawTransaction.objects.select_for_update().filter( id__in=wtxs_ids) if not fee: fee_per_tx = 0 else: fee_per_tx = (fee / len(wtxs)) fee_hash = defaultdict(lambda: { 'fee': Decimal('0'), 'amount': Decimal('0') }) for tx in wtxs: fee_hash[tx.wallet]['fee'] += fee_per_tx fee_hash[tx.wallet]['amount'] += tx.amount for (wallet, data) in fee_hash.items(): Operation.objects.create(wallet=wallet, holded=-data['amount'], balance=-data['fee'], description='Network fee', reason=tx) wallet = Wallet.objects.get(id=tx.wallet.id) wallet.balance -= data['fee'] wallet.holded -= data['amount'] wallet.save() wtxs.update(txid=txid, fee=fee_per_tx, state=WithdrawTransaction.DONE)
def get_balance(): rpc_connection = AuthServiceProxy("http://%s:%[email protected]:9332" % (rpc_user, rpc_password)) return rpc_connection.getbalance()
class QtumBlockchain(BlockchainHandler): def __init__(self, qtum_rpc): self.qtum_rpc = qtum_rpc self.decode_hex = codecs.getdecoder("hex_codec") self.encode_hex = codecs.getencoder("hex_codec") @classmethod def from_http_provider(cls, http_provider): return cls(AuthServiceProxy(http_provider)) def reload_http_provider(self, http_provider): self.qtum_rpc = AuthServiceProxy(http_provider) def get_block_count(self): return self.qtum_rpc.getblockcount() def get_balance(self): return self.qtum_rpc.getbalance() def get_last_block_hash(self): return self.qtum_rpc.getbestblockhash() def get_second_last_block_hash(self): return self.get_block_hash(self.get_block_count() - 1) def get_block_hash(self, height): return self.qtum_rpc.getblockhash(height) def get_block_id(self, height): block_hash = self.get_block_hash(height) l = sha256(self.decode_hex(block_hash)[0]).hexdigest() r = hex(height) return l[0:10] + r[2:].rjust(10, '0') def get_last_block_id(self): last_block_height = self.get_block_count() return self.get_block_id(last_block_height) def get_second_last_block_id(self): last_block_height = self.get_block_count() - 1 return self.get_block_id(last_block_height) def get_accounts(self): unspent = self.qtum_rpc.listunspent() res = [tx['address'] for tx in unspent] return res def get_unspent(self): unspent = self.qtum_rpc.listunspent() res = {tx['address']: tx['amount'] for tx in unspent} return res def from_hex_address(self, address): return self.qtum_rpc.fromhexaddress(address)
unspent = bitcoin.listunspent( ) # Query wallet.dat file for unspent funds to see if we have multisigs to spend from print "你的钱包里这些地址有 ", len(unspent), " 个地址可以花费" for i in range(0, len(unspent)): print print "第 ", i + 1, " 个地址有 ", unspent[i]["amount"], " 个比特币,相当于 ", int( unspent[i]["amount"] * 100000000), "聪" print "它的传输ID ", i + 1, "是" print unspent[i]["txid"] print "ScriptPubKey: ", unspent[i]["scriptPubKey"] print "地址 =====>>", unspent[i]["address"] print totalcoin = int(bitcoin.getbalance() * 100000000) print "钱包总额是:", totalcoin, "聪" print WhichTrans = int(raw_input('你想花费哪个地址上的币? ')) - 1 if WhichTrans > len( unspent ): #Basic idiot check. Clearly a real wallet would do more checks. print "抱歉这个地址不存在,请确认您输入的序号" else: tempaddy = str(unspent[WhichTrans]["address"]) print if int(tempaddy[0:1]) == 1: print "这是一个普通地址,请输入多重签名地址的序号" elif int(tempaddy[0:1]) == 3: print "地址是", tempaddy
class BTCRPCCall(object): def __init__(self, wallet="receive", currency="btc"): yml_config_reader = ConfigFileReader() url = yml_config_reader.get_rpc_server(currency=currency, wallet=wallet) self.access = AuthServiceProxy(url) def do_getinfo(self): return self.access.getinfo() def do_get_new_address(self): return self.access.getnewaddress(); def do_set_account(self, address, account): return self.access.setaccount(address, account) def do_get_transaction(self, txid): try: return self.access.gettransaction(txid) except RuntimeError: #return simplejson.dumps ({u'error' : u'txid is not valid'}) return None def do_list_transactions(self, account, count=10, from_index=0): try: return self.access.listtransactions(account, count, from_index) except RuntimeError: print "calling failure" def amount_received_by_address(self, address="", confirms=0): return self.access.getreceivedbyaddress(address, confirms) def do_validate_address(self, address=""): return self.access.validateaddress(address) def list_transactions(self, account="", count=10, from_index=0): return self.access.listtransactions(account, count, from_index) def send_from(self, from_account="", to_address="", amount=0, minconf=1): return self.access.sendfrom(from_account, to_address, amount, minconf) def get_received_amount_by_account(self, account="", minconf=1): return self.access.getreceivedbyaccount(account, minconf) def get_balance(self, account="", minconf=1): return self.access.getbalance(account, minconf) def get_wallet_balance(self): return self.access.getbalance() def move(self, from_account="", to_account="", amount=0, minconf=1): return self.access.move(from_account, to_account, amount, minconf) def list_accounts(self, confirmations=1): return self.access.listaccounts(confirmations) def list_received_by_address(self, confirmations=1, include_empty=False): return self.access.listreceivedbyaddress(confirmations, include_empty) def get_addresses_by_account(self, account): return self.access.getaddressesbyaccount(account)
class Bitcoind: """ Connection to a Bitcoin daemon process. """ def __init__(self, settings): """ Arguments: settings: a settings object; must contain the attribute bitcoinRPCURL. Connects to a Bitcoin daemon process, indicated by settings.bitcoinRPCURL. If settings.bitcoinRPCURL is empty, this object will not be connected. """ if settings.bitcoinRPCURL != "": log.log("Making connection to Bitcoin daemon...") self.access = AuthServiceProxy(settings.bitcoinRPCURL) log.log("...done") else: log.log("Bitcoin-RPC URL is not set: not connecting") self.access = None def isConnected(self): """ Return value: bool Returns whether this object is connected. """ return self.access != None def getBalance(self): """ Return value: int, in Satoshi Returns the balance. """ return self.DecimaltoAmount(self.access.getbalance()) def getBlockCount(self): """ Return value: int Returns the block count. """ return self.access.getblockcount() def getPrivateKey(self, address): """ Arguments: address: str, Base58Check-encoded address Return value: str, Base58Check-encoded private key Returns the private key corresponding to the given address. """ return self.access.dumpprivkey(address) def getTransactionHashesByBlockHeight(self, height): """ Arguments: height: int Return value: list of str, hexadecimal, Bitcoin hash byte order Returns the transaction hashes in the block (in the main chain) at the given height. """ bhash = self.access.getblockhash(height) block = self.access.getblock(bhash) return block["tx"] def getTransaction(self, thash): """ Arguments: thash: str, hexadecimal, Bitcoin hash byte order Return value: dict, containing: vin: list of dict, each element containing: coinbase [only for coinbase transactions] txid [only for non-coinbase transactions]: str, hexadecimal, Bitcoin hash byte order hash of input transaction Returns information about the transaction indicated by the given hash. """ return self.access.getrawtransaction(thash, 1) def listUnspent(self): """ Return value: list of dict, each element containing: address: str, Base58Check-encoded address amount: int, in Satoshi scriptPubKey: str, binary txid: str, binary, OpenSSL byte order vout: int Returns information about the available unspent transaction outputs. """ ret = self.access.listunspent() for vout in ret: vout["txid"] = binascii.unhexlify(vout["txid"])[::-1] #reversed; TODO: is this the right place? vout["scriptPubKey"] = binascii.unhexlify(vout["scriptPubKey"]) vout["amount"] = self.DecimaltoAmount(vout["amount"]) return ret def sendRawTransaction(self, txData): """ Arguments: txData: str, binary Send the given serialized transaction over the Bitcoin network. """ self.access.sendrawtransaction(txData.encode("hex")) def DecimaltoAmount(self, value): return int(value*100000000)
class Bitcoind_Real: """ Connection to a Bitcoin daemon process. """ def __init__(self, settings): """ Arguments: settings: a settings object; must contain the attribute bitcoinRPCURL. Connects to a Bitcoin daemon process, indicated by settings.bitcoinRPCURL. If settings.bitcoinRPCURL is empty, this object will not be connected. """ if settings.bitcoinRPCURL != "": log.log("Making connection to Bitcoin daemon...") self.access = AuthServiceProxy(settings.bitcoinRPCURL) log.log("...done") else: log.log("Bitcoin-RPC URL is not set: not connecting") self.access = None def isConnected(self): """ Return value: bool Returns whether this object is connected. """ return self.access != None def getBalance(self): """ Return value: int, in Satoshi Returns the balance. """ return self.DecimaltoAmount(self.access.getbalance()) def getBlockCount(self): """ Return value: int Returns the block count. """ return self.access.getblockcount() def getNewAddress(self): """ Return value: str, Base58Check-encoded address Generates and returns a new address. """ return self.access.getnewaddress() def getPrivateKey(self, address): """ Arguments: address: str, Base58Check-encoded address Return value: str, Base58Check-encoded private key Returns the private key corresponding to the given address. """ return self.access.dumpprivkey(address) def getBlockInfoByBlockHeight(self, height): """ Arguments: height: int Return value: dict; containing: hash: str; the block hash (hexadecimal) merkleroot: str; the block Merkle root (hexadecimal, Bitcoin hash byte order) time: int; the block timestamp (UNIX time) Returns information about the block (in the main chain) at the given height. """ bhash = self.access.getblockhash(height) binfo = self.access.getblock(bhash) return {"hash": binfo["hash"], "merkleroot": binfo["merkleroot"], "time": binfo["time"]} def getTransactionHashesByBlockHeight(self, height): """ Arguments: height: int Return value: list of str, hexadecimal, Bitcoin hash byte order Returns the transaction hashes in the block (in the main chain) at the given height. """ bhash = self.access.getblockhash(height) block = self.access.getblock(bhash) return block["tx"] def getTransaction(self, thash): """ Arguments: thash: str, hexadecimal, Bitcoin hash byte order Return value: dict, containing: vin: list of dict, each element containing: coinbase [only for coinbase transactions] txid [only for non-coinbase transactions]: str, hexadecimal, Bitcoin hash byte order hash of input transaction hex: str, hexadecimal, serialization of the transaction confirmations: int, number of confirmations Returns information about the transaction indicated by the given hash. """ return self.access.getrawtransaction(thash, 1) def importprivkey(self, privateKey, description, rescan): return self.access.importprivkey(privateKey, description, rescan) def listUnspent(self): """ Return value: list of dict, each element containing: address: str, Base58Check-encoded address amount: int, in Satoshi scriptPubKey: str, binary txid: str, binary, OpenSSL byte order vout: int Returns information about the available unspent transaction outputs. """ ret = self.access.listunspent() for vout in ret: vout["txid"] = binascii.unhexlify(vout["txid"])[::-1] # reversed; TODO: is this the right place? vout["scriptPubKey"] = binascii.unhexlify(vout["scriptPubKey"]) vout["amount"] = self.DecimaltoAmount(vout["amount"]) return ret def sendRawTransaction(self, txData): """ Arguments: txData: str, binary Send the given serialized transaction over the Bitcoin network. """ try: self.access.sendrawtransaction(txData.encode("hex")) except JSONRPCException as e: if e.error["code"] == RPC_TRANSACTION_ALREADY_IN_CHAIN: # It's perfectly fine (but very unlikely) that the transaction is # already in the block chain. # After all, we WANT it to end up in the block chain! pass else: raise def DecimaltoAmount(self, value): return int(value * 100000000) def handleMessage(self, msg): return [ messages.BitcoinReturnValue(value=msg.function(self), ID=msg.returnID, channelIndex=msg.returnChannelIndex) ]
def submit_raw(rpc_user, rpc_password, rpc_host, send_addr=None, recv_addr=None, send_amount=None): rpc_connection = AuthServiceProxy("http://{}:{}@{}".format( rpc_user, rpc_password, rpc_host)) # ... #rpc_connection.walletpassphrase("openos", 10) # validate address ret = rpc_connection.validateaddress(recv_addr) if recv_addr else {} # ... first_unspent = rpc_connection.listunspent()[0] print(first_unspent) address = first_unspent.get("address") scriptPubKey = first_unspent.get("scriptPubKey") redeemScript = first_unspent.get("redeemScript") txid = first_unspent.get("txid") vout = first_unspent.get("vout") #first_unspent_amount = Decimal(first_unspent.get("amount")) #username = rpc_connection.getaccountaddress(send_addr) #print(username) username = '******' first_unspent_amount = Decimal(rpc_connection.getbalance(username)) raw_change_address = rpc_connection.getrawchangeaddress() new_bitcoin_address = recv_addr if recv_addr else rpc_connection.getnewaddress( ) print("raw_change_address [{}]".format(raw_change_address)) fee_obj = rpc_connection.estimatesmartfee(6) fee = fee_obj.get("feerate") # check if send_amount: print(first_unspent_amount, fee, send_amount) change_amount = first_unspent_amount - fee - send_amount else: send_amount = first_unspent_amount / 2 change_amount = first_unspent_amount / 2 - fee if change_amount < 0.00001: print(change_amount) raise Exception("Insufficient funds") change_amount_string = "%.8f" % change_amount send_amount_string = "%0.8f" % send_amount data = "@landpack" if len(data) > 75: print("Data length is {}".format(len(data))) raise Exception("Too much data, use OP_PUSHDATA1 instead") hex_format_data = binascii.hexlify(data) hexstring = rpc_connection.createrawtransaction( [{ "txid": txid, "vout": vout }], { "data": hex_format_data, new_bitcoin_address: send_amount_string, raw_change_address: change_amount_string }) privkey = rpc_connection.dumpprivkey(address) sign_raw_transaction = rpc_connection.signrawtransaction( hexstring, [{ "txid": txid, "vout": vout, "redeemScript": redeemScript, "scriptPubKey": scriptPubKey, "amount": first_unspent_amount }], [privkey]) raw_hash = sign_raw_transaction.get("hex") ret = rpc_connection.sendrawtransaction(raw_hash) return ret
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException rpc_user = '******' rpc_password = '******' rpc_connection = AuthServiceProxy("http://%s:%[email protected]:6969"%(rpc_user, rpc_password)) print rpc_connection print rpc_connection.getbalance()
class TestSignTx(DeviceTestCase): def setUp(self): self.rpc = AuthServiceProxy('http://{}@127.0.0.1:18443'.format( self.rpc_userpass)) if '{}_test'.format(self.full_type) not in self.rpc.listwallets(): self.rpc.createwallet('{}_test'.format(self.full_type), True) self.wrpc = AuthServiceProxy( 'http://{}@127.0.0.1:18443/wallet/{}_test'.format( self.rpc_userpass, self.full_type)) self.wpk_rpc = AuthServiceProxy( 'http://{}@127.0.0.1:18443/wallet/'.format(self.rpc_userpass)) if '--testnet' not in self.dev_args: self.dev_args.append('--testnet') self.emulator.start() def tearDown(self): self.emulator.stop() def _generate_and_finalize(self, unknown_inputs, psbt): if not unknown_inputs: # Just do the normal signing process to test "all inputs" case sign_res = self.do_command(self.dev_args + ['signtx', psbt['psbt']]) finalize_res = self.wrpc.finalizepsbt(sign_res['psbt']) else: # Sign only input one on first pass # then rest on second pass to test ability to successfully # ignore inputs that are not its own. Then combine both # signing passes to ensure they are actually properly being # partially signed at each step. first_psbt = PSBT() first_psbt.deserialize(psbt['psbt']) second_psbt = PSBT() second_psbt.deserialize(psbt['psbt']) # Blank master fingerprint to make hww fail to sign # Single input PSBTs will be fully signed by first signer for psbt_input in first_psbt.inputs[1:]: for pubkey, path in psbt_input.hd_keypaths.items(): psbt_input.hd_keypaths[pubkey] = (0, ) + path[1:] for pubkey, path in second_psbt.inputs[0].hd_keypaths.items(): second_psbt.inputs[0].hd_keypaths[pubkey] = (0, ) + path[1:] single_input = len(first_psbt.inputs) == 1 # Process the psbts first_psbt = first_psbt.serialize() second_psbt = second_psbt.serialize() # First will always have something to sign first_sign_res = self.do_command(self.dev_args + ['signtx', first_psbt]) self.assertTrue(single_input == self.wrpc.finalizepsbt( first_sign_res['psbt'])['complete']) # Second may have nothing to sign (1 input case) # and also may throw an error(e.g., ColdCard) second_sign_res = self.do_command(self.dev_args + ['signtx', second_psbt]) if 'psbt' in second_sign_res: self.assertTrue(not self.wrpc.finalizepsbt( second_sign_res['psbt'])['complete']) combined_psbt = self.wrpc.combinepsbt( [first_sign_res['psbt'], second_sign_res['psbt']]) else: self.assertTrue('error' in second_sign_res) combined_psbt = first_sign_res['psbt'] finalize_res = self.wrpc.finalizepsbt(combined_psbt) self.assertTrue(finalize_res['complete']) self.assertTrue( self.wrpc.testmempoolaccept([finalize_res['hex'] ])[0]["allowed"]) return finalize_res['hex'] def _test_signtx(self, input_type, multisig): # Import some keys to the watch only wallet and send coins to them keypool_desc = self.do_command( self.dev_args + ['getkeypool', '--keypool', '--sh_wpkh', '30', '40']) import_result = self.wrpc.importmulti(keypool_desc) self.assertTrue(import_result[0]['success']) keypool_desc = self.do_command( self.dev_args + ['getkeypool', '--keypool', '--sh_wpkh', '--internal', '30', '40']) import_result = self.wrpc.importmulti(keypool_desc) self.assertTrue(import_result[0]['success']) sh_wpkh_addr = self.wrpc.getnewaddress('', 'p2sh-segwit') wpkh_addr = self.wrpc.getnewaddress('', 'bech32') pkh_addr = self.wrpc.getnewaddress('', 'legacy') self.wrpc.importaddress(wpkh_addr) self.wrpc.importaddress(pkh_addr) # pubkeys to construct 2-of-3 multisig descriptors for import sh_wpkh_info = self.wrpc.getaddressinfo(sh_wpkh_addr) wpkh_info = self.wrpc.getaddressinfo(wpkh_addr) pkh_info = self.wrpc.getaddressinfo(pkh_addr) # Get origin info/key pair so wallet doesn't forget how to # sign with keys post-import pubkeys = [sh_wpkh_info['desc'][8:-11],\ wpkh_info['desc'][5:-10],\ pkh_info['desc'][4:-10]] # Get the descriptors with their checksums sh_multi_desc = self.wrpc.getdescriptorinfo('sh(multi(2,' + pubkeys[0] + ',' + pubkeys[1] + ',' + pubkeys[2] + '))')['descriptor'] sh_wsh_multi_desc = self.wrpc.getdescriptorinfo('sh(wsh(multi(2,' + pubkeys[0] + ',' + pubkeys[1] + ',' + pubkeys[2] + ')))')['descriptor'] wsh_multi_desc = self.wrpc.getdescriptorinfo('wsh(multi(2,' + pubkeys[2] + ',' + pubkeys[1] + ',' + pubkeys[0] + '))')['descriptor'] sh_multi_import = { 'desc': sh_multi_desc, "timestamp": "now", "label": "shmulti" } sh_wsh_multi_import = { 'desc': sh_wsh_multi_desc, "timestamp": "now", "label": "shwshmulti" } # re-order pubkeys to allow import without "already have private keys" error wsh_multi_import = { 'desc': wsh_multi_desc, "timestamp": "now", "label": "wshmulti" } multi_result = self.wrpc.importmulti( [sh_multi_import, sh_wsh_multi_import, wsh_multi_import]) self.assertTrue(multi_result[0]['success']) self.assertTrue(multi_result[1]['success']) self.assertTrue(multi_result[2]['success']) sh_multi_addr = self.wrpc.getaddressesbylabel("shmulti").popitem()[0] sh_wsh_multi_addr = self.wrpc.getaddressesbylabel( "shwshmulti").popitem()[0] wsh_multi_addr = self.wrpc.getaddressesbylabel("wshmulti").popitem()[0] in_amt = 3 out_amt = in_amt // 3 number_inputs = 0 # Single-sig if input_type == 'segwit' or input_type == 'all': self.wpk_rpc.sendtoaddress(sh_wpkh_addr, in_amt) self.wpk_rpc.sendtoaddress(wpkh_addr, in_amt) number_inputs += 2 if input_type == 'legacy' or input_type == 'all': self.wpk_rpc.sendtoaddress(pkh_addr, in_amt) number_inputs += 1 # Now do segwit/legacy multisig if multisig: if input_type == 'legacy' or input_type == 'all': self.wpk_rpc.sendtoaddress(sh_multi_addr, in_amt) number_inputs += 1 if input_type == 'segwit' or input_type == 'all': self.wpk_rpc.sendtoaddress(wsh_multi_addr, in_amt) self.wpk_rpc.sendtoaddress(sh_wsh_multi_addr, in_amt) number_inputs += 2 self.wpk_rpc.generatetoaddress(6, self.wpk_rpc.getnewaddress()) # Spend different amounts, requiring 1 to 3 inputs for i in range(number_inputs): # Create a psbt spending the above if i == number_inputs - 1: self.assertTrue((i + 1) * in_amt == self.wrpc.getbalance("*", 0, True)) psbt = self.wrpc.walletcreatefundedpsbt( [], [{ self.wpk_rpc.getnewaddress('', 'legacy'): (i + 1) * out_amt }, { self.wpk_rpc.getnewaddress('', 'p2sh-segwit'): (i + 1) * out_amt }, { self.wpk_rpc.getnewaddress('', 'bech32'): (i + 1) * out_amt }], 0, { 'includeWatching': True, 'subtractFeeFromOutputs': [0, 1, 2] }, True) # Sign with unknown inputs in two steps self._generate_and_finalize(True, psbt) # Sign all inputs all at once final_tx = self._generate_and_finalize(False, psbt) # Send off final tx to sweep the wallet self.wrpc.sendrawtransaction(final_tx) # Test wrapper to avoid mixed-inputs signing for Ledger def test_signtx(self): supports_mixed = {'coldcard', 'trezor_1', 'digitalbitbox', 'keepkey'} supports_multisig = {'ledger', 'trezor_1', 'digitalbitbox', 'keepkey'} if self.full_type not in supports_mixed: self._test_signtx("legacy", self.full_type in supports_multisig) self._test_signtx("segwit", self.full_type in supports_multisig) else: self._test_signtx("all", self.full_type in supports_multisig) # Make a huge transaction which might cause some problems with different interfaces def test_big_tx(self): # make a huge transaction that is unrelated to the hardware wallet outputs = [] num_inputs = 60 for i in range(0, num_inputs): outputs.append({self.wpk_rpc.getnewaddress('', 'legacy'): 0.001}) psbt = self.wpk_rpc.walletcreatefundedpsbt([], outputs, 0, {}, True)['psbt'] psbt = self.wpk_rpc.walletprocesspsbt(psbt)['psbt'] tx = self.wpk_rpc.finalizepsbt(psbt)['hex'] txid = self.wpk_rpc.sendrawtransaction(tx) inputs = [] for i in range(0, num_inputs): inputs.append({'txid': txid, 'vout': i}) psbt = self.wpk_rpc.walletcreatefundedpsbt( inputs, [{ self.wpk_rpc.getnewaddress('', 'legacy'): 0.001 * num_inputs }], 0, {'subtractFeeFromOutputs': [0]}, True)['psbt'] # For cli, this should throw an exception try: result = self.do_command(self.dev_args + ['signtx', psbt]) if self.interface == 'cli': self.fail('Big tx did not cause CLI to error') if self.type == 'coldcard': self.assertEqual(result['code'], -7) else: self.assertNotIn('code', result) self.assertNotIn('error', result) except OSError as e: if self.interface == 'cli': pass
class BtcWallet(): """btc钱包""" BTC_BLOCK_API = 'https://blockchain.info/' def __init__(self, app=None, consul_client=None): if app and consul_client: self.init_consul(app, consul_client) def init_consul(self, app, consul_client): try: rpc_user = app.config.get('CONFIG_BITCOIND_RPC_USER') rpc_pwd = app.config.get('CONFIG_BITCOIND_RPC_PASSWORD') wallet_passphrase = app.config.get('CONFIG_BITCOIND_WALLET_PASSWORD') self.ipport = consul_client.getRandomOneAvailableServiceIpPort(ConsulServiceName.BTC_CLI) # s = "http://%s:%s@" % (self.user, self.pwd) + self.ipport # print(s) self.bitcoin_cli = AuthServiceProxy( "http://%s:%s@" % (rpc_user, rpc_pwd) + self.ipport, timeout=10) print("Succeed to connect to the BTC node") except Exception as e: print(str(e)) print("Failed to connect to the BTC node") # 是否连接BTC节点 def is_connected(self): try: if self.bitcoin_cli.getwalletinfo().get('walletversion'): return True return False except Exception as e: print(str(e)) print("Failed to connect to the BTC node") # 节点是否同步 def is_sync(self): ret = self.bitcoin_cli.getblockchaininfo() if ret.get('blocks') != ret.get("headers"): return False else: return True # btc地址是否有效 def is_valid_address(self, coin_address): if coin_address is None or coin_address == '': return False else: ret = self.bitcoin_cli.validateaddress(coin_address).get('isvalid') print('账户检查结果:', ret) return ret # return self.bitcoin_cli.validateaddress(coin_address).get('isvalid') # 获取账户余额, 默认经过6个区块确认 def get_balance(self, coin_address): transaction_lists = self.bitcoin_cli.listunspent(1, 99999999, [coin_address]) print(transaction_lists) current_amount = 0 for transaction_list in transaction_lists: amount = transaction_list.get('amount') amount = float(amount) current_amount += amount return current_amount def get_balance_by_account(self, account): try: ret = self.bitcoin_cli.getbalance(account) return ret except Exception as e: logging.error('get balance error:{}'.format(str(e))) return None def estimate_fee(self): try: fee = self.bitcoin_cli.estimatefee(6) return fee except Exception as e: logging.error('get fee error:{}'.format(str(e))) return None def create_account(self, stellar_account): # private = random_key() # address = pubtoaddr(privtopub(private)) # print(address, private) # return address, private address = self.bitcoin_cli.getnewaddress(stellar_account) private_key = self.bitcoin_cli.dumpprivkey(address) return address, private_key def get_block_num(self): """获取最新区块数""" try: block_num = self.bitcoin_cli.getblockcount() return block_num except Exception as e: logging.error('Get btc node block number error:{}'.format(str(e))) return None def get_chain_info(self): ret = self.bitcoin_cli.getblockchaininfo() return ret def get_block_info(self, block_num): """获取区块的详细信息""" param = "block-height/{}?format=json".format(block_num) api_url = self.BTC_BLOCK_API + param # print(api_url) blocks = requests.get(api_url, timeout=500).json() # print(type(blocks)) return blocks # 链外转帐,普通交易 def payment(self, btc_base_account, address_to, amount): try: txid = self.bitcoin_cli.sendfrom(btc_base_account, address_to, amount) return True, txid except Exception as e: logging.error('btc payment error:{}'.format(str(e))) return False, str(e) def hash_get_detail(self, tx_id): """ Arguments: 1. "txid" (string, required) The transaction id """ # 根据txid获取确认链外交易信息 ret = self.bitcoin_cli.gettransaction(tx_id) abandoned = ret.get("details")[0].get("abandoned") # 获取abandon信息 confirmation_num = ret.get('confirmations') # 获取确认数 # 如果确认数小于1,则未确认 if confirmation_num < 1: msg = dict(confirm=str(ret)) # msg = ret.get("details")[0] return False, False, msg, None # 如果确认数大于1,则确认 else: msg = dict(confirm=str(ret)) # msg = ret fee = abs(ret.get("fee")) if abandoned: return True, False, msg, None else: return True, True, msg, fee def raw_payment(self, address_from, address_to, collect_amount): inputs = [] # 获取地址余额信息 try: unspend_lists = self.bitcoin_cli.listunspent(1, 9999999, [address_from]) for unspend_list in unspend_lists: # if unspend_list.get('amount') <= 0: # continue # else: txid = unspend_list.get('txid') vout = unspend_list.get('vout') inputs.append({'txid': txid, 'vout': vout}) outputs = {address_to: round(collect_amount, 8)} # 交易建立和签名时不用连接比特币网络,只有在执行交易时才需要将交易发送到网络 # 创建裸交易 transaction_hash = self.bitcoin_cli.createrawtransaction(inputs, outputs) # 使用私钥签名,获取16进制信息 hex = self.bitcoin_cli.signrawtransaction(transaction_hash).get('hex') # 广播到p2p网络,返回交易哈希 trading_hash = self.bitcoin_cli.sendrawtransaction(hex, False) return True, trading_hash, '' except Exception as e: print(e) return None, None, '' def btc_transaction_record(self, block_num): # 获取某一区块信息 block_info = self.get_block_info(block_num) blocks = block_info.get('blocks') txs = blocks[0].get('tx') records = [] for tx in txs: outs = tx.get('out') hash = tx.get('hash') inputs = tx.get('inputs') p_out = inputs[0].get('prev_out') if not p_out: continue else: addr_from = p_out.get('addr') for out in outs: re = [] addr_to = out.get('addr') value = out.get('value') / (10 ** 8) # addr_to与User表中绑定的地址进行对比,如果有,则说明此address_to有冲币记录 user = User.address_query_user('BTC', addr_to) if not user: continue else: re.append(addr_from) re.append(addr_to) re.append(value) re.append(hash) records.append(re) return records def get_accounts(self, addr): try: ad = self.bitcoin_cli.getaccount(addr) return ad except Exception as e: # logging.error('get btc_account error:{}'.format(str(e))) return None def get_address_byaccount(self, account): re = self.bitcoin_cli.getaddressesbyaccount(account) return re def test1(self): transaction_list = self.bitcoin_cli.listaccounts() # transaction_list = self.bitcoin_cli.getwalletinfo() print(transaction_list)
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: print access.getbalance(acct, mc) except: print access.getbalance() except: print "\n---An error occurred---\n" elif cmd == "getbestblockhash": print access.getbestblockhash() elif cmd == "getblockbycount": height = raw_input("Height: ") print access.getblockbycount(height) elif cmd == "getblockcount": print access.getblockcount() elif cmd == "getblocknumber":
async def tip(self, ctx, mention=None, amount=None): 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 if mention is None or amount is None: embed = discord.Embed(color=0xffd800) embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url_as( format='png', size=256)) embed.add_field( name= "No user or amount specified. Please check **!help** for information.", value=" :warning: :warning: :warning: ") 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) elif not str_isfloat(amount): embed = discord.Embed(color=0xff0000) embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url_as( format='png', size=256)) embed.add_field( name= "Invalid tip amount. Please check **!help** for information.", value="`{0}`".format(amount)) 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 tipfrom = str(ctx.author.id) tipto = str(mention.replace('<@', '').replace('>', '')) amount = Decimal(str(float(amount))) if amount < Decimal('0.01'): embed = discord.Embed(color=0xff0000) embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url_as( format='png', size=256)) embed.add_field( name="Tip amount must be atleast 0.01 UMBRU", value="`{0}`".format(amount)) 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: if len(tipto) != 18 and len(tipto) != 17: embed = discord.Embed(color=0xff0000) embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url_as( format='png', size=256)) embed.add_field( name= "Invalid User. Please check **!help** for information.", value="`{0}`".format(str(mention))) 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) elif tipfrom == tipto: embed = discord.Embed(color=0xff0000) embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url_as( format='png', size=256)) embed.add_field(name="Sorry you cannot tip yourself!", value=" :wink: ") 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) elif amount > client.getbalance(tipfrom, config.CONFIRM): embed = discord.Embed(color=0xff0000) embed.set_author(name=ctx.author.display_name, icon_url=ctx.author.avatar_url_as( format='png', size=256)) embed.add_field( name="Sorry you do not have enough UMBRU for that.", value="Your balance is: **{0} UMBRU**".format( client.getbalance(tipfrom, config.CONFIRM))) 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: if tipto == str(self.bot.user.id): try: move_istrue = client.move( tipfrom, 'tipbot_wallet', float(amount)) except: embed = discord.Embed(color=0xff0000) embed.set_author( name=ctx.author.display_name, icon_url=ctx.author.avatar_url_as( format='png', size=256)) embed.add_field( name= "Invalid tip amount. Please check **!help** for information.", value="`{0}`".format(amount)) 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) if move_istrue: embed = discord.Embed(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="Thank you for the donation!", value="**{0} UMBRU**".format(amount)) 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: try: move_istrue = client.move( tipfrom, tipto, float(amount)) except: embed = discord.Embed(color=0xff0000) embed.set_author( name=ctx.author.display_name, icon_url=ctx.author.avatar_url_as( format='png', size=256)) embed.add_field( name= "Invalid tip amount. Please check **!help** for information.", value="`{0}`".format(amount)) 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) if move_istrue: embed = discord.Embed(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="{0} has tipped {1} `{2} UMBRU`". format( ctx.author.display_name, self.bot.get_user( int(tipto)).display_name, amount), value="Spend it wisely!") 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)
class BTCRPCCall(object): def __init__(self, wallet="receive", currency="btc"): yml_config_reader = ConfigFileReader() url = yml_config_reader.get_rpc_server(currency=currency, wallet=wallet) self.access = AuthServiceProxy(url) def do_getinfo(self): return self.access.getinfo() def do_get_new_address(self): return self.access.getnewaddress(); def do_set_account(self, address, account): return self.access.setaccount(address, account) def do_get_transaction(self, txid): try: return self.access.gettransaction(txid) except RuntimeError: # return simplejson.dumps ({u'error' : u'txid is not valid'}) return None def do_list_transactions(self, account, count=10, from_index=0): try: return self.access.listtransactions(account, count, from_index) except RuntimeError: print("calling failure") def do_get_transaction(self, tx_id): try: return self.access.gettransaction(tx_id) except RuntimeError: #return simplejson.dumps ({u'error' : u'txid is not valid'}) return None def amount_received_by_address(self, address="", confirms=0): return self.access.getreceivedbyaddress(address, confirms) def do_validate_address(self, address=""): return self.access.validateaddress(address) def list_transactions(self, account="", count=10, from_index=0): return self.access.listtransactions(account, count, from_index) def send_from(self, from_account="", to_address="", amount=0, minconf=1): return self.access.sendfrom(from_account, to_address, amount, minconf) def get_received_amount_by_account(self, account="", minconf=1): return self.access.getreceivedbyaccount(account, minconf) def get_balance(self, account="", minconf=1): return self.access.getbalance(account, minconf) def get_wallet_balance(self): return self.access.getbalance() def move(self, from_account="", to_account="", amount=0, minconf=1): return self.access.move(from_account, to_account, amount, minconf) def list_accounts(self, confirmations=1): return self.access.listaccounts(confirmations) def list_received_by_address(self, confirmations=1, include_empty=False): return self.access.listreceivedbyaddress(confirmations, include_empty) def get_addresses_by_account(self, account): return self.access.getaddressesbyaccount(account) def set_tx_fee(self, amount): return self.access.settxfee(amount) def send_to_address(self, address, amount, subtractfeefromamount=True): return self.access.sendtoaddress(address, amount, "", "", subtractfeefromamount) # amount is type of dictionary def send_many(self, from_account="", minconf=1, **amounts): log.info("From account: %s", from_account) log.info("To accounts: %s", json.dumps(amounts)) amounts_string = json.dumps(amounts['amounts']) amounts_object = json.loads(amounts_string) try: return True, self.access.sendmany(from_account, amounts_object, minconf) except JSONRPCException as ex: return False, ex except socket.error as e: return False, e
donation_address = "1ForFeesAndDonationsSpendHerdtWbWy"; def to_satoshi(s): return int (100000000 * float (s)); def from_satoshi(s): return float (s) / 100000000; if len(sys.argv) < 3: print ("Usage: %s <input size> <target output size in BTC>" % sys.argv[0]); exit (0); service = AuthServiceProxy ("http://%s:%s@%s:%d" % (rpc_user, rpc_pass, rpc_host, rpc_port)); balance = to_satoshi (service.getbalance()); unspent = service.listunspent(); target_in = to_satoshi (sys.argv[1]); target_out = to_satoshi (sys.argv[2]); if balance < target_in: print ("Cannot spend %f; only have %f in wallet." % (from_satoshi (target_in), from_satoshi (balance))); exit (0); if target_out > target_in: print ("Please have a smaller target output than input value."); exit (0); # FIND INPUTS # TODO: have a smarter coin selection algo
mintx = Decimal(config.get('config', 'mintx')) txfee = Decimal(config.get('config', 'txfee')) account = config.get('config', 'account') stakeholders = eval(config.get('config', 'stakeholders')) email = config.getboolean('config', 'email') binary = config.get('config', 'binary') path = config.get('config', 'path') try: # getting current account state access = AuthServiceProxy("{!s}://{!s}:{!s}@{!s}:{!s}" .format(protocol, rpcuser, rpcpass, host, port)) currentbalance = Decimal(access.getbalance(account)) if currentbalance > (mintx + txfee): # setting tx fee access.settxfee(float(txfee)) # summing the total shares totalshares = Decimal(0) for key, value in stakeholders.items(): totalshares += value['shares'] # calculating the pay per share pps = (currentbalance - txfee) / totalshares # calculating amounts to send
ChangeAddress = bitcoin.getnewaddress(); unspent = bitcoin.listunspent() # Query wallet.dat file for unspent funds to see if we have multisigs to spend from print "你的钱包里这些地址有 ",len(unspent)," 个地址可以花费" for i in range(0, len(unspent)): print print "第 ",i+1," 个地址有 ",unspent[i]["amount"]," 个比特币,相当于 ",int(unspent[i]["amount"]*100000000),"聪" print "它的传输ID ",i+1,"是" print unspent[i]["txid"] print "ScriptPubKey: ", unspent[i]["scriptPubKey"] print "地址 =====>>",unspent[i]["address"] print totalcoin = int(bitcoin.getbalance()*100000000) print "钱包总额是:", totalcoin, "聪" print WhichTrans = int(raw_input('你想花费哪个地址上的币? '))-1 if WhichTrans > len(unspent): #Basic idiot check. Clearly a real wallet would do more checks. print "抱歉这个地址不存在,请确认您输入的序号" else: tempaddy = str(unspent[WhichTrans]["address"]) print if int(tempaddy[0:1]) == 1: print "这是一个普通地址,请输入多重签名地址的序号" elif int(tempaddy[0:1]) == 3: print "地址是",tempaddy print "以3开头的地址意味着这是一个多重签名地址." print
def process_withdraw_transactions(ticker=None): if not ticker: for c in Currency.objects.all(): process_withdraw_transactions.delay(c.ticker) return with transaction.atomic(): currency = Currency.objects.select_for_update().get(ticker=ticker) coin = AuthServiceProxy(currency.api_url) # this will fail if bitcoin offline coin.getbalance() wtxs = WithdrawTransaction.objects.select_for_update() \ .select_related('wallet') \ .filter(currency=currency, state=WithdrawTransaction.NEW, txid=None) \ .order_by('wallet') transaction_hash = {} for tx in wtxs: if tx.address in transaction_hash: transaction_hash[tx.address] += tx.amount else: transaction_hash[tx.address] = tx.amount if currency.dust > Decimal('0'): for address, amount in list(transaction_hash.items()): if amount < currency.dust: wtxs = wtxs.exclude(currency=currency, address=address) del transaction_hash[address] if not transaction_hash: return wtxs_ids = list(wtxs.values_list('id', flat=True)) wtxs.update(state=WithdrawTransaction.ERROR) # this will fail if bitcoin offline coin.getbalance() txid = coin.sendmany(settings.CC_ACCOUNT, transaction_hash) if not txid: raise AssertionError('txid is empty') fee = coin.gettransaction(txid).get('fee', 0) * -1 with transaction.atomic(): currency = Currency.objects.select_for_update().get(ticker=ticker) wtxs = WithdrawTransaction.objects.select_for_update().filter(id__in=wtxs_ids) if not fee: fee_per_tx = 0 else: fee_per_tx = (fee / len(wtxs)) fee_hash = defaultdict(lambda : {'fee': Decimal('0'), 'amount': Decimal('0')}) for tx in wtxs: fee_hash[tx.wallet]['fee'] += fee_per_tx fee_hash[tx.wallet]['amount'] += tx.amount for (wallet, data) in fee_hash.items(): Operation.objects.create( wallet=wallet, holded=-data['amount'], balance=-data['fee'], description='Network fee', reason=tx ) wallet = Wallet.objects.get(id=tx.wallet.id) wallet.balance -= data['fee'] wallet.holded -= data['amount'] wallet.save() wtxs.update(txid=txid, fee=fee_per_tx, state=WithdrawTransaction.DONE)
class BTCRPCCall(object): def __init__(self, wallet="receive", currency="btc"): yml_config_reader = ConfigFileReader() url = yml_config_reader.get_rpc_server(currency=currency, wallet=wallet) self.access = AuthServiceProxy(url) def do_getinfo(self): return self.access.getinfo() def do_get_new_address(self): return self.access.getnewaddress() def do_set_account(self, address, account): return self.access.setaccount(address, account) def do_get_transaction(self, txid): try: return self.access.gettransaction(txid) except RuntimeError: # return simplejson.dumps ({u'error' : u'txid is not valid'}) return None def do_list_transactions(self, account, count=10, from_index=0): try: return self.access.listtransactions(account, count, from_index) except RuntimeError: print "calling failure" def do_get_transaction(self, tx_id): try: return self.access.gettransaction(tx_id) except RuntimeError: #return simplejson.dumps ({u'error' : u'txid is not valid'}) return None def amount_received_by_address(self, address="", confirms=0): return self.access.getreceivedbyaddress(address, confirms) def do_validate_address(self, address=""): return self.access.validateaddress(address) def list_transactions(self, account="", count=10, from_index=0): return self.access.listtransactions(account, count, from_index) def send_from(self, from_account="", to_address="", amount=0, minconf=1): return self.access.sendfrom(from_account, to_address, amount, minconf) def get_received_amount_by_account(self, account="", minconf=1): return self.access.getreceivedbyaccount(account, minconf) def get_balance(self, account="", minconf=1): return self.access.getbalance(account, minconf) def get_wallet_balance(self): return self.access.getbalance() def move(self, from_account="", to_account="", amount=0, minconf=1): return self.access.move(from_account, to_account, amount, minconf) def list_accounts(self, confirmations=1): return self.access.listaccounts(confirmations) def list_received_by_address(self, confirmations=1, include_empty=False): return self.access.listreceivedbyaddress(confirmations, include_empty) def get_addresses_by_account(self, account): return self.access.getaddressesbyaccount(account) def set_tx_fee(self, amount): return self.access.settxfee(amount) def send_to_address(self, address, amount, subtractfeefromamount=True): return self.access.sendtoaddress(address, amount, "", "", subtractfeefromamount) # amount is type of dictionary def send_many(self, from_account="", minconf=1, **amounts): log.info("From account: %s", from_account) log.info("To accounts: %s", json.dumps(amounts)) amounts_string = json.dumps(amounts['amounts']) amounts_object = json.loads(amounts_string) try: return True, self.access.sendmany(from_account, amounts_object, minconf) except JSONRPCException as ex: return False, ex except socket.error as e: return False, e
class Wallet(object): """ Wallet with one account """ def __init__(self, uri, account_name, fee): self._connection = AuthServiceProxy(uri) self._account_name = account_name self._connection.settxfee(fee) @property def account_name(self): return self._account_name def get_address(self): return self._connection.getnewaddress(self._account_name) def get_accounts(self): return self._connection.listaccounts(MINIMUM_CONFIRMATIONS) @property def balance(self): return self._connection.getbalance(self._account_name, MINIMUM_CONFIRMATIONS) def move_to_account(self, source_account, destination_account, amount, comment=None): if amount > Decimal('0.0'): self._connection.move(source_account, destination_account, amount, MINIMUM_CONFIRMATIONS, comment) elif amount < Decimal('0.0'): self._connection.move(destination_account, source_account, -amount, MINIMUM_CONFIRMATIONS, comment) # just fall through if amount == 0.0 as there is nothing to do def transfer_to(self, destination, amount): """ Create an address for each wallet and transfer the funds between them """ to_address = destination.get_address() validation = self._connection.validateaddress(to_address) if validation['isvalid']: try: transaction_id = self._connection.sendfrom(self._account_name, to_address, amount, MINIMUM_CONFIRMATIONS, 'out', 'in') if transaction_id is not None: transaction_details = self._connection.gettransaction(transaction_id) fee = transaction_details.get(u'fee') # LOG.info('transaction_id %r, fee %r', transaction_id, fee) return transaction_id, fee else: return None, None except JSONRPCException as json_ex: LOG.exception('JSON Exception calling sendfrom(%s,_,%d) %r' % (self._account_name, amount, json_ex.error)) raise else: return None, None def find_transaction(self, including_transaction, confirmations=MINIMUM_CONFIRMATIONS): for transaction in self._connection.listtransactions(): if transaction.get(u'txid') == including_transaction: if transaction[u'confirmations'] >= confirmations: return True return False def wait_for_transaction( self, including_transaction, confirmations=MINIMUM_CONFIRMATIONS, max_wait=60, secs_between_checks=0.1 ): current = time() timeout = current + max_wait while current < timeout and not self.find_transaction(including_transaction, confirmations): sleep(secs_between_checks) current = time() return current < timeout def __repr__(self): """ Provide a string representation """ return "{}('{}')".format(self.__class__.__name__, self._account_name)