 So, I'm going to talk to you a little bit about the design of Plutus. How many people here actually work with smart contracts? Right, a relatively small number of you. How many people are aware of all the exploits that occur against Ethereum? Okay, that's more of you. So I actually found a place where they've got a documented list. So this is a site called DASP.co, and this has all the main ones. So there's DAO, which lost a huge number of Ether. That was about, I've seen different estimates, between 50 million and 150 million US dollars at the time. Ether's gone down a bit since then. And then there was the two parity multi-stake bugs. So this one lost 150,000 Ether and then this one lost, right? So this was stolen. But this actually just got locked up. Nobody could ever get at it again, and that was more than 500,000 Ether. So those are the three main ones, and then you can see there are a bunch of smaller ones. And this is the most recently reported one, but I am sure this list is going to grow, right? When Charles talks to me about saying, yeah, we're going to have a strand for running Solidity and the EVM, I say, great, yep, you are guaranteeing to all your clients on that platform that they are opening themselves up to more exploits. So the question is, how do you avoid exploits? Some of the exploits against Ethereum are just like, well, they don't deal with overflow. Okay, that's really stupid. Let's catch overflow. But other of them are more subtle. And so I think it's a really interesting research issue what we do about this. And some people just say, well, we'll verify things. But all right, that's good. But what exactly do we want to validate and how do we go about doing it? So they're interesting research questions here, I think. So, right, IOHK has three smart contract languages. There's Marlowe, which is a higher level language for those of you who know Simon Payton-Jones work with Mark Eber. And do you remember the third author? I always forget the name of the third author, which is not fair. Stuart? Yeah, Julian Stuart. Julian Stuart. So that paper appeared, that was actually one of the first functional pearls. I was chair of ICFP and we introduced functional pearls and that was one of the first functional pearls, was that paper. So that's had several descendants, including Fritz Henglein's deontic work. And one of the advantages that we've just been chatting with the deontic people. And the really interesting thing there is that you don't need programmers to write the scripts. There are people who are called business engineers and they talk to the business engineers. And then the business engineers can take over the maintenance of the script. So you don't need programmers, which is great. So some kind of high level domain specific language, I think is going to be very important in this space. And so Marlowe's exploring how we go about doing that. So Marlowe will then compile down to and run on Plutus, which I'll tell, I said a wee bit about this morning. I'll say a wee bit more about now. And then Manuel will be talking about it this afternoon. And then there's a third strand, which is software verification and Gregorio is here in the audience. So runtime verification has been pushing the K system for a long time. So when I first saw, so K just lets you write down a specification as rewrite rules. And then it actually will execute it for you. So they've been improving that and they're getting reasonably fast execution now. So they've got a K model of the EVM that actually runs close to the speed of the C++ implementation now? Not yet. Not yet. So it's factor of ten. Factor of eight, okay. So either one order of magnitude if you're decimal or three orders of magnitude if you're binary. Ten, three, it's ten orders of magnitude, are you there? Right, so there's the K system. I actually had something for a long time called KNV. When I was working on my textbook on programming language foundations in Agda, I thought, well, we want to animate this stuff. It took me a long time before I realized, wait, as soon as you prove progress and preservation, you have animated the stuff. But in K, but that's not going to be within a factor of eight of the EVM. So K is very interesting, and then they're looking more and more at how you extend K so that it supports validation as well. But it gives you a very nice, and I didn't really trust this. I thought, well, wait, no, it's a concert where you actually write down a spec and then prove the compiler correct. You've done it twice, you've got the spec, you've got the compiler. So that will give you high reliability. I thought, I bet K has lower reliability. So there's a K implementation of C, and we thought, right, C Smith found lots of bugs in implementations of C. Let's try out the K implementation, which is just writing down a very large number of rewrite rules, and I bet that will still be buggy. And we have found only one bug in it. At the same time, we found only one bug in CompCert itself, in the bit that's not yet verified, because they've added new stuff that's still not verified. And oddly, in the major things like Clang and GCC, we found zero bugs, we were really surprised by that. So those systems have gotten quite mature. But K did very well. I was expecting it would do worse. And I went back to Grigory, I said, how did you do so well? He said, we test a lot. So even if you're doing specifications, testing a lot is very important. But anyhow, so K has some impressive results, and they have something called ELA, which looks a lot like LLVM. It's at about that level. So I think that's too low level for the blockchain. But if you like that sort of thing, then this is a strand that's moving forward also as a smart contract language to run on Cardano. Did I cover enough there? One of the important things you want to do, as I mentioned with smart contracts, is reason about them. And what I'd really like is, is there some property that I would expect a smart contract to satisfy, such that if you could show no, it didn't satisfy, you would have caught something like the DAO exploit. So if you work in concurrency, the people in concurrency say, yeah, we would never would have done that. But that's easy to say after the fact. Could you come up with a general purpose thing that if you'd actually tried to validate against it, would have caught the problem in advance? And I still don't know of such a thing. So if you did something like check that the total money compares to exactly what the ledger says should be there, that would have caught it. But that's not a general purpose property. So are there any general purpose properties? So in programming languages, we have things called progress and preservation. These are very different than those, but I gave them the same name to be cute. And the idea is progress says, well, if you've got some kind of contract, can you guarantee that it always is going to be able to take a next step? That it won't get locked? That maybe if one person decides, nah, I'm not gonna do anything. That the contract doesn't progress. That can also be a problem in the real world. So you'd really like to have a guarantee that the participants in the contract can always move it forward. So that would be an interesting thing to validate. Another thing is preservation, which is just that you never want the contract to lose money. That the sum of available money that people can get at will always stay the same. This would have caught that last parody bug that lost 500,000 ether. Because that's a violation of the preservation property. And I mentioned these in a recent workshop on smart contracts. And Massimo Bartoletti was there. So they have something called BitML. That's sort of like a cut down version of Marlowe that you can actually run on the Bitcoin using the smart, not very smart, contract scripts that they support. So I have a limited language for scripting. But that's enough to support BitML, which is very similar. And then Massimo said, oh yeah, that he's looking at something very similar to preservation. But my formulation here is rather high level and vague. And he has a quite precise formulation that works for BitML. And in fact, it corresponds to both progress and preservation. So they have formal proofs of those for BitML. And I'm pretty sure you could prove those properties for Marlowe as well, so that you can just say every single Marlowe contract satisfies these properties. So that's the beginning of a way forward. But I think we need much more work in this area. And so I'm really glad to have an audience of academics here where I can say, I think this is a really interesting problem. If I can encourage some of you to look at that problem, I think that would be a great way forward. OK, I did have a bit in here about formal methods at IOHK. But to stick to half an hour, I'm going to skip over that. But that's OK, because this afternoon, Duncan Coots at the main session is also going to be talking about exactly this. So you're not losing out on anything. In fact, you're going to get it straight from the horse's mouth, as it were. So I won't talk about that. What I did want to talk about a little bit is how we deal with integers, overflow, and precision in, there's no clock in here. Right, give me a moment. I'm going to try to pull out my phone so I can keep track of the time and not go over time. That would be a bad thing to do. Right, I'm going to say a little bit about integers, overflow, and precision. So I already mentioned that, oh, let's see, do I have any? Yeah, I do have data now. So as an example of this sort of thing, there's something called Monero Gold. Now some of you might have heard of Monero, which is a popular cryptocurrency that's popular because it uses zero knowledge proofs to preserve privacy. Monero Gold had absolutely nothing to do with Monero except for sticking the word Monero in its name to try to get people to buy. And they succeeded pretty well. They had a market cap of that's not actually $2. That's $2 million US, was their market capitalization. And they did have a peak and then went down. But then you can see here they went down very steeply. And that was the guys who created it cashing out. And the way they cashed out was very interesting. One thing in the contract that people write, everybody can read the contract. That's why you're supposed to trust the contract because you can read it. And one thing they said, OK, you can actually get rid of a certain amount of money. You can take some money that's there and burn it, make it inaccessible to everybody. But you notice what this does not do is check that the amount that you're burning is an unsigned in, so it must be positive. But there's nothing to guarantee that it's less than or equal to the actual balance. So you could make it greater than the balance and you would underflow. And all of a sudden, there'd be a very large amount of money. So in fact, it was this amount. That's a lot more than the number of grains of sand on the earth. Possibly more than the number of fundamental particles in the earth, I'm not sure. And it was a very, very large amount. And they had a huge amount that they could just sell off very quickly. And that was why it went down from $1 million to zero very rapidly. And they just put that in their pocket. And that was thanks to this underflow not being caught and nobody noticing, oh, wait, you could underflow there. But it was very deliberate that they built that in. Many of these things are just poor programming practice. This was a deliberate scam. We don't need that. OK, so how do you avoid this? So one way you do this, and this was the first idea that occurred to us, is to have unbounded integers. So Erlang has unbounded integers. And this is really great because, say you deploy, so Erlang is used, was created for writing phone switches. So you've got a phone switch out there. And it's out there for a long time. It could actually be out there for long enough that your 32-bit word overflows. And your counter goes back down to zero, which could cause serious problems. If you were using this for, say, to count phone calls and tell when one phone call was later than another one. So they just said, fine, we'll get rid of that problem. We'll use unbounded integers. This is a great idea. So we thought, yeah, we'll use this same great idea. We'll have unbounded integers. But one day I was in the shower thinking about this. I thought, ah, well, of course, for smart contracts like Ethereum and like Plutus, what you make use of is gas that's charged. And that prevents somebody from submitting a program. It'll take a really long time to run. And essentially, that actually creates a denial of service attack against the blockchain because all the people trying to create blocks are running this program that runs forever. So what you do is you submit gas, which costs money. And each operation costs you a little bit of gas. And when you've used up the gas, you stop. It's very important that the cost of the gas is actually proportional to the amount of computation that you do. Because if you're charging too little gas, you're still open to this kind of attack. And right, so in Ethereum, there are 256-bit integers, which is a constant cost for arithmetic. Fine. Wait a minute. We're using unbounded integers. I just thought, oh, yeah, well, we'll just charge a constant cost for arithmetic. I'm in the shower, right? And this happens. You should all have Bernard Herrmann's shrieking violins in your head. And I'm thinking, wait a minute, unbounded integers. That's not a constant cost. So we have to charge a cost proportional to the number of bits representing the integer. And that means you don't know what number is going to be in the integer. So it's actually, instead of working out the cost statically at compile time, you'd have to work out the cost dynamically at runtime. So you can do that with gas. Gas is dynamic. But if you actually want to compute in advance how much gas your contract's going to use, it suddenly become a lot harder. Because instead of counting a constant cost for each arithmetic operation, then you would need to count a cost proportional to the actual size of the integer. So you've got much more work to do to work out the cost. Anyhow, so all of a sudden, oh, wait a minute, what do we do about this? So we thought about for a long time. So Iyela just uses the unbounded integers. And as a result, you actually have to determine the amount of gas at runtime. We ended up deciding on a different choice for Plutus, because Plutus has this nice polymorphic kite system, as I mentioned, based on system F. It's actually based on system F omega, which means we can have types like list of A. But it also means you can have integer of size S. And that fits into exactly the same framework. So we have actually two different kinds. One is kind type, and the other is kind size. So you know about sizes as part of your type system. So that means you know about them when you write the program. You know about them at compile time rather than at runtime. So we've got type integer of S, integer of size S. And then we know how much gas to use at compile time rather than at runtime. Now, it does force more work on the programmer. The programmer actually has to think, what do I want S to be? And our argument is, no, that's actually a good thing in this case, forcing more work on the programmer. Because they should think, what size do I need? Given that, it's going to cost more as the size gets bigger. So you don't want to just go for unbounded size, because then the cost could be unbounded. You want to think, what's the appropriate size to use, given that this is going to interact with how much gas I need to pay for. There's a system called Resource Aware ML, which actually lets you work out some of these costs. And I did some work to show, yep, if the cost is constant, ramble can work out it out for a simple contract, what the cost will be. But if the cost varies with the size, ramble gets lost and can't do it. So there's a real advantage to us having a fixed size that's known at runtime. You could apply techniques like ramble to work out what the gas cost for your contract is. So one of the problems that's going to be faced by IELE is you might deploy a successful smart contract that runs for a long time. And again, if your counter passes the word size, it's not going to stop running. But since the amount of gas you use is proportional, at some point you're going to pass this boundary and you'll start using more gas. Well, if you've been running the counter contract with the same amount of gas every time, all of a sudden it will start failing because you haven't given it enough gas. So you still have this problem of things failing, but now because they're out of gas rather than because of overflow. But also at the same time, you've made the gas cost harder to compute. So that's why we decided that for Plutus, this wasn't the right way forward. It's not too late, Grigory. You guys could go to using. Yes. So that might be a reason why it's less of an issue for you. But you'd like to make it easy to verify the gas consumption. That'll be a lot easier with a fixed size. Yeah. I'm just wondering, is the arithmetic then modular arithmetic or do you get an overflow? For us, we get an overflow. Right. So we just stop with an overflow. We do not wrap around. We're going to avoid that particular bug from Ethereum. That's a pretty easy one, fortunately, to avoid. So we use fixed size integers. You have to think about what size to use. So in this case, if you set the counter a certain size and it overflows, yep, you're going to get overflowing. You're going to get an error at runtime. So you do need to think about what you're doing. We're hoping that by encouraging people to think about the size that they'll be less likely to make an error by mistake. Notice all of this is just sort of, well, I think this will work this way. I could imagine somebody making an argument the other way. The reason I'm really glad to be presenting to an audience like this one is to say, this is actually an interesting problem. We think the right solution is to use integers whose sizes determined at compile time by the type system. But there's a discussion to have here. And this is exactly the right audience to have the discussion with. So by saying all this, I'm hoping I'm beginning this process of starting an interesting discussion. And then, oops, right. One reason I want to have this discussion is what really worries me, what makes me behave like that, is thinking, well, maybe there's some other issues with overflow that we haven't thought of yet. And I mentioned this morning how important it is to have an academic community that reviews your ideas and can find the flaws. There might be a flaw we haven't thought of yet. And I want to encourage people to see if they can find any such flaw. The more I can get people thinking about that, the less likely it is that there's a flaw in their waiting to be discovered. You have the answer before or after they've exploited it? Well, often it's simultaneous, right? Because you end up publishing the exploit. And before you can fix it, somebody exploits it. That can be one of the issues. Well, may or may not be somebody else. Yeah, in one case, it was exploited by white hat programmers. They said, wait a minute. Somebody had started stealing all the money using an exploit. And they just said, we'll steal it first. And then they handed it back to the people it belonged to. OK, so that's all I wanted to say about overflow. Are there any questions about that? OK, and then I wanted to say a word or two about how data abstraction works in Plutus Core. So we're all used to the way data abstraction works in Haskell, so I'm talking about data abstraction. So of course, I have to use stack as an example. And the way you would do it is you'd have a new type, stack. And you've got some constructor make stack of a list of ints. So stack is represented as a list of integers. And then you've got create an empty stack, check if it's empty, push something on just using cons, and so on. The key trick in Haskell is you export the type stack. You export all the operations on it. You do not export the constructor make stack. So by hiding that constructor make stack, we turn this into an abstract data type. And this is standard for Haskell. So of course, that's what we're going to use for Plutus TX, because that's done in Haskell. But there is actually a much better way of doing it, which I want to remind people of. The way data abstraction was done in Miranda, you would declare stack to be an abstract type. And then you say its implementation is in Miranda, this type is called num rather than int. So it's a list of num. And then you give signatures for each of the operations, but they're just implemented in the normal way as before. The nice thing is here you don't get the definitions cluttered up with lots of uses of make stack. So with make stack, I'd have to use make stack wrapped around every list that's returned, and also wrapped around every list that's taken as input. So this is much more compact. This is actually what's supported by system F, is this style of abstraction. So at the low level, we could use this. In fact, the way things work is you have two scripts. You have one script, which is attached to the output of a transaction. So an output, some money that somebody else might spend later, has attached to an invalidator, which is a function basically of type A to B for any A and B. And then to spend it, you provide another script of type A called a redeemer. Of course, you can guess what happens. You apply the first one to the second one, and you run it. And as long as running the combination does not result in an error message, then you're allowed to spend the money. So this B is actually ignored. The point is that you've not failed before you return a B. So one thing we can do is pick the types as follows. The validator type could actually be for all of x. You've got a function that takes an A of x and returns a B of x. And that gives you a C. And then your redeemer's type has to exactly match this argument. So it's for all of x, A of x gives you a B of x. And the point is, so this is something that actually, so here we're taking an A. Here, the key thing provided by the redeemer is a B. It's given this big A by the validator. And this lets the validator define an abstract type that it passes into the redeemer. The redeemer could also define an abstract type that passes into the validator. This is showing that way around. So you just give this type signature as before, and then they pass to the redeemer the implementation of the thing, the type stack, and all the operations on it. So this lets us support data abstraction in a very simple way. And the point is this lets us do as modular a system as we like. So we can compile any kind of modules down to this. Now one thing that you often have in a system is data types. Right, so you declare some type like NAT, which is either a zero or a successor. Anybody who knows Haskell or any other functional language will be very familiar with these ideas. But this pattern matching here is my argument is zero or is it a successor. If you've got data constructors, that's a special operation. And then if you want to have a module system, you'd have to say some way of saying what the constructors are and in particular what the deconstructor is so that you could import that from some other module. Now there are various ways of doing this. Standard ML has different ways of doing it. I guess Haskell with backpack now has ways of doing this. But nothing is standard. Nothing is 40 years old like system F is. So we just thought, right, we'll just use system F or I suggested, let's just use system F. We won't have any data constructors and code data instructors. There's a standard way of doing this called the church encoding. Church encoding you actually don't want to use because computing n minus one takes time proportional to n. And you'd like to compute n minus one in constant time. So there's something else called the Scott encoding that lets you do just that. It depends on being able to do recursive type definitions. So the type NAT is just the deconstructor for NAT. So that says this is the zero case, this is the successor case, and the successor case for that branch you're of course given the previous natural number and then you return a value. So this just represents natural numbers as their case expressions. It's just a function. We know how to deal with function so all of this can be dealt with in system F without any difficulty. So that's why we went for system F omega and we don't have any constructors or anything. Constructors would be much more efficient. We don't care that much about efficiency. All the time in a smart contract is going to be spent on cryptographic validation. So the rest of it is very little so we don't need to worry about that. And then you get Plutus Core and I've got a definition written out here but you've actually got a more precise definition of the abstract machine, the CK machine for Plutus Core written out on napkins that have been handed to you. We also have an investigation of it written out in Agda by James Chapman and he'll tell you a little bit more about that but I just wanted to give you. So Roman, when I was writing my textbook I read a lot of stuff written by Roman and then we ended up hiring for IOHK so I was very pleased. But then Roman was very impressed by what James had done. He said, I haven't talked with James except for a couple of messages but I read what he wrote in Agda. I'm very surprised that you can formalize system F in a non-disgusting way or at least I do not see those huge clunky theorems which I see everywhere including in my own attempts. So I was very pleased that IOHK could hire James Chapman to do this for us and he'll tell you a bit more about what he's doing in a few minutes. I'm gonna end with a shameless plug. One reason I was glad to be using Agda is I've just written a textbook about programming language foundations in Agda. It's available on the web. That's me at the Brazilian Symposium on Formal Methods where I was two weeks ago and the paper that I wrote to describe PLFA actually won first place. I was very pleased. They also asked me to chair it next year which is I'm not sure to be pleased or that or not but I think I'll be pleased. You should all present at SBMF next year. It will be great. And so you can just look at it online there or you can fetch it from GitHub there and this is particularly great because if you find any typos or anything else I've done wrong you can fix it yourself and send me a pull request. I've received huge numbers of pull requests from people sending small fixes to the book. So I encourage everybody write your textbooks this way you can get your audience to fix it for you. And that's me. Thank you very much.