Example #1
0
 def sign(self, private_seed: bytes) -> None:
     # TODO
     # self.app_log.error("TODO: Message.sign()")
     self._sourceNodeIdentifier = KeyUtil.private_to_public(
         private_seed.hex())
     self._sourceNodeSignature = KeyUtil.signBytes(
         self.get_bytes_for_signing(), private_seed)
Example #2
0
def load(dir: str = './'):
    """
    Overload info with config.default.txt and config.txt
    :return:
    """
    global PRIVATE_KEY
    global PUBLIC_KEY
    if path.exists(dir + "config.default.txt"):
        _overload(dir + "config.default.txt")
    if path.exists(dir + "config.txt"):
        _overload(dir + "config.txt")

    # Load the keys
    if not path.isfile(NYZO_SEED):
        print(f"No key file, creating one into {NYZO_SEED}")
        PRIVATE_KEY = KeyUtil.generateSeed()
        KeyUtil.save_to_private_seed_file(NYZO_SEED, PRIVATE_KEY)
    PRIVATE_KEY, PUBLIC_KEY = KeyUtil.get_from_private_seed_file(NYZO_SEED)
    # We can tweak verbosity later on, do not print here but later on.
    if DEBUG:
        print(
            f"Key Loaded, public id {ByteUtil.bytes_as_string_with_dashes(PUBLIC_KEY.to_bytes())}"
        )

    return {var: globals()[var] for var in _VARS}
Example #3
0
def token_burn(ctx, token_name: str, amount: str, key_: str = ""):
    # ./Nyzocli.py --verbose token burn TEST3 1.12345
    if key_ == "":
        seed = config.PRIVATE_KEY.to_bytes()
        key_ = NyzoStringEncoder.encode(
            NyzoStringPrivateSeed.from_hex(seed.hex()))
    else:
        seed = NyzoStringEncoder.decode(key_).get_bytes()
    key, pub = KeyUtil.get_from_private_seed(seed.hex())
    address = pub.to_ascii(encoding="hex").decode('utf-8')
    if float(amount) <= 0:
        raise ValueError("Amount has to be > 0")
    if not re.match(r"[0-9A-Z_]{3,32}", token_name):
        raise ValueError(f"Token name '{token_name}' does not follow rules")
    if VERBOSE:
        print(f"token burn {token_name} amount {amount}")
    data = f"TB:{token_name}:{amount}"
    fees = 0.000001
    # Test via API
    recipient = CYCLE_ADDRESS_HEX
    url = f"{ctx.obj['token']}/check_tx/{address}/{recipient}/{fees:0.6f}/{data}"
    if VERBOSE:
        print(url)
    res = get(url).text
    if VERBOSE:
        print(res)
    if "Error:" in res:
        print(res)
    else:
        # Assemble, sign and forward if ok
        client = NyzoClient(ctx.obj['client'])
        res = client.send(recipient, fees, data, key_)
        print(res)
Example #4
0
def token_ownership(ctx, token_name: str, recipient: str, key_: str = ""):
    # ./Nyzocli.py --verbose token ownership TEST3 3f19e603b9577b6f91d4c84531e1e94e946aa172063ea3a88efb26e3fe75bb84
    if key_ == "":
        seed = config.PRIVATE_KEY.to_bytes()
        key_ = NyzoStringEncoder.encode(
            NyzoStringPrivateSeed.from_hex(seed.hex()))
    else:
        seed = NyzoStringEncoder.decode(key_).get_bytes()
    key, pub = KeyUtil.get_from_private_seed(seed.hex())
    address = pub.to_ascii(encoding="hex").decode('utf-8')
    id__recipient, recipient = normalize_address(recipient, asHex=True)
    print(f"token ownership transfer {token_name} to {recipient}")
    data = f"TO:{token_name}"
    fees = 0.000001
    # Test via API
    url = f"{ctx.obj['token']}/check_tx/{address}/{recipient}/{fees:0.6f}/{data}"
    if VERBOSE:
        print(url)
    res = get(url).text
    if VERBOSE:
        print(res)
    if "Error:" in res:
        print("E", res)
    else:
        # Assemble, sign and forward if ok
        client = NyzoClient(ctx.obj['client'])
        res = client.send(recipient, fees, data, key_)
        print(res)
Example #5
0
 def send(self, recipient: str, amount: float = 0, data: str = "", key_: str = "", frozen: dict=None):
     """
     Send Nyzo with data string to a RECIPIENT.
     """
     if key_ == "":
         raise ValueError("Need a key_")
     seed = NyzoStringEncoder.decode(key_).get_bytes()
     # convert key to address
     address = KeyUtil.private_to_public(seed.hex())
     recipient, recipient_raw = self.normalize_address(recipient, as_hex=True)
     if frozen is None:
         frozen = self.get_frozen()
     # print (f"Sending {amount} to {recipient} since balance of {address} is > {above}.")
     # print(f"Frozen edge is at {frozen['height']}")
     # Create a tx
     timestamp = int(time() * 10) * 100 + 10000  # Fixed 10 sec delay for inclusion
     # print(timestamp, hex(timestamp))
     data_bytes = data[:32].encode("utf-8")
     transaction = Transaction(buffer=None, type=Transaction.type_standard, timestamp=timestamp,
                               sender_identifier=bytes.fromhex(address), amount=int(amount * 1e6),
                               receiver_identifier=bytes.fromhex(recipient_raw),
                               previous_block_hash=bytes.fromhex(frozen["hash"]),
                               previous_hash_height=frozen['height'],
                               signature=b'', sender_data=data_bytes)
     # print(transaction.to_json())
     key, _ = KeyUtil.get_from_private_seed(seed.hex())
     to_sign = transaction.get_bytes(for_signing=True)
     sign = KeyUtil.sign_bytes(to_sign, key)
     tx = NyzoStringTransaction(Transaction.type_standard, timestamp, int(amount * 1e6),
                                bytes.fromhex(recipient_raw),
                                frozen['height'],
                                bytes.fromhex(frozen["hash"]),
                                bytes.fromhex(address), data_bytes,
                                sign)
     tx__ = NyzoStringEncoder.encode(tx)
     # Send the tx
     url = "{}/forwardTransaction?transaction={}&action=run".format(self.client, tx__)
     res = get(url)
     # print(res.text)
     temp = self.fake_table_to_list(res.text)
     # print(temp)
     temp = temp[0]
     # Add tx to data
     temp["tx__"] = tx__
     return temp
Example #6
0
def vote(ctx, cycle_tx_sig: str, vote: int = 1, key_: str = ""):
    """
    Vote for the given cycle tx sig with the provided seed.
    If no seed is given, use the wallet one.
    - ex: python3 Nyzocli.py vote sig_gc6VHCY_yfjRc_DyosRLdi084AbY5wP9yVdTTRhajp4JUk7nbRw9c-aufwEwGY~.x0m55u.v.tGzjnA7VYP4V0m-eXyG
    - ex: python3 Nyzocli.py vote sig_gc6VHCY_yfjRc_DyosRLdi084AbY5wP9yVdTTRhajp4JUk7nbRw9c-aufwEwGY~.x0m55u.v.tGzjnA7VYP4V0m-eXyG 1
    - ex: python3 Nyzocli.py vote sig_gc6VHCY_yfjRc_DyosRLdi084AbY5wP9yVdTTRhajp4JUk7nbRw9c-aufwEwGY~.x0m55u.v.tGzjnA7VYP4V0m-eXyG 0 key_...
    """
    if key_ == "":
        seed = config.PRIVATE_KEY.to_bytes()
    else:
        seed = NyzoStringEncoder.decode(key_).get_bytes()
    key, _ = KeyUtil.get_from_private_seed(seed.hex())
    # reconvert key to address
    address = KeyUtil.private_to_public(seed.hex())
    if VERBOSE:
        app_log.info(f"Voting {vote} for {cycle_tx_sig} with id {address}")
    cycle_tx_sig_bytes = NyzoStringEncoder.decode(cycle_tx_sig).get_bytes()
    # Create a tx
    timestamp = int(
        time() * 10) * 100 + 10000  # Fixed 10 sec delay for inclusion
    # print(timestamp, hex(timestamp))
    cycle_transaction_signature_hex = cycle_tx_sig_bytes.hex()
    transaction = Transaction.from_vote_data(timestamp, bytes.fromhex(address),
                                             vote, cycle_tx_sig_bytes)
    print(transaction.to_json())
    sign = KeyUtil.sign_bytes(
        transaction.get_bytes(for_signing=True)[:106], key)
    tx = NyzoStringTransaction.from_hex_vote(hex(timestamp), address,
                                             sign.hex(), vote,
                                             cycle_transaction_signature_hex)
    tx__ = NyzoStringEncoder.encode(tx)
    # Send the tx
    url = "{}/forwardTransaction?transaction={}&action=run".format(
        ctx.obj['client'], tx__)
    if VERBOSE:
        app_log.info(f"Calling {url}")
    res = get(url)
    if VERBOSE:
        app_log.info(res)
    if path.isdir("tmp"):
        # Store for debug purposes
        with open("tmp/answer.txt", "w") as fp:
            fp.write(res.text)
    print(json.dumps(fake_table_to_list(res.text)))
Example #7
0
def safe_send(ctx,
              recipient,
              amount: float = 0,
              data: str = "",
              key_: str = ""):
    """
    Send Nyzo to a RECIPIENT then makes sure it is embedded in the planned block.
    If no seed is given, use the wallet one.
    - ex: python3 Nyzocli.py safe_send abd7fede35a84b10-8a36e6dc361d9b32-ca84d149f6eb85b4-a4e63015278d4c9f 10
    - ex: python3 Nyzocli.py safe_send abd7fede35a84b10-8a36e6dc361d9b32-ca84d149f6eb85b4-a4e63015278d4c9f 10 key_...
    """
    if key_ == "":
        seed = config.PRIVATE_KEY.to_bytes()
        key_ = NyzoStringEncoder.encode(
            NyzoStringPrivateSeed.from_hex(seed.hex()))
    else:
        seed = NyzoStringEncoder.decode(key_).get_bytes()
    # convert key to address
    address = KeyUtil.private_to_public(seed.hex())

    my_balance = ctx.invoke(balance, address=address)
    if amount == -1:
        if my_balance is None:
            my_balance = ctx.invoke(balance, address=address)
            print(my_balance)
            # my_balance = balance(ctx, address)
        amount = float(my_balance)
        if amount <= 0:
            if VERBOSE:
                app_log.warning(
                    "Balance too low or unknown {}, dropping.".format(
                        my_balance))
            print(
                json.dumps({
                    "result": "Error",
                    "reason": "Balance too low, {}".format(my_balance)
                }))
            return
        else:
            if VERBOSE:
                app_log.warning("Sending full balance {}.".format(my_balance))

    recipient, recipient_raw = normalize_address(recipient, asHex=True)

    client = NyzoClient(ctx.obj['client'])
    res = client.safe_send(recipient,
                           amount,
                           data,
                           key_,
                           max_tries=5,
                           verbose=True)
    print(res)
    return
Example #8
0
def test_keys_1(verbose=False):
    master = b'9444'  # Nyzo port as test seed
    seed = hashlib.sha256(master).digest()
    assert seed == b',V@?\xcf\xfb\xd14M\xfbw&\x89\xf6\x0eDoDq\xd2\xca\x17\xf3\xa5\xea\xa6)\xf6\xc52<l'
    # NEVER USE THAT KEY IN REAL WORLD!!!
    signing_key = ed25519.SigningKey(seed)
    hex = signing_key.to_ascii(encoding="hex").decode('utf-8')
    if verbose:
        print("private", hex)
    assert hex == '2c56403fcffbd1344dfb772689f60e446f4471d2ca17f3a5eaa629f6c5323c6c'
    public = KeyUtil.private_to_public(hex)
    if verbose:
        print("public", public)
    assert public == 'a34abe2176eeb545735b25ff68c41d716db462e55c7c3a5d48db0ae4fc95ae9e'
Example #9
0
def token_issue(ctx,
                token_name: str,
                decimals: int,
                supply: str,
                key_: str = ""):
    # ./Nyzocli.py --verbose token issue -- TEST3 3 -1
    if key_ == "":
        seed = config.PRIVATE_KEY.to_bytes()
        key_ = NyzoStringEncoder.encode(
            NyzoStringPrivateSeed.from_hex(seed.hex()))
    else:
        seed = NyzoStringEncoder.decode(key_).get_bytes()
    key, pub = KeyUtil.get_from_private_seed(seed.hex())
    address = pub.to_ascii(encoding="hex").decode('utf-8')
    if decimals < 0:
        raise ValueError("Decimals have to be >= 0")
    if decimals > 18:
        raise ValueError("Decimals have to be <= 18")
    dec = str(decimals)
    while len(dec) < 2:
        dec = "0" + dec
    if not re.match(r"[0-9A-Z_]{3,32}", token_name):
        raise ValueError(f"Token name '{token_name}' does not follow rules")
    if VERBOSE:
        print(f"token issue {token_name} decimals {dec} supply {supply}")
    data = f"TI:{token_name}:d{dec}:{supply}"
    # get fees
    url = f"{ctx.obj['token']}/fees"
    res = get(url)
    fees = res.json()
    issue_fees = fees[-1]["issue_fees"]  # micro_nyzos
    amount = issue_fees / 1000000
    if VERBOSE:
        print(f"Issue fees are {issue_fees} micro nyzos.")
    # Test via API
    recipient = CYCLE_ADDRESS_HEX
    url = f"{ctx.obj['token']}/check_tx/{address}/{recipient}/{amount:0.6f}/{data}"
    if VERBOSE:
        print(url)
    res = get(url).text
    if VERBOSE:
        print(res)
    if "Error:" in res:
        print(res)
    else:
        # Assemble, sign and forward if ok
        client = NyzoClient(ctx.obj['client'])
        res = client.send(recipient, amount, data, key_)
        print(res)
Example #10
0
    def __init__(self, a_type: MessageType, sourceNodePrivateKey, content: MessageObject, app_log: object = None,
                 sourceNodeIdentifier: bytes = None, sourceNodeSignature: bytes=None, source_ip_address: bytes=None, timestamp: int=0):
        """This is the constructor for a new message originating from this system AND from the outside,
        depending on the params."""
        self.app_log = base_app_log(app_log)
        self._type = a_type
        self._content = content
        self._valid = True

        # if sourceNodeIdentifier is None:
        self._timestamp = int(time()*1000)
        if sourceNodePrivateKey is not None:
            private_key, pub_key = KeyUtil.get_from_string(sourceNodePrivateKey)
            self._sourceNodeIdentifier = pub_key.to_bytes()
            self._sourceNodeSignature = KeyUtil.sign_bytes(self.get_bytes_for_signing(), private_key)
        else:
            print(sourceNodePrivateKey)
            # From our system
            print('wrong')
            print(dir())
            self._sourceNodeIdentifier = config.PUBLIC_KEY.to_bytes()
            self._sourceNodeSignature = KeyUtil.sign_bytes(self.get_bytes_for_signing(), config.PRIVATE_KEY)
            # As a test, we can verify our sig before sending
        """
Example #11
0
    def __init__(self,
                 a_type: MessageType,
                 content: MessageObject,
                 app_log: object = None,
                 sourceNodeIdentifier: bytes = None,
                 sourceNodeSignature: bytes = None,
                 source_ip_address: bytes = None,
                 timestamp: int = 0):
        """This is the constructor for a new message originating from this system AND from the outside,
        depending on the params."""
        self.app_log = base_app_log(app_log)
        self._type = a_type
        self._content = content
        self._valid = True

        if sourceNodeIdentifier is None:
            # From our system
            self._timestamp = int(time() * 1000)
            self._sourceNodeIdentifier = config.PUBLIC_KEY.to_bytes()
            self._sourceNodeSignature = KeyUtil.sign_bytes(
                self.get_bytes_for_signing(), config.PRIVATE_KEY)
            # As a test, we can verify our sig before sending
            """
            KeyUtil.signature_is_valid(self._sourceNodeSignature, self.get_bytes_for_signing(), 
                                       config.PUBLIC_KEY.to_bytes())
            """
        else:
            # From another system
            self._timestamp = timestamp
            self._sourceNodeIdentifier = sourceNodeIdentifier
            self._sourceNodeSignature = sourceNodeSignature
            self._sourceIpAddress = source_ip_address
            # self._valid = KeyUtil.signature_is_valid(sourceNodeSignature, self.get_bytes_for_signing(),
            # sourceNodeIdentifier)
            self.valid = True
            # TODO: needs all the chain of get_bytes to validate; let suppose for now it is valid.
            if config.VERBOSE:
                self.app_log.warning(
                    f"TODO: Did NOT validate message from "
                    f"{ByteUtil.bytes_as_string_with_dashes(sourceNodeIdentifier)} "
                    f"of type {self._type.name}")
            if not self._valid:
                self.app_log.warning(
                    f"message from {ByteUtil.bytes_as_string_with_dashes(sourceNodeIdentifier)} "
                    f"of type {self._type.name} is not valid")  # Temp log
Example #12
0
def send(ctx,
         recipient,
         amount: float = 0,
         above: float = 0,
         data: str = "",
         key_: str = ""):
    """
    Send Nyzo to a RECIPIENT.
    ABOVE is optional, if > 0 then the tx will only be sent when balance > ABOVE
    Using -1 as amount will send the FULL balance of the address
    If no seed is given, use the wallet one.
    - ex: python3 Nyzocli.py send abd7fede35a84b10-8a36e6dc361d9b32-ca84d149f6eb85b4-a4e63015278d4c9f 10
    - ex: python3 Nyzocli.py send abd7fede35a84b10-8a36e6dc361d9b32-ca84d149f6eb85b4-a4e63015278d4c9f 10 0 key_...
    """
    # TODO: Use newest helper from pynyzo
    if key_ == "":
        seed = config.PRIVATE_KEY.to_bytes()
    else:
        seed = NyzoStringEncoder.decode(key_).get_bytes()
    # convert key to address
    address = KeyUtil.private_to_public(seed.hex())

    my_balance = None
    if above > 0:
        my_balance = ctx.invoke(balance, address=address)
        if my_balance <= above:
            if VERBOSE:
                app_log.warning(
                    "Balance too low, {} instead of required {}, dropping.".
                    format(my_balance, above))
            print(
                json.dumps({
                    "result":
                    "Error",
                    "reason":
                    "Balance too low, {} instead of required {}".format(
                        my_balance, above)
                }))
            return
    if amount == -1:
        if my_balance is None:
            my_balance = ctx.invoke(balance, address=address)
            print(my_balance)
            # my_balance = balance(ctx, address)
        amount = float(my_balance)
        if amount <= 0:
            if VERBOSE:
                app_log.warning(
                    "Balance too low or unknown {}, dropping.".format(
                        my_balance))
            print(
                json.dumps({
                    "result": "Error",
                    "reason": "Balance too low, {}".format(my_balance)
                }))
            return
        else:
            if VERBOSE:
                app_log.warning("Sending full balance {}.".format(my_balance))

    recipient, recipient_raw = normalize_address(recipient, asHex=True)
    frozen = get_frozen(ctx)
    if VERBOSE:
        app_log.info(
            f"Sending {amount} to {recipient} since balance of {address} is > {above}."
        )
        app_log.info(f"Frozen edge is at {frozen['height']}")

    # Create a tx
    timestamp = int(
        time() * 10) * 100 + 10000  # Fixed 10 sec delay for inclusion
    # print(timestamp, hex(timestamp))
    data_bytes = data[:32].encode("utf-8")
    transaction = Transaction(buffer=None,
                              type=Transaction.type_standard,
                              timestamp=timestamp,
                              sender_identifier=bytes.fromhex(address),
                              amount=int(amount * 1e6),
                              receiver_identifier=bytes.fromhex(recipient_raw),
                              previous_block_hash=bytes.fromhex(
                                  frozen["hash"]),
                              previous_hash_height=frozen['height'],
                              signature=b'',
                              sender_data=data_bytes)
    # transaction = Transaction.from_vote_data(timestamp, bytes.fromhex(address), vote, cycle_tx_sig_bytes)
    if VERBOSE:
        print(transaction.to_json())

    key, _ = KeyUtil.get_from_private_seed(seed.hex())
    # print("key", key.to_bytes().hex())
    to_sign = transaction.get_bytes(for_signing=True)
    # print("To Sign", to_sign.hex())
    sign = KeyUtil.sign_bytes(to_sign, key)
    # print("Sign", sign.hex())
    """"    
        tx_type: int,
        timestamp: int,
        amount: int,
        receiver_identifier: bytes,
        
        previous_hash_height: int,
        previous_block_hash: bytes,
        sender_identifier: bytes,
        sender_data: bytes,
        signature: bytes,
        vote: int = 0,
        transaction_signature: bytes = b''
    """
    tx = NyzoStringTransaction(Transaction.type_standard, timestamp,
                               int(amount * 1e6), bytes.fromhex(recipient_raw),
                               frozen['height'], bytes.fromhex(frozen["hash"]),
                               bytes.fromhex(address), data_bytes, sign)
    tx__ = NyzoStringEncoder.encode(tx)
    # Send the tx
    url = "{}/forwardTransaction?transaction={}&action=run".format(
        ctx.obj['client'], tx__)
    if VERBOSE:
        app_log.info(f"Calling {url}")
    res = get(url)
    if VERBOSE:
        app_log.info(res)
    if path.isdir("tmp"):
        # Store for debug purposes
        with open("tmp/answer.txt", "w") as fp:
            fp.write(res.text)
    temp = fake_table_to_list(res.text)
    if ctx.obj['json']:
        print(json.dumps(temp))
    else:
        if "error" in temp[-1]:
            print("Error:", temp[-1]["error"])
        else:
            print("Ok")
Example #13
0
        if ASK_NYZO_TODAY:
            hex_sig = NyzoStringEncoder.decode(sig[0]).get_bytes().hex()
            res = get(f"https://nyzo.today/api/transactionvotes/{hex_sig}")
            VOTED[sig[0]] = json.loads(res.text)
        else:
            VOTED[sig[0]] = {}

    total_pre = len(sigs) * len(keys)
    estimate = ((MIN_WAIT_BETWEEN_VOTE + MAX_WAIT_BETWEEN_VOTE) / 2 + 3) * total_pre / 60
    print("{} keys and {} sigs, total {} votes.\nEstimated time {} min"
          .format(len(keys), len(sigs), total_pre, estimate))
    total = list()
    for key in keys:
        key_hex = NyzoStringEncoder.decode(key).get_bytes().hex()
        # calc matching id as hex
        id_hex = KeyUtil.private_to_public(key_hex)
        for sig in sigs:
            if id_hex not in VOTED[sig[0]]:
                total.append((sig, key))
    shuffle(total)
    estimate = ((MIN_WAIT_BETWEEN_VOTE + MAX_WAIT_BETWEEN_VOTE) / 2 + 3) * len(total) / 60
    print(f"{len(keys)} keys and {len(sigs)} sigs, total after filter {len(total)} votes "
          f"instead of {total_pre}.\nEstimated time {estimate} min")
    bash = ["#!/bin/bash"]
    for item in total:
        line = "../Nyzocli.py vote {} {} {}".format(item[0][0], item[0][1], item[1])
        bash.append(line)
        delay = randint(MIN_WAIT_BETWEEN_VOTE, MAX_WAIT_BETWEEN_VOTE)
        line = "sleep {}".format(delay)
        bash.append(line)
    # print("\n".join(bash))