0

I converted contract address to bytes using pack , and the result is this 050a00000016014b168ccb96310249aade4ce010e4e2ec8dd4602900 pasting this on online byte to string tool shows an error Invalid UTF-8 detected, How to convert this to string ? How to find out which one is the prefix and which one is the actual data ? Any idea on this?

3
  • What are you actually trying to accomplish? Apr 2, 2023 at 13:04
  • Michelson string are ASCII, you cannot PACK / UNPACK UTF-8 strings No event in Japanese or fancy emoji :)
    – Thomas
    Apr 3, 2023 at 7:01
  • 050a00000016014b168ccb96310249aade4ce010e4e2ec8dd4602900 so what is this ? It seems like a hex but it shows error when I try to convert it to string .
    – lee brune
    Apr 4, 2023 at 5:27

3 Answers 3

1

There is no michelson function to convert an address to a string in a smart contract.

Sure 050a00000016014b168ccb96310249aade4ce010e4e2ec8dd4602900 is hexa but not a string.

  • The first byte 05 means it is a micheline expression.
  • The second byte 0a means it is an address.
  • The 4 next bytes are the length of the data 00000016, so 22 bytes.
  • And then The next 22 bytes 014b168ccb96310249aade4ce010e4e2ec8dd4602900 are the data encoding of the address KT1FRoFxDhnKXGPggejHPAnMs27j6rcVfwzV

You can only unpack to an address.

KT1FRoFxDhnKXGPggejHPAnMs27j6rcVfwzV as a string would be 0501000000244b543146526f467844686e4b5847506767656a4850416e4d7332376a3672635666777a56

  • The first byte 05 means it is a micheline expression.
  • The second byte 01 means it is a string.
  • The 4 next bytes are the length of the data 00000024, so 36 bytes.
  • And then The next 36 bytes 4b543146526f467844686e4b5847506767656a4850416e4d7332376a3672635666777a56 is the hexa of the string KT1FRoFxDhnKXGPggejHPAnMs27j6rcVfwzV
4
  • Is there a way I can convert the data part of address i.e. 22bytes into normal UTF-8 string ?
    – lee brune
    Apr 4, 2023 at 23:24
  • Also why is the pack function in encoding string and address behave in different way , Strings once packed and then converting that packed bytes to strings works as expected , but why does it not work as expected in address data type. What I mean is decoding 0x 4b543146526f467844686e4b5847506767656a4850416e4d7332376a3672635666777a56 gives KT1FRoFxDhnKXGPggejHPAnMs27j6rcVfwzV but decoding the data of address gives i.e 0x014b168ccb96310249aade4ce010e4e2ec8dd4602900 gives error . How is address data type encoded or what are they encoded into ?
    – lee brune
    Apr 5, 2023 at 1:53
  • 1
    It uses far less bytes to encode addresses this way, that's the reason.
    – Jordan_tez
    Apr 5, 2023 at 8:15
  • Note that you would not have to read an address as a string inside a smart contract, you are likely trying to do something unsafe ;)
    – Thomas
    Apr 5, 2023 at 9:19
0

You can convert back using sp.unpack. For your address you can do sp.unpack(sp.bytes("0x050a00000016014b168ccb96310249aade4ce010e4e2ec8dd4602900"), sp.TAddress).

3
  • I need to convert this to 050a00000016014b168ccb96310249aade4ce010e4e2ec8dd4602900 address as string , "KT1FRoFxDhnKXGPggejHPAnMs27j6rcVfwzV" By using unpack I was able to take it on address data type , but I want it on string. Can you help ?
    – lee brune
    Apr 3, 2023 at 9:23
  • I just need to show it as a string , "KT1FRoFxDhnKXGPggejHPAnMs27j6rcVfwzV"
    – lee brune
    Apr 3, 2023 at 9:34
  • You cannot convert an address to a string
    – Thomas
    Apr 3, 2023 at 15:52
0

Here is a Python example of decoding a packed address using code taken from PyTezos https://github.com/baking-bad/pytezos/blob/master/src/pytezos/michelson/forge.py#L180

import base58

def tb(l):
    return b''.join(map(lambda x: x.to_bytes(1, 'big'), l))

base58_encodings = [
    #    Encoded   |               Decoded             |
    # prefix | len | prefix                      | len | Data type
    (b"B", 51, tb([1, 52]), 32, "block hash"),
    (b"o", 51, tb([5, 116]), 32, "operation hash"),
    (b"Lo", 52, tb([133, 233]), 32, "operation list hash"),
    (b"LLo", 53, tb([29, 159, 109]), 32, "operation list list hash"),
    (b"P", 51, tb([2, 170]), 32, "protocol hash"),
    (b"Co", 52, tb([79, 199]), 32, "context hash"),
    (b"tz1", 36, tb([6, 161, 159]), 20, "ed25519 public key hash"),
    (b"tz2", 36, tb([6, 161, 161]), 20, "secp256k1 public key hash"),
    (b"tz3", 36, tb([6, 161, 164]), 20, "p256 public key hash"),
    (b"tz4", 36, tb([6, 161, 16]), 20, "BLS-MinPk"),
    (b"KT1", 36, tb([2, 90, 121]), 20, "originated address"),
    (b"txr1", 37, tb([1, 128, 120, 31]), 20, "tx_rollup_l2_address"),
    (b"sr1", 36, tb([6, 124, 117]), 20, "address prefix for originated smart rollup"),
    (b"id", 30, tb([153, 103]), 16, "cryptobox public key hash"),
    (b'expr', 54, tb([13, 44, 64, 27]), 32, u'script expression'),
    (b"edsk", 54, tb([13, 15, 58, 7]), 32, "ed25519 seed"),
    (b"edpk", 54, tb([13, 15, 37, 217]), 32, "ed25519 public key"),
    (b"spsk", 54, tb([17, 162, 224, 201]), 32, "secp256k1 secret key"),
    (b"p2sk", 54, tb([16, 81, 238, 189]), 32, "p256 secret key"),
    (b"edesk", 88, tb([7, 90, 60, 179, 41]), 56, "ed25519 encrypted seed"),
    (b"spesk", 88, tb([9, 237, 241, 174, 150]), 56, "secp256k1 encrypted secret key"),
    (b"p2esk", 88, tb([9, 48, 57, 115, 171]), 56, "p256_encrypted_secret_key"),
    (b"sppk", 55, tb([3, 254, 226, 86]), 33, "secp256k1 public key"),
    (b"p2pk", 55, tb([3, 178, 139, 127]), 33, "p256 public key"),
    (b"SSp", 53, tb([38, 248, 136]), 33, "secp256k1 scalar"),
    (b"GSp", 53, tb([5, 92, 0]), 33, "secp256k1 element"),
    (b"edsk", 98, tb([43, 246, 78, 7]), 64, "ed25519 secret key"),
    (b"edsig", 99, tb([9, 245, 205, 134, 18]), 64, "ed25519 signature"),
    (b"spsig", 99, tb([13, 115, 101, 19, 63]), 64, "secp256k1 signature"),
    (b"p2sig", 98, tb([54, 240, 44, 52]), 64, "p256 signature"),
    (b"sig", 96, tb([4, 130, 43]), 64, "generic signature"),
    (b'Net', 15, tb([87, 82, 0]), 4, "chain id"),
    (b'nce', 53, tb([69, 220, 169]), 32, 'seed nonce hash'),
    (b'btz1', 37, tb([1, 2, 49, 223]), 20, 'blinded public key hash'),
    (b'vh', 52, tb([1, 106, 242]), 32, 'block_payload_hash'),
]

def base58_encode(v: bytes, prefix: bytes) -> bytes:
    """Encode data using Base58 with checksum and add an according binary prefix in the end.

    :param v: Array of bytes
    :param prefix: Human-readable prefix (use b'') e.g. b'tz', b'KT', etc
    :returns: bytes (use string.decode())
    """
    try:
        encoding = next(encoding for encoding in base58_encodings if len(v) == encoding[3] and prefix == encoding[0])
    except StopIteration as e:
        raise ValueError('Invalid encoding, prefix or length mismatch.') from e
    return base58.b58encode_check(encoding[2] + v)

def unforge_address(data: bytes) -> str:
    """Decode address or key_hash from bytes.

    :param data: encoded address or key_hash
    :returns: base58 encoded address
    """
    tz_prefixes = {
        b'\x00\x00': b'tz1',
        b'\x00\x01': b'tz2',
        b'\x00\x02': b'tz3',
        b'\x00\x03': b'tz4',
    }

    for bin_prefix, tz_prefix in tz_prefixes.items():
        if data.startswith(bin_prefix):
            return base58_encode(data[2:], tz_prefix).decode()

    if data.startswith(b'\x01') and data.endswith(b'\x00'):
        return base58_encode(data[1:-1], b'KT1').decode()
    elif data.startswith(b'\x02') and data.endswith(b'\x00'):
        return base58_encode(data[1:-1], b'txr1').decode()
    elif data.startswith(b'\x03') and data.endswith(b'\x00'):
        return base58_encode(data[1:-1], b'sr1').decode()
    else:
        return base58_encode(data[1:], tz_prefixes[b'\x00' + data[:1]]).decode()



def hex_to_utf8_address(hex_str: str) -> str:
    return unforge_address(bytes.fromhex(hex_str[12:]))


print(hex_to_utf8_address("050a00000016014b168ccb96310249aade4ce010e4e2ec8dd4602900"))
1
  • Can you also share for string to address ?
    – Kin
    Apr 18, 2023 at 16:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.