Decentralized Protocol Monetization and Forks

The idea of releasing a new currency as a mechanism for funding protocol development is perhaps one of the most interesting economic innovations to come out of the cryptocurrency space. In the past twenty years, we have seen a growing centralization in the protocols that underlie the internet, with the rise of proprietary chat systems and social networks like Facebook, and a large part of the reason for this trend has been the need for monetization; if Facebook was cryptographically secure and decentralized, the developers would have no way to make money by data mining their users’ activities and taking a 30% cut of their internal currency, and so decentralized alternatives to Facebook have largely fizzled due to lack of institutional support and funding. With decentralized protocols, however, we have discovered a new mechanism for monetizing them: create internal assets, and sell them to pay for the development of the protocol.

In general, so far we know of two classes of “internal assets” that can be sold in this way; first, there is the idea of creating an internal token system, a crypto-fuel with a floating price that has some value in the network, and second, one can introduce name registrations; for example, a decentralized Twitter might fund itself by building in its own decentralized username registration mechanism similar to Namecoin and selling off the 1-4 letter names. This new monetization model is powerful, and in the first of the two above-described implementations already has a number of proven successes, but it is also incredibly non-intrusive – it requires no licensing schemes, proprietary software, crippleware or privacy infringement, and in fact no one actually has to explicitly “pay” for anything at all (if you buy tokens you are just swapping into a different asset, which may well even go up in value relative to other assets). However, in this model there is one concern that many people have raised, and that is the question of forks. In short, if one releases a new decentralized protocol that is based on a token system, why won’t someone else release a fork with either their own token system, or a token system that is somehow tied to an asset with an existing userbase, and if one releases a decentralized Twitter with a built-in name registration system why won’t someone release a fork that points to their own name registration system, or even the original Namecoin?

In traditional business, there are two solutions to the problem. One is to give up the idea of making everything open-source, and keep at least the latest version of the client proprietary. The other is to release the protocol for free, and then sell services. Of course, both approaches have their own very well-understood flaws. In the context of a decentralized blockchain application, most of the benefits of decentralization are lost when the code becomes proprietary – with a proprietary mining algorithm, for example, there is no way to prove that it does not have a backdoor for its developers, and is therefore equivalent to the developers simply running a centralized server and asking the community to trust them. The second approach, selling services, is also flawed; first, the revenue is in most cases vastly insufficient, and second, it incentivizes the organization to produce only a minimal decentralized protocol in order to then sell centralized services on top, rather than building up an entire decentralized ecosystem.

Many decentralized projects are pursuing neither of these strategies; for example, Ethereum itself is 100% open source, and have been since even before the day that it publicly launched. Many protocol organizations, including our own, are interested in transforming themselves into “decentralized autonomous organizations”, which necessarily implies a very high degree of transparency. Given this, what is a decentralized protocol’s “moat” against forks? What stops another group from taking all of our code and research ready-made and creating their own version of the blockchain, perhaps with one or two superior features (or simply having a large endowment and dumping it all into superior marketing), and taking us over? The question is a difficult one, but it has a number of interesting answers, both in terms of Ethereum specifically and decentralized protocols as a whole.

On Flimsy Moats and Dictators

In order to answer the question, it is important to first understand that, in the space of tech companies and especially social networking startups, a large number of them are literally backed by almost nothing but social consensus. Theoretically, it is entirely possible for all of the employees at Snapchat, Tinder, Twitter or any other such startup to all suddenly agree to quit and start their own business, completely rebuild all of the software from scratch within months, and then immediately proceed to build a superior product. The only reason why such companies have any valuation at all is a set of two coordination problems: the problem of getting all employees to quit at the same time, and the problem of getting all of the customers to simultaneously move over onto the new network. In the context of a service like Dropbox, the latter issue does not exist; because Dropbox is just as useful to each individual if one other person is using it or a million, there is no reason why people can’t move over a few at a time. In the context of a social network, which is useless unless everyone else is already on it, the problem is fundamental.

In the abstract, this may seem like a flimsy justification for why tech companies are valuable; when thinking about something that represents billions of dollars of value, one naturally expects that value to be backed up by something tangible like physical resources or government force, not just some ethereal instantiation of the fact that it’s hard for large groups of people to suddenly move from one social configuration to another. In reality, however, even physical resources and government force are backed by nothing but a social coordination problem – if 70% of the victims of a dictatorship were to simultaneously rise up against their dictator, the government would get toppled pretty quickly, and yet most dictators even running rather brutally oppressive regimes are quite comfortable sitting in their lofty thrones knowing that such a thing will almost certainly not happen.

Given this background in theory, what exactly are the social coordination problems backing up a decentralized blockchain? What exactly is the “moat” that is backing up the value of the “official” Ethereum blockchain or Mastercoin state transition system, and ether as a mechanism of storing value and paying for transaction fees, as opposed to alternate clones like “aethereum“? Specifically, what are the necessary factors that make the original version of a given decentralized protocol superior, when all of its underlying features can easily be cloned, and even improved upon as soon as a group discovers even one flaw in the original (in the case of Bitcoin, for example, one can trivially improve the Bitcoin protocol by removing the requirement for multisig spending transactions to have an extraneous zero in the spending script code, an anti-feature which was introduced accidentally)? As it turns out, there is quite a lot.

Teams

First of all, every project has a core development team. In fact, this aspect is actually stronger in the case of a decentralized token system than a traditional tech company. While in a traditional tech company, there might be only a very small number of people with shares in the company and who are thus incentivized to stick with it and see it succeed, in the case of a decentralized token system there are dozens or even hundreds of people holding tokens associated with the project; in fact, many people actually choose to be paid predominantly in tokens. In the case of Ethereum, for example, the size of the list of people who will be receiving ether as compensation for work done currently stands at sixty-eight, and will increase even further as time goes on. And all of these tokens are, of course, untradeable until the protocol actually launches, so all of the token holders are strongly incentivized to do their best to ensure that the system does as well as possible. Thus, the team, the set of people who know the most about how the protocol works from the experience of having actually developed it, is a decentralized project’s core asset that competitive spinoffs cannot so easily “fork” and replicate, and it is the team that will be responsible for much of the rest of the project’s “moat”.

Network Effects of Exposure

The simplest reason why people will use the original blockchain and not a fork is simple: it’s the default. People hear about Bitcoin first, so they go to bitcoin.org and download the Bitcoin client, and use Bitcoin to buy and sell goods and services, not Bitcoin Scrypt. For the same reason, people use the official version of most open-source projects and not any of the thousands of forks, buy music, books and movies instead of trying to download them via torrents, and use popular Bitcoin wallets instead of less popular ones. Any fork of a given protocol necessarily comes after the original, and is therefore much less likely to gain media attention.

Moral Pressure

Another important reason why the original version of a protocol is more likely to gain media attention than a fork is plain old public morality: people believe that the developers of a project deserve to get compensated, and so a fork which is developed with the primary purpose of depriving the developers of compensation is likely to be viewed negatively, or at least less favorably, by many people. This moral effect can be a very powerful one, and contributes heavily to the original protocol’s greater exposure; the best empirical evidence for this is likely the success of services like Netflix over filesharing-based alternatives.

At the same time, however, if the original developers of a protocol start taking development in an undesirable direction (eg. introducing backdoors, introducing excessively intrusive monetization vehicles, or even just being too plain slow), then the moral effect can rapidly turn on its head and even support the first credible effort to try to wrest away a project from its creators; following the prior example, the pertinent example here is the media success of the Pirate Bay and Popcorn Time. Thus, moral pressure can work both for and against a decentralized protocol, and it is the protocol developers’ responsibility to ensure that the community opinion of their project remains positive, and serves as an important check-and-balance to make sure that the core team behind a project continues to move the project forward at a solid pace and in an agreeable direction.

Network Effects of Currency Unit Liquidity

One argument that is often raised against forks of Bitcoin is the idea of liquidity, or specifically market depth: smaller currencies are inherently weaker than larger currencies because there are fewer people buying and selling them, and so you will move the price much more if you try to sell a large amount. However, this argument is only important up to a certain point; once a currency reaches a sufficient size, it has enough market depth to cover all ordinary usage, and so additional depth provides little value. Hence, this network effect provides a moderately strong edge against forks with a new token system, which will have very low market depth to start off, although at the cost of a slight disadvantage against forks that tie in existing large currencies via two-way-pegging mechanisms.

Ecosystemic Network Effects

An important feature of decentralized protocols, and social protocols in general, is that they also build ecosystems. On a social network, for example, there is a one-dimensional network effect: a social network is more useful if more people use it. With a currency, that effect becomes two-dimensional: a currency attracts more users if there are more merchants, and more merchants if there are more users. Once development effort, security and liquidity come into play, this increases to three to six dimensions. All of these interdependencies make it hard for a new version of a social network to bore its way into mainstream acceptance, as initially it starts off with nothing.

In the case of Ethereum, the tightly integrated nature of the currency system actually makes the network effect in some respects highly multi-dimensional. The relevant property of the Ethereum architecture is the first-class-citizen property of contracts: contracts can interact with, send and receive messages from and hold accounts with other contracts much like external accounts can. This allows you to cleverly pull together long chains of contracts and applications, using contracts of different types at each step of the interaction process. For example, I might hold some shares of a decentralized autonomous organization (contract A), where the shares are held on a decentralized market (contract B) in a multisignature account (contract C) for added security. The co-signer of said multisig account is paranoid about quantum computing, so he uses custom cryptography (contract D) based on verifying Lamport signatures for authentication. The organization would then store some of its funds in a USD-pegged asset using a financial derivatives market (contract F) using a combination of centralized and decentralized data feeds (contracts G, H, I), and internally uses a name registration system (contract J) to store all of the functions that it calls. A single transaction may end up calling all of these contracts multiple times.

Liquid markets for on-blockchain assets, liquid markets for message publication, and a robust ecosystem of DAOs, decentralized exchanges, financial markets and data feeds all support each other and make the Ethereum blockchain stronger. The Ethereum blockchain is not just a blockchain; it’s really one large decentralized computer where all of the components are tightly linked together, and each component provides additional tools for other components to play with.

Bugs and Attacks

This is a small point, but an important one. There is always a risk that either the protocol or the client implementation will be flawed in some way. As hard as the Bitcoin developers have tried, the bitcoind source code has had problems crop up over the years, and twice in Bitcoin’s history (specifically, the integer overflow exploit in 2010 and the fork in 2013) such problems have even led to a consensus failure that required manual resolution. In theory, developers of every protocol try as hard as they can to ensure that bugs never happen in the first place. In practice, of course, there is always a chance that something will slip by, the price will start crashing ten or twenty percent within an hour, and it will be up to the developers, the miners and the large businesses to quickly push out and coordinate a fix. Sometimes, such errors may not even be the protocol’s fault; a massive megacorporate or government-sponsored 51% attack or a globally coordinated distributed denial of service on the entire network are also possibilities, and might need special measures to be dealt with. Thus, as decentralized as peer to peer protocols aspire to be, ultimately they do benefit considerably from some degree of institutional support in times of crisis – support that the original developers who understand the protocol and software best are the best-equipped to provide.

Protocol upgrades

Ethereum 1.0 is far from perfect, and between our discussions on the development roadmap and the Hard Problems of Cryptocurrency we have been very open about admitting this. There are plenty of ways that blockchain technology could be improved, ranging from research on price-stabilized currencies to better fee structures, alternative consensus models and, as a holy grail, multi-blockchain architectures or SCIP. However, the intricacies of actually coming up with the math and then implementing these mechanisms, are in many cases even figuring out whether or not they are even possible, are sufficiently complex that we have decided there is a large list of features we are simply not going to do for Ethereum 1.0. To that end, we have established the long-term roadmap that we will release Ethereum 1.0 in Q4 2014 at the latest, and at the same time we have already started to set up efforts to research the kinds of improvements that we can theoretically add, specifically in terms of scalability, with a plan to crystallize them into Ethereum 2.0 at some point around 2016. Ethereum 2.0 will use “ether 2.0” as its currency, where the main initial mechanism for obtaining a unit of ether 2.0 is simply to provably destroy a unit of ether 1.0.

Thus, the currency inside of a protocol is backed not just by the utility and network effects of the current implementation of that protocol, but also the promise of better future versions of the protocol to come. Of course, cryptocurrency protocols are hard to change, and in practice Bitcoin has proven very difficult to change in the short term, but more large-scale re-architectures are actually somewhat easier to implement than small changes when one looks at the ratio of effort to effect. We have already seen the Master Protocol make several upgrades, and we will likely see Ethereum 2.0, 3.0 and perhaps even further over the next few years and decades.

What’s the Point?

Finally, the most important argument of all is, what’s the point of a fork? In the case of Bitcoin, there are many reasons to fork the code – you might want to add support for more transaction types, change the currency supply, replace the currency with a centralized alternative backed by the US dollar, or change the type of cryptography used. If a protocol is correctly generalized, however, there simply is no way to improve that can’t be replicated inside the protocol itself. For example, if you are using Ripple then you can use Ripple equally easily to store XRP, cryptocurrencies, fiat currencies, local community currencies or Little Bobby’s Magic Token Points. Hence, concerns about optimal monetary policy, politicization or depoliticization of money or many of the other debates surrounding Bitcoin have no bearing on the success of the Ripple protocol itself. In the case of Ethereum, the protocol has a generic programming language, making the system even more malleable: if someone comes up with a blockchain-based system that is better than Ethereum in some fashion (with the exception of secure near-instant block times), then someone else can fork it right back inside of Ethereum itself by simply implementing it as a contract. This fork would immediately benefit from Ethereum’s ecosystemic network effects, allowing users to benefit from both the superior feature and the ability to interface seamlessly and directly with an existing ecosystem of liquid markets, data feeds and DAOs. Using this power of the contract mechanism, Ethereum will be able to contain side-chains of Bitcoin, Litecoin and Dogecoin (yes, even Scrypt-based coins can be turned into side-chains via computational stacktraces and an economically incentivized challenge-response protocol), name registrations, post-quantum cryptography and an unlimited number of other features.

Thus, on the whole decentralized protocols lie in an interesting place in the modern economy. On the one hand, much like Bitcoin itself, they are in a very clear way “backed by nothing”. On the other hand, they actually have quite a powerful backing underneath, and one that is difficult to unseat; in practice, we have seen very few examples of any open source software fork unseating the original, both in the cryptocurrency space and outside of it. Nothing has unseated Bitcoin, nothing has unseated Litecoin and nothing has unseated Dogecoin. The only forks that do gain serious community acceptance are the ones that add a large body of new features, and these forks always succeed in carving out a niche of their own. Fortunately, we still have many decades to go in seeing exactly how the decentralized protocol ecosystem is going to play out.

The Issuance Model in Ethereum

Ether (ETH), the cryptofuel that powers distributed applications on the Ethereum platform, will be issued at a constant annual linear rate via the block mining process. This rate is 0.3 times the total amount of ETH that will be purchased in the pre-sale.

While the best metaphor for ETH is “fuel for running the contract processing engine,” for the purposes of this post, we will treat ETH purely as a currency.

There are two common definitions of “inflation.”  The first relates to prices and the second relates to the total amount of money in a system – the monetary base or supply.  Similarly for the term “deflation.”  In this post we will distinguish between “price inflation,” the rise in the general price level of goods and services in an economy, and “monetary inflation,” the growth in the supply of money in an economy due to some sort of issuance mechanism.  Often, but not always, monetary inflation is a cause of price inflation.

Though the issuance of ETH is in a fixed amount each year, the rate of growth of the monetary base (monetary inflation) is not constant.  This monetary inflation rate decreases every year making ETH a disinflationary currency (in terms of monetary base).  Disinflation is a special case of inflation in which the amount of inflation shrinks over time.

It is expected that the amount of ETH that will be lost each year caused by transmissions to addresses which are no longer accessible is estimated to be on the order of 1% of the monetary base. ETH may be lost due to loss of private keys, death of owner without transmission of private keys, or purposeful destruction by sending to an address that never had an associated private key generated.

If we assume that Ethereum sells 40,000 BTC worth of ETH in the pre-sale, and if we assume that the average price is 1500 ETH/ BTC, 60,000,000 ETH will be created in the genesis block and assigned to purchasers. Every year, in perpetuity, 18,000,000 ETH will be issued though the mining process.  Taking into account both creation of new ETH and loss of existing ETH, in the first year, this represents a monetary inflation rate of 22.4%.  In the second year the rate drops to 18.1%.  By the tenth year, the rate is 7.0%.  In year 38, it hits 1.9%. And in the 64th year, the level of 1.0% is reached.

Image

Figure 1.  Amount of ETH in existence (dark green curve) on the left axis.  Monetary base inflation rate (light green curve) on the right axis.  Years on the horizontal axis.  (Adapted from Arun Mittal with thanks.)

 

By approximately the year 2140, the issuance of BTC ceases and since some BTC will likely be lost each year, the monetary base of Bitcoin is expected to start shrinking at that point.

At approximately the same time, the expected rate of annual loss and destruction of ETH will balance the rate of issuance.  Under this dynamic, a quasi-steady state is reached and the amount of extant ETH no longer grows. If the demand for ETH is still growing at that point due to an expanding economy, prices will be in a deflationary regime.  This is not an existential problem for the system since ETH is theoretically infinitely divisible. As long as the rate of price deflation is not too rapid, pricing mechanisms will adjust and the system will operate smoothly.  The traditional main objection to deflationary economies, wage stickiness, is likely not to be an issue since all payments systems will be fluid.  Another frequent objection, borrowers forced to repay loans with a currency that grows in purchasing power over time, will also not be a problem if this regime is persistent, since terms of lending will be defined to account for this.

Note that while the monetary inflation remains greater than zero for many years, price levels (tracked as price inflation and deflation) are dependent on supply and demand, so are related to, but not totally controlled by the rate of issuance (supply).  Over time it is anticipated that growth of the Ethereum economy will significantly outpace growth of the supply of ETH, which could lead to an increase in the value of ETH with respect to legacy currencies and BTC.

One of Bitcoin’s great value propositions was the algorithmically fixed total issuance of the currency which mandated that only 21,000,000 BTC will ever be created.  In a time of profligate legacy currency printing in an exponentially doomed attempt to patch over the fact that there is too much debt in the global economic system (with more debt), the prospect of a universally accepted cryptocurrency that can serve eventually as a relatively stable store of value is attractive.  Ethereum recognizes this and seeks to emulate this core value proposition.

Ethereum also recognizes that a system intended to serve as a distributed, consensus-based application platform for global economic and social systems, must strongly emphasize inclusiveness. One of the many ways we intend to foster inclusiveness is by maintaining an issuance system which possesses some churn.  New participants in the system will be able to purchase new ETH or mine for new ETH whether they are living in the year 2015 or 2115. We believe we have a achieved a good balance between the two goals of fostering inclusiveness and maintaining a stable store of value. And the constant issuance, especially in the early years, will likely make using ETH to build businesses in the Ethereum economy more lucrative than hoarding speculatively.

 

Pyethereum and Serpent Programming Guide

The content of this tutorial is intended to apply to PoC5. Most of the instructions given below will not work in the older PoC4 implementations of AlethZero (C++) and Ethereal (Go)

Over the last few weeks, we have made a large number of changes to the Ethereum protocol. POC4, introducing a large body of changes made by Gavin Wood and myself, was announced as an informal description two weeks ago, and has been formally specified in Gavin Wood’s “yellow paper” at http://gavwood.com/Paper.pdf. The protocol spec did change substantially, but at the same time things are solidifying; we know why we want transactions to pay fees instead of contracts, so that’s not likely to change, we know that code and data will be separate, and the byte-based code and memory and 32-byte-block-based stack and storage are unlikely to change, and we know that the workings of the EVM in general will be similar to what they are now instead of some kind of elaborate Merkle-code-tree construction. POC4 has given myself what I wanted out of Ethereum Script 2, Gavin a much more optimization-friendly VM architecture, and users a shiny new currency. Meanwhile, Chen Houwu, Heiko Kees and Konrad Feldmeier have taken the lead as our main Python developers, and the networking side of the pyethereum client is getting to the point where it is getting ready to talk to Go and C++. At the same time, aside from all of the managerial tasks that are part and parcel of having a key role in a large project, I have taken it upon myself to bring up to speed the pyethereum VM implementation and the compiler for the HLL programming language.

The purpose of this post will be to provide an in-depth technical tutorial into the workings of pyethereum and Serpent, and show you how you can start writing the tools to build your own contracts and applications. The Bitcoin Expo hackathon is happening today and tomorrow, so feel free to make an Ethereum contract your project if you are among those attending.

First of all, importantly, HLL is no longer called HLL; the language is now called Serpent. Why? Because it’s basically Python.

With recent upgrades to the compiler, Serpent is now a highly feature-filled programming language, with powerful features including:

  • Arrays (eg. x[0] = 123)
  • Array literals (eg. x = [ 34, 56, 78 ])
  • Nested arrays (eg. z = [ 34, [ 5, 6 ], y ])
  • Hex support (eg. receiving_address = 0xb156066c2978d7b9188f2467b815d4c62ae32fe2)
  • String support (eg. x = "cow")
  • Inline message calling (eg. usdprice = eth * msg(ethcontract,0,tx.gas-100,[500],1))
  • Out of line message calling (eg. msg(multifeedcontract,0,tx.gas-100,inparray,5,outarray,5))
  • Simple value sending operation (eg. send(receiver, value, tx.gas-100))
  • Returning values (eg. return(45) and return([10,20,30,40],4))
  • Treating message data and storage as arrays (eg. contract.storage[1000] = msg.data[0])
  • Byte arrays (eg. x = bytes(100), setch(x,45,"c")), y = getch(x,45)

The intent of the Serpent language is to make programming smart contracts and decetralized applications in Ethereum as easy as programming boring command line apps is in Python. The language is designed to be maximally clean and maximally simple, combining the benefits of a compiled language with an easy-to-use coding experience. Just the logic, and nothing but the logic. Unfortunately, floating point numbers are missing, as are higher-order constructs like list comprehensions and closures, but aside from that Serpent has basically everything that you need.

Getting Started

So how do you code in Serpent? The first step is to set up the development and execution environment. To do this, first download two libraries: pyethereum and serpent. The simplest way to download is to either download the zip files from Github and unpack them, or run git clone http://github.com/ethereum/pyethereum and git clone http://github.com/ethereum/serpent. Then, enter the pyethereum directory, and run sudo python setup.py install to install pyethereum to your system, and do the same with serpent.

Now that the software is downloaded, let’s get right to it. To start off, try this:

> serpent compile_to_assembly 'x = 5'
["$begincode_0.endcode_0", "DUP", "MSIZE", "SWAP", "MSIZE", "$begincode_0", "CALLDATACOPY", "RETURN", "~begincode_0", "#CODE_BEGIN", 5, 0, "MSTORE", "#CODE_END", "~endcode_0"]

The compile_to_assembly instruction compiles the code down into an intermediate human-readable “assembly language” format rather than plain old bytecode. Using plain old serpent compile would give you the much more incomprehensible but compact 6005515b525b600a37f26005600054. In this case, the “core” of the code is [5, 0, "MSTORE"], putting the value 5 into memory slot 0, and the rest of the code basically says to return a contract containing that code. Another command that you may find useful is serpent get_vars; this will give you a list of all the variables together with their associated memory indices. In this case, you get {'x': 0}, meaning that the compiler is choosing to use the memory index 0 to store the variable x. The last interesting command is parse to convert Serpent into an intermediate high-level parse tree. Now, since Serpent is a programming language, we want to run programs, and so ideally we would like to actually create contracts and run them as quickly as possible. Let’s try that. First, open a file, call it “namecoin.se“, and put the following code into it:

if !contract.storage[msg.data[0]]:
    contract.storage[msg.data[0]] = msg.data[1]
    return(1)
else:
    return(0)

This is the two-line Namecoin example that we love so much, but embellished with return values to make it easier to work with for this tutorial. Typing serpent compile namecoin.se should give:

6025515b525b600a37f260003556601b596020356000355760015b525b54602052f260255860005b525b54602052f2

Now, let’s see if we can actually get the code running. To do that, the first step is actually to create for ourselves an account. The process here is almost exactly the same as in my Python Bitcoin library pybitcointools; in general, anyone who is familiar with pybitcointools should feel right at home in pyethereum, although unfortunately in pyethereum it was not really practical to stick to pybitcointools’ “no classes” mantra in the code. The first step is to generate a private key:

> pyethtool sha3 cow
c85ef7d79691fe79573b1a7064c19c1a9819ebdbd1faaab1a8ec92344438aaf4

In production code, you should obviously replace “cow” with an actually secure password. If you want your account to be a “brainwallet” that you can easily remember, my main advice is to prepend a username, eg. “vbuterin:bl@hbl@hm0nk33y#!$!%”, ensuring that attackers need to target you individually instead of performing a blanket attack on everyone simultaneously; assuming 10000 brainwallet users this reduces your risk from a trial-and-error attack by 99.99%.

If you want to use your key later, on any standard Linux shell you can also type in key=`pyethtool sha3 cow`, and then use $key to use the key thereafter. We’ll use that format here from now on, so if you are following along then you should also do both:

> key=`pyethtool sha3 cow`
> code=`serpent compile namecoin.se`

So now, let’s keep going.

> addr=`pyethtool privtoaddr $key`
> echo $addr
cd2a3d9f938e13cd947ec05abc7fe734df8dd826

Now, we create a new genesis block, and we’ll set the initial endowment to 1018 wei (1 ether) for your address.

> genesis=`pyethtool mkgenesis $addr 1000000000000000000`
> echo $genesis
f8b2f8aea00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0bcddd284bf396739c224dba0411566c891c32115feb998a3e2b4e61f3f35582a80834000008087038d7ea4c68000830f4240808080a004994f67dc55b09e814ab7ffc8df3686b4afb2bb53e60eae97ef043fe03fb829c0c0

Now that we have that out of the way, we can get to actually doing stuff to the block. The only way to do anything in a blockchain-based architecture, in general, is to create and apply a transaction. Here, we will need multiple transactions: the first to create the contract, and then the latter ones to actually use it. Here’s contract creation:

> unsignedtx=`pyethtool mkcontract 0 0 $code`
> echo $unsignedtx
f83c8085e8d4a510008227108080af6025515b525b600a37f260003556601b596020356000355760015b525b54602052f260255860005b525b54602052f2
> tx=`pyethtool sign $unsignedtx $key`
> echo $tx
f87f8085e8d4a510008227108080af6025515b525b600a37f260003556601b596020356000355760015b525b54602052f260255860005b525b54602052f21ca04565b5a48b29ef623ad2caffe0917a3fc6a6f1b50f1df06876f3caa6fb4957c6a0123c928257c1f248fb3d362c125a0aea091ab08467efb52f8c3676ca73d727bf

Or, the easier way:

> tx=`pyethtool mkcontract 0 0 $code | pyethtool -s sign $key`
> echo $tx
f87f8085e8d4a510008227108080af6025515b525b600a37f260003556601b596020356000355760015b525b54602052f260255860005b525b54602052f21ca04565b5a48b29ef623ad2caffe0917a3fc6a6f1b50f1df06876f3caa6fb4957c6a0123c928257c1f248fb3d362c125a0aea091ab08467efb52f8c3676ca73d727bf

The first field in mkcontract is a nonce, which must be equal to the number of transactions you already sent from that account. The purpose of requiring a nonce is to prevent replay attacks; otherwise, if you sent Bob 200 ether, Bob could simply replay that transaction over and over again until you run out of money, whereas here due to the nonce requirement the transaction can only go through once. The second field is the amount of ether to send (in the case of contract creation, the amount of ether to initially provide to the contract), and the third field is the code. Note that the Transaction.contract function call also has two more fields between value and recipient: gasprice and startgas. Pyethtool is nice to you and initializes these values to 1 szabo (ie. 1012 wei or one millionth of an ether) per gas and 10000 gas, respectively. This will give you a theoretical maximum of 10000 computational steps for the code to run, although in practice it may run out after 1000 if you use many expensive operations. Finally, once you create the transaction, you need to sign it with your private key.

Once that’s done, we just, well:

> pyethtool applytx $genesis $tx
{"result": "da7ce79725418f4f6e13bf5f520c89cec5f6a974", "block": "f9017ef8d0a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a00bcec36bf7ffc27418b1746986574526efeb09b34f733039749f291f778d4aaca03575f60ad6c929d7c98a50a12ff1ef9b07ecf3182e74962872064648a66f3da0834000008087038d7ea4c68000830f42408204b08080a004994f67dc55b09e814ab7ffc8df3686b4afb2bb53e60eae97ef043fe03fb829f8a9f8a7b881f87f8085e8d4a510008227108080af6025515b525b600a37f260003556601b596020356000355760015b525b54602052f260255860005b525b54602052f21ca04565b5a48b29ef623ad2caffe0917a3fc6a6f1b50f1df06876f3caa6fb4957c6a0123c928257c1f248fb3d362c125a0aea091ab08467efb52f8c3676ca73d727bfa00bcec36bf7ffc27418b1746986574526efeb09b34f733039749f291f778d4aac8204b0c0"}

This gives you two values. The first is the address of the contract, and the second is the new block data. Note that the block data does not represent the entire block; there is also the state data hidden in the statedb folder. Hence, if you try to deserialize the block on a fresh machine it likely will not work. From the values returned, set the first value to contract and the second to med so we can use them later. Now, we need to craft a transaction to actually use this contract. Suppose we want to register “george” to 45. To do that, however, we first need to do another annoying chore: package up the data. Fortunately, the serpent compiler has a utility for doing just that:

> data=`echo '["george",45]' | serpent -j encode_datalist`
> echo $data
000000000000000000000000000000000000000000000000000067656f726765000000000000000000000000000000000000000000000000000000000000002d

The namecoin contract takes data in two fields, the key and the value, so we simply put them into a JSON array and use Serpent to encode it. The encoder can accept strings and numbers as the individual elements in the array. Note that unfortunately Python’s JSON decoder requires double quotes for internal strings; "['george',45]" would not work.

Now, we do this:

> tx2=`pyethtool mktx 1 $contract 0 $data | pyethtool -s sign $key`
> echo $tx2
f8a50185e8d4a5100082271094da7ce79725418f4f6e13bf5f520c89cec5f6a97480b840000000000000000000000000000000000000000000000000000067656f726765000000000000000000000000000000000000000000000000000000000000002d1ba064363844c718f0f38907d39508adb2c2b9134e52e7d436fb20965044c01f41c2a0e1123d26cf810c4ef9d397974e2fc336d16e452d71df3c3d7245b40ed12c603b

And:

> pyethtool applytx $med $tx2
{"result": "0000000000000000000000000000000000000000000000000000000000000001", "block": "f9024ef8d0a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a066d2524d921fadb5056983cf4bb215d339cdaeb7048b8913bfdf8fe867eb5682a0d669d3b5cfb150e4ef7f900cc613b0231abc8551544c389ddcd6668f784c4cb3834000008087038d7ea4c68000830f4240820a8f8080a004994f67dc55b09e814ab7ffc8df3686b4afb2bb53e60eae97ef043fe03fb829f90178f8a7b881f87f8085e8d4a510008227108080af6025515b525b600a37f260003556601b596020356000355760015b525b54602052f260255860005b525b54602052f21ca04565b5a48b29ef623ad2caffe0917a3fc6a6f1b50f1df06876f3caa6fb4957c6a0123c928257c1f248fb3d362c125a0aea091ab08467efb52f8c3676ca73d727bfa00bcec36bf7ffc27418b1746986574526efeb09b34f733039749f291f778d4aac8204b0f8cdb8a7f8a50185e8d4a5100082271094da7ce79725418f4f6e13bf5f520c89cec5f6a97480b840000000000000000000000000000000000000000000000000000067656f726765000000000000000000000000000000000000000000000000000000000000002d1ba064363844c718f0f38907d39508adb2c2b9134e52e7d436fb20965044c01f41c2a0e1123d26cf810c4ef9d397974e2fc336d16e452d71df3c3d7245b40ed12c603ba066d2524d921fadb5056983cf4bb215d339cdaeb7048b8913bfdf8fe867eb5682820a8fc0"}

Registration successful! The result here is two values, just as before: the first is the new block state, and the second is the response returned by the contract. Based on the definition of the contract above, “1” means success. Now, just to be sure, let’s set end to the block hex returned by the previous command and peek at the state:

> pyethtool getstate $end
{'nonce': '\x04\x99Og\xdcU\xb0\x9e\x81J\xb7\xff\xc8\xdf6\x86\xb4\xaf\xb2\xbbS\xe6\x0e\xae\x97\xef\x04?\xe0?\xb8)', 'min_gas_price': 1000000000000000L, 'extra_data': '', 'state_root': 'f\xd2RM\x92\x1f\xad\xb5\x05i\x83\xcfK\xb2\x15\xd39\xcd\xae\xb7\x04\x8b\x89\x13\xbf\xdf\x8f\xe8g\xebV\x82', 'difficulty': 4194304L, 'timestamp': 0L, 'number': 0L, 'gas_used': 2703L, 'coinbase': '0000000000000000000000000000000000000000', 'tx_list_root': '\xd6i\xd3\xb5\xcf\xb1P\xe4\xef\x7f\x90\x0c\xc6\x13\xb0#\x1a\xbc\x85QTL8\x9d\xdc\xd6f\x8fxLL\xb3', 'state': {'0000000000000000000000000000000000000000': {'nonce': 0L, 'balance': 2703000000000000L, 'storage': {}, 'code': ''}, 'da7ce79725418f4f6e13bf5f520c89cec5f6a974': {'nonce': 0L, 'balance': 0L, 'storage': {113685359126373L: 45L}, 'code': '60003556601b596020356000355760015b525b54602052f260255860005b525b54602052f2'}, 'cd2a3d9f938e13cd947ec05abc7fe734df8dd826': {'nonce': 2L, 'balance': 997297000000000000L, 'storage': {}, 'code': ''}}, 'uncles_hash': '\x1d\xccM\xe8\xde\xc7]z\xab\x85\xb5g\xb6\xcc\xd4\x1a\xd3\x12E\x1b\x94\x8at\x13\xf0\xa1B\xfd@\xd4\x93G', 'prevhash': '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'gas_limit': 1000000L}

You can see the contract account near the beginning of the state description, with “george” registered to 45 as expected. We’re done! As an exercise, try constructing two more transactions, one registering “george” to 60 and another registering “harry” to 80. If you apply them all sequentially after these two, the one registering “george” to 60 should return 0, but the one registering “harry” to 80 should succceed.

Doing it in Python

That’s pyethtool, the command line utility. Now, how does it work using pyethereum itself? As it turns out, it’s surprisingly easy. Here’s the session:

>>> import serpent
>>> from pyethereum import transactions, blocks, processblock, utils
>>> code = serpent.compile(open('namecoin.se').read())
>>> key = utils.sha3('cow')
>>> addr = utils.privtoaddr(key)
>>> genesis = blocks.genesis({ addr: 10**18 })
>>> tx1 = transactions.contract(0,10**12,10000,0,code).sign(key)
>>> result, contract = processblock.apply_tx(genesis,tx1)
>>> tx2 = transactions.Transaction(1,10**12,10000,contract,0,serpent.encode_datalist(['george',45])).sign(key)
>>> result, ans = processblock.apply_tx(genesis,tx2)
>>> serpent.decode_datalist(ans)
[1]
>>> genesis.to_dict()
'nonce': '\x04\x99Og\xdcU\xb0\x9e\x81J\xb7\xff\xc8\xdf6\x86\xb4\xaf\xb2\xbbS\xe6\x0e\xae\x97\xef\x04?\xe0?\xb8)', 'min_gas_price': 1000000000000000L, 'extra_data': '', 'state_root': '', 'difficulty': 4194304, 'timestamp': 0, 'number': 0, 'gas_used': 2712L, 'coinbase': '0000000000000000000000000000000000000000', 'tx_list_root': '\x17\x90\x87\x966\xbdb!\x14|R\xb0& \xb04\x90\xb9bs\x12\x85\x90\xdaB\xed\x83n*\x8eE\x8e', 'state': {'0000000000000000000000000000000000000000': {'nonce': 0L, 'balance': 2712000000000000L, 'storage': {}, 'code': ''}, 'da7ce79725418f4f6e13bf5f520c89cec5f6a974': {'nonce': 0L, 'balance': 0L, 'storage': {113685359126373L: 45L}, 'code': '60003556601e596020356000355760015b525b54602052f260285860005b525b54602052f2'}, 'cd2a3d9f938e13cd947ec05abc7fe734df8dd826': {'nonce': 2L, 'balance': 997288000000000000L, 'storage': {}, 'code': ''}}, 'uncles_hash': '\x1d\xccM\xe8\xde\xc7]z\xab\x85\xb5g\xb6\xcc\xd4\x1a\xd3\x12E\x1b\x94\x8at\x13\xf0\xa1B\xfd@\xd4\x93G', 'prevhash': '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'gas_limit': 1000000}
>>> genesis.get_balance(addr)
997288000000000000L
>>> genesis.get_storage_data(contract,'george')
45L

Another important command is processblock.debug = 1; this starts printing code execution step by step, helping you debug what is wrong in your contract code – or my pyethereum VM or Serpent implementation!

Getting into the Code

So that’s your introduction to how to use pyethereum. Now, let’s get into the most fun part, writing contracts. For reading efficiency, let’s provide the Namecoin contract again:

if !contract.storage[msg.data[0]]:
    contract.storage[msg.data[0]] = msg.data[1]
    return(1)
else:
    return(0)

What does this contract do? Essentially, this contract implements a name registration database by simply using that as the sole function of the long-term storage of the contract. Contract code theoretically has three places to put data: stack, memory and storage. Of those three, stack and memory are used implicitly in Serpent to support arithmetic and variables, but long-term storage is the only one that survives once execution is over. Here, when you register “george” to 45, the contract first checks if contract.storage["george"] is not nonzero, ie. is zero. If it is, then it sets that storage index to the value provided, 45, and then returns 1. If it is not, then it returns zero. Note that this contract has no way for other contracts to access it; it is only really usable by external applications. More advanced name registries would have an API for contracts to fetch the data associated with a name as well.

Now, on to a more intricate example:

init:
    contract.storage[0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826] = 1000000
code:
    if msg.datasize == 1:
        addr = msg.data[0]
        return(contract.storage[addr])
    else:
        from = msg.sender
        fromvalue = contract.storage[from]
        to = msg.data[0]
        value = msg.data[1]
        if fromvalue >= value:
            contract.storage[from] = fromvalue - value
            contract.storage[to] = contract.storage[to] + value
            return(1)
        else:
            return(0)

This is the “currency contract”, or more precisely an embellished version of it with return values to make debugging easier. This contract is interesting for several reasons. First, it has an initialization step, which gets called when the contract is first made. This initializes an account with 1000000 currency units owned by that account.

After that, there are two code paths. First, incoming messages might contain only one data field. In that case, these messages are treated as balance queries, and simply return the balance of the queried address. Note that msg.data[0] provides the integer at bytes 0…31 of the transaction data, msg.data[1] provides the integer at bytes 32…63, and so forth. This is a convenience introduced in Serpent; the underlying transaction data is all byte-based. Incidentally, this is why we needed to use Serpent’s encode_datalist function to generate the transaction data.

Second, incoming messages might contain two data fields. In that case, the messages are treated as requests to send to that address. The sender is inferred from the sender of the message, and the recipient and the value are taken from the first two fields (ie. first 64 bytes) in msg.data. If there is enough money to transfer, it transfers the money and returns 1; otherwise it returns 0.

Challenge: create a currency contract which takes a fee, denominated in its internal currency, from every transaction, and refunds a small amount of ether to everyone sending a successful transaction, so people (or contracts) who want to deal in this currency would not have to worry about simultaneously maintaining currency and ether balances themselves. The contract would also include a third transaction type, perhaps taking 0 arguments, through which someone can buy internal currency units from the contract by sending it ether. The contract should keep track of two variables: its own balance in its currency, and its ether balance, and it should dynamically adjust the transaction fee and the exchange rate in order to keep both its ether balance and its internal currency balance in bal- uh, in an approximate equilibrium.

Contracts Calling Contracts

This is a proprietary data feed contract:

owner = 0xcd2a3d9f938e13cd947ec05abc7fe734df8dd826
if msg.sender == owner and msg.datasize == 2:
    contract.storage[msg.data[0]] = msg.data[1]
    return(1)
else:
    return(contract.storage[msg.data[0]])

This contract is designed to work as a key/value that can be edited only by its owner, but also also allows anyone to query its contents; the point is for the owner to use various storage indices to record changing data like the USD price of ether. Here, there are two main “clauses” in the contract, one for modifying storage which triggers if a key and a value are provided and the message originates from the contract’s owner, and the other for just reading storage. The msg.datasize variable tells you the number of 32-byte data fields there is in the message data. There are no particularly new features here; this contract is actually fairly simple, and I encourage you to first follow and make sure you understand the logic involved and then play with the contract, instantiating it in a block and then pushing set and query transactions to it.

The interesting part, however, comes when we use this contract inside of another contract. Meet this monstrosity, a hedging contract:

if !contract.storage[1000]:
    contract.storage[1000] = msg.sender
    contract.storage[1002] = msg.value
    contract.storage[1003] = msg.data[0]
    contract.storage[1004] = msg.data[1]
    return(1)
elif !contract.storage[1001]:
    ethvalue = contract.storage[1002]
    if msg.value >= ethvalue:
        contract.storage[1001] = msg.sender
    datasource = contract.storage[1003]
    dataindex = contract.storage[1004]
    othervalue = ethvalue * msg(datasource,0,tx.gas-100,[dataindex],1)
    contract.storage[1005] = othervalue
    contract.storage[1006] = block.timestamp + 86400
    return([2,othervalue],2)
else:
    datasource = contract.storage[1003]
    dataindex = contract.storage[1004]
    othervalue = contract.storage[1005]
    ethvalue = othervalue / msg(dataindex,0,tx.gas-100,[datasource],1)
    if ethvalue >= contract.balance: 
        send(contract.storage[1000],contract.balance,tx.gas-100)
        return(3)
    elif block.timestamp > contract.storage[1006]:
        send(contract.storage[1001],contract.balance - ethvalue,tx.gas-100)
        send(contract.storage[1000],ethvalue,tx.gas-100)
        return(4)
    else:
        return(5)

This contract is bulky because it’s designed to be more testing-friendly; an optimal implementation is roughly half the size. The contract works as follows:

1. Party A sends in X ether alongside a data feed contract D and a currency code C as data items, and is registered at contract storage index 1000. X, D and C are registered in contract storage indices 1002, 1003 and 1004. In this case, suppose that the currency code represents USD.
2. Party B sends in X ether, and is registered at contract storage index 1001. The contract then calls D with data C to determine the price of ether in the given currency, and uses this to compute V, the amount of value in USD sent by each party. V is stored at index 1005, and an expiry time set to 24 hours in the future is stored at index 1006.
3. Maybe, the price of ether in USD drops by more than 50%. If this happens, then there is not enough ether in the contract altogether to pay V USD. To prevent this, as soon as the price slips under the 50% mark, anyone (usually A) can ping the contract to withdraw all 2X ether into A’s address and thereby recover to A’s address almost all of the amount, as measured in USD, that A put in, and leave B with nothing. If this happens, the contract returns 3.
4. Otherwise, after one day, anyone can send a transaction to “ping” the contract and cause it to send V USD worth of ether to A and the remaining ether to B, returning 4.
5. If there is no “margin call” or “expiry” event, then a ping to the contract does nothing and returns 5.

The point of the hedging contract is that A benefits by always getting back the same quantity of USD that he put in, and B benefits if he believes that the value of ether will go up, since a 10% rise in the ether price will, in this circumstance, give him a 20% profit. USD can of course be substituted with anything, including CNY, gold or the consumer price index.

The important new features explored here are msg, send and array literals. msg and send are both ways of sending message to other contracts. The syntaxes are:

send(to, value, gas)
out = msg(to¸ value, gas, datastart, datalength)
msg(to, value, gas, datastart, datalength, outstart, outlength)

Send is simpler, assuming that all you want to do is send money with no bells and whistles involved. The latter two are equivalent ways of sending a message to another contract, differing only in how they handle the output: the first caps output to 32 bytes and sticks it straight into a variable, whereas the second takes in two arguments for the position in memory where to dump the output. The “output” of a message is blank if the recipient is not-yet-existent, an externally owned account, or does not explicitly specify a return value, and if the output does specify a return value then the output is that value (“value” in this context being an arbitrary-length byte array, not a 32-byte number). These two are thus both ways of saying the same thing:

d = array(3)
d[0] = 5
d[1] = 10
d[2] = 15
x = msg(A, B, C, d, 3)

And:

d = array(3)
d[0] = 5
d[1] = 10
d[2] = 15
w = array(1)
msg(A, B, C, d, 3, w, 1)
x = w[0]

In the contract example above, we used the data feed contract to provide the price of ether in USD, and then directly plugged it into the formula othervalue = ethvalue * msg(datasource,0,tx.gas-100,[dataindex],1).

Array literals are another nice convenience feature; the truly optimal way to write the above code is as follows:

x = msg(A, B, C, [5, 10, 15], 3)

Note that you unfortunately still need to specify the array length. However, here the array itself is created and referenced all inline, without needing to manually set things up. All of the magic is done by the Serpent compiler.

So that’s basically it for today. What might you want to code in Serpent? Well, here are a few possibilities:

1. SchellingCoin
2. A contract-based implementation of JustDice.
3. Some skeleton code for a decentralized organization.
4. A board game (eg. chess, Go)
5. A decentralized exchange, with a contract-based order book, between ether and the sub-currency contract given above.
6. Any of the other examples in our whitepaper

Enjoy, and have fun! Also, if you do find any bugs in pyethereum or Serpent, please be sure to point them out.

See also: list of Serpent language operations