def wsend(param): if DATA.account: amount = floatAmount(param["<amount>"]) weighting = loadJson(param["<weighting>"]) try: checksum = sum(weighting.values()) if checksum != 1.0: sys.stdout.write(" Bad weighting : checksum=%f (should be 1.0)\n" % checksum) return except: sys.stdout.write(" Not a valid weighting file\n") return prettyPrint(weighting) if amount and askYesOrNo("Send %(amount).8f %(token)s to %(recipientId)s addresses ?" % \ {"token": cfg.token, "amount": amount, "recipientId": len(weighting)}) \ and checkSecondKeys(): for address, weight in weighting.items(): share = weight * amount if share * 100000000 > cfg.fees["send"]: _send(arky.core.bakeTransaction( amount=share * 100000000 - cfg.fees["send"], recipientId=address, vendorField=param["<message>"], publicKey=DATA.firstkeys["publicKey"], privateKey=DATA.firstkeys["privateKey"], secondPrivateKey=DATA.secondkeys.get("privateKey", None) )) DATA.daemon = checkRegisteredTx("%s.registry" % (DATA.account["address"]), os.path.join(HOME, ".registry", cfg.network), quiet=True)
def validate(param): unlink(param) if param["<registry>"]: registry = loadJson(param["<registry>"], os.path.join(HOME, ".escrow", cfg.network)) if len(registry): thirdpartyKeys = arky.core.crypto.getKeys(hidenInput("Enter thirdparty passphrase: ")) if registry["secondPublicKey"] == thirdpartyKeys["publicKey"]: items = [] for tx in registry["transactions"]: if tx.get("asset", False): items.append("type=%(type)d, asset=%(asset)s" % tx) else: items.append("type=%(type)d, amount=%(amount)d, recipientId=%(recipientId)s" % tx) if not len(items): sys.stdout.write(" No transaction found in registry\n") return choices = chooseMultipleItem("Transactions(s) found:", *items) if askYesOrNo("Validate transactions %s ?" % ",".join([str(i) for i in choices])): for idx in choices: tx = registry["transactions"].pop(idx - 1) tx["signSignature"] = arky.core.crypto.getSignature(tx, thirdpartyKeys["privateKey"]) tx["id"] = arky.core.crypto.getId(tx) _send(tx) dumpJson(registry, param["<registry>"], os.path.join(HOME, ".escrow", cfg.network)) else: sys.stdout.write(" Validation canceled\n") else: sys.stdout.write(" Not the valid thirdparty passphrase\n") else: sys.stdout.write(" Transaction registry not found\n") if os.path.exists(os.path.join(HOME, ".registry", cfg.network, "thirdparty.registry")): DATA.daemon = checkRegisteredTx("thirdparty.registry", os.path.join(HOME, ".registry", cfg.network), quiet=True)
def register(param): if DATA.account: if param["2ndSecret"]: secondPublicKey = arky.core.crypto.getKeys(param["<secret>"])["publicKey"] if askYesOrNo("Register second public key %s ?" % secondPublicKey) \ and checkSecondKeys(): sys.stdout.write(" Broadcasting second secret registration...\n") _send(arky.core.bakeTransaction( type=1, publicKey=DATA.firstkeys["publicKey"], privateKey=DATA.firstkeys["privateKey"], secondPrivateKey=DATA.secondkeys.get("privateKey", None), asset={"signature": {"publicKey": secondPublicKey}} )) elif param["escrow"]: if DATA.account["secondPublicKey"]: sys.stdout.write(" This account can not be locked by thirdparty\n") return resp = rest.GET.api.accounts(address=param["<thirdparty>"]) if resp["success"]: secondPublicKey = resp["account"]["publicKey"] else: secondPublicKey = arky.core.crypto.getKeys(param["<thirdparty>"])["publicKey"] if askYesOrNo("Register thirdparty public key %s ?" % secondPublicKey) \ and checkSecondKeys(): sys.stdout.write(" Broadcasting thirdparty registration...\n") _send(arky.core.bakeTransaction( type=1, publicKey=DATA.firstkeys["publicKey"], privateKey=DATA.firstkeys["privateKey"], secondPrivateKey=DATA.secondkeys.get("privateKey", None), asset={"signature": {"publicKey": secondPublicKey}} )) else: username = param["<username>"] if askYesOrNo("Register %s account as delegate %s ?" % (DATA.account["address"], username)) \ and checkSecondKeys(): sys.stdout.write(" Broadcasting delegate registration...\n") _send(arky.core.bakeTransaction( type=2, publicKey=DATA.firstkeys["publicKey"], privateKey=DATA.firstkeys["privateKey"], secondPrivateKey=DATA.secondkeys.get("privateKey", None), asset={"delegate": {"username": username, "publicKey": DATA.firstkeys["publicKey"]}} ))
def vote(param): lst, verb, to_vote = _getVoteList(param) if len(lst) and askYesOrNo("%s %s ?" % (verb, ", ".join(to_vote))) \ and checkSecondKeys(): _send(arky.core.bakeTransaction( type=3, recipientId=DATA.account["address"], publicKey=DATA.firstkeys["publicKey"], privateKey=DATA.firstkeys["privateKey"], secondPrivateKey=DATA.secondkeys.get("privateKey", None), asset={"votes": lst} ))
def send(param): if DATA.account: amount = floatAmount(param["<amount>"]) if amount and askYesOrNo("Send %(amount).8f %(token)s to %(recipientId)s ?" % \ {"token": cfg.token, "amount": amount, "recipientId": param["<address>"]}) \ and checkSecondKeys(): _send(arky.core.bakeTransaction( amount=amount * 100000000, recipientId=param["<address>"], vendorField=param["<message>"], publicKey=DATA.firstkeys["publicKey"], privateKey=DATA.firstkeys["privateKey"], secondPrivateKey=DATA.secondkeys.get("privateKey", None) ))
def share(param): if cli.DATA.delegate and SHARE: # get blacklisted addresses if param["--blacklist"]: if os.path.exists(param["--blacklist"]): with io.open(param["--blacklist"], "r") as in_: blacklist = [e for e in in_.read().split() if e != ""] else: blacklist = param["--blacklist"].split(",") else: blacklist = [] # separate fees from rewards forged_json = "%s-%s.forged" % (cli.DATA.delegate["username"], cfg.network) forged_details = rest.GET.api.delegates.forging.getForgedByAccount( generatorPublicKey=cli.DATA.delegate["publicKey"]) rewards = int(forged_details["rewards"]) last = util.loadJson(forged_json, FOLDER) if "rewards" in last: rewards -= int(last["rewards"]) else: blockreward = int( rest.GET.api.blocks.getReward(returnKey="reward")) rewards = int(cli.DATA.account["balance"]) * rewards / max( 1, float(forged_details["forged"])) rewards = (rewards // blockreward) * blockreward forged_details.pop("success", False) # computes amount to share using reward if param["<amount>"].endswith("%"): amount = int(float(param["<amount>"][:-1]) / 100 * rewards) elif param["<amount>"][0] in ["$", "€", "£", "¥"]: price = util.getTokenPrice(cfg.token, { "$": "usd", "EUR": "eur", "€": "eur", "£": "gbp", "¥": "cny" }[amount[0]]) result = float(param["<amount>"][1:]) / price if cli.askYesOrNo( "%s=%f %s (%s/%s=%f) - Validate ?" % (amount, result, cfg.token, cfg.token, amount[0], price)): amount = int(min(rewards, result * 100000000)) else: sys.stdout.write(" Share command canceled\n") return else: amount = int(min(rewards, float(param["<amount>"]) * 100000000)) # amount = int(float(param["<amount>"])*100000000) # define treshold and ceiling if param["--lowest"]: minimum = int( float(param["--lowest"]) * 100000000 + cfg.fees["send"]) else: minimum = int(cfg.fees["send"]) if param["--highest"]: maximum = int( float(param["--highest"]) * 100000000 + cfg.fees["send"]) else: maximum = amount if amount > 100000000: sys.stdout.write("Writing share for %.8f %s\n" % (amount / 100000000, cfg.token)) # get voter contributions voters = rest.GET.api.delegates.voters( publicKey=cli.DATA.delegate["publicKey"]).get("accounts", []) if param["--delay"]: delay = int(param["--delay"]) sys.stdout.write("Checking %s day%s true vote weight...\n" % (delay, "s" if delay > 1 else "")) contributions = {} for voter in [ v for v in voters if v["address"] not in blacklist ]: # print(">>>", voter) voteforce = util.getVoteForce(voter["address"], balance=int( voter["balance"]), days=delay) contributions[voter["address"]] = voteforce sys.stdout.write(" %s : %.2f\n" % (voter["address"], voteforce)) else: contributions = dict( [v["address"], int(v["balance"])] for v in voters if v["address"] not in blacklist) k = 1.0 / max(1, sum(contributions.values())) contributions = dict((a, b * k) for a, b in contributions.items()) waiting_json = "%s-%s.waiting" % (cli.DATA.delegate["username"], cfg.network) payroll_json = "%s-%s.payroll" % (cli.DATA.delegate["username"], cfg.network) saved_payroll = util.loadJson(waiting_json, FOLDER) tosave_payroll = {} complement = {} payroll = {} for address, ratio in contributions.items(): share = amount * ratio + saved_payroll.pop(address, 0) if share >= maximum: payroll[address] = int(maximum) - cfg.fees["send"] elif share < minimum: tosave_payroll[address] = int(share) else: complement[address] = share pairs = list(pshare.applyContribution(**complement).items()) for address, share in pairs: if share < minimum: tosave_payroll[address] = share else: payroll[address] = share - cfg.fees["send"] payroll = collections.OrderedDict( sorted(payroll.items(), key=lambda e: e[-1])) tosave_payroll = collections.OrderedDict( sorted(tosave_payroll.items(), key=lambda e: e[-1])) sys.stdout.write("Payroll in SATOSHI [%s file]:\n" % payroll_json) util.prettyPrint(payroll) sys.stdout.write("Saved payroll in SATOSHI [%s file]):\n" % waiting_json) util.prettyPrint(tosave_payroll) if cli.askYesOrNo("Validate share payroll ?") \ and cli.checkSecondKeys(): tosave_payroll.update(saved_payroll) util.dumpJson(tosave_payroll, waiting_json, FOLDER) util.dumpJson(payroll, payroll_json, FOLDER) util.dumpJson(forged_details, forged_json, FOLDER) _payroll(param) else: sys.stdout.write(" Share canceled\n") else: sys.stdout.write(" No reward to send since last share\n") else: sys.stdout.write(" Share feature not available\n")