Skip to content

Step by step towards creating a safe smart contract: lessons from a cryptocurrency lab

September 1, 2017

Step by step towards creating a safe smart contract: lessons and insights from a cryptocurrency lab Delmolino et al., 2015.

This is an experience report from teaching a smart contract programming course to undergraduates at the University of Maryland, back in the Fall of 2014. Of course that’s a very long time ago in the world of blockchains, and the paper shows its age in a few areas such as the use of the Serpent programming language rather than Solidity. Nonetheless, it still contains some good insights on the mindset change needed to start programming smart contracts vs. other kinds of development. From previous editions of The Morning Paper we know to be aware of mishandled exceptions, transaction-ordering dependencies, timestamp dependencies, and re-entrancy issues as well as general concurrent execution concerns. What else do Delmolino et al., have for us?

As we show below, surprisingly, even for a very simple smart contract it is difficult to create it correctly!

During the course students were divided into groups of four. In the first phase they created a smart contract program of their own choice. The contracts were then critiqued by the instructor, TAs, and fellow students, often revealing a number of flaws. In the second phase the students addressed the bugs found and amended their designs.

In contrast to traditional software development where bugs such as buffer overflows are typical, in our lab, we observed bugs and pitfalls that arise due to the unique nature of smart contract programs. Our lab experiences show that even for very simple smart contracts (e.g., a “Rock, Paper, Scissors” game), designing and implementing them correctly was highly non-trivial. This suggests that extra precautions and scrutiny are necessary when programming smart contracts.

In particular, contracts require an ‘economic thinking’ perspective to ensure fairness even when counterparties attempt to cheat in arbitrary ways to maximise their economic gains.

Using the rock, paper, scissors game, the authors illustrate three classes of mistake the students tended to make: leaking money, hiding in plain sight, and misaligned incentives.

Leaking money

Programming smart contracts typically involves encoding complex state machines. Logical errors in encoding state machines were commonly observed. The simplest type of logical error is a contract that leaks money in corner cases.

In the following extract, there are two ways money can be lost. On lines 19-20, if a third player tries to join and sends money, then the money becomes inaccessible. Note that miners control the ordering of transactions in a block, so a player attempting to join as the second player cannot always protect themselves from joining the party too late. Likewise on line 13, if a player sends an amount other than 1000 wei then the money will also be lost.

The following extract fixes these bugs:

Hiding in plain sight.

Another mistake is more subtle: players send their inputs in cleartext. Since transactions are broadcast across the entire cryptocurrency network, a cheating player may wait to see what his opponent chooses before providing his own input.

The solution to this is to use some form of cryptographic commitments – both players submit their commitment in one phase, and the inputs are revealed in a later phase. For example, players could create a random nonce and then send hash(input, nonce) as their commitment. You can see such a scheme at work in the following revised code:

Misaligned incentives.

What if one party waits for the other to open its commitment, and then seeing that it will lose, just abandons the games (does not send any further messages)? This saves the loser the gas cost of sending a transaction to open a commitment that won’t win, but also denies payment to the winner.

This generalizes to a broader question of how to ensure the incentive compatibility of a contract. Can any player profit by deviating from the intended behavior? Does the intended behavior have hidden costs?

To fix this issue, we need to make sure players are incented to do the right thing. For example: introducing a deadline before which the second player must reveal, otherwise the player who revealed first gets the reward. Additionally, players could make a security deposit in the first stage, which they forfeit unless they open their commitments in a timely manner.

The paper also introduces a number of Ethereum-specific gotchas, such as the call-stack limit. The ‘Security Considerations‘ section of the Ethereum docs does a good job today providing a high level overview of many of these: publicly visible state, re-entrancy, gas limits and loops, pitfalls when sending and receiving ether, callstack depth, and the use of tx.origin.

I also found the following ‘Ethereum Contract Security Techniques and Tips‘ document to be very useful. From the introduction:

Smart contract programming requires a different engineering mindset than you may be used to. The cost of failure can be high, and change can be difficult, making it in some ways more similar to hardware programming or financial services programming than web or mobile development. It is therefore not enough to defend against known vulnerabilities. Instead, you will need to learn a new philosophy of development…

If you want to get into smart contract development, it seems you’d better bring your A-game! Getting it right is going to require combinations of skills in verification, concurrency, cryptography, cybersecurity, and game theory as a starter!

4 Comments leave one →
  1. Ben permalink
    September 2, 2017 12:10 pm

    do you have any insight as to why the refunding mechanism for values that exceed 1000 units (added in the second listing) refunds those units that exceed 1000 (so far so good) but still adds the full amount to the reward before refunding (in line 12 of the second listing)? I would think you first refund and only add 1000 to the reward in any case (or subtract the refunded money from the reward again). Else there’s prize money in the pool that was actually refunded later, or not? Maybe I’m also misunderstanding the semantics of the send function a bit.

    Just curious if I missed something, thanks for the insightful article. šŸ™‚

    • September 3, 2017 8:27 am

      Hi Ben, I just looked through the listing, and this looks like a genuine bug to me! Line 12 assigns the full value to the reward, and lines 51, 55 send it all (not just 1000). Send is now deprecated and you should use transfer instead. I *think* this contract will lose money forever if someone does initially send > 1000 as the final send will fail and there seems to be no way to recover from that. An unintended example from the authors of the difficulty of getting this right perhaps? (Though it looks to be a fairly straightforward bug, just unfixable if this contract was ever deployed!). Rgds, A.

  2. araybold permalink
    September 8, 2017 2:06 pm

    The warning you quoted from “Ethereum Contract Security Techniques and Tips” strikes me as completely missing the real issues. The security problem is not “more similar” to financial services programming; it is well beyond anything that has ever been addressed in financial services, or anywhere else.

    Firstly, financial services security depends on physical isolation – the hardware, data, software, and software source code are not available to attackers, except through compromising a relatively few hardened access points (and then there are often internal controls), while the whole of Ethereum is intentionally and unavoidably open to everyone. The “many eyes make all bugs shallow” proverb, which was never particularly valid, is completely inapplicable to security issues, because attackers are more motivated and only have to get lucky once (one might argue that legitimate users have more to lose, but we know empirically that that does not translate into action.)

    Secondly, financial services have the option of hitting the reset button and fixing problems out-of-band, but that is not an option with smart contracts (well, it was done once to save Ethereum’s founders from their complacency, but it was only possible because nothing else of consequence was going on in the blockchain at the time.)

    I would be interested in other papers that address the securing of smart contracts (I would propose some myself, but I don’t know of any.)


  1. SmartPool: Practical decentralized mining | the morning paper

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: