For fucking ever I've been trying to come up with a way to have old Discord style discriminated usernames that basically back DIDs (decentralized identifiers):

Display style: @username goes here#123456

URI style: did:whatever:username%20goes%20here:123456

  • Discriminator is 4-6 digits [length distinct; so 0000 and 000000 are not the same], always randomly assigned

  • Chosen usernames would have a few limits on them but it should be somewhere between old Discord usernames and most modern usernames, i.e. special characters are allowed, just not hash, at, colon, slash, zero-width, and maybe emoji

    • Uppercase letters would be lowercased for ease of comparison, except for in display of already-known users (in which case, the casing used in the DID document is what should be displayed).

    • I might enforce that the leading character is always ASCII/Latin alphanumeric, and I might enforce minimum length limits, but hey maybe I don't and I let people take a as a username if they're quick to it (but the leading character will probably be very heavily restricted for easy typing).

Anyway, I just learned someone's done something similar, a non-cryptocurrency blockchain-based DNS alternative called Alfis. From a bit of an outsider's perspective, theoretically, I could fork it and make a completely new chain for it with a new data model and everything, basically with these changes:

The username would not be tied to a TLD, and it would be largely reusable (as long as the discriminator is free for the taking).

Instead of storing DNS records or any arbitrary information, the associated data would consist of a length-limited URI, recommended to be over HTTPS or IPNS or point to a different DID (i.e. PLC) to reference. That's it. Nothing else. The only other thing you can do is update it, and it can be updated to an empty string to give up the username.

Updating a username to point to a new DID document can be done by signing the change with the Ed25519 key published with the mint block that claims the username.

There'll be a "renewal" system as well that requires popular usernames (i.e. many discriminators taken) to be renewed monthly to remain valid, and less popular usernames yearly. Renewal restarts the timer, and that's it. The timer might even be shorter the next time you renew it, so you want to renew it as late as possible but not too late, generally. If it's not renewed, it remains valid until 1 year after expiry or until someone takes it (which could be you). Generally, applications should warn about expired usernames anywhere they might still show up.

Normal DID verification would also be a thing here, applied on the client-side upon lookup of the DID document: the same key published with the block to allow it to update also has to be mentioned as a verification method, and the DID looked up must be in either the ID or alsoKnownAs field (preferably the ID field; if it's in alsoKnownAs, the main DID should be used instead if possible).

I'd like to have validation enforce renewal/expiration, but generally it's going to be up to whatever client-side implementor to make sure it gets the right name.

I think I'd also make the proof-of-work very very difficult and require a unique update-key for every username claimed -- even if one you previously used expired.

All-zeroes discriminators are reserved for consuming applications to use however they please. This could be a compatibility layer or represent local-only accounts or an app-sent notification profile or whatever you want. This constitutes three distinct discriminators which never resolve over the network: 0000, 00000, and 000000.

I'd also like to have a system for sub-usernames, mostly for use with bots and plural alters. Those would be entirely off-chain, so the main DID document would have to specify somehow where to find sub-usernames. I'm not sure what that would look like yet, but I think it would probably be a Service that is then called with the sub-part.

Display style: @username goes here/subusername#123456 ???

URI style: did:whatever:username%20goes%20here:123456:subusername

I'm thinking about enhancing privacy by hiding the username (hash?) and using the username (not hash?) as a symmetric encryption key for the included URI somehow. Hiding the username would still let verifiers find collisions, but then the username itself can't be validated at verification. I think it's probably enough to have minting and consuming nodes validate it when they receive it from a user.

I don't know what Alfis does or doesn't do here, but I don't want to have every node store the entire database. But I do want it to be replicated pretty well, so maybe synchronizing only the chunks that are needed/requested and maybe some others?