The decentralized identity system built on Bitcoin.
Introduction
Profile Explorers
Viewing Profiles
Registering Users
Usernames
Profiles
Key-value Entries
OneName is a protocol for a decentralized identity system (DIS) with a user directory comprised of entries in a decentralized key-value store. OneName currently uses the Namecoin blockchain, but any decentralized key-value store may be used.
Users are added to the OneName directory via an entry into the key-value store, where the key is the username and the value is the profile data (in JSON format).
The OneName protocol provides formatting specifications for usernames and profiles and defines conventions for OneName profile crawlers/explorers (which read from the key-value store, digest profile data, and display profiles).
Nobody owns or controls OneName and users are in complete control of their data.
With Bitcoin, private keys provide us with complete control over our funds - nobody can move it without our permission. In the same way, OneName private keys provide us with complete control over our identities - no individual or entity can usurp our usernames or modify our public data or control the release of our private data without our permission.
OneName is open source, has a public design, and is for all to take part.
## Profile ExplorersOneName profile explorers are systems that read OneName user data from the key-values store and provide an interface for viewing profiles. This is similar to how Bitcoin has block explorers that read data from the blockchain and provide an interface for viewing transaction data. As with bitcoin block explorers, developers are free to crawl the key-value store and set up their own OneName profile explorers.
## Viewing ProfilesProfiles may be viewed on any OneName profile explorer.
onename.io comes with it's own default OneName explorer.
The URL pattern for viewing a profile on onename.io:
https://www.onename.io/<username>
The URL pattern for viewing a profile as raw JSON data on onename.io:
https://www.onename.io/<username>.json
To register a user on OneName:
- choose an available OneName username
- construct a valid JSON object that adheres to the OneName profile specifications
- register the username and profile as an entry in the key-value store
Usernames may be up to 60 characters long and contain lowercase letters, numbers, and underscores.
Note: usernames with ANY uppercase letters will be ignored by OneName crawlers, so make sure to only use lowercase letters when you register a name.
Regex: ^/[a-z0-9_]{1,60}$
Namecoin's key-value store has several namespaces. By convention, key entries that start with "d/" are interpreted as domain names. Likewise, those that start with "u/" are interpreted as OneName usernames.
When registering a username on Namecoin, prepend "u/" to the username and use that as your key in the key-value entry.
Regex: ^u/[a-z0-9_]{1,60}$
Example:
Username: someuser
Key: u/someuser
Full instructions for registering usernames on Namecoin can be found below.
## ProfilesUser profiles in OneName are collections of attributes that are expressed as JSON objects.
For profiles to be properly read by OneName crawlers and displayed on OneName profile explorers, their fields must adhere to the conventions outlined below.
Field Name | Description | Example(s) |
---|---|---|
name | The user's name, including his/her given name and family name. | { "formatted": "John Smith" } |
avatar | A url to an image that serves as the user's avatar. | { "url": "http://example.com/avatar.jpg"} |
cover | A url to an image that serves as the user's cover photo. | { "cover": "http://example.com/cover.jpg" } |
location | The user's current location. | { "formatted": "New York, NY" } |
website | The user's website or blog. | "http://example.com" |
bio | The user's biography/self-summary. | "Just a guy with his head in the cloud." |
bitcoin | The user's bitcoin address. | { "address": "1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T", "signature": "Gyk26Le4ER0...", "message": "This is a signed message." } |
pgp | The user's PGP key and fingerprint. | { "fingerprint": "D34987E8FAD4AE18C8680B4604DE396333BDC0E1", "url": "https://s3.amazonaws.com/97p/pubkey.txt" } |
The user's twitter account. | { "username": "someuser", "proof": "https://twitter.com/someuser/status/958360498327054801" } | |
github | The user's github account. | { "username": "someuser", "proof": "https://gist.github.com/someuser/e8dd382ccf7c19c2e041" } |
The user's facebook account. | { "username": "someuser", "proof": "https://www.facebook.com/someuser/posts/10152292145311923" } | |
The user's linkedin account. | { "url": "http://www.linkedin.com/in/someuser" } | |
bitmessage | The user's message account. | { "address": "BM-orkCbppXWSqPpAxnz6jnfTZ2djb5pJKDb" } |
[name of service or social network] | The user's account on a given service or social network. | { "username": "someuser" } |
v | The version number of the profile data format. | "0.2" |
{
"name": { "formatted": "John Smith" },
"avatar": { "url": "http://example.com/avatar.jpg" },
"cover": { "url": "http://example.com/cover.jpg" },
"location": { "formatted": "New York, NY" },
"website": "http://example.com",
"bio": "Just a guy with his head in the cloud.",
"github": { "username": "someuser" },
"facebook": { "username": "someuser" },
"twitter": { "username": "someuser" },
"linkedin": { "url": "http://www.linkedin.com/in/someuser" },
"bitcoin": { "address": "1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T" },
"bitmessage": { "address": "BM-orkCbppXWSqPpAxnz6jnfTZ2djb5pJKDb" },
"pgp": {
"fingerprint": "D34987E8FAD4AE18C8680B4604DE396333BDC0E1",
"url": "https://s3.amazonaws.com/97p/pubkey.txt"
},
"v": "0.2"
}
When providing proof of OneName ownership on social media profiles, include onename-username
in your verification posts. For example, if you're offering proof on Twitter and your OneName username is bob
, then include onename-bob
in your verification Twitter post. This makes it easy for crawlers to parse the post and automatically verify ownership.
To prove ownership of a website, you must upload a blank html file with the filename "onename-username.html" to the ROOT of your website. This is to prevent false ownership on websites that allow users to upload files to their servers.
It is important to note that any proof you provide must be publicly and perpetually available. If you ever delete a social media post or website html file that provides proof of your OneName ownership, that account will no longer be verified from that point forward.
- github
- bitmessage
- dribbble
- foursquare
- behance
- skype
- stackoverflow
- stackexchange
- googleplus
- flickr
You'll need either a desktop Namecoin client (Namecoin-Qt) or a UNIX Namecoin daemon. Instructions for building namecoind from source are here. Once you have a running version of either Namecoin-Qt or namecoind you will need to buy some namecoins (from exchanges like Kraken or BTC-e) and send them to yourself. Now you're ready to register new names:
- issue a "name new" with the key (the username with "u/" prepended)
- issue a "name first update" with the chunked profile
The "name new" operation is the first operation required to register a key-value pair on Namecoin (and by extension, a username/profile pair in accordance with the OneName protocol). This is the operation that communicates intent to register and use a given name. Without "name first update," however, the name registration is not complete.
Current cost: 0.01 NMC
After the "name new" operation is complete, the "name first update" operation completes the name registration.
Current cost: 0.00 NMC
Key-value entries in Namecoin are limited to a maximum of 519 bytes.
As a result, profiles exceeding 519 bytes must be split into several linked components in order to be embedded in the blockchain.
To chunk a JSON object, simply do the following:
- check if all the remaining data fits in one chunk
- if not, choose an unregistered Namecoin key (e.g. "i/username-1" - this will be the key of the "next" chunk) and create an empty JSON object (the current chunk), then add a pointer from this chunk to the next one (e.g. "next": "i/username-1")
- fill the JSON object with as many properties as possible
- go back to 1
Note: we recommend not using the "u/" namespace for linked chunks.
The sample profile above could be chunked as follows:
"u/username"
{
"next": "i/username-1"
"name": { "formatted": "John Smith" },
"location": { "formatted": "New York, NY" },
"website": "http://example.com",
"github": { "username": "someuser" },
"facebook": { "username": "someuser" },
"twitter": { "username": "someuser" },
"bitcoin": { "address": "1JwSSubhmg6iPtRjtyqhUYYH7bZg3Lfy1T" },
"bitmessage": { "address": "BM-orkCbppXWSqPpAxnz6jnfTZ2djb5pJKDb" },
"pgp": {
"fingerprint": "D34987E8FAD4AE18C8680B4604DE396333BDC0E1",
"url": "https://s3.amazonaws.com/97p/pubkey.txt"
},
"v": "0.2",
}
"i/username-1"
{
"avatar": { "url": "http://example.com/avatar.jpg" },
"cover": { "url": "http://example.com/cover.jpg" },
"bio": "Just a guy with his head in the cloud.",
"linkedin": { "url": "http://www.linkedin.com/in/someuser" }
}