A Brief History
Bitcoin was the first to introduce the concept of addresses as distinct from accounts. A wallet can have multiple accounts, and an account can have multiple addresses.
Although removed from v0.17.0 (Oct. 2018), the account
RPC can be found directly in older Bitcoin releases. This is why I always believe that in Satoshi’s vision, not only did accounts exist, but accounts and addresses were completely different concepts. In Bitcoin (and UTXO models), accounts only exist off-chain and can correspond to multiple addresses, while addresses correspond to scripts. Scripts are native to UTXO chains, addresses and accounts are derivatives.
Satoshi was clearly aware of the privacy threats posed by accounts, thus deliberately introduced the account/address separation, and implemented wallets to use new generated addresses by default for each payment. In Satoshi’s original design, unless specifically noted by the user, these new addresses all belong to the same default account (named “”).
Why was it later renamed to label? I believe it’s because Bitcoin’s design limitations made it impossible to construct complex applications, causing the account concept to become virtually useless, with little practical value. Moreover, it could be confused with accounts in systems like Ethereum. Therefore, it eventually degraded to just being a label.
Address and Account, Bitcoin and Ethereum
Bitcoin addresses encode UTXO unlock script (scriptPubkey). By decoding the unlock script from this address, you can find all UTXOs protected by this script on the Bitcoin chain and spend them (unlock with the private key signature corresponding to the pubkey). In the early days scriptPubkey has two major types:
- P2PKH - Pay to pubkey Hash, one pubkey corresponds to one address.
- P2SH - Pay to Script Hash, one unlock script corresponds to one address.
Therefore, in Bitcoin’s worldview, whether addresses or scripts, they correspond to methods of “unlocking”. In web2 terms, they represent “identity authentication” methods, not “identity”, because a single “identity” can have multiple authentication methods (e.g. passwords, passkeys, OTPs) and a single user can have many different addresses. User identities matches better with accounts or even higher-level concepts like DIDs and human-readable names.
However Bitcoin users got more used to addresses and almost forgot accounts. Then Ethereum rose, the default worldview of blockchain also changed. User habits shifted from being address-centric to account-centric. One important reason why Ethereum chose to build a world centered on accounts is certainly its ease of use and intuitiveness—accounts correspond to objects, objects directly send messages to each other, a pattern developers have long accepted. But the essence of this choice is privacy giving way to usability: users no longer default to using different addresses. Instead all user activities are usually associated to one single account, much to data analysts’ delight. Users gradually get used to the 1-1 mapping between account and address, multiple addresses equal “multiple accounts I have”. Nowadays users usually use rarely changing one or few accounts/addresses.
Many find changing addresses difficult to use, but schemes like HD wallets and stealth addresses offer strong counterexamples. HD wallets simplify Bitcoin address management, while stealth addresses allow payers to dynamically generate unlinkable payee addresses from a public address for enhanced privacy. I believe there’re other improvements waiting us to discover. Unfortunately, these innovations are overlooked in the “move fast and break privacy” era, where many mistakenly believe that “one account, one address” is the only user-friendly option. (HD wallets are widely used today but I think they’re greatly underused in account systems - no need for a lot of addresses, no need for ‘hierarchical’ the H.)
Can CKB Do Better?
As a challenger to Ethereum and a Satoshi follower hoping to push the industry back on track, CKB continues Bitcoin design, and always tries to advance it to a new level. Looking at the current situation:
- In Bitcoin one account can have unlimited addresses, but due to lack of applications, the account concept has nearly disappeared; privacy > utility
- In Ethereum one address maps to one account, a single account/address interacts with many apps as in Web2; utility > privacy
- In CKB one account can/should have unlimited addresses, but address/account are also used in a 1-to-1 mapped way (except in Neuron) for now, making them look like Ethereum account/address. CAN WE DO BETTER?
1-1 mapped account-address is easy and widely adopted, but it sacrifices privacy, hides UTXOs advantage, might amplify UTXOs disadvantages in scenarios like shared UTXOs’ race conditions. On the other hand building applications on “multiple addresses per account” is very challenging. What should be used to identify accounts here? How should apps interact with account and many changing addresses? What should be shown to user and what should not?
Even challenging I still believe we need to face the problem head-on, so we can get both ease-of-use and privacy, which sounds more like Web5 to me. The benefit of distinguishing between accounts and authentication is that it provides developers with a unified interface. Regardless of the authentication method, once verified, the application gets an “account ID” and only needs to interact with this “account”, without caring about how the user authenticated. Like in Ethereum, contracts see that a message comes from addr A know it’s account A’s operation, without caring how the account op was authenticated - addr A is the “account ID”. (Although Ethereum happens to have only one authentication method which is secp256k1 signing.)
We can introduce similar ‘account ID’ concept into CKB. .bit names is a possible solution, however it’s more of a human-readable naming service and .bit names are not free. The did:web5
scheme (a web5 experimental component, still in progress) is another possible fit. In did:web5
the identity/operation authentication is handled by methods in verificationMethod
/ rotationKey
, and authentication rules can be encoded in did:web5
cell’s type script. A web5 app or CKB on-chain script only needs to know the did:web5
id it’s interacting with, without caring about how the associated identity/operation is authenticated (could be secp256k1, joyID, quantum lock, bitcoin/doge address verification, etc.). By doing this authentication and account are decoupled.
On the other hand we can possibly combine did:web5
with stealth address to achieve greater privacy: a stealth address will be generated on each application interaction and only thedid:web5
owner knows all associated stealth addresses and activities. did:web5
can also be composed with registry-based naming services like .bit, to get human-readable alias for ease-of-use, by reusing alsoKnowAs
or a new field.
As an open, self-generating identity standard, it seems did:web5
can well play the missing ‘account’ role in the CKB/UTXO ecosystem, becoming the nexus between authentication, address, actions, human-readable names, and privacy. did:web5
may be initially designed as a web5 DID good for both on-chain and off-chain use cases, but it may also help turn the 1-1 mapped account-address tide, complete UTXO address-account design, and allows us to enjoy both UX ease and privacy.
Account ID | Authentication ID | |
---|---|---|
Bitcoin | label | address |
Ethereum | address | N/A |
CKB (now) | address | address |
CKB on Web5 | did:web5 | address |