How should centralized wallets handle user accounts? I tried to generalize this question from one I asked on the BitcoinJ development list.

I'm working on a project that requires a centralized wallet. From what I gather, these types of services generally rely upon simple balance checks to ensure that an individual user doesn't spend more than is in their wallet. That is, all users share a pool of keys, and the only thing tracking each user's balance is the service's database.

The Bitcoin daemon exposes functionality not in the GUI, namely that of accounts. An account is a string that groups keys. You can send from an account, and it will only gather coins owned by the keys in that account. This is beneficial, but is fairly limited. Using this however, you could have each account be a unique identifier for a user, and then that user "owns" the associated keys. One seeming drawback to this is that there is one centralized location to change ownership of an account.

I came up with a potentially better solution. Each account "owns" one or more public key hashes (the meat of a Bitcoin address). When creating a transaction, the service will transmit these hashes, letting the wallet know that when scanning unspent outputs, only use those with a public key hash owned by the user. In this way, without associating a user account with the private key itself, we are able to allow the user to have exclusive access to any number of keys.

Does this seem like a good solution to the problem? Is there something better that I'm missing?
In this way, without associating a user account with the private key itself, we are able to allow the user to have exclusive access to any number of keys. 


A very significant benefit that wallet services can offer is immediate and invisible transfer of coins between their accounts, by just updating their internal databases, without going through the block chain. This is how you can facilitate trades on MtGox for example, and it also provides increased anonymity, because you can now make transactions that are not visible on the block chain (and the transactions that are visible are withdrawal and deposits into the service as a whole, and those addresses are shared between many users, so also effectively anonymized). Obviously, this will not work unless the service can "redistribute" all the coins in all its addresses at will internally. (And obviously this also only works if every account holder trusts the wallet service to not take all the coins and make a run for it).


  Each account "owns" one or more public key hashes (the meat of a Bitcoin address). 


Actually, for making deposits, this is how it already works with wallet services. There is a (or many) receiving address (sometimes for one-time use, sometimes stable and fit for publication) that is associated with every account holder. You deposit to the account using that address. However, the private key remains with the wallet service, and can be used by it for all kinds of unrelated payments.