 Hi, everyone. So yeah, I'm Andrew Miller. I'm a professor at the University of Illinois at Urbana-Champaign. I'm also a member of the Research Initiative IC3, the Initiative for Cryptocurrencies and Contracts. I'm also a board member of the Zcash Foundation and Enterprise Ethereum Alliance. I'm also a technical advisor to a bunch of Ethereum-related projects, for example, Chainlink, which I know was talked about earlier. And what I want to tell you about today is basically the culmination of the last couple of years of research into smart contract programming that I've been doing. I've been doing research in cryptocurrencies since prior to Ethereum back in the Bitcoin times and have been trying to include Ethereum smart contract programming in things like assignments at the University of Maryland and computer security courses since as early back as 2014, like before Ethereum was even released. And what I want to talk about is basically how we evaluate the languages that we use to write smart contracts in. So you all know the story that we now think about cryptocurrencies as not just a place where money goes and you can transfer money from one person to another. We think more generally about writing programs that run on the blockchain. And we need smart contract programming languages to define these. Now, you probably all know that there's two main paradigms for writing smart contracts to run on a blockchain cryptocurrency. You've got your Bitcoin style programming language, which is not Turing complete. And you've got your Ethereum style programming languages, which are Turing complete. And so you probably have at least seen this kind of idea. This is the main difference between these two programming styles. On the right, you've got more complicated control flow. Maybe these are going to be more difficult to analyze and maybe the simplified Bitcoin scripts more rigid, less expressive, hopefully easier to analyze. Now, there's a version of this talk that I give that really just drives in on this point. This really isn't the right way to think about the differences between smart contract programming languages. Turing completeness is really a red herring. It's just not the real point. The compressed version of this, I'll just list the kind of summaries of this. It's not really the case that Ethereum's Turing complete. All of the things about halting problem and infinite loops being undecidable, they don't apply because of the gas limit that effectively makes Ethereum programming not Turing complete. You know how long something's going to run at most. And it's not the case that you ever need Turing completeness. So it's not necessarily the most important thing that you want anyway. And if you have a Turing complete language, it doesn't necessarily mean you can do everything you want to in it. It's not just what you can compute that matters, but how input and output are handled, concurrency, things like that. And something that I hear a lot, but it's just not true. It's not the case that Turing complete languages are not possible to apply formal validation to. It's really awesome that the Ethereum community is moving full ahead and caring about formal methods. And it's the case that formal methods can also apply to programs written in a Turing complete language as well. Maybe it's not decidable. Maybe you can't do all analysis for all programs, but you can still have very effective formal verification methods. So if you buy this premise and you say, OK, Turing completeness is a red herring, how else should we go about evaluating the difference between smart contract programming languages and what do we want from one? So the approach that I've been taking in my research, I should also say that I'm going to talk about a couple of different research projects that are joint work with some collaborators of Mayanid Obentav, Ranjit Kumarisan, and Patrick Nakori, who you would have heard talk earlier in one of the breakout sessions. And the approach that we've been taking is basically to come up with interesting applications and try to refine them over time to get them as efficient or as effective as we can in some kind of quantitative way and to see how far we can go by implementing these applications in the different smart contract programming languages. Now there's a common theme that you all, this Ethereum audience, might find heartening that this common theme runs through all of these applications that we've tried, which is that there's some quantitative reason where we can do a better job of implementing these applications in Ethereum than we can in the Bitcoin-style programming language. And that's what I'm going to try to explain. Just to give a quick preview of these three things, I'll tell you a little bit about lottery applications in Ethereum. And to do a coin flip lottery in Ethereum, you can do quite simply and quite efficiently. Whereas to try to do the same thing in Bitcoin, you require this kind of trade-off of either an exponential amount of computation in the number of parties that are playing or else, you have to lock up a bunch of extra money as security deposits that you don't have to in the Ethereum case. And then I'll tell you a little bit later about payment channels and things like the Lightning or Radon network. And there's an optimization that you can make in Ethereum that reduces the amount of money that you have to have locked up for a certain amount of time in these payment channels that we can't figure out how to get this benefit in Bitcoin. This trick only works in Ethereum. And then finally, I'll end by telling you a little bit about a poker protocol that we worked on where there's really two properties that you would want, and you can't get both of them at the same time with Bitcoin, whereas you can do that in Ethereum. All right, so let me start by just introducing this lottery application. And let me explain to you how this goes. So you all know the lottery application. It's perfectly simple. You have n players. They each put in one coin. And then some random selection process happens, and then one of them walks away with all n of the coins. Now, I'm going to say that the condition that I want, you would probably think of using the block hash for this. Let's just say that's out of bounds. What we care about is the fair cryptographic commit and reveal kind of lottery. So not relying on a block hash, which miners might be able to influence. So the way that this works, the coin flip lottery, you've probably seen this in some kind of form. It's similar to what Ethereum name services bidding does. All of the parties are going to pick some random value, and they're going to, before some time limit, they're going to place the hash of this random value on the blockchain. And then they have up to some time limit after all of the commitments are in to reveal what those random values were that they committed to. And then the random winner has decided somehow by adding up all of these secret values that are revealed, and then hashing them, and that picks one of the winners. Now, this is simple. In order to make it secure, though, you want to have this so that it's a fair lottery, so that even if n minus 1 of the parties are bad, they can't cheat against the one remaining on us party. And where the problem ends up happening that you need a technical solution to is, what happens if one of these players just doesn't show up and doesn't reveal their secret value that they committed to in the earlier round? You have to have some way of handling this case. Maybe the first thing that you would think of is just to take a security deposit, like you have an extra coin that each party has to put in, and if they don't reveal their value, then they lose that coin. So this makes sense, but it doesn't actually solve the problem, because if there are more than one player that collude against even the one remaining on us party, then just doing this still penalizes the on us parties that are remaining. This simple solution doesn't give you a fair lottery. Now, this idea of a coin flip lottery has been an interesting test case. It was one of the first smart contracts examples that people tried to work out how to do in Bitcoin. And what I'm going to describe is that the version that you can do in Bitcoin still has this trade-off, like I mentioned. You either have to collect really big security deposits, or you have to do a kind of ridiculous amount of extra computation, whereas in Ethereum, there's a way of doing a lottery quite simply that doesn't require any of this extra collateral. So to start, let me explain how this works in Bitcoin. Again, this has been an important test case for smart contract programming since even prior to Ethereum. The main tool that we have at our disposal is this idea of a claim or refund gadget. It's denoted by this little arrow, which has some parameters like an amount of money queue, a hash H, and some deadline T. And what this arrow is saying is that Alice is promising to Bob that she's going to reveal the pre-image of this hash value by some deadline T. And if she fails to reveal that pre-image, then Bob gets the Q dollars. So that's what's meant by this claim or refund gadget. To implement the claim or refund gadget in Bitcoin, I won't go all the way through this. It's something you can do with the Bitcoin scripting language. It's especially easier now. It used to be possible, but a lot harder before a check-lock time verify. It's a lot simpler now with the check-lock time verify opcode. It's like you make a UTXO that has a piece of script pub key Bitcoin script in it that says this can be claimed before a deadline. If you reveal the pre-image of this hash, then Alice can spend it. It comes with a signature from Alice and the pre-image. Or if time T1 elapses, then Bob can take the coin just with his signature. He doesn't have to reveal anything, but he can only do this after this deadline. So there's two ways to spend this. There's the refund transaction, which has to come along with X. And so Alice can make this by revealing X before the deadline or else a claim transaction means Alice forfeited it. She didn't reveal her pre-image in time, so Bob gets the coins instead. All right, so it actually turned out that a lottery that implemented this was one of the contributions of a really interesting paper that actually won the best paper award in 2014 at the Oakland Conference. This is the most prestigious computer security conference in the academic computer security research community. And they came up with a way of... They didn't express it in terms of the claim refund that little abstraction came later from Ido and Ranjit, but it uses this basic technique, but the catch is that it requires this really large amount of collateral. The idea is that every party deposits enough security collateral that if they get caught failing to reveal their committed value, they compensate every other party for the total amount that any of the parties could have won. So it's like whatever is the total amount of the lottery times the number of parties there are, that's what each party has to put up as a security deposit. And the way that this is implemented is kind of a monstrosity. This isn't even the full transaction graph of all the parts that are needed. This is actually kind of the plain case. Basically what happens is all of the parties make these claim or refund commitments to each other. All right, and then they'll all get settled at once, but it requires collecting this large amount of security to deposit up front. And so each party has to put in n squared coins, and so it's n cubed in total is the amount of collateral that's required in addition to the bet. Now Ido and Ranjit came up with a way to improve on this, which is also extremely clever, and yet you also get the feeling it's kind of complicated. I won't be able to even describe it in a way that I think you'll totally be comfortable with it. You can think of it like this. It involves proceeding in sequential rounds where in each round the parties make a claim or refund to the next party in line. All right, and then there's like a separate unwinding phase where they also make commitments. They make these claim or refunds with where you have to reveal multiple pre-images, and each one of them one more pre-image than the last. It's really hard to describe it, but it requires now like a linear number of rounds. Like you have to do this one at a time. The timeouts get larger and larger each time. It's kind of like if any party fails to reveal their pre-image, then the next party in line has enough money to compensate them plus everyone else after this. All right, the net result is it reduces the total amount of extra security deposits you need to collect down from n cubed in total to merely n squared in total. All right, but it also comes at a trade-off, which is that this ends up stretching out over n rounds. Like the lottery takes longer, the more parties that you have participating, whereas the original one took more collateral, but finished in a constant number of rounds. And it still has this quality that I think it's a little bit hard to wrap your head around, so I'm not going to try to explain it any more clearly than that. The technique's really clever though. Now, you might start to wonder, is there a simpler way of doing this? And so I should say, again, all of these were done in Bitcoin prior to Ethereum being so widely appreciated anyway. We started to look at how you could do a lottery in Ethereum, and it just immediately was simple. Oh, you can do something a lot easier than this. What you can do is have a tournament bracket, where you always have two parties just playing a coin flip game against each other. All right, and at each time, you lay them out like a tournament bracket after the first two parties play, then whoever wins that lottery goes on to the next round, all right? And then you keep doing this like a tournament until you get to the final of the tournament and then whoever's there wins. And now the rule is that the way that you handle aborts is that since you're always just playing with an opponent, if you fail to reveal your secret in time, then the other party wins. It's like you forfeit the other party immediately goes on to the next level. And this is really easy to do in Ethereum because you can keep track of who was the winner at each bracket. It's really easy to do this with lots of contracts, like one contract for each match and then the contracts talk to each other. It's also easy just to unfold it and write one big contract that keeps an array, keeping track of all of the different stages of the tournaments. It's really pretty simple. It's something you could implement in Solidity. We started to look then at, okay, so you can do the simple tournament bracket in Ethereum. And I should say also that this tournament doesn't require any extra collateral because you don't have to take a security deposit from someone if they forfeit. You just, the other person goes on to the next level. So we looked at to try to see if we could emulate this tournament structure rather than this linear structure or one round expensive structure in Bitcoin. And we came up with something that's a little bit unsatisfying, but it is still technically a tournament structure. We came up with this extension of the Claimor refund gadget. That's really like a two-way Claimor refund gadget. It involves a sequence of two transaction scripts rather than just one. It's like Alice has a turn to commit, Bob has a turn, Alice has a turn to reveal, Bob has a turn to reveal. The net of it is that there are, everyone has to, all of these transactions have to be signed by all of the parties involved ahead of time. Like all of the parties in the tournament have to sign all of these transactions. Everything except for the hash pre-images is the only thing that's left out of the signature. All right, and no matter what, there will be at least this transaction on the blockchain and then there's some case where you can go straight to one of these outcomes. Basically, there's three possible transactions that can be the outcomes of this. Like two of the transactions involve Bob winning. One of the possible output transactions involves Alice winning. It's a little bit tricky to explain, but it's basically the same kind of thing. You're encoding this condition of, reveal a pre-image before some time. You can do that in Bitcoin script. The trick is in chaining these things together by having multiple transactions pre-signed that all refer to each other. And this structure you can actually combine into a tournament bracket, just like the Ethereum example, but with a catch. All right, so the catch is that because in Bitcoin transaction script, even making use of Segwit, even making use of the most modern op codes, when you have a transaction that receives inputs, you have to expressly indicate the transaction ID of the transaction whose input, whose outputs you're spending as an input. So what that means is that if one of the matches in this first round has three possible output transactions, all right, then to make the next round of the tournament that depends on it, it has to have, you know, you have to have one pre-signed transaction for each of those possible inputs. And so if you have the next round of transactions has two possible matches, not two possible matches, it has two, like the winner from each of these two matches goes on to the next round. You end up having to have three times three different contracts each combination of the ways that that could end. And then it gets worse from there because now this stack of transactions has 27 possible outcomes, all right? And so the next layer has to have 27 times 27 of those and it goes on by the time you get to the end, you've got this tournament bracket that worked, but you end up having an exponential number of transactions that everyone has to sign up front. Only one of them will end up getting put on the blockchain but you have to sign them all up front. And so that's where this exponential amount of computation comes in. It's kind of unsatisfying, it's a little bit awkward. It's kind of like having one hot encoding where the one hot is which of these transactions you sign up front actually gets placed on the blockchain and you have one of these, you know, transactions for every possible combination of all the different ways the tournament could have gone up to that point. All right, it's this bit of a convoluted structure. The lesson that we get here immediately is a qualitative one which is that things that are pretty simple to express in Ethereum are sometimes really complicated to express in Bitcoin. Sometimes there's a way to do it. I'm surprised at just how often there's something that I thought there'd be no way to do and yet we can figure out a way to do it in Bitcoin script but it's a little bit unsatisfying and unnecessarily convoluted. It's a little bit like trying to build a web browser inside a TI-83 calculator. You can do it, but TI-83 basic is not the most friendly language to be entering in button key presses at a time. But really the power of this is that we have not just that qualitative statement but this actually gives us a quantitative statement about the difference between these two programming paradigms. This is like the scoreboard of how well we can do a lot of reason in these different environments. These original Bitcoin ones earlier traded off this amount of collateral that you had to take for varying amounts of computation or running time. And then this weird one that we figured out how to do has this exponential cost but back down to no extra collateral. Whereas the one that we get in Ethereum is pretty efficient in the number of rounds and it doesn't require any extra collateral or any unusual amount of computation, despite being qualitatively simpler. I want to switch to then talking about the next application. Maybe you'll find this one more interesting because payment channels are invoked these days. This is a paper called Sprites and you can find this paper online. And the upshot of it is that if you have a lightning network situation where you have payments that are going across some lengths in this payment channel graph, the amount of collateral costs that you need is quadratic, all right, in the worst case as a function of the length of the hops that you have to go. I'll give you some explanation of that. Whereas in Ethereum we can do something simpler and we can reduce this collateral cost from quadratic down to linear. So you all know what a payment channel is by now. It's where you make a smart contract where you deposit some money for two parties and then after doing that initial deposit you can do off chain payments to each other really rapidly, all right. And then what's really especially cool about them is that if you have a chain of payment channels from one party to another, like you have Alice and Bob here, Alice wants to pay Bob, she doesn't already have a payment channel to Bob but she has a sequence, you know, she has some intermediaries to whom she does have payment channels and there's some path of payment channels from her to Bob. You can do this linked payment where each party pays the next person down in the chain and you do this in a way where there's like an atomicity guarantee which means that these parties in the middle they're not losing any money, like they're getting X from their incoming channel, they're paying X on their upcoming channel, they net out, all right, and there's no risk of them actually losing their money. Now the fun of this, right, this is this idea of the Lightning Network that we can have with a relatively small number of payment channels. We can build paths connecting any two parties with fairly low path length between them while still each one only is pretty small degree like no one person has to have too many payment channels. Now what you care about in this case is the collateral cost, which you should think of as like the dollar hours or the money times time that your money's tied up because the payments in a payment channel don't necessarily happen instantaneously, especially if one of the parties goes offline. So when one of these payments begins, it doesn't just happen immediately, it's in a pending state for a while until it settles. And so this guy's outgoing payment is also in a pending state. And if something happens and someone doesn't send immediately what they should, this pending state might last for a while. Meanwhile, this intermediary note is asking when's you gonna get the money back, how long is this X dollar tied up? All right, that's this money times time collateral cost. Now the way that Lightning and also Raiden go is that when you establish these linked payments, it's like you set up conditional payments from one party to the next. And these are similar to that claim a refund thing, they have a dollar amount, they have a pre-image and they have a deadline. And what happens is that each deadline has to be a little bit larger than the next. What happens in the typical case is that, this party on the right end has the pre-image X and he waits until he gets his incoming payment and then he goes ahead and reveals it to anyone who's listening. In the typical case, it just completes immediately after that, it's pretty quick, an entirely off chain. But the reason why you need that extra delay is because what can happen is that if, say these two orange colored parties are bad, they actually hold on to that pre-image X, they don't just send it to everyone when they get their incoming conditional payments made. It may be that this guy right here, this blue one only finds out about the pre-image X because this orange guy was petty, which I mean he waits till the very last possible moment and then actually puts X on the blockchain and gets his payment. So when this happens, this guy gets it in right at his deadline, T plus one, this blue guy here has to turn around and then put that X on the blockchain himself in order to get this payment from the other guy. All right, so as a result, he needs to have some extra amount of time. He has to wait to see this transaction on the blockchain and then be able to get his transaction in before his timeout goes. That's why each party has to have a longer timeout than the party to their right. All right, so as a result, if you have a length L chain of payments that you wanna make, then you have to have L times, whatever's an appropriate amount of time for this guy to, in the worst case, have to have his money locked up. All right, this means that the total collateral cost in the worst case when other people in the chain are delaying in this way is you may have to have L squared in total among all of these parties, it could be up to L squared times X in dollar hours, this collateral cost. Now here's what we can do in Ethereum. This is the idea of sprites, it's an optimization. We actually come up with a way that you can have chained payments that works really similar to this, except the lock times, the deadlines for each one of these conditional payments is exactly the same and the way it works is that the rules for settling this payment make use of a global condition, not just a local condition, the way that you do it in Lightning and in Raiden. We have a single contract we call the global pre-image manager. And the idea is that rather than requiring each value to be sent on each payment channel, the rules for settling this payment channel say, go to the global pre-image manager contract and check whether a value was published there in time. All right, what it looks like in the worst case is that if some party goes and puts their value at the last possible moment, it's like it sets an on-blockchain event that then guarantees that all of the channels, if they go to this dispute handling case, are gonna close in exactly the same way. These other parties upstream in the payment channel no longer have a burden of responding at a certain deadline. They know that whenever they get around to it, the channels are gonna settle in a consistent atomic way, which will guarantee that known of the intermediaries lose any money, which is what we want. The key to this is making use of this global pre-image manager contract, which is something that's straightforward to do in Ethereum, but for which there's no real way to do it in Bitcoin. I'm just gonna really briefly mention this last application of poker. I'm not gonna go into very details about it, although there's a paper online that you can read to see it, right? Online poker is one of these holy grails of cryptographic applications. It's really exciting because people like playing poker and it's an interesting exercise of your cryptography because you have private cards that you need to deal and need to keep secret. And the basic structure of handling the housekeeping of keeping track of whose turn it is and whether anyone forfeited a turn and therefore needs to be punished, that can be handled by the state channel generalization of this payment channel's idea. So without going into any of the cryptography that's there, I just wanna point out that we've had the sequence of works, mostly just of Ranji Denito I only helped in this last one. There's really two properties that you would like from a good poker application. One is that you would like it to be off-chain only in the typical case, so you can play many rounds of poker without having to make an on-chain transaction and pay fees. And you would also like the poker game not just to end up telling you who the winner is, but to actually give you the amount of money that you want. Do I have my slide back? Okay, my screen went out. Okay, so well, I think you got the gist of that end of it. The only way to get both of these properties combined is to make use of the flexibility in the Ethereum smart contract model. We couldn't find any way of being able to get both of these desired properties, both having off-chain in the usual case and actually being able to do a payment out. Oh, this just dropped, okay. No, it's a weird Linux thing. I have to open up Hudson James and everyone. Okay, all right, the only point I wanted to make here is we wanna have both of these qualities, like these ones here that say no cash distribution, what it means is that you learn who the winner was but it doesn't actually make any money change hands at the end, right? You wanna play poker for some kind of stakes in order to get both of these qualities where you can actually settle for money on-chain when you have to, but it's off-chain only in the typical case, all right? We weren't able to figure out how to do that in Bitcoin whereas all of these one desirable property of the other, we figured out some way of doing it in Bitcoin, but to get both seems to rely on the ability of having like references to dynamic transactions rather than having like a fixed transaction input which is what is constrained to do in the UTXO model. All right, so I just wanna wrap up then here by saying more about what I think is the lesson that we've learned from this. So first of all, I think this is a way to go about evaluating the expressiveness of smart contract languages. I think that if someone proposes a new smart contract language, one of the first things you should try to do is to see can you implement the high score on the scoreboard for all of these applications? If you get stuck, there's a sign that there's something useful that you would like to be able to do in smart contract programming that this language isn't affording. All right, there are other like trade-offs and so maybe there's some justification like that. So for example, the UTXO model in Bitcoin supports benign reorgs, like if there is a reorg then all of the transactions will be shortly played right after. And there's some trade-off involving privacy with Sprite so I'm not saying that you absolutely need to have this benefit. I think it's the case that doing UTXO prototyping first actually slows down research by obscuring the main idea behind a smart contract application and sort of obscuring the key ideas and I think that the fact that Raiden was designed the way that it is was because it was mimicking the design in Bitcoin which was only necessary because of Bitcoin's limited script. So even the Raiden clone of the lightning design fails to make use of Ethereum's full power even though it's in the Ethereum language. So my suggestion is that you should use a language like Ethereum to prototype your new application even if it's something that you're eventually going to eventually try to port to Bitcoin or to other applications. So I'll stop there. Thanks.