Skip to main content

A note to my former self: You're not supposed to take care of everything

In 2012-2013, I led the development of an open-source project called "Colored Coins", which defined a protocol for user-issued fungible tokens on the Bitcoin blockchain. In fact, this was the first protocol of its kind; before colored coins, the only fungible tokens on a blockchain were the native tokens (e.g., BTC on the Bitcoin blockchain).

How did I become the lead dev?

It was simple: I thought it was a cool project and relatively easy to implement.

In August 2012, I stumbled upon an article about colored coins while browsing a Bitcoin forum. At that point, it was merely a theoretical concept. Intrigued by the idea, I believed that it could be implemented in a few weeks and might be a nice addition to my CV. Back then, the world of "crypto" was less about money and more about exploring the possibilities of decentralized, peer-to-peer networks.

The project started with just a few people discussing it on a mailing list.

The first implementation

I created the first implementation in a week, modifying the official C++ Bitcoin node software (now known as Bitcoin Core). My proof-of-concept patch was only a few hundred lines of code.

Here's what it did, briefly: Bitcoin transactions form a directed acyclic graph, as transaction's inputs point to previous transactions' outputs. It is possible to associate a property (e.g. "color") with transactions outputs and trace this property through the graph in such a way that the amount of "colored" coins is conserved. My code associated "color" property with each unspent transaction output a Bitcoin node keeps track of, and made it possible to select only coins (unspent transaction outputs) of a particular color in node's wallet, thus making it possible to send coins of a particular color.

The colored coin mailing list was impressed with my prototype, even though I felt it had its shortcomings: color definition was hard-coded, and it was not possible to add more colors dynamically. Still, it could function as a Minimum Viable Product (MVP) even in this primitive form: if somebody wanted to wish to make e.g. "USD coin" on top of the existing Bitcoin network they could release their own version of Bitcoin Core wallet with support of their "color".

I also posted notes about my proof-of-concept on the Bitcoin forum. It generated a lot of curiosity and confusion. Questions about how someone could mint tokens like USD Coin or how tokens could be backed by real-world assets came up. I explained that a company could hold reserves in a particular asset and mint tokens on the blockchain to represent those reserves, similar to what Circle eventually did with USDC on the Ethereum blockchain.

People kept asking questions about possible legal implications, how colored coin software could validated asset definitions and so on. On some level I felt that this should be out of scope for the software I'm working on: it just enforces conservation rules for tokens. What these tokens really "mean" is out of scope. On the other hand, I felt that I need to give people examples. Otherwise they'd just ignore it, and I didn't want it to happen. And this made me feel that what I'm doing is not enough and I should try harder...

Next steps

Since no one else seemed interested in continuing the development of colored coins software, I decided to take it further. I envisioned a GUI wallet that made it easy to mint colored coins, import color definitions from others, and even facilitate a peer-to-peer exchange for trading coins.

Furthermore, thinking about how people might use this protocol, I got an idea to integrate p2p exchange with a payment protocol to address a potential problem of fragmentation. E.g. suppose a merchant accepts USDC but you firmly believe in holding gold and only have GOLD coins in your wallet. Software could handle the conversion automatically: if we can find someone willing to exchange GOLD to USDC, we can create a single atomic transaction doing both exchange and payment at the same time. 

I was not comfortable with making a wallet from scratch, so I decided to modify an existing wallet - Bitcoin Armory. It was written in a combination of C++ and Python and was particularly hacking-friendly, as the wallet scanned the entire blockchain at start (at that time it was 2 GB) - so I didn't even need to think how to store color information: it was computed anew each time.

Development of the colored coin version of Armory, which I called ArmoryX, took about 3 calendar months - mid-September 2012 to mid-January 2013. (Less than 20% of that time was actually spent on coding - I spent most time arguing with people on forums and mailing lists.)

I added ability to mint colored coins directly from GUI, load "color definitions" by name from a registry (a web server) and trade coins via p2prade protocol with UI which looks more-or-less like a regular "order book" exchange. (FWIW p2ptrade was not "p2p" as in a "p2p network" - it used a HTTP server for communication. Trades were done directly between people without intermediaries and were trustless. By the way, some parts of p2ptrade were implemented by now-famous Vitalik Buterin who was hired to help a little bit.)

So almost everything I wanted was in there, only payment protocol integration was left for the later times.

Burned out

This looks like a solid accomplishment to me now, but back in the day, I felt like shit.

Why? ArmoryX was not practically usable, and there was no easy way to fix it.

As it turned out, the underlying Bitcoin Armory suffered from random memory corruption issues due to a poor C++ <-> Python integration: Armory's author thought that memory handling is done automatically by the tool he used (e.g. Boost.Python), but it wasn't. Furthermore, Armory became increasingly unusable due to scan-entire-blockchain-at-start architecture as the Bitcoin blockchain grew.

Furthermore, I felt pressure from questions which people asked. Should we add PGP support to verify color definitions? Is issuance protocol solid enough? How do we take care of corner cases like overlapping colors? People also proposed alternatives like "Why don't you implement protocol differently?" and I felt pressure to respond. All this doubt about the protocol made me doubt myself...

As a result, I ended up feeling burned out. I didn't touch the project for several months after a demo release.

How other people do it

Interestingly, when Ethereum launched in 2015, it didn't have a wallet or user-issued token protocol in place. Instead, it evolved over time, embracing a "worse is better" approach. Many problems I felt I need to address are essentially still unsolved in Ethereum. For example, there's no established way of finding an issuer of a given token: it's not functionality offered by Ethereum wallets. Instead, there are web sites which might help people to investigate, but nothing is guaranteed.

This makes me wonder how I ended up setting a larger scope for myself than a well-funded project like Ethereum.

Reflections

If I could go back in time, would I change my approach? It's difficult to say for certain.

Ethereum had the advantage of significant momentum, allowing core developers to concentrate on the base node functionality and leave "usability" questions to a larger developer community within the ecosystem.

In contrast, the crypto community in 2012 was much smaller, and there was no "ecosystem" to which I could delegate tasks to. My work's primary purpose was educational, as I aimed to demonstrate the potential of user-defined tokens to others. As a result, it needed an appealing UI and built-in functionality.

To some extent, it succeeded. An article with a title "Colored coins paint sophisticated future for Bitcoin" was published in CoinDesk in June 2013, seemingly sparking broader interest in user-defined tokens. This likely contributed to the success of later token-focused projects like Mastercoin and Ethereum.

However, I believe I could have managed my mental well-being better by explicitly labeling my work as an educational prototype. There was always a nagging concern that people might take this prototype and use it in production, leaving me responsible for any bad decisions, bugs, and deficiencies.

But, ultimately, I didn't need to take care of everything. The lesson learned? Just create the prototype, mate, and stop worrying.

Comments

Popular posts from this blog

Lisp web tutorial?

"PHP vs. Lisp: Unfortunately, it's true..." article initiated quite active discussion on reddit , one fellow asking : Can someone post a tutorial for taking a clean install of Ubuntu (or windows or anything) to finish with serving a basic CRUD application using lisp? Maybe a TODO list with entires consisting of: incomplete/complete boolean, due date, subject, body? actually i had an impression that there are more than enough such tutorials, but as nobody replied i've tried finding one myself, starting with Hunchentoot tutorials. surprisingly, none of them covered a short path from clean OS install to working examples. neither i've found my ABCL-web  tutorial suitable for this, so i decided to try myself.  my idea was that Linux distros like Debian and Ubuntu contain a lot of Lisp packages, and it should be fairly easy to install them, as it automatically manages dependencies etc. i've decided to try Hunchentoot -- i'm not using it myself, but it's k

Lisp syntax is great!

lots of people complain about Lisp syntax -- they find it too weird and verbose, they call LISP "Lots of Irritating  Silly Parentheses"; and sometimes they even pop up with proposals to "fix Lisp" on comp.lang.lisp -- "Lisp is sort of cool, but this syntax... let me show you my great ideas." on the other hand, most lispers (and I among them) actually love s-expression syntax. who is right here? are syntax preferences a subjective thing, or one can decide which is better quite in an (more-or-less) objective way? or, perhaps, that's just a matter of taste and custom? i've got a good example today.. i'm using Parenscript -- cool Common Lisp library that automatically generates JavaScript from Lisp-like syntax -- and i've wrote a function that caches document.getElementById results (that makes sence for dumb browsers like IE):   (defun my-element-by-id (cache id) (return (or (slot-value cache id)     (setf (slot-value cache

out-of-memory: a sad case

the problem.. while Turing machine's tape is infinite, all real world programs are running within some resource constraints -- there is no such thing as infinite memory. for some programs that ain't a problem -- amount of memory needed by the algoritm can bee known beforehands, at programming time. but for most real world applications memory requirements are not known until run time, and sometimes it is very hard to predict how much does it need. obvious example is an application that allocates memory according to a user input -- for example, an image editor asks user for a dimension of an image he'd like to create. it needs to allocate an array in memory for the image (to have a fast access), so when dimensions exceed possible bounds, good-behaving application should notify user -- and user can either reduce image size or, perhaps, upgrade his machine, if he really wants to work with large images. while it is fairly easy to implement such functionality on a single-task O