A Year’s Experience with Ethereum

Since 2009, I’ve been captivated by the idea of the blockchain. Using cryptography as the backbone for structured storage was such a pure use of the field that I’ve researched in school and my free time for years that I couldn’t tear myself away from it. I’ve read through Bitcoin’s wiki about transactions, blocks, mining, reward schedules, keys, addresses, and so much more. It was my first dip into elliptic curve crypto as well. I always dreamed I’d create my own altcoin, one that wasn’t just a slightly modified fork like all the others. I still might, but until then I’ve been keeping busy.

Fast forward to a year ago, almost to the day. I was contracting, jumping from place to place in hopes of finding a company with fun technologies and a business plan I agreed with. Mostly I was pigeon holed into being a front end developer. A little Angular goes a long way. I told my recruiter that I’d love a contract that worked with Go if they had any. The language really appealed to me. Compiled to a native binary, concurrency primitives, and while it does enforce a lot of style decisions as requirements those decisions lined up with my preferences. So when my recruiter came to me with a contract working with Go and Ethereum for a startup I was ecstatic about the possibility.

Ethereum was new to me. I’d heard the name, I knew it’s coin was called Ether, and I had this vague understanding that you could write code and put it on the blockchain. Up until this point I was still focused on understanding all the intricacies of Bitcoin so I didn’t have room on my plate in my free time to figure out this new ecosystem. That quickly changed. I was dropped into the world of smart contracts, testrpc, truffle, solidity and no good documentation. It’s a fast moving market where github is multiple versions ahead of the documentation, where testrpc didn’t always fire solidity events when it should have, or where errors often have you diving into other people’s code because Google or StackExchange didn’t know what caused the problem. Every turn felt like I was being lied to. Documentation would say a function I needed existed but it wouldn’t build if I tried to call it. The solidity compiler would tell me it ran out of stack memory if there was a syntax error in the contract. There seemed to be a dozen ways to get “invalid instruction” errors when interacting with a contract. It was a nightmare. I definitely doubted the reliability of Ethereum as a whole. I struggled to make all this work for months until I fired up geth for the first time.

Go-ethereum, aka geth, is what makes Ethereum run. It’s how you setup a node, it acts as the keystore for your wallets, it can even be a CPU miner once the node is synchronized. If you download the Ethereum wallet or Mist you’ll find that they both start up and manage a background geth process. In fact, Ethereum wallet and Mist are lacking any original functionality, they’re simply interfaces as far as I can tell. Almost entirely written in Go (at least some of the crypto is cgo) geth is all that as well as a Go library of types, protocols, and endless utility functions. It’s solid, it’s reliable, albeit also mostly undocumented. The code is decently commented but big picture documentation ends at command line parameters and what’s available in the javascript console when you attach to a running geth instance. Web3, the javascript library for interfacing with geth, is pretty well documented and works most of the time but it’s slow and only interacts with JSON RPC. Single threaded NodeJS scripts didn’t let you behind the curtain enough to do things efficiently.

Geth opened doors to constructing raw transactions in some of the services. It is the only library I could find that was successful in reversing an elliptic curve signature back to it’s public key and therefore the address of the signer. It does RLP even though the wiki’s documentation gives you broken python for encoding and decoding (neither Python 2 nor 3 have a substr function, either way I didn’t want to rewrite RLP if I didn’t have to). I really don’t understand why geth isn’t pushed as the de facto way of interacting with the Ethereum network. I did run into some issues with abigen, geth’s tool for converting solidity contracts to Go code that can call into the contracts. It doesn’t like dynamic arrays of fixed sized arrays (i.e. [][2]int) but that can be worked around by modifying abigen’s output to both dimensions being dynamic arrays (i.e. [][]int).

In the last few months I’ve had to deepen my understanding as I work towards transactions being generated and signed on IoT devices. That means raw C implementations of keccak, private key management, gas estimation, and nonce management. Thankfully I have coworkers who are good with C because I know I’m no expert in it. I just need to coach them through the protocols and encodings to make it work. Ethereum for some strange reason decided to use keccak, the hash that won the NIST competition to become SHA-3. There was one change between the submission of keccak and it becoming SHA-3. Ethereum uses the pre-modification version but so many sites around the web use the names interchangeably making it hard to find a proper instance of the code. Gas estimation is usually done by passing your transaction on to geth and running it under a special circumstance. With IoT devices over a cellular connection that simply isn’t an option for every transaction. Instead, a contract written to remove variability streamlines gas estimation. Do it once and it (almost) never changes. There’s not a lot of conditionals in our use cases so it works.

Ethereum is constantly changing. Improving. Stabilizing. It still has a lot of progress to make. The parts that work, work great. It can be a long drawn out road to that point though. It either works or it doesn’t. Either hashes match or they don’t. You have no idea if you get close. I’ve had a hell of a time in my first year and I can’t wait to keep going.

Leave a Reply

Your email address will not be published. Required fields are marked *