Sunday, 29 May 2011

Learning about Bitcoin or why I'll never use Bitcoin

Bitcoin is quite a promising e-currency. Created by some-guy-we-don't-really-know-or-a-double-agent-of-some-kind-who-is-probably-quite-Bitcoin-rich-now, it has some very useful properties:

  1. Creation of the money is an implicit and transparent agreement between users. That is, there is no centralized issuing authority and there is a finite quantity. Almost like gold.
  2. It is completely electronic and therefore very cheap to transfer. As a result, transaction fees are "low".
  3. Transactions are anonymized, yet completely public to avoid against double-spending.
  4. Some crypto stuff to make sure it is as secure as it can be today

The main desired outcome of a currency with these rules is autonomy of the currency from the somewhat arbitrary influence of centralized planners.

How you are supposed to use Bitcoin

So how do you use Bitcoin (BTC) as a consumer or vendor? Let us assume that you already have some BTC in your account.

  1. Visit place of business
  2. Locate item of interest which costs 0.02 BTC
  3. Go to cashier
  4. Pull out smart phone with your Bitcoin wallet or some kind of link to your Bitcoin wallet
  5. Use QR-code at register to find vendor's payment address. This address will likely be generated at the point of purchase
  6. Send Bitcoin to that address from your Bitcoin wallet
  7. The cashier and network verifies your payment (speed depends on transaction fee) and you go on your way

This is how it would work today if a business accepted BTC. I expect that if I am wrong and if Bitcoin does indeed take off, there will be clearing houses to speed up transactions like these. I think that these confirmations will necessarily be done outside the network but eventually, the network will also validate these which will be the final settlement step.

This exchange is appealing for various reasons. My favourite one is that the users of the system itself benefit by confirming transactions. That is, you can make Bitcoin just by verifying transactions.

Bitcoin Wallet

It is probably useful to discuss where Bitcoins are stored. This location, a file on your hard disk, is called a wallet. It consists of a set of private keys that correspond to each address generated as in the above scenario. This is your vault. If it is stolen in unencrypted form, your money is probably as as good as gone. But the coolest part is that if you have a backup and it was encrypted, you simply transfer the money to an account in a new wallet before the thieves are able to crack the encryption and almost by magic, your money is back again.

Anonymous vs Anonymized

Earlier, I said that transactions are anonymized. This is different from them being anonymous because an anonymizing technology does not imply anonymity. A transaction being anonymous means untraceable which is something that is quite easy to disprove in the BTC world.

Let's start at the beginning. How do you get BTC? There are a couple of ways. One way involves a lot of geekery and stuff that very few people have time for. This is called Bitcoin mining. For most people, just outright buying BTC like they buy USD is the most convenient. Currency is a proxy for labour so it is fine to buy BTC. As the market will continue to be volatile due to the simultaneous debasing of the USD, demand-side pressure as well as the continuous creation of BTC, I would spread out bigger purchases over a few months.

A convenient way to buy BTC is through an exchange. So let us walk through that process:
  1. Create an account with a BTC exchange. I used Bitcoin Market. This requires you to give them two things: an email address and a Bitcoin payment address. Notice how your email address is tied to your BTC address.
  2. Figure out the trade you want to make. I used BMBTC for PPUSD where BM = Bitcoin Market and PP = PayPal.
  3. Execute the trade by making a payment to some email address on PayPal.
When I executed this process, it took a total of 15 minutes for the trade to complete but it was a full hour before the money was in my actual wallet and verified by the network. You must note that this is the equivalent of someone on the other side of the world paying me $10 and someone delivering that $10 to me personally. Not to a bank account, not a promise for $10, but cold hard cash to me personally.

Notice that the process of conveniently buying BTC itself has multiple weak links:
  1. Your email address is tied to a Bitcoin address by Bitcoin Market
  2. Paypal knows who you are definitively through the use of your credit card
  3. Some random dude knows you bought some BTC
To avoid leaking too much information, you can create a new receiving address for every trade and update it on the Bitcoin Market. Note that Bitcoin Market has full trade information and PayPal has amount information. To reduce the risk there, you can use anonymizing email services or a special email just for Bitcoin purchases.

The main point is that once you use a credit card or a personal email address, your anonymity is compromised.

That's not such a big deal, to be honest. After all, you already trust a lot of people with your information online.

De-anonymizing the transactions

If the seller of the BTC was interested in which address bought the BTC through the exchange, s/he would just track the blocks for the specific amount.

When I purchased my BTC, I chose 2 BTC to see how difficult it would be to find in the block explorer. It was pretty easy! Why? Because I knew there would be three related transactions: one for 2, one for 1.99 and one for 0.01 (transaction fee by exchange.) The seller would know this as well.

So all I did was wait for a few blocks to come through the explorer and opened them all up in a browser tab and searched for 1.99. It took less than a minute.

So now, the seller of the BTC has tied my name (through Paypal) to an address.

You may be interested in the actual transaction as currently being confirmed by computers worldwide. Because of this decentralized confirmation, it is now impossible for the seller to re-sell the same BTC to someone else.

Using my Bitcoin or why I'll never use it

Can you figure out what I did with my BTC? Actually, you have all the information you need in this blog post. Once you figure it out, you'll understand why I'll never use it. The first person to add a comment with the right answer and their Bitcoin receiving address will get the remainder of my balance transferred to their Bitcoin address. It's not much, but I probably won't use it...

How to stay anonymous

There are ways to stay anonymous by obfuscating the block chain. However, this is not right. For a currency to be useful, its primitive form must be practically anonymous and not just anonymizing.

How I'd change Bitcoin

My main issues with Bitcoin:
  • Not anonymous: Identity "anchors" are very easy to establish by transacting with people as described above. This leads to a situation where an attacker can find out what you spend your BTC on for their own nefarious purposes.
  • The currency has no decay value. That is, it can be hoarded without consequence. I would like BTC to expire so that the currency can keep circulating. This maintains the value of the currency but prevents hoarding. The block chain has enough information to do this. Miners should be interested in this because it means they can continue to mine forever and keep a healthy Bitcoin economy.
I think the anonymity problem is the most hard to solve. I am only concerned with the ability to transfer coin between my own accounts easily without notifying anyone else. If some way could be devised to solve these problems, goodbye centralized currencies.


Tuesday, 26 April 2011

Deconstructing a dependency injection-driven application

I've been using my C++ dependency injection library for a project in the last year and it's gone pretty well. There are a lot of rough edges but I thought it could be interesting to the 3 of you still subscribed to this blog to de-construct the stock quote application.

About the application

The example itself is pretty straight forward. You have a choice of 3 stock quote providers: Yahoo!, static and phone. You choose one and ask for a stock quote. Magic happens and your stock quote arrives.

Example session (with some debug output)

Welcome to the DI Stock Quote App. Simplifying and complicating software development since 2010.
Which stock quote service would you like to use?
1: static
2: phone
3: yahoo
Enter your choice (1-3) and press enter: 3
You chose: yahoo
[DICPP]: No scope constructing: di::type_key<YahooStockQuoteService, void>
[DICPP]: Constructing: di::type_key<di::typed_provider<HttpDownloadService>, void>
[DICPP]: Completed constructing: di::type_key<di::typed_provider<HttpDownloadService>, void> with address: 0x100750
Stock symbol (type quit to quit): goog
[DICPP]: No scope constructing: di::type_key<HttpDownloadService, void>
[DICPP]: Constructing: di::type_key<boost::asio::io_service, void>
[DICPP]: Singleton: constructing: di::type_key<boost::asio::io_service, void>
[DICPP]: Completed constructing: di::type_key<boost::asio::io_service, void> with address: 0x1008a0
Current price for goog: 532.82
Stock symbol (type quit to quit): quit

See how the construction of the HTTP service is automatically delayed until actually needed. This is done through a concept called a "provider" which is basically an automatically generated factory.

About Dependency Injection

A really good introduction to the dependency injection technique as implemented by Guice can be found here. It's probably one of my favourite tech talks of all time.

Anyway, to refresh your memory, here are some of the main benefits of the technique used in Guice:

  • Object construction and lifecycle management is mostly handled for you.
  • Less boilerplate.
  • Makes code more testable.
  • Scopes (~object creation/lifecycle) can be customized by the user.

In short: a lot of the time, you no longer need to allocate objects or pass some object unused down multiple layers of functions or object constructors just to use them once way deep down in some code.

Magic!

I don't really recall how it is done in Guice but in the C++ library linked above, this magic is driven by a type registry which recursively registers constructor arguments as well as user customizations.

In extreme cases, you can initialize an entire application with a few lines of code:

  di::registry r;
r.add( r.type<MyApplication>() );
r.construct<shared_ptr<MyApplication>>()->execute();

This constructs the type registry which is a kind of factory. There is a mini-DSL for describing how you want the registry to handle the type. More on this later. In this case, we are asking the registry to "learn" about the MyApplication type as well as all objects that are required for constructing MyApplication.

"Pish-posh", you say. "MyApplication has a 0-arg constructor. I could do that in my sleep."

Would you be surprised if I said that the MyApplication type actually has 3 arguments?

Well, the above is almost what the StockQuote application looks like. Here is the main function for the stock quote example:

di::injector inj;
inj.install( StockQuoteAppModule() );
StockQuoteApp & app = inj.construct<StockQutoeApp&>(); // lifetime
app.execute();

And here is the constructor for the StockQuoteApp type:

DI_CONSTRUCTOR ( StockQuoteApp ,
( boost :: shared_ptr < UserInterface > ui ,
boost :: shared_ptr < StockQuoteServiceFactory > factory ));

When we ask the "injector" to construct the StockQuoteApp instance, it automatically creates the UserInterface as well as the StockQuoteServiceFactory instance.

The di::injector type is just a thin wrapper around the registry so you can treat it as such. The only thing it really provides is a little bit of syntax to allow you to create modules in a similar manner as Guice. The guts of StockQuoteAppModule accept a registry as a parameter and register the various types. You can see the mini-DSL referred to earlier:

void
StockQuoteAppModule::operator()( di::registry & r ) const
{
// In each module we define the module's root objects, in this case,
// StockQuoteApp as well as implementations/specializations of any
// abstract classes. For example, UserInterface is an ABC and we choose
// the console-based UI here.

r.add(
r.type<StockQuoteApp>()
.in_scope<di::scopes::singleton>() // The reason we can request a reference in the main function!
);

r.add(
r.type<UserInterface>()
.implementation<ConsoleInterface>()
.in_scope<di::scopes::singleton>()
);

r.add(
r.type<StockQuoteServiceFactory>()
.implementation<StaticStockQuoteServiceFactory>()
.in_scope<di::scopes::singleton>()
);

r.add(
r.type<HttpDownloadService>()
.implementation<AsioHttpDownloadService>()
);

r.add(
r.type<boost::asio::io_service>()
.in_scope<di::scopes::singleton>()
);
}

As you can see, the mini-DSL (ugly, ugly, ugly, details) describes a few things:

  • Default implementations for various interface classes. See UserInterface and ConsoleInterface, for example.
  • Life-cycle management. Singleton is mostly used here but you can also have HTTP-session scopes, thread-local scopes or no scopes (as in HttpDownloadService).

What this means is wherever a type T with a DI_CONSTRUCTOR macro is registered, the registry will use these rules described by the DSL to construct any arguments to T.

Providers
In this library, there is a concept of a type called a provider whose sole responsibility it is to construct objects (usually within the constraints of a scope). In the app session above, I pointed out how the HTTP download service is not instantiated until it is actually needed. This is done via a provider. You can see the YahooStockQuoteService has a constructor which accepts a provider and a function which makes use of it.

That should be enough information to peruse the example itself. Check the README as there are a couple of interesting exercises you can try.

By the way, this requires a Boost checkout with a built version of Boost Build. I apologize if you can't get it to build on checkout, but I haven't really focused on having other people use it!

Comments and thoughts welcome.


Tuesday, 29 March 2011

C++ has not jumped the shark

I love John's blog. If you are not subscribed, you should be subscribed. He is one of my favourite bloggers as I actually learn something when he posts.

Somehow, I managed to miss his post on C++ going about as far as it can go in its evolution. Fortunately, it showed up on YCombinator News a few days back so I got the chance to catch up.

From my reading, John is concerned about the following:

  • The language has stopped evolving because it is too long between revisions of the standard.
  • He doesn't need anything new therefore new features are not useful for him.
  • Something about concepts.

I don't intend on refuting or accepting those points as that's not what this is about. I just wanted to give a short summary. Also, I'm not really that interested in concepts but that is no reason to not include them. I'm sure I would also have said "TEMPLATES? WHY DO WE NEED THIS COMPLEXITY?!!!!"

The current C++ standard has been greatly influenced by the various Boost libraries. From lambda to thread, the influence of the Boost development experience is obvious, if not prevalent. Boost made it easy to decide what libraries to include. After all, we've had a few years of practical experience with them.

Reading the list of libraries in first-released order, there are a lot of libraries for various holes in the standard library. The Wikipedia article on the Boost libraries makes it much more clear as to where Boost development has been focused.

There is another trend: the number of libraries dealing with language issues has steadily decreased over time. Now, that is not to say that there will not be another set of C++0B libraries, there probably will. But I don't know if it will trigger the same kind of innovation.

So if that is all true, is C++ over?

In the last few years, there has been a gigantic evolution in C++-land: Clang. I have been fortunate enough to spend some quality time with Clang in the last little while and I have to say that I have enjoyed it a lot more than the last time I spent some time with another open-source C++ compiler.

With Clang, it is reasonably easy to add new features, even easier to add features that translate into combinations of existing features.

So while it was straightforward to add library changes to C++0B due to Boost, it was a lot harder to do the same for language syntax because there was no real experience with many of the proposed features.

Clang can enable, for the language, what Boost enabled for libraries.

However, I don't think Clang is really at the point from an organizational and technical perspective where it can enable and manage the kind of innovation that Boost was able to oversee.

That being said, I look forward to its role in the future of C++. I think it's a bright one*.

* Someone please make C++0B lambda polymorphic.