Abstract

This defines convertion of address and transaction hash in Ethereum Classic network to readable strings, similar to how Urbit handles its ship names. As an example, EthMine’s coinbase address (0xdf7d7e053933b5cc24372f878c90e62dadad5d42) written in this scheme becomes ~hocwyt~misper~difmev~dabryd~livtep~dotpun~nibbex~nalbyn~pocmug~morden.

This ECIP only proposes an optional implementation for wallets and other dapp interface, and does not change anything in the underlying protocol, or in JSON RPC.

Motivation

Ethereum Classic’s address is 160-bit, and transaction hash is 256-bit. They’re currently only represented in a long hex string. This, when exchanged by users (for example, in situations where it needs to be transmitted by hand) can result in errors. This ECIP proposes a way to rewrite the 160-bit address or the 256-bit transaction hash in a human readable way similar to Urbit.

Specification

Group the bytearray of 160-bit addresses or 256-bit transaction hashes into pairs of two bytes. For each pair, use names at index of the first item of the pair, appended by endings at index of the second item of the pair. Each pair is also prefixed by ~. The list of names and endings can be found in the Python implementation in the appendix.

Generate shorter address

When an address starts with 2*x bytes of zero, they can be ignored and not included in the readable string generation. The last “prefix” can also be ignored if it is zero.

Hex Readability Fix

In addition, allow . to be put in a hex address string for every two bytes. For example, EthMine’s coinbase address (0xdf7d7e053933b5cc24372f878c90e62dadad5d42) becomes 0xdf7d.7e05.3933.b5cc.2437.2f87.8c90.e62d.adad.5d42. Dot is used because it is the same character used in Urbit and in IPv4 addresses.

Reference

Appendix: Reference Python Implementation

Below is a reference Python implementation for this ECIP.

names = "dozmarbinwansamlitsighidfidlissogdirwacsabwissibrigsoldopmodfoglidhopdardorlorhodfolrintogsilmirholpaslacrovlivdalsatlibtabhanticpidtorbolfosdotlosdilforpilramtirwintadbicdifrocwidbisdasmidloprilnardapmolsanlocnovsitnidtipsicropwitnatpanminritpodmottamtolsavposnapnopsomfinfonbanmorworsipronnorbotwicsocwatdolmagpicdavbidbaltimtasmalligsivtagpadsaldivdactansidfabtarmonranniswolmispallasdismaprabtobrollatlonnodnavfignomnibpagsopralbilhaddocridmocpacravripfaltodtiltinhapmicfanpattaclabmogsimsonpinlomrictapfirhasbosbatpochactidhavsaplindibhosdabbitbarracparloddosbortochilmactomdigfilfasmithobharmighinradmashalraglagfadtopmophabnilnosmilfopfamdatnoldinhatnacrisfotribhocnimlarfitwalrapsarnalmoslandondanladdovrivbacpollaptalpitnambonrostonfodponsovnocsorlavmatmipfip"
endings = "zodnecbudwessevpersutletfulpensytdurwepserwylsunrypsyxdyrnuphebpeglupdepdysputlughecryttyvsydnexlunmeplutseppesdelsulpedtemledtulmetwenbynhexfebpyldulhetmevruttylwydtepbesdexsefwycburderneppurrysrebdennutsubpetrulsynregtydsupsemwynrecmegnetsecmulnymtevwebsummutnyxrextebfushepbenmuswyxsymselrucdecwexsyrwetdylmynmesdetbetbeltuxtugmyrpelsyptermebsetdutdegtexsurfeltudnuxruxrenwytnubmedlytdusnebrumtynseglyxpunresredfunrevrefmectedrusbexlebduxrynnumpyxrygryxfeptyrtustyclegnemfermertenlusnussyltecmexpubrymtucfyllepdebbermughuttunbylsudpemdevlurdefbusbeprunmelpexdytbyttyplevmylwedducfurfexnulluclennerlexrupnedlecrydlydfenwelnydhusrelrudneshesfetdesretdunlernyrsebhulrylludremlysfynwerrycsugnysnyllyndyndemluxfedsedbecmunlyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes"

def split_len(seq, length):
    return [seq[i:i+length] for i in range(0, len(seq), length)]

prefix = split_len(names, 3)
suffix = split_len(endings, 3)

def hex_to_readable(data, skip):
    ret = ""
    for i in range(0, len(data) // 2):
        if skip and data[i*2] == 0 and data[i*2+1] == 0:
            continue
        if skip and i*2 == len(data) // 2 - 2 and data[i*2] == 0:
            continue
        ret += "~%s%s" % (prefix[data[i*2]], suffix[data[i*2+1]])
    if ret == "":
        ret += "~%s%s" % (prefix[0], suffix[0])
    return ret

def address_to_readable(address):
    return hex_to_readable(bytearray.fromhex(address), True)

def transaction_to_readable(transaction):
    return hex_to_readable(bytearray.fromhex(transaction), False)

print(address_to_readable("df7d7e053933b5cc24372f878c90e62dadad5d42"))