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)
def test_vector0(): nyzo_string = NyzoStringPrivateSeed.from_hex( "74d84ed425f51e6f-aa9bae140e952601-29d16a73241231dc-6962619b5fbc6e27") encoded = NyzoStringEncoder.encode(nyzo_string) assert encoded == "key_87jpjKgC.hXMHGLL50Ym9x4GSnGR918PV6CzpqKwM6WEgqRzfABZ" decoded = NyzoStringEncoder.decode(encoded) assert decoded.get_bytes() == nyzo_string.get_bytes()
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)
def test_vector79000(): nyzo_string = NyzoStringPrivateSeed.from_hex( "d60987f22773e4c7-7efb079e9900554e-b6efb568de81ec74-f7396efab7f5605d") encoded = NyzoStringEncoder.encode(nyzo_string) assert encoded == "key_8dp9y_8Et~j7wMJ7EGB0mkYUZZmFVF7JuftXsMHV.n1upfKfwunh" decoded = NyzoStringEncoder.decode(encoded) assert decoded.get_bytes() == nyzo_string.get_bytes()
def test_vector25000(): nyzo_string = NyzoStringPrivateSeed.from_hex( "2882cc9feb9e0861-ccb999c8400cf515-49b73fab4cc6c7a8-0cffef201fc2e777") encoded = NyzoStringEncoder.encode(nyzo_string) assert encoded == "key_82z2R9_IExyyRbDqQ40c.hm9KR~Ijcs7H0R_ZQ0wNLuV9ieWk_p4" decoded = NyzoStringEncoder.decode(encoded) assert decoded.get_bytes() == nyzo_string.get_bytes()
def test_vector19000(): nyzo_string = NyzoStringPrivateSeed.from_hex( "c253802154f4aa04-906275b8f922ed86-81cf11d2cac11a92-8dcdf3bee1c5af32") encoded = NyzoStringEncoder.encode(nyzo_string) assert encoded == "key_8c9jx25k.aF4B69TLfBzZpr1RP7iQJ4rBFVd-ZZyPr-QQWm3Ivcv" decoded = NyzoStringEncoder.decode(encoded) assert decoded.get_bytes() == nyzo_string.get_bytes()
def test_vector13000(): nyzo_string = NyzoStringPrivateSeed.from_hex( "e58d51a913e209db-8645d6d78f061309-d2af2ef1ed651788-4ea8d4bc4f678401") encoded = NyzoStringEncoder.encode(nyzo_string) assert encoded == "key_8endkrBjWxEsyBonTW-64NEiIQZPZnkoz4YFTbPfqWg1jt28sUiM" decoded = NyzoStringEncoder.decode(encoded) assert decoded.get_bytes() == nyzo_string.get_bytes()
def test_vector8000(): nyzo_string = NyzoStringPrivateSeed.from_hex( "83a2c34eef86da60-e0d26b82a305367b-cf4ed6893ed5d807-0f2fae99a97d77bd") encoded = NyzoStringEncoder.encode(nyzo_string) assert encoded == "key_88ezNSZMyKGxWd9IxHc5dEMfjKr9fKop1N-MIGDGwov.tBBqPRDY" decoded = NyzoStringEncoder.decode(encoded) assert decoded.get_bytes() == nyzo_string.get_bytes()
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
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)
def decode(cls, encoded_string: str) -> NyzoString: result = None try: # Map characters from the old encoding to the new encoding. A few characters were changed to make Nyzo # strings more URL-friendly. encoded_string = encoded_string.replace('*', '-').replace( '+', '.').replace('=', '~') # Map characters that may be mistyped. Nyzo strings contain neither 'l' nor 'O'. encoded_string = encoded_string.replace('l', '1').replace('O', '0') # Get the type from the prefix. Here, type is the 4 char prefix as string. string_type = encoded_string[:4] # If the type is valid, continue. if string_type in NYZO_PREFIXES: # Get the array representation of the encoded string. expanded_array = cls.bytes_for_encoded_string(encoded_string) # Get the content length from the next byte and calculate the checksum length. content_length = expanded_array[3] & 0xff # print("content_length", content_length) checksum_length = len(expanded_array) - content_length - 4 # print("checksum_length", checksum_length) # Only continue if the checksum length is valid. if 4 <= checksum_length <= 6: # Calculate the checksum and compare it to the provided checksum. # Only create the result array if the checksums match. content_buffer = memoryview( expanded_array)[0:HEADER_LENGTH + content_length] calculated_checksum = sha256( sha256(content_buffer).digest()).digest( )[:checksum_length] provided_checksum = memoryview( expanded_array)[-checksum_length:] if provided_checksum.tobytes() == calculated_checksum: # Get the content array. This is the encoded object with the prefix, length byte, and checksum # removed. content_bytes = memoryview( expanded_array)[HEADER_LENGTH:content_length + HEADER_LENGTH] # print("Content", content_bytes.tobytes()) # Make the object from the content array. if string_type == 'pre_': result = NyzoStringPrefilledData.from_bytes( content_bytes) elif string_type == 'key_': result = NyzoStringPrivateSeed(content_bytes) elif string_type == 'id__': result = NyzoStringPublicIdentifier(content_bytes) elif string_type == 'pay_': result = NyzoStringMicropay.from_bytes( content_bytes) elif string_type == 'tx__': result = NyzoStringTransaction.from_bytes( content_bytes) else: print("Invalid checksum: <{}> vs calc <{}>".format( provided_checksum.tobytes(), provided_checksum)) else: print("Invalid checksum len: <{}>".format(checksum_length)) else: print("Unknown String type: <{}>".format(string_type)) except Exception as e: print("Exception decode: {}".format(e)) # debug return result