def main(): parser = argparse.ArgumentParser( description= 'Tool for updating votes from vote_only keys. The votes have to be defined using the (GUI) client.' ) #parser.add_argument('addresses', nargs='+', type=str, help='coldaddresses with BTS for which to update the vote') parser.add_argument('--rpcurl', type=str, help='') parser.add_argument('--rpcuser', type=str, help='') parser.add_argument('--rpcpasswd', type=str, help='') parser.add_argument('--prefix', type=str, help='defaults to "BTS" (advanced feature)') parser.set_defaults(rpcurl=config.url, rpcuser=config.user, rpcpasswd=config.passwd) #parser.set_defaults(addresses=config.coldaddresses) parser.set_defaults(prefix="BTS") args = parser.parse_args() PREFIX = args.prefix ''' Connect to bitshares client via RPC ''' print("Opening connection to client") rpc = bitsharesrpc.client(args.rpcurl, args.rpcuser, args.rpcpasswd) print("Opening wallet %s" % config.wallet) ret = rpc.wallet_open(config.wallet) print("Unlocking wallet") ret = rpc.unlock(999999, config.unlock) ''' Gather balanceids from the blockchain corresponding to the cold addresses ''' #for address in args.addresses : for address in config.coldaddresses: balances = rpc.blockchain_list_address_balances(address)["result"] print("\nGetting fund from address %s : " % (address), end="", flush=True) for balance in balances: balanceId = balance[0] asset_id = balance[1]["condition"]["asset_id"] if balance[1]["balance"] == 0.0: continue if asset_id not in assets: assets[asset_id] = rpc.blockchain_get_asset(asset_id)["result"] asset = assets[asset_id] symbol = asset["symbol"] print("%s " % (symbol), end="", flush=True) amount = ((balance[1]["balance"]) / float(asset["precision"])) if symbol in funds: funds[symbol] += amount else: funds[symbol] = amount print("") print(json.dumps(funds, indent=4)) rpc.lock()
def main() : parser = argparse.ArgumentParser(description='Tool to update the voter key of a coldstorage address') parser.add_argument('--voteaddress', type=str, help='address that will be allowed to vote with cold funds instead') parser.add_argument('--account', type=str, help='account that will be allowed to vote with cold funds instead') parser.add_argument('--rpcurl', type=str, help='') parser.add_argument('--rpcuser', type=str, help='') parser.add_argument('--rpcpasswd', type=str, help='') parser.add_argument('--output', type=str, help='filename into which the signed output is stored') parser.set_defaults(rpcurl=config.url, rpcuser=config.user, rpcpasswd=config.passwd) parser.set_defaults(output="signedtx.txt") args = parser.parse_args() slate_id = None ''' Connect to bitshares client via RPC ''' rpc = bitsharesrpc.client(args.rpcurl, args.rpcuser, args.rpcpasswd) if not args.voteaddress and not args.account : print("No voteaddress given! Please specify!") args.voteaddress = ask_for_address() if args.account : args.voteaddress = rpc.wallet_address_create(args.account)[ "result" ] print("Using %s from account %s" %(args.voteaddress, args.account)) ''' Ask for the private key ''' privkey = ask_for_privkey() address = Address.priv2btsaddr(Address.wif2hex(privkey)) ''' balance ids ''' balances = rpc.blockchain_list_address_balances(address)["result"] print("This address holds the following BTS funds (ignoring other assets):") ops = [] for balance in balances : balanceId = balance[0] asset_id = balance[1]["condition"]["asset_id"] asset = rpc.blockchain_get_asset(asset_id)["result"] if asset_id == 0 : if balance[1]["balance"] == 0: continue print("- %f BTS" % ((balance[1]["balance"])/float(asset["precision"]))) votekeyop = Transaction.UpdateBalanceVote(balanceId, args.voteaddress, slate_id) ops.append(Transaction.Operation( "update_balance_vote_op_type", votekeyop )) tx = Transaction.Transaction( 60*60*12, None, ops ) sigtx = Transaction.SignedTransaction(tx, [privkey]) ''' Store signed transaction ''' with open(args.output,"wb") as fp : fp.write(json.dumps(sigtx.tojson())) print("\n%d transaction successfully signed and output written to file '%s'" % (len(ops), args.output) ) print("To broadcast transaction copy the file and run ./broadcast_signed_tx.py on online computer")
def main() : parser = argparse.ArgumentParser(description='Tool for updating votes from vote_only keys. The votes have to be defined using the (GUI) client.') #parser.add_argument('addresses', nargs='+', type=str, help='coldaddresses with BTS for which to update the vote') parser.add_argument('--rpcurl', type=str, help='') parser.add_argument('--rpcuser', type=str, help='') parser.add_argument('--rpcpasswd', type=str, help='') parser.add_argument('--prefix', type=str, help='defaults to "BTS" (advanced feature)') parser.set_defaults(rpcurl=config.url, rpcuser=config.user, rpcpasswd=config.passwd) #parser.set_defaults(addresses=config.coldaddresses) parser.set_defaults(prefix="BTS") args = parser.parse_args() PREFIX = args.prefix ''' Connect to bitshares client via RPC ''' print( "Opening connection to client" ) rpc = bitsharesrpc.client(args.rpcurl, args.rpcuser, args.rpcpasswd) print( "Opening wallet %s" % config.wallet ) ret = rpc.wallet_open(config.wallet) print( "Unlocking wallet" ) ret = rpc.unlock(999999, config.unlock) ''' Gather balanceids from the blockchain corresponding to the cold addresses ''' #for address in args.addresses : for address in config.coldaddresses : balances = rpc.blockchain_list_address_balances(address)["result"] print("\nGetting fund from address %s : " % (address), end="",flush=True) for balance in balances : balanceId = balance[0] asset_id = balance[1]["condition"]["asset_id"] if balance[1]["balance"] == 0.0 : continue if asset_id not in assets: assets[asset_id] = rpc.blockchain_get_asset(asset_id)["result"] asset = assets[asset_id] symbol = asset["symbol"] print("%s " % (symbol), end="",flush=True) amount = ((balance[1]["balance"])/float(asset["precision"])) if symbol in funds : funds[symbol] += amount else : funds[symbol] = amount print("") print(json.dumps(funds,indent=4)) rpc.lock()
def main(): parser = argparse.ArgumentParser( description= 'Tool for updating votes from vote_only keys. The votes have to be defined using the (GUI) client.' ) #parser.add_argument('addresses', nargs='+', type=str, help='coldaddresses with BTS for which to update the vote') parser.add_argument('--rpcurl', type=str, help='') parser.add_argument('--rpcuser', type=str, help='') parser.add_argument('--rpcpasswd', type=str, help='') parser.add_argument('--prefix', type=str, help='defaults to "BTS" (advanced feature)') parser.set_defaults(rpcurl=config.url, rpcuser=config.user, rpcpasswd=config.passwd) #parser.set_defaults(addresses=config.coldaddresses) parser.set_defaults(prefix="BTS") args = parser.parse_args() PREFIX = args.prefix ''' Connect to bitshares client via RPC ''' print("Opening connection to client") rpc = bitsharesrpc.client(args.rpcurl, args.rpcuser, args.rpcpasswd) print("Opening wallet %s" % config.wallet) ret = rpc.wallet_open(config.wallet) print("Unlocking wallet") ret = rpc.unlock(999999, config.unlock) ''' Gather balanceids from the blockchain corresponding to the cold addresses ''' #for address in args.addresses : for address in config.coldaddresses: balances = rpc.blockchain_list_address_balances(address)["result"] print("Updating votes for address %s:" % (address)) for balance in balances: balanceId = balance[0] asset_id = balance[1]["condition"]["asset_id"] asset = rpc.blockchain_get_asset(asset_id)["result"] if asset_id == 0: if balance[1]["balance"] == 0: continue print("- %f BTS" % ((balance[1]["balance"]) / float(asset["precision"]))) try: rpc.wallet_balance_set_vote_info(balanceId, "", "vote_recommended") except Exception, e: print("Error: %s", e)
def main() : parser = argparse.ArgumentParser(description='Broadcast signed transaction to the network!') parser.add_argument('--filename', type=str, help='File containing the signed transaction') parser.add_argument('--rpcurl', type=str, help='') parser.add_argument('--rpcuser', type=str, help='') parser.add_argument('--rpcpasswd', type=str, help='') parser.set_defaults(rpcurl=config.url, rpcuser=config.user, rpcpasswd=config.passwd) parser.set_defaults(filename="signedtx.txt") args = parser.parse_args() ''' Connect to bitshares client via RPC ''' rpc = bitsharesrpc.client(args.rpcurl, args.rpcuser, args.rpcpasswd) print( "Broadcasting transaction:" ) with open( args.filename, "r" ) as f : js = json.loads(f.read()) print( json.dumps(js, indent=4) ) if query_yes_no("Are you sure?") : print(rpc.blockchain_broadcast_transaction(js))
def main(): parser = argparse.ArgumentParser( description='Offline tool to gather balances in cold storage address') parser.add_argument( '--coldaddress', type=str, help='cold storage address to get funds from (required)') parser.add_argument('--filename', type=str, help='filename in which to store the available funds') parser.add_argument('--rpcurl', type=str, help='') parser.add_argument('--rpcuser', type=str, help='') parser.add_argument('--rpcpasswd', type=str, help='') parser.set_defaults(rpcurl=config.url, rpcuser=config.user, rpcpasswd=config.passwd) parser.set_defaults(filename="availablefunds.txt") args = parser.parse_args() if not args.coldaddress: print("No voteaddress given! Please specify!") args.coldaddress = ask_for_address() ''' Connect to bitshares client via RPC ''' rpc = bitsharesrpc.client(args.rpcurl, args.rpcuser, args.rpcpasswd) ''' Get available funds ''' balances = get_available_balances(rpc, args.coldaddress) ''' Format for transfer ''' print("Available Funds in cold storage address %s:" % args.coldaddress) funds = [] for t in balances: funds.append("%f ; %s ; %d ; %d ; %s ; %s\n" % (t["balance"], t["symbol"], t["asset_id"], t["precision"], t["balanceid"], t["owner"])) print("- %f %s" % (t["balance"], t["symbol"])) with open(args.filename, "w") as fp: fp.write(str("".join(funds))) print( "Stored funds for %d assets in '%s' for offline construction & signing." % (len(funds), args.filename))
def enable( ) : parser = argparse.ArgumentParser(description='Switch over the activately signign machine') parser.add_argument('machine', nargs=1, type=str, help='Machine to activate for block signing') parser.add_argument('-force', help='Force enable machine and disable others', action='store_true') args = parser.parse_args() rpc = dict() machines = config.machines activate = args.machine[0] if activate not in machines.keys() : raise Exception("Given machine not configured!") print "checking connectivity of all machines" for m in machines : machine = machines[m] try : rpc[m] = bitsharesrpc.client(machine["url"], machine["user"], machine["passwd"]) rpc[m].info() except : print "Machine: %s not reachable." % m if args.force : print "Exiting!" return # First enable the new activate machine print("activate block production on machine: %s" % activate) rpc[activate].wallet_delegate_set_block_production("ALL","true") rpc[activate].unlock(999999, machines[activate]["unlock"]) rpc[activate].network_set_advanced_node_parameters({"desired_number_of_connections":50,"maximum_number_of_connections":200}) # then disable all others for m in machines : if m == activate : continue print("Disable block production on machine: %s" % m) machine = machines[m] if machine is not activate : rpc[m].lock() rpc[m].wallet_delegate_set_block_production("ALL","false")
def main(): parser = argparse.ArgumentParser( description='Broadcast signed transaction to the network!') parser.add_argument('--filename', type=str, help='File containing the signed transaction') parser.add_argument('--rpcurl', type=str, help='') parser.add_argument('--rpcuser', type=str, help='') parser.add_argument('--rpcpasswd', type=str, help='') parser.set_defaults(rpcurl=config.url, rpcuser=config.user, rpcpasswd=config.passwd) parser.set_defaults(filename="signedtx.txt") args = parser.parse_args() ''' Connect to bitshares client via RPC ''' rpc = bitsharesrpc.client(args.rpcurl, args.rpcuser, args.rpcpasswd) print("Broadcasting transaction:") with open(args.filename, "r") as f: js = json.loads(f.read()) print(json.dumps(js, indent=4)) if query_yes_no("Are you sure?"): print(rpc.blockchain_broadcast_transaction(js))
def main() : parser = argparse.ArgumentParser(description='Tool for updating votes from vote_only keys. The votes have to be defined using the (GUI) client.') #parser.add_argument('addresses', nargs='+', type=str, help='coldaddresses with BTS for which to update the vote') parser.add_argument('--rpcurl', type=str, help='') parser.add_argument('--rpcuser', type=str, help='') parser.add_argument('--rpcpasswd', type=str, help='') parser.add_argument('--prefix', type=str, help='defaults to "BTS" (advanced feature)') parser.set_defaults(rpcurl=config.url, rpcuser=config.user, rpcpasswd=config.passwd) #parser.set_defaults(addresses=config.coldaddresses) parser.set_defaults(prefix="BTS") args = parser.parse_args() PREFIX = args.prefix ''' Connect to bitshares client via RPC ''' print( "Opening connection to client" ) rpc = bitsharesrpc.client(args.rpcurl, args.rpcuser, args.rpcpasswd) print( "Opening wallet %s" % config.wallet ) ret = rpc.wallet_open(config.wallet) print( "Unlocking wallet" ) ret = rpc.unlock(999999, config.unlock) ''' Gather balanceids from the blockchain corresponding to the cold addresses ''' #for address in args.addresses : for address in config.coldaddresses : balances = rpc.blockchain_list_address_balances(address)["result"] print("Updating votes for address %s:" % (address)) for balance in balances : balanceId = balance[0] asset_id = balance[1]["condition"]["asset_id"] asset = rpc.blockchain_get_asset(asset_id)["result"] if asset_id == 0 : if balance[1]["balance"] == 0: continue print("- %f BTS" % ((balance[1]["balance"])/float(asset["precision"]))) try : rpc.wallet_balance_set_vote_info(balanceId, "", "vote_recommended") except Exception, e: print("Error: %s", e)
#!/usr/bin/python import bitsharesrpc import config import genbtskey import os from pprint import pprint txfee = 0.5*1e5 if __name__ == "__main__": rpc = bitsharesrpc.client(config.url, config.user, config.passwd) rpc.wallet_open(config.wallet) rpc.unlock(999999, config.unlock) print("# Reading delegates") privkeys = [] accounts = rpc.wallet_list_accounts()["result"] for account in accounts : if account["delegate_info"] : if not rpc.wallet_dump_private_key(account["owner_key"])["result"] : print("- %s (owner key not available! Skipping...)" % account["name"]) continue if account["name"] == "delegate.xeroc" : print("- %s (paying account! Skipping...)" % account["name"]) continue if rpc.market.get_balance( account["name"], 0 ) < txfee : print("- %s (Not funded! Requires %.2f BTS! Skipping...)" % (account["name"], txfee/1.0e5)) continue print("- %s" % account["name"]) ## store private keys in a variable p = os.urandom(32).encode('hex')
#!/usr/bin/python import bitsharesrpc import config import genbtskey import os from pprint import pprint txfee = 0.5 * 1e5 if __name__ == "__main__": rpc = bitsharesrpc.client(config.url, config.user, config.passwd) rpc.wallet_open(config.wallet) rpc.unlock(999999, config.unlock) print("# Reading delegates") privkeys = [] accounts = rpc.wallet_list_accounts()["result"] for account in accounts: if account["delegate_info"]: if not rpc.wallet_dump_private_key(account["owner_key"])["result"]: print("- %s (owner key not available! Skipping...)" % account["name"]) continue if account["name"] == "delegate.xeroc": print("- %s (paying account! Skipping...)" % account["name"]) continue if rpc.market.get_balance(account["name"], 0) < txfee: print("- %s (Not funded! Requires %.2f BTS! Skipping...)" % (account["name"], txfee / 1.0e5)) continue print("- %s" % account["name"])
if True: # if need conversion with open( ORIGIN_PATH ) as distribution_file: distribution = json.load(distribution_file) distribution_list = [] total = 0 for addr, bal in distribution.iteritems(): total += bal distribution_list.append([addr, bal]) print total with open(LIST_FORM_PATH, 'w') as native_file: native_file.write(json.dumps(distribution_list, indent=4)) subprocess.check_output(["../bts_convert_addresses", LIST_FORM_PATH, NATIVE_FORM_PATH]) rpc = bitsharesrpc.client("http://localhost:8000/rpc", "user", "password") print "Checking status of distribution of blockchain" rpc.blockchain_generate_issuance_map(asset, "/tmp/issuance_map.json") issued = {} total_issued = 0 with open("/tmp/issuance_map.json") as issued_file: issued_list = json.load(issued_file) for pair in issued_list: if pair[0] in issued: print "warning, duplicate issuances!" sys.exit(1) issued[pair[0]] = pair[1] total_issued += pair[1]
def main(): parser = argparse.ArgumentParser( description='Construct paperwallets according to file') parser.add_argument('fromaddress', type=str, help='Address to take funds from') parser.add_argument('number', type=int, help='Number of sharedrop addresses to create') parser.add_argument('fundwith', nargs='+', type=str, help='Fund to send to each address') parser.add_argument('--displayprecision', type=str, help='Display precision for paper wallet') parser.add_argument('--txfee', type=str, help='Transaction fee') parser.add_argument('--rpcurl', type=str, help='') parser.add_argument('--rpcuser', type=str, help='') parser.add_argument('--rpcpasswd', type=str, help='') parser.add_argument('--wallet', type=str, help='') parser.add_argument('--unlock', type=str, help='') parser.add_argument('--filename', type=str, help='') parser.add_argument('--account', help='user keys linked to account') parser.set_defaults(rpcurl=config.url, rpcuser=config.user, rpcpasswd=config.passwd, wallet=config.wallet, unlock=config.unlock, txfee=config.txfee, displayprecision=2, filename="sharedrop-signed-transaction.txt") args = parser.parse_args() ''' Connect to bitshares client via RPC ''' rpc = bitsharesrpc.client(args.rpcurl, args.rpcuser, args.rpcpasswd) rpc.wallet_open(args.wallet) rpc.unlock(999999, args.unlock) ### print("Assets for sharedrop into each address:") fundwith = {} sharedroptext = "" for fund in args.fundwith: try: amount, symbol = str(fund).split(" ") amount = float(amount) asset = rpc.blockchain_get_asset(symbol)['result'] assert asset is not None, "Asset %s does not exist on the blockchain" % symbol except: print("Something went wrong when loading 'fundwith'.") parser.print_usage() raise fundwith[symbol] = amount * asset["precision"] sharedroptext += "%.*f%s " % (args.displayprecision, amount, symbol) print(" + %f %s" % (amount, symbol)) ### Withdraw Fee in BTS! have = {} print("Getting balance from given address") balanceids = rpc.blockchain_list_address_balances( args.fromaddress)['result'] for bIDobj in balanceids: bID = bIDobj[0] balance = bIDobj[1] if symbol == "BTS": ## Substract TX fee right away balance["balance"] -= int(float(args.txfee) * 1e5) asset_id = balance["condition"]["asset_id"] asset = rpc.blockchain_get_asset(asset_id)["result"] precision = float(asset["precision"]) amount = int(balance["balance"]) symbol = asset["symbol"] have[symbol] = [amount, bIDobj, asset] ''' Check if enough funded ''' for symbol in fundwith.keys(): if symbol in have: amount = have[symbol][0] if fundwith[symbol] * args.number > amount: raise Exception( "Not enough funds. Need %f %s, but only have %f %s" % (fundwith[symbol] * args.number, symbol, amount, symbol)) else: raise Exception("Missing asset %s in address." % symbol) privkeys = [] ops = [] print("Constructing Withdraw operations") for symbol in fundwith.keys(): bIDobj = have[symbol][1] asset = have[symbol][2] bID = bIDobj[0] balance = bIDobj[1] asset_id = asset["id"] precision = float(asset["precision"]) amount = fundwith[symbol] * args.number if symbol == "BTS": amount += float(args.txfee) * 1e5 ops.append( Transaction.Operation("withdraw_op_type", Transaction.Withdraw(bID, amount))) owner = balance["condition"]["data"]["owner"] privkeys.append(rpc.wallet_dump_private_key(owner)["result"]) ''' Ensure that TX fee is paied ''' if "BTS" not in fundwith: symbol = "BTS" print("Enforcing TX fee") if symbol in have: if have[symbol] < float(args.txfee) * 1e5: raise Exception( "Not enough funds. Need %f %s, but only have %f %s" % (float(args.txfee), symbol, have[symbol], symbol)) else: raise Exception("Missing asset %s in address." % symbol) bIDobj = have[symbol][1] asset = have[symbol][2] bID = bIDobj[0] balance = bIDobj[1] asset_id = asset["id"] precision = float(asset["precision"]) amount = float(args.txfee) * precision ops.append( Transaction.Operation("withdraw_op_type", Transaction.Withdraw(bID, amount))) owner = balance["condition"]["data"]["owner"] print(" - Getting private key for signature of owner %s" % owner) privkeys.append(rpc.wallet_dump_private_key(owner)["result"]) print("Constructing Deposit operations") wifs = [] for didx in xrange(0, args.number): if args.account: address = rpc.wallet_address_create(args.account)["result"] wif = rpc.wallet_dump_private_key(address)["result"] wifs.append(wif) else: wif = Address.newwif() address = Address.wif2btsaddr(wif) wifs.append(wif) print(" + Address: %s" % address) for symbol in fundwith.keys(): bIDobj = have[symbol][1] asset = have[symbol][2] asset_id = asset["id"] amount = fundwith[symbol] wst = Transaction.WithdrawSignatureType(address) wc = Transaction.WithdrawCondition(asset_id, None, "withdraw_signature_type", wst) deposit = Transaction.Deposit(amount, wc) ops.append(Transaction.Operation("deposit_op_type", deposit)) print("Finalizing Transaction") tx = Transaction.Transaction(60 * 60 * 12, 0, ops) print("Signing Transaction") sigtx = Transaction.SignedTransaction(tx, privkeys) print("Storing WIF and ADDRESS in wallet.csv backup") with open('wallet.csv', 'wb') as csvfile: spamwriter = csv.writer(csvfile, delimiter=';') for wif in wifs: spamwriter.writerow( [wif, Address.wif2btsaddr(wif), "%s" % sharedroptext, ""]) # Send operation print(json.dumps(sigtx.tojson(), indent=4)) with open(args.filename, 'wb') as fp: fp.write(json.dumps(sigtx.tojson())) print("Transaction stored in %s" % args.filename) if query_yes_no("Please confirm the transaction"): print("Broadcasting transaction to the blockchain") print(rpc.blockchain_broadcast_transaction(sigtx.tojson())) else: print("Not broadcasted. Signed transaction stored in file %s" % args.filename) rpc.lock()
#!/usr/bin/python import csv import os import bitsharesrpc import config rpc2 = bitsharesrpc.client(config.backupurl, config.backupuser, config.backuppasswd) rpc = bitsharesrpc.client(config.mainurl, config.mainuser, config.mainpasswd) def enable( ) : print "checking connectivity" rpc2.info() # rpc.info() print "enabling backup block production" rpc2.wallet_open("delegate") rpc2.wallet_delegate_set_block_production("ALL","true") rpc2.unlock(9999999, config.backupunlock) #rpc2.setnetwork(25,30) print "disabling main block production" rpc.wallet_open("delegate") rpc.lock() rpc.wallet_delegate_set_block_production("ALL","false") if __name__ == "__main__": enable( )
def main() : parser = argparse.ArgumentParser(description='Construct paperwallets according to file') parser.add_argument('fromaddress', type=str, help='Address to take funds from') parser.add_argument('number', type=int, help='Number of sharedrop addresses to create') parser.add_argument('fundwith', nargs='+', type=str, help='Fund to send to each address') parser.add_argument('--displayprecision', type=str, help='Display precision for paper wallet') parser.add_argument('--txfee', type=str, help='Transaction fee') parser.add_argument('--rpcurl', type=str, help='') parser.add_argument('--rpcuser', type=str, help='') parser.add_argument('--rpcpasswd', type=str, help='') parser.add_argument('--wallet', type=str, help='') parser.add_argument('--unlock', type=str, help='') parser.add_argument('--filename', type=str, help='') parser.add_argument('--account', help='user keys linked to account') parser.set_defaults(rpcurl=config.url, rpcuser=config.user, rpcpasswd=config.passwd, wallet=config.wallet, unlock=config.unlock, txfee=config.txfee, displayprecision=2, filename="sharedrop-signed-transaction.txt") args = parser.parse_args() ''' Connect to bitshares client via RPC ''' rpc = bitsharesrpc.client(args.rpcurl, args.rpcuser, args.rpcpasswd) rpc.wallet_open(args.wallet) rpc.unlock(999999, args.unlock) ### print("Assets for sharedrop into each address:") fundwith = {} sharedroptext = "" for fund in args.fundwith : try : amount,symbol = str(fund).split(" ") amount = float(amount) asset = rpc.blockchain_get_asset(symbol)['result'] assert asset is not None, "Asset %s does not exist on the blockchain" % symbol except : print("Something went wrong when loading 'fundwith'.") parser.print_usage() raise fundwith[symbol] = amount*asset["precision"] sharedroptext += "%.*f%s " % (args.displayprecision, amount, symbol) print(" + %f %s" % (amount, symbol)) ### Withdraw Fee in BTS! have = {} print("Getting balance from given address") balanceids = rpc.blockchain_list_address_balances(args.fromaddress)['result'] for bIDobj in balanceids : bID = bIDobj[0] balance = bIDobj[1] if symbol == "BTS" : ## Substract TX fee right away balance["balance"] -= int( float(args.txfee) * 1e5) asset_id = balance["condition"]["asset_id"] asset = rpc.blockchain_get_asset(asset_id)["result"] precision = float(asset["precision"]) amount = int(balance["balance"]) symbol = asset["symbol"] have[symbol] = [amount, bIDobj, asset] ''' Check if enough funded ''' for symbol in fundwith.keys() : if symbol in have : amount = have[ symbol ][ 0 ] if fundwith[symbol] * args.number > amount : raise Exception("Not enough funds. Need %f %s, but only have %f %s" %(fundwith[symbol]*args.number, symbol, amount, symbol)) else : raise Exception("Missing asset %s in address." % symbol) privkeys = [] ops = [] print( "Constructing Withdraw operations" ) for symbol in fundwith.keys() : bIDobj = have[symbol][1] asset = have[symbol][2] bID = bIDobj[0] balance = bIDobj[1] asset_id = asset["id"] precision = float(asset["precision"]) amount = fundwith[symbol] * args.number if symbol == "BTS" : amount += float(args.txfee) * 1e5 ops.append(Transaction.Operation("withdraw_op_type", Transaction.Withdraw(bID, amount) )) owner = balance["condition"]["data"]["owner"] privkeys.append(rpc.wallet_dump_private_key(owner)["result"]) ''' Ensure that TX fee is paied ''' if "BTS" not in fundwith : symbol = "BTS" print( "Enforcing TX fee" ) if symbol in have : if have[symbol] < float(args.txfee) * 1e5 : raise Exception("Not enough funds. Need %f %s, but only have %f %s" %( float(args.txfee), symbol, have[symbol], symbol)) else : raise Exception("Missing asset %s in address." % symbol) bIDobj = have[symbol][1] asset = have[symbol][2] bID = bIDobj[0] balance = bIDobj[1] asset_id = asset["id"] precision = float(asset["precision"]) amount = float(args.txfee) * precision ops.append(Transaction.Operation("withdraw_op_type", Transaction.Withdraw(bID, amount) )) owner = balance["condition"]["data"]["owner"] print( " - Getting private key for signature of owner %s" % owner) privkeys.append(rpc.wallet_dump_private_key(owner)["result"]) print( "Constructing Deposit operations" ) wifs = [] for didx in xrange( 0, args.number ) : if args.account : address = rpc.wallet_address_create( args.account )[ "result" ] wif = rpc.wallet_dump_private_key(address)["result"] wifs.append(wif) else : wif = Address.newwif() address = Address.wif2btsaddr(wif) wifs.append(wif) print(" + Address: %s" % address) for symbol in fundwith.keys() : bIDobj = have[symbol][1] asset = have[symbol][2] asset_id = asset["id"] amount = fundwith[symbol] wst = Transaction.WithdrawSignatureType( address ) wc = Transaction.WithdrawCondition( asset_id, None, "withdraw_signature_type", wst) deposit = Transaction.Deposit( amount, wc ) ops.append(Transaction.Operation( "deposit_op_type", deposit)) print( "Finalizing Transaction" ) tx = Transaction.Transaction( 60*60*12, 0, ops ) print( "Signing Transaction" ) sigtx = Transaction.SignedTransaction(tx, privkeys) print( "Storing WIF and ADDRESS in wallet.csv backup" ) with open('wallet.csv', 'wb') as csvfile: spamwriter = csv.writer(csvfile, delimiter=';') for wif in wifs : spamwriter.writerow([wif, Address.wif2btsaddr(wif), "%s" %sharedroptext, ""]) # Send operation print( json.dumps( sigtx.tojson(), indent=4 ) ) with open(args.filename,'wb') as fp : fp.write(json.dumps(sigtx.tojson())) print("Transaction stored in %s" % args.filename) if query_yes_no( "Please confirm the transaction" ) : print( "Broadcasting transaction to the blockchain" ) print(rpc.blockchain_broadcast_transaction(sigtx.tojson())) else : print("Not broadcasted. Signed transaction stored in file %s" % args.filename) rpc.lock()
def main(): parser = argparse.ArgumentParser( description='Tool to update the voter key of a coldstorage address') parser.add_argument( '--voteaddress', type=str, help='address that will be allowed to vote with cold funds instead') parser.add_argument( '--account', type=str, help='account that will be allowed to vote with cold funds instead') parser.add_argument('--rpcurl', type=str, help='') parser.add_argument('--rpcuser', type=str, help='') parser.add_argument('--rpcpasswd', type=str, help='') parser.add_argument('--output', type=str, help='filename into which the signed output is stored') parser.set_defaults(rpcurl=config.url, rpcuser=config.user, rpcpasswd=config.passwd) parser.set_defaults(output="signedtx.txt") args = parser.parse_args() slate_id = None ''' Connect to bitshares client via RPC ''' rpc = bitsharesrpc.client(args.rpcurl, args.rpcuser, args.rpcpasswd) if not args.voteaddress and not args.account: print("No voteaddress given! Please specify!") args.voteaddress = ask_for_address() if args.account: args.voteaddress = rpc.wallet_address_create(args.account)["result"] print("Using %s from account %s" % (args.voteaddress, args.account)) ''' Ask for the private key ''' privkey = ask_for_privkey() address = Address.priv2btsaddr(Address.wif2hex(privkey)) ''' balance ids ''' balances = rpc.blockchain_list_address_balances(address)["result"] print( "This address holds the following BTS funds (ignoring other assets):") ops = [] for balance in balances: balanceId = balance[0] asset_id = balance[1]["condition"]["asset_id"] asset = rpc.blockchain_get_asset(asset_id)["result"] if asset_id == 0: if balance[1]["balance"] == 0: continue print("- %f BTS" % ((balance[1]["balance"]) / float(asset["precision"]))) votekeyop = Transaction.UpdateBalanceVote(balanceId, args.voteaddress, slate_id) ops.append( Transaction.Operation("update_balance_vote_op_type", votekeyop)) tx = Transaction.Transaction(60 * 60 * 12, None, ops) sigtx = Transaction.SignedTransaction(tx, [privkey]) ''' Store signed transaction ''' with open(args.output, "wb") as fp: fp.write(json.dumps(sigtx.tojson())) print( "\n%d transaction successfully signed and output written to file '%s'" % (len(ops), args.output)) print( "To broadcast transaction copy the file and run ./broadcast_signed_tx.py on online computer" )