diff --git a/bin/silkaj b/bin/silkaj index 3cf945564064af3a47706eb083167f3d7e2f13e1..3b0ce2d6dbceeadefac7a5644858db73a45b67dd 100755 --- a/bin/silkaj +++ b/bin/silkaj @@ -1,10 +1,14 @@ #!/usr/bin/env python3 -from silkaj.network_tools import check_port, best_node +from sys import exit + +from silkaj.network_tools import check_port, best_node, EndPoint from silkaj.silkaj import cli, manage_cmd if __name__ == '__main__': - ep, cli_args = cli() - check_port(ep["port"]) - best_node(ep, 1) - manage_cmd(ep, cli_args) + cli_args = cli() + ep = EndPoint().ep + if not check_port(ep["port"]): + exit(1) + best_node(ep, True) + manage_cmd(cli_args) diff --git a/silkaj/blockchain_tools.py b/silkaj/blockchain_tools.py new file mode 100644 index 0000000000000000000000000000000000000000..3698bd3dccf1ac2b59e57ab1d7f466af7103c8a3 --- /dev/null +++ b/silkaj/blockchain_tools.py @@ -0,0 +1,13 @@ +from silkaj.network_tools import get_request + + +class BlockchainParams(object): + __instance = None + + def __new__(cls): + if BlockchainParams.__instance is None: + BlockchainParams.__instance = object.__new__(cls) + return BlockchainParams.__instance + + def __init__(self): + self.params = get_request("blockchain/parameters") diff --git a/silkaj/cert.py b/silkaj/cert.py index 12e37b2793092060efabf2c78a2307e74293053d..fec6cae4b9a3fd6b8afbc7f97d6906abd7ccd703 100644 --- a/silkaj/cert.py +++ b/silkaj/cert.py @@ -3,27 +3,26 @@ from tabulate import tabulate from silkaj.auth import auth_method from silkaj.tools import get_publickey_from_seed, message_exit, sign_document_from_seed -from silkaj.network_tools import get_current_block, post_request +from silkaj.network_tools import post_request, HeadBlock from silkaj.license import license_approval from silkaj.wot import is_member,\ get_uid_from_pubkey, get_informations_for_identity -def send_certification(ep, cli_args): - current_blk = get_current_block(ep) - id_to_certify = get_informations_for_identity(ep, cli_args.subsubcmd) +def send_certification(cli_args): + id_to_certify = get_informations_for_identity(cli_args.subsubcmd) main_id_to_certify = id_to_certify["uids"][0] # Display license and ask for confirmation - license_approval(current_blk["currency"]) + license_approval(HeadBlock().head_block["currency"]) # Authentication seed = auth_method(cli_args) # Check whether current user is member issuer_pubkey = get_publickey_from_seed(seed) - issuer_id = get_uid_from_pubkey(ep, issuer_pubkey) - if not is_member(ep, issuer_pubkey, issuer_id): + issuer_id = get_uid_from_pubkey(issuer_pubkey) + if not is_member(issuer_pubkey, issuer_id): message_exit("Current identity is not member.") if issuer_pubkey == id_to_certify["pubkey"]: @@ -36,11 +35,11 @@ def send_certification(ep, cli_args): # Certification confirmation if not certification_confirmation(issuer_id, issuer_pubkey, id_to_certify, main_id_to_certify): return - cert_doc = generate_certification_document(current_blk, issuer_pubkey, id_to_certify, main_id_to_certify) + cert_doc = generate_certification_document(issuer_pubkey, id_to_certify, main_id_to_certify) cert_doc += sign_document_from_seed(cert_doc, seed) + "\n" # Send certification document - post_request(ep, "wot/certify", "cert=" + urllib.parse.quote_plus(cert_doc)) + post_request("wot/certify", "cert=" + urllib.parse.quote_plus(cert_doc)) print("Certification successfully sent.") @@ -54,13 +53,14 @@ def certification_confirmation(issuer_id, issuer_pubkey, id_to_certify, main_id_ return True -def generate_certification_document(current_blk, issuer_pubkey, id_to_certify, main_id_to_certify): +def generate_certification_document(issuer_pubkey, id_to_certify, main_id_to_certify): + head_block = HeadBlock().head_block return "Version: 10\n\ Type: Certification\n\ -Currency: " + current_blk["currency"] + "\n\ +Currency: " + head_block["currency"] + "\n\ Issuer: " + issuer_pubkey + "\n\ IdtyIssuer: " + id_to_certify["pubkey"] + "\n\ IdtyUniqueID: " + main_id_to_certify["uid"] + "\n\ IdtyTimestamp: " + main_id_to_certify["meta"]["timestamp"] + "\n\ IdtySignature: " + main_id_to_certify["self"] + "\n\ -CertTimestamp: " + str(current_blk["number"]) + "-" + current_blk["hash"] + "\n" +CertTimestamp: " + str(head_block["number"]) + "-" + head_block["hash"] + "\n" diff --git a/silkaj/commands.py b/silkaj/commands.py index 60a05edd38a5dceab868675fc47253d8516ee6a6..267540153fefb09a2cf4fa5799d13b37cee922b1 100644 --- a/silkaj/commands.py +++ b/silkaj/commands.py @@ -6,27 +6,26 @@ from tabulate import tabulate from operator import itemgetter from silkaj.wot import get_uid_from_pubkey -from silkaj.network_tools import discover_peers, get_request, best_node, get_current_block -from silkaj.tools import convert_time, get_currency_symbol, message_exit +from silkaj.network_tools import discover_peers, get_request, best_node, EndPoint, HeadBlock +from silkaj.tools import convert_time, message_exit, CurrencySymbol from silkaj.constants import NO_MATCHING_ID -def currency_info(ep): - info_type = ["newcomers", "certs", "actives", "leavers", "excluded", "ud", "tx"] - i, info_data = 0, dict() - while (i < len(info_type)): - info_data[info_type[i]] = get_request(ep, "blockchain/with/" + info_type[i])["result"]["blocks"] - i += 1 - current = get_current_block(ep) +def currency_info(): + info_data = dict() + for info_type in ["newcomers", "certs", "actives", "leavers", "excluded", "ud", "tx"]: + info_data[info_type] = get_request("blockchain/with/" + info_type)["result"]["blocks"] + head_block = HeadBlock().head_block + ep = EndPoint().ep system("clear") - print("Connected to node:", ep[best_node(ep, 1)], ep["port"], - "\nCurrent block number:", current["number"], - "\nCurrency name:", get_currency_symbol(current["currency"]), - "\nNumber of members:", current["membersCount"], - "\nMinimal Proof-of-Work:", current["powMin"], - "\nCurrent time:", convert_time(current["time"], "all"), - "\nMedian time:", convert_time(current["medianTime"], "all"), - "\nDifference time:", convert_time(current["time"] - current["medianTime"], "hour"), + print("Connected to node:", ep[best_node(ep, False)], ep["port"], + "\nCurrent block number:", head_block["number"], + "\nCurrency name:", CurrencySymbol().symbol, + "\nNumber of members:", head_block["membersCount"], + "\nMinimal Proof-of-Work:", head_block["powMin"], + "\nCurrent time:", convert_time(head_block["time"], "all"), + "\nMedian time:", convert_time(head_block["medianTime"], "all"), + "\nDifference time:", convert_time(head_block["time"] - head_block["medianTime"], "hour"), "\nNumber of blocks containing: \ \n- new comers:", len(info_data["newcomers"]), "\n- Certifications:", len(info_data["certs"]), @@ -57,12 +56,12 @@ def power(nbr, pow=0): return "{0:.1f} × 10^{1}".format(nbr, pow) -def difficulties(ep): +def difficulties(): while True: - diffi = get_request(ep, "blockchain/difficulties") + diffi = get_request("blockchain/difficulties") levels = [OrderedDict((i, d[i]) for i in ("uid", "level")) for d in diffi["levels"]] diffi["levels"] = levels - current = get_current_block(ep) + current = get_request("blockchain/current") issuers, sorted_diffi = 0, sorted(diffi["levels"], key=itemgetter("level"), reverse=True) for d in diffi["levels"]: if d["level"] / 2 < current["powMin"]: @@ -97,7 +96,7 @@ def get_network_sort_key(endpoint): return tuple(t) -def network_info(ep, discover): +def network_info(discover): rows, columns = popen('stty size', 'r').read().split() # print(rows, columns) # debug wide = int(columns) @@ -105,14 +104,14 @@ def network_info(ep, discover): message_exit("Wide screen need to be larger than 146. Current wide: " + wide) # discover peers # and make sure fields are always ordered the same - endpoints = [OrderedDict((i, p.get(i, None)) for i in ("domain", "port", "ip4", "ip6", "pubkey")) for p in discover_peers(ep, discover)] + endpoints = [OrderedDict((i, p.get(i, None)) for i in ("domain", "port", "ip4", "ip6", "pubkey")) for p in discover_peers(discover)] # Todo : renommer endpoints en info - diffi = get_request(ep, "blockchain/difficulties") + diffi = get_request("blockchain/difficulties") i, members = 0, 0 print("Getting informations about nodes:") while (i < len(endpoints)): print("{0:.0f}%".format(i/len(endpoints) * 100, 1), end=" ") - best_ep = best_node(endpoints[i], 0) + best_ep = best_node(endpoints[i], False) print(best_ep if best_ep is None else endpoints[i][best_ep], end=" ") print(endpoints[i]["port"]) try: @@ -135,7 +134,7 @@ def network_info(ep, discover): endpoints[i]["diffi"] = d["level"] if len(endpoints[i]["uid"]) > 10: endpoints[i]["uid"] = endpoints[i]["uid"][:9] + "…" - current_blk = get_current_block(endpoints[i]) + current_blk = get_request("blockchain/current", endpoints[i]) if current_blk is not None: endpoints[i]["gen_time"] = convert_time(current_blk["time"], "hour") if wide > 171: @@ -144,7 +143,7 @@ def network_info(ep, discover): endpoints[i]["difftime"] = convert_time(current_blk["time"] - current_blk["medianTime"], "hour") endpoints[i]["block"] = current_blk["number"] endpoints[i]["hash"] = current_blk["hash"][:10] + "…" - endpoints[i]["version"] = get_request(endpoints[i], "node/summary")["duniter"]["version"] + endpoints[i]["version"] = get_request("node/summary", endpoints[i])["duniter"]["version"] if endpoints[i].get("domain") is not None and len(endpoints[i]["domain"]) > 20: endpoints[i]["domain"] = "…" + endpoints[i]["domain"][-20:] if endpoints[i].get("ip6") is not None: @@ -159,13 +158,13 @@ def network_info(ep, discover): print(tabulate(endpoints, headers="keys", tablefmt="orgtbl", stralign="center")) -def list_issuers(ep, nbr, last): - current_blk = get_current_block(ep) - current_nbr = current_blk["number"] +def list_issuers(nbr, last): + head_block = HeadBlock().head_block + current_nbr = head_block["number"] if nbr == 0: - nbr = current_blk["issuersFrame"] + nbr = head_block["issuersFrame"] url = "blockchain/blocks/" + str(nbr) + "/" + str(current_nbr - nbr + 1) - blocks, list_issuers, j = get_request(ep, url), list(), 0 + blocks, list_issuers, j = get_request(url), list(), 0 issuers_dict = dict() while j < len(blocks): issuer = OrderedDict() @@ -180,7 +179,7 @@ def list_issuers(ep, nbr, last): j += 1 for pubkey in issuers_dict.keys(): issuer = issuers_dict[pubkey] - uid = get_uid_from_pubkey(ep, issuer["pubkey"]) + uid = get_uid_from_pubkey(issuer["pubkey"]) for issuer2 in list_issuers: if issuer2.get("pubkey") is not None and issuer.get("pubkey") is not None and \ issuer2["pubkey"] == issuer["pubkey"]: @@ -217,28 +216,29 @@ def list_issuers(ep, nbr, last): tabulate(sorted_list, headers="keys", tablefmt="orgtbl", floatfmt=".1f", stralign="center"))) -def argos_info(ep): +def argos_info(): info_type = ["newcomers", "certs", "actives", "leavers", "excluded", "ud", "tx"] pretty_names = {'g1': 'Ğ1', 'gtest': 'Ğtest'} i, info_data = 0, dict() while (i < len(info_type)): - info_data[info_type[i]] = get_request(ep, "blockchain/with/" + info_type[i])["result"]["blocks"] + info_data[info_type[i]] = get_request("blockchain/with/" + info_type[i])["result"]["blocks"] i += 1 - current = get_current_block(ep) - pretty = current["currency"] - if current["currency"] in pretty_names: - pretty = pretty_names[current["currency"]] + head_block = HeadBlock().head_block + pretty = head_block["currency"] + if head_block["currency"] in pretty_names: + pretty = pretty_names[head_block["currency"]] print(pretty, "|") print("---") - href = 'href=http://%s:%s/' % (ep[best_node(ep, 1)], ep["port"]) - print("Connected to node:", ep[best_node(ep, 1)], ep["port"], "|", href, - "\nCurrent block number:", current["number"], - "\nCurrency name:", get_currency_symbol(current["currency"]), - "\nNumber of members:", current["membersCount"], - "\nMinimal Proof-of-Work:", current["powMin"], - "\nCurrent time:", convert_time(current["time"], "all"), - "\nMedian time:", convert_time(current["medianTime"], "all"), - "\nDifference time:", convert_time(current["time"] - current["medianTime"], "hour"), + ep = EndPoint().ep + href = 'href=http://%s:%s/' % (ep[best_node(ep, False)], ep["port"]) + print("Connected to node:", ep[best_node(ep, False)], ep["port"], "|", href, + "\nCurrent block number:", head_block["number"], + "\nCurrency name:", CurrencySymbol().symbol, + "\nNumber of members:", head_block["membersCount"], + "\nMinimal Proof-of-Work:", head_block["powMin"], + "\nCurrent time:", convert_time(head_block["time"], "all"), + "\nMedian time:", convert_time(head_block["medianTime"], "all"), + "\nDifference time:", convert_time(head_block["time"] - head_block["medianTime"], "hour"), "\nNumber of blocks containing… \ \n-- new comers:", len(info_data["newcomers"]), "\n-- Certifications:", len(info_data["certs"]), diff --git a/silkaj/money.py b/silkaj/money.py index fb7e5f5877e5df115dd7b5bece629d88fdac6bce..1fb41ac232c0e60c3c243a370e13229250a373dc 100644 --- a/silkaj/money.py +++ b/silkaj/money.py @@ -1,10 +1,10 @@ -from silkaj.network_tools import get_request, get_current_block -from silkaj.tools import get_currency_symbol, get_publickey_from_seed +from silkaj.network_tools import get_request, HeadBlock +from silkaj.tools import get_publickey_from_seed, CurrencySymbol from silkaj.auth import auth_method from silkaj.wot import check_public_key -def cmd_amount(ep, cli_args): +def cmd_amount(cli_args): if not cli_args.subsubcmd.startswith("--"): pubkeys = cli_args.subsubcmd.split(":") for pubkey in pubkeys: @@ -13,45 +13,44 @@ def cmd_amount(ep, cli_args): return total = [0, 0] for pubkey in pubkeys: - value = get_amount_from_pubkey(ep, pubkey) - show_amount_from_pubkey(ep, pubkey, value) + value = get_amount_from_pubkey(pubkey) + show_amount_from_pubkey(pubkey, value) total[0] += value[0] total[1] += value[1] if (len(pubkeys) > 1): - show_amount_from_pubkey(ep, "Total", total) + show_amount_from_pubkey("Total", total) else: seed = auth_method(cli_args) pubkey = get_publickey_from_seed(seed) - show_amount_from_pubkey(ep, pubkey, get_amount_from_pubkey(ep, pubkey)) + show_amount_from_pubkey(pubkey, get_amount_from_pubkey(pubkey)) -def show_amount_from_pubkey(ep, pubkey, value): +def show_amount_from_pubkey(pubkey, value): totalAmountInput = value[0] amount = value[1] # output - UDvalue = get_last_ud_value(ep) - current_blk = get_current_block(ep) - currency_symbol = get_currency_symbol(current_blk["currency"]) + currency_symbol = CurrencySymbol().symbol + ud_value = UDValue().ud_value if totalAmountInput - amount != 0: print("Blockchain:") print("-----------") - print("Relative =", round(amount / UDvalue, 2), "UD", currency_symbol) + print("Relative =", round(amount / ud_value, 2), "UD", currency_symbol) print("Quantitative =", round(amount / 100, 2), currency_symbol + "\n") print("Pending Transaction:") print("--------------------") - print("Relative =", round((totalAmountInput - amount) / UDvalue, 2), "UD", currency_symbol) + print("Relative =", round((totalAmountInput - amount) / ud_value, 2), "UD", currency_symbol) print("Quantitative =", round((totalAmountInput - amount) / 100, 2), currency_symbol + "\n") print("Total amount of: " + pubkey) print("----------------------------------------------------------------") - print("Total Relative =", round(totalAmountInput / UDvalue, 2), "UD", currency_symbol) + print("Total Relative =", round(totalAmountInput / ud_value, 2), "UD", currency_symbol) print("Total Quantitative =", round(totalAmountInput / 100, 2), currency_symbol + "\n") -def get_amount_from_pubkey(ep, pubkey): - sources = get_request(ep, "tx/sources/" + pubkey)["sources"] +def get_amount_from_pubkey(pubkey): + sources = get_request("tx/sources/" + pubkey)["sources"] listinput = [] amount = 0 @@ -65,12 +64,11 @@ def get_amount_from_pubkey(ep, pubkey): str(source["noffset"])) # pending source - history = get_request(ep, "tx/history/" + pubkey + "/pending")["history"] + history = get_request("tx/history/" + pubkey + "/pending")["history"] pendings = history["sending"] + history["receiving"] + history["pending"] # print(pendings) - current_blk = get_current_block(ep) - last_block_number = int(current_blk["number"]) + last_block_number = int(HeadBlock().head_block["number"]) # add pending output for pending in pendings: @@ -110,8 +108,16 @@ def get_amount_from_pubkey(ep, pubkey): return int(totalAmountInput), int(amount) -def get_last_ud_value(ep): - blockswithud = get_request(ep, "blockchain/with/ud")["result"] - NBlastUDblock = blockswithud["blocks"][-1] - lastUDblock = get_request(ep, "blockchain/block/" + str(NBlastUDblock)) - return lastUDblock["dividend"] * 10 ** lastUDblock["unitbase"] +class UDValue(object): + __instance = None + + def __new__(cls): + if UDValue.__instance is None: + UDValue.__instance = object.__new__(cls) + return UDValue.__instance + + def __init__(self): + blockswithud = get_request("blockchain/with/ud")["result"] + NBlastUDblock = blockswithud["blocks"][-1] + lastUDblock = get_request("blockchain/block/" + str(NBlastUDblock)) + self.ud_value = lastUDblock["dividend"] * 10 ** lastUDblock["unitbase"] diff --git a/silkaj/network_tools.py b/silkaj/network_tools.py index e78989687ba8bc34bb3af8fd91e89f99d98f6dbb..3fbfb398c9345072550d0c10b5451469a41e76ba 100644 --- a/silkaj/network_tools.py +++ b/silkaj/network_tools.py @@ -5,37 +5,39 @@ import socket import urllib.request import logging from sys import exit, stderr +from commandlines import Command +from silkaj.constants import G1_DEFAULT_ENDPOINT, G1_TEST_DEFAULT_ENDPOINT CONNECTION_TIMEOUT = 10 -def discover_peers(ep, discover): +def discover_peers(discover): """ From first node, discover his known nodes. Remove from know nodes if nodes are down. If discover option: scan all network to know all nodes. display percentage discovering. """ - endpoints = parse_endpoints(get_request(ep, "network/peers")["peers"]) + endpoints = parse_endpoints(get_request("network/peers")["peers"]) if discover: print("Discovering network") - for i, ep in enumerate(endpoints): + for i, endpoint in enumerate(endpoints): if discover: print("{0:.0f}%".format(i / len(endpoints) * 100)) - if best_node(ep, 0) is None: - endpoints.remove(ep) + if best_node(endpoint, False) is None: + endpoints.remove(endpoint) elif discover: - endpoints = recursive_discovering(endpoints, ep) + endpoints = recursive_discovering(endpoints, endpoint) return endpoints -def recursive_discovering(endpoints, ep): +def recursive_discovering(endpoints): """ Discover recursively new nodes. If new node found add it and try to found new node from his known nodes. """ - news = parse_endpoints(get_request(ep, "network/peers")["peers"]) + news = parse_endpoints(get_request("network/peers")["peers"]) for new in news: - if best_node(new, 0) is not None and new not in endpoints: + if best_node(new, False) is not None and new not in endpoints: endpoints.append(new) recursive_discovering(endpoints, new) return endpoints @@ -62,6 +64,27 @@ def parse_endpoints(rep): return endpoints +class EndPoint(object): + __instance = None + + # Try to inheritate this part for all singleton classes + def __new__(cls): + if EndPoint.__instance is None: + EndPoint.__instance = object.__new__(cls) + return EndPoint.__instance + + def __init__(self): + cli_args = Command() + ep = dict() + if cli_args.contains_switches('p'): + ep["domain"], ep["port"] = cli_args.get_definition('p').rsplit(':', 1) + else: + ep["domain"], ep["port"] = G1_TEST_DEFAULT_ENDPOINT if cli_args.contains_switches("gtest") else G1_DEFAULT_ENDPOINT + if ep["domain"].startswith('[') and ep["domain"].endswith(']'): + ep["domain"] = ep["domain"][1:-1] + self.ep = ep + + def parse_endpoint(rep): """ rep: raw endpoint, sep: split endpoint @@ -101,8 +124,8 @@ def check_ip(address): return 0 -def get_request(ep, path): - address = best_node(ep, 0) +def get_request(path, ep=EndPoint().ep): + address = best_node(ep, False) if address is None: return address url = "http://" + ep[address] + ":" + ep["port"] + "/" + path @@ -114,8 +137,9 @@ def get_request(ep, path): return loads(response.read().decode(encoding)) -def post_request(ep, path, postdata): - address = best_node(ep, 0) +def post_request(path, postdata): + ep = EndPoint().ep + address = best_node(ep, False) if address is None: return address url = "http://" + ep[address] + ":" + ep["port"] + "/" + path @@ -154,12 +178,20 @@ def check_port(port): port = int(port) except: print("Port must be an integer", file=stderr) - exit(1) + return False if (port < 0 or port > 65536): print("Wrong port number", file=stderr) - exit(1) - return 1 + return False + return True + + +class HeadBlock(object): + __instance = None + def __new__(cls): + if HeadBlock.__instance is None: + HeadBlock.__instance = object.__new__(cls) + return HeadBlock.__instance -def get_current_block(ep): - return get_request(ep, "blockchain/current") + def __init__(self): + self.head_block = get_request("blockchain/current") diff --git a/silkaj/silkaj.py b/silkaj/silkaj.py index 5ac91f27c4b9860eae1f6c5b0136a7c14f28b240..c4e66716585d5876a0a9e3c6d08244562a3e77c5 100644 --- a/silkaj/silkaj.py +++ b/silkaj/silkaj.py @@ -8,6 +8,7 @@ from silkaj.cert import send_certification from silkaj.commands import currency_info, difficulties, set_network_sort_keys,\ network_info, argos_info, list_issuers from silkaj.tools import message_exit +from silkaj.network_tools import get_request from silkaj.wot import received_sent_certifications, id_pubkey_correspondence from silkaj.auth import generate_auth_file from silkaj.license import display_license @@ -80,63 +81,54 @@ def usage(): def cli(): - # ep: endpoint, node's network interface - ep, cli_args = dict(), Command() + cli_args = Command() subcmd = ["license", "about", "info", "diffi", "net", "network", "issuers", "argos", "amount", "tx", "transaction", "cert", "generate_auth_file", "id", "identities", "wot"] if cli_args.is_version_request(): message_exit(SILKAJ_VERSION) if cli_args.is_help_request() or cli_args.is_usage_request() or cli_args.subcmd not in subcmd: usage() - ep["domain"], ep["port"] = G1_TEST_DEFAULT_ENDPOINT if cli_args.contains_switches("gtest") else G1_DEFAULT_ENDPOINT - try: - ep["domain"], ep["port"] = cli_args.get_definition('p').rsplit(':', 1) - except: - print("Requested default node: <{}:{}>".format(ep["domain"], ep["port"]), file=stderr) - if ep["domain"].startswith('[') and ep["domain"].endswith(']'): - ep["domain"] = ep["domain"][1:-1] - return ep, cli_args + return cli_args -def manage_cmd(ep, cli_args): - +def manage_cmd(cli_args): if cli_args.subcmd == "about": about() elif cli_args.subcmd == "info": - currency_info(ep) + currency_info() elif cli_args.subcmd == "diffi": - difficulties(ep) + difficulties() elif cli_args.subcmd == "net" or cli_args.subcmd == "network": if cli_args.contains_switches("sort"): set_network_sort_keys(cli_args.get_definition("sort")) if cli_args.contains_switches("s"): set_network_sort_keys(cli_args.get_definition("s")) - network_info(ep, cli_args.contains_switches("discover")) + network_info(cli_args.contains_switches("discover")) elif cli_args.subcmd == "issuers" and cli_args.subsubcmd and int(cli_args.subsubcmd) >= 0: - list_issuers(ep, int(cli_args.subsubcmd), cli_args.contains_switches('last')) + list_issuers(int(cli_args.subsubcmd), cli_args.contains_switches('last')) elif cli_args.subcmd == "argos": - argos_info(ep) + argos_info() - elif cli_args.subcmd == "amount" and cli_args.subsubcmd: - cmd_amount(ep, cli_args) + elif cli_args.subcmd == "amount": + cmd_amount(cli_args) elif cli_args.subcmd == "tx" or cli_args.subcmd == "transaction": - send_transaction(ep, cli_args) + send_transaction(cli_args) elif cli_args.subcmd == "cert": - send_certification(ep, cli_args) + send_certification(cli_args) elif cli_args.subcmd == "generate_auth_file": generate_auth_file(cli_args) elif cli_args.subcmd == "id" or cli_args.subcmd == "identities": - id_pubkey_correspondence(ep, cli_args.subsubcmd) + id_pubkey_correspondence(cli_args.subsubcmd) elif cli_args.subcmd == "wot": - received_sent_certifications(ep, cli_args.subsubcmd) + received_sent_certifications(cli_args.subsubcmd) elif cli_args.subcmd == "license": display_license() diff --git a/silkaj/tools.py b/silkaj/tools.py index 6a965d9f8e44105644bf4690b099988bf6ae0b29..5f5ec04356088c138bab66726801a5c86bf5af60 100644 --- a/silkaj/tools.py +++ b/silkaj/tools.py @@ -4,6 +4,7 @@ from re import compile, search from sys import exit from silkaj.constants import G1_SYMBOL, GTEST_SYMBOL +from silkaj.blockchain_tools import BlockchainParams def convert_time(timestamp, kind): @@ -22,11 +23,20 @@ def convert_time(timestamp, kind): return datetime.fromtimestamp(ts).strftime(pattern) -def get_currency_symbol(currency): - if currency == "g1": - return G1_SYMBOL - elif currency == "g1-test": - return GTEST_SYMBOL +class CurrencySymbol(object): + __instance = None + + def __new__(cls): + if CurrencySymbol.__instance is None: + CurrencySymbol.__instance = object.__new__(cls) + return CurrencySymbol.__instance + + def __init__(self): + currency = BlockchainParams().params["currency"] + if currency == "g1": + self.symbol = G1_SYMBOL + elif currency == "g1-test": + self.symbol = GTEST_SYMBOL def sign_document_from_seed(document, seed): diff --git a/silkaj/tx.py b/silkaj/tx.py index 7e209a0ad509d8e3bb7735a37ad33415b776654f..743f25c8b430c8dc5e02571ce20bad405d6a4e01 100644 --- a/silkaj/tx.py +++ b/silkaj/tx.py @@ -4,35 +4,34 @@ from time import sleep import urllib from tabulate import tabulate -from silkaj.network_tools import get_request, post_request, get_current_block -from silkaj.tools import get_currency_symbol, get_publickey_from_seed, sign_document_from_seed,\ - check_public_key, message_exit +from silkaj.network_tools import get_request, post_request, HeadBlock +from silkaj.tools import get_publickey_from_seed, sign_document_from_seed,\ + check_public_key, message_exit, CurrencySymbol from silkaj.auth import auth_method from silkaj.wot import get_uid_from_pubkey -from silkaj.money import get_last_ud_value, get_amount_from_pubkey +from silkaj.money import get_amount_from_pubkey, UDValue from silkaj.constants import NO_MATCHING_ID -def send_transaction(ep, cli_args): +def send_transaction(cli_args): """ Main function """ - ud = get_last_ud_value(ep) - amount, output, comment, allSources, outputBackChange = cmd_transaction(cli_args, ud) + amount, output, comment, allSources, outputBackChange = cmd_transaction(cli_args) seed = auth_method(cli_args) issuer_pubkey = get_publickey_from_seed(seed) - pubkey_amount = get_amount_from_pubkey(ep, issuer_pubkey)[0] + pubkey_amount = get_amount_from_pubkey(issuer_pubkey)[0] outputAddresses = output.split(':') check_transaction_values(comment, outputAddresses, outputBackChange, pubkey_amount < amount * len(outputAddresses), issuer_pubkey) if cli_args.contains_switches('yes') or cli_args.contains_switches('y') or \ - input(tabulate(transaction_confirmation(ep, issuer_pubkey, amount, ud, outputAddresses, comment), + input(tabulate(transaction_confirmation(issuer_pubkey, amount, outputAddresses, comment), tablefmt="fancy_grid") + "\nDo you confirm sending this transaction? [yes/no]: ") == "yes": - generate_and_send_transaction(ep, seed, issuer_pubkey, amount, outputAddresses, comment, allSources, outputBackChange) + generate_and_send_transaction(seed, issuer_pubkey, amount, outputAddresses, comment, allSources, outputBackChange) -def cmd_transaction(cli_args, ud): +def cmd_transaction(cli_args): """ Retrieve values from command line interface """ @@ -44,7 +43,7 @@ def cmd_transaction(cli_args, ud): if cli_args.contains_definitions('amount'): amount = int(float(cli_args.get_definition('amount')) * 100) if cli_args.contains_definitions('amountUD'): - amount = int(float(cli_args.get_definition('amountUD')) * ud) + amount = int(float(cli_args.get_definition('amountUD')) * UDValue().ud_value) output = cli_args.get_definition('output') comment = cli_args.get_definition('comment') if cli_args.contains_definitions('comment') else "" @@ -70,32 +69,32 @@ def check_transaction_values(comment, outputAddresses, outputBackChange, enough_ message_exit(issuer_pubkey + " pubkey doesn’t have enough money for this transaction.") -def transaction_confirmation(ep, issuer_pubkey, amount, ud, outputAddresses, comment): +def transaction_confirmation(issuer_pubkey, amount, outputAddresses, comment): """ Generate transaction confirmation """ + currency_symbol = CurrencySymbol().symbol tx = list() - currency_symbol = get_currency_symbol(get_current_block(ep)["currency"]) tx.append(["amount (" + currency_symbol + ")", amount / 100 * len(outputAddresses)]) - tx.append(["amount (UD " + currency_symbol + ")", round(amount / ud, 4)]) + tx.append(["amount (UD " + currency_symbol + ")", round(amount / UDValue().ud_value, 4)]) tx.append(["from", issuer_pubkey]) - id_from = get_uid_from_pubkey(ep, issuer_pubkey) + id_from = get_uid_from_pubkey(issuer_pubkey) if id_from is not NO_MATCHING_ID: tx.append(["from (id)", id_from]) for outputAddress in outputAddresses: tx.append(["to", outputAddress]) - id_to = get_uid_from_pubkey(ep, outputAddress) + id_to = get_uid_from_pubkey(outputAddress) if id_to is not NO_MATCHING_ID: tx.append(["to (id)", id_to]) tx.append(["comment", comment]) return tx -def generate_and_send_transaction(ep, seed, issuers, AmountTransfered, outputAddresses, Comment="", all_input=False, OutputbackChange=None): +def generate_and_send_transaction(seed, issuers, AmountTransfered, outputAddresses, Comment="", all_input=False, OutputbackChange=None): while True: - listinput_and_amount = get_list_input_for_transaction(ep, issuers, AmountTransfered * len(outputAddresses), all_input) + listinput_and_amount = get_list_input_for_transaction(issuers, AmountTransfered * len(outputAddresses), all_input) intermediatetransaction = listinput_and_amount[2] if intermediatetransaction: @@ -104,9 +103,9 @@ def generate_and_send_transaction(ep, seed, issuers, AmountTransfered, outputAdd print(" - From: " + issuers) print(" - To: " + issuers) print(" - Amount: " + str(totalAmountInput / 100)) - transaction = generate_transaction_document(ep, issuers, totalAmountInput, listinput_and_amount, outputAddresses, "Change operation") + transaction = generate_transaction_document(issuers, totalAmountInput, listinput_and_amount, outputAddresses, "Change operation") transaction += sign_document_from_seed(transaction, seed) + "\n" - post_request(ep, "tx/process", "transaction=" + urllib.parse.quote_plus(transaction)) + post_request("tx/process", "transaction=" + urllib.parse.quote_plus(transaction)) print("Change Transaction successfully sent.") sleep(1) # wait 1 second before sending a new transaction @@ -119,25 +118,25 @@ def generate_and_send_transaction(ep, seed, issuers, AmountTransfered, outputAdd print(" - Amount: " + str(listinput_and_amount[1] / 100)) else: print(" - Amount: " + str(AmountTransfered / 100 * len(outputAddresses))) - transaction = generate_transaction_document(ep, issuers, AmountTransfered, listinput_and_amount, outputAddresses, Comment, OutputbackChange) + transaction = generate_transaction_document(issuers, AmountTransfered, listinput_and_amount, outputAddresses, Comment, OutputbackChange) transaction += sign_document_from_seed(transaction, seed) + "\n" - post_request(ep, "tx/process", "transaction=" + urllib.parse.quote_plus(transaction)) + post_request("tx/process", "transaction=" + urllib.parse.quote_plus(transaction)) print("Transaction successfully sent.") break -def generate_transaction_document(ep, issuers, AmountTransfered, listinput_and_amount, outputAddresses, Comment="", OutputbackChange=None): +def generate_transaction_document(issuers, AmountTransfered, listinput_and_amount, outputAddresses, Comment="", OutputbackChange=None): totalAmountTransfered = AmountTransfered * len(outputAddresses) listinput = listinput_and_amount[0] totalAmountInput = listinput_and_amount[1] - current_blk = get_current_block(ep) - currency_name = current_blk["currency"] - blockstamp_current = str(current_blk["number"]) + "-" + str(current_blk["hash"]) - curentUnitBase = current_blk["unitbase"] + head_block = HeadBlock().head_block + currency_name = head_block["currency"] + blockstamp_current = str(head_block["number"]) + "-" + str(head_block["hash"]) + curentUnitBase = head_block["unitbase"] if not OutputbackChange: OutputbackChange = issuers @@ -196,9 +195,9 @@ def generate_transaction_document(ep, issuers, AmountTransfered, listinput_and_a return transaction_document -def get_list_input_for_transaction(ep, pubkey, TXamount, allinput=False): +def get_list_input_for_transaction(pubkey, TXamount, allinput=False): # real source in blockchain - sources = get_request(ep, "tx/sources/" + pubkey)["sources"] + sources = get_request("tx/sources/" + pubkey)["sources"] if sources is None: return None listinput = [] @@ -208,11 +207,10 @@ def get_list_input_for_transaction(ep, pubkey, TXamount, allinput=False): listinput.append(str(source["amount"]) + ":" + str(source["base"]) + ":" + str(source["type"]) + ":" + str(source["identifier"]) + ":" + str(source["noffset"])) # pending source - history = get_request(ep, "tx/history/" + pubkey + "/pending")["history"] + history = get_request("tx/history/" + pubkey + "/pending")["history"] pendings = history["sending"] + history["receiving"] + history["pending"] - current_blk = get_current_block(ep) - last_block_number = int(current_blk["number"]) + last_block_number = int(HeadBlock().head_block["number"]) # add pending output for pending in pendings: diff --git a/silkaj/wot.py b/silkaj/wot.py index 3dceb56db26f925dda83b6a890c6778534f1d26e..889475b56cb923c201f9ca42b262dab0998a3019 100644 --- a/silkaj/wot.py +++ b/silkaj/wot.py @@ -5,6 +5,7 @@ from collections import OrderedDict from silkaj.network_tools import get_request from silkaj.tools import message_exit, check_public_key, convert_time +from silkaj.blockchain_tools import BlockchainParams from silkaj.constants import NO_MATCHING_ID @@ -18,33 +19,33 @@ def get_sent_certifications(certs, time_first_block, params): return sent, expire -def received_sent_certifications(ep, id): +def received_sent_certifications(id): """ get searched id get id of received and sent certifications display on a chart the result with the numbers """ - params = get_request(ep, "blockchain/parameters") - time_first_block = get_request(ep, "blockchain/block/1")["time"] - id_certs = get_informations_for_identity(ep, id) + time_first_block = get_request("blockchain/block/1")["time"] + id_certs = get_informations_for_identity(id) certifications = OrderedDict() system("clear") + params = BlockchainParams().params for certs in id_certs["uids"]: if certs["uid"].lower() == id.lower(): pubkey = id_certs["pubkey"] - req = get_request(ep, "wot/requirements/" + pubkey)["identities"][0] + req = get_request("wot/requirements/" + pubkey)["identities"][0] certifications["received_expire"] = list() certifications["received"] = list() for cert in certs["others"]: certifications["received_expire"].append(expiration_date_from_block_id(cert["meta"]["block_number"], time_first_block, params)) certifications["received"].append(cert_written_in_the_blockchain(req["certifications"], cert)) - certifications["sent"], certifications["sent_expire"] = get_sent_certifications(id_certs, time_first_block, params) + certifications["sent"], certifications["sent_expire"] = get_sent_certifications(id_certs, time_first_block,params) nbr_sent_certs = len(certifications["sent"]) if "sent" in certifications else 0 print("{0} ({1}) from block #{2}\nreceived {3} and sent {4}/{5} certifications:\n{6}\n" .format(id, pubkey[:5] + "…", certs["meta"]["timestamp"][:15] + "…", len(certifications["received"]), nbr_sent_certs, params["sigStock"], tabulate(certifications, headers="keys", tablefmt="orgtbl", stralign="center"))) - membership_status(ep, params, certifications, certs, pubkey, req) + membership_status(certifications, certs, pubkey, req) def cert_written_in_the_blockchain(written_certs, certifieur): @@ -54,10 +55,11 @@ def cert_written_in_the_blockchain(written_certs, certifieur): return certifieur["uids"][0] -def membership_status(ep, params, certifications, certs, pubkey, req): +def membership_status(certifications, certs, pubkey, req): + params = BlockchainParams().params if len(certifications["received"]) >= params["sigQty"]: print("Membership expiration due to certifications expirations: " + certifications["received_expire"][len(certifications["received"]) - params["sigQty"]]) - member = is_member(ep, pubkey, certs["uid"]) + member = is_member(pubkey, certs["uid"]) print("member:", member) if not member and req["wasMember"]: print("revoked:", req["revoked"], "\nrevoked on:", req["revoked_on"], "\nexpired:", req["expired"], "\nwasMember:", req["wasMember"]) @@ -75,11 +77,11 @@ def date_approximation(block_id, time_first_block, avgentime): return time_first_block + block_id * avgentime -def id_pubkey_correspondence(ep, id_pubkey): +def id_pubkey_correspondence(id_pubkey): if check_public_key(id_pubkey, False): - print("{} public key corresponds to identity: {}".format(id_pubkey, get_uid_from_pubkey(ep, id_pubkey))) + print("{} public key corresponds to identity: {}".format(id_pubkey, get_uid_from_pubkey(id_pubkey))) else: - pubkeys = get_informations_for_identities(ep, id_pubkey) + pubkeys = get_informations_for_identities(id_pubkey) if pubkeys == NO_MATCHING_ID: print(NO_MATCHING_ID) else: @@ -87,18 +89,18 @@ def id_pubkey_correspondence(ep, id_pubkey): for pubkey in pubkeys: print("→", pubkey["pubkey"], end=" ") try: - print("↔ " + get_request(ep, "wot/identity-of/" + pubkey["pubkey"])["uid"]) + print("↔ " + get_request("wot/identity-of/" + pubkey["pubkey"])["uid"]) except: print("") -def get_informations_for_identity(ep, id): +def get_informations_for_identity(id): """ Check that the id is present on the network many identities could match return the one searched """ - certs_req = get_informations_for_identities(ep, id) + certs_req = get_informations_for_identities(id) if certs_req == NO_MATCHING_ID: message_exit(NO_MATCHING_ID) for certs_id in certs_req: @@ -107,9 +109,9 @@ def get_informations_for_identity(ep, id): message_exit(NO_MATCHING_ID) -def get_uid_from_pubkey(ep, pubkey): +def get_uid_from_pubkey(pubkey): try: - results = get_request(ep, "wot/lookup/" + pubkey) + results = get_request("wot/lookup/" + pubkey) except: return NO_MATCHING_ID i, results = 0, results["results"] @@ -119,29 +121,29 @@ def get_uid_from_pubkey(ep, pubkey): i += 1 -def get_informations_for_identities(ep, identifier): +def get_informations_for_identities(identifier): """ :identifier: identity or pubkey in part or whole Return received and sent certifications lists of matching identities if one identity found """ try: - results = get_request(ep, "wot/lookup/" + identifier) + results = get_request("wot/lookup/" + identifier) except: return NO_MATCHING_ID return results["results"] -def is_member(ep, pubkey, uid): - members = get_request(ep, "wot/members")["results"] +def is_member(pubkey, uid): + members = get_request("wot/members")["results"] for member in members: if (pubkey in member["pubkey"] and uid in member["uid"]): return(True) return(False) -def get_pubkey_from_id(ep, uid): - members = get_request(ep, "wot/members")["results"] +def get_pubkey_from_id(uid): + members = get_request("wot/members")["results"] for member in members: if (uid == member["uid"]): return(member["pubkey"])