 which is our programming language, REACH, which is designed for helping you adapt in as easy a way as possible. I'm going to talk a little bit about our organization and the structure of the REACH programming language, but I want to spend the majority of the time today doing programming of an app. Now, if you want to follow along on the code that we've been talking about, what you can do is you can go to our website, which is REACH.sh. If you go to REACH.sh, you'll get to that site right there. And if you click on come to our workshop at DevCon, then you'll see our reddit here. And the reddit has a copy of the slides that you can open if you would like, as well as a link to our git repository for this lecture. That git repository will look like this. And in the repository is all the code that we'll be writing today. If you want to follow along, then you can start from the initial version and, you know, enter code as we start. And then after, eventually we'll get to a point where we've written the entire REACH part of the program, and then we'll switch and talk about making the client-side code. And the next version is minimal. And then the final code will be the final one that's already targeted for the end of the day. So if you want, you can work those things. Now, to use the REACH language, right now, to use the compiler, you'll need to have Docker and Docker compilers themselves, and, of course, have the basic units and parameters. So if, while I'm talking to the introductory part, if you want to go to the site, click on it, and then from the base directory, go into, say, final, make, clean, mil-front, then that will make sure that you have all the Docker engines down, but if you want to follow along. But if you don't want to follow along, then you can just do this later. And there will be value in experiencing the rest of the project. Our team is Chris Winner. Chris will be the great, great, great panel. And then me, James McCartney. So Chris is a serial entrepreneur who's had a lot of experience in the space. And my background is that I am a research professor at the University of Massachusetts, Lowell. And I'm also one of the developers of the Racket programming language. So Racket is a list-based language that's very popular as far as list-based programming languages go. It's commonly used in a lot of colleges and universities. And my research is mostly focused on doing verification of progress for calls and formal verification of other systems. So the READ project really represents the culmination of bi-research. Now, our goal as a organization is to try to dramatically lower the barrier to entry to blockchain. So we think that there's a huge amount of potential in this space, but right now it's just too complicated to build real apps. And our goal is to dramatically lower that. And we'll show you that today by building something here over the next 40 minutes. Now, the idea of the READ platform is that we want to solve three problems. We want to abstract over the decentralization platform. Right now, Ethereum is extremely productive and popular. There are many people who believe that there are problems with Ethereum and other platforms. But it's too risky to invest in one of these other platforms. If you write your product in each, then you will be able to compile to any different platform. So we are trying to, we're trying to live up to the right ones right in many of these cases. The next thing that we want to solve is that we want to make sure that the dApps that people write are trustworthy. So a major and part of what we'll be talking about later is the way that formal verification is integral to the operation of each compiler and the way that we implement it. Finally, part of being trustworthy is ensuring that there is consistency between the expectations of contracts and the expectations of the clients. And the way that we realize that in the READ language is that it is not a smart contract language. It is a dApp language where when you write your program in this one language, you get the clients that will drive the behavior of the contract as well as the contract itself. And there's a guarantee that there is consistency. Now we have some interesting techniques that we use to do that. And I'll talk a little bit about that before we focus on the code. Now one of the ways that we get the abstraction of being able to provide to go to many different decentralization platforms is that we have a very straightforward constrained model of what a blockchain provides. Our idea is that we really think of the blockchain as providing common knowledge about a monotonically increasing dangerousness. And those adjectives, you might say, they really constrain all the ways that we look at what a contract or what the clients provide. The contract is this repository of knowledge and the clients react to that information and attempt to add things to it if necessary. And so I'm not going to go into the details here as much as I do to understand what our big picture is. Now the other principle that we use inside of REACH is that the REACH language performs a lot of sophisticated analysis on your code. At the most basic level we have a sound type as you should expect in a modern language. In addition to that, however, we have analyses that are particular to the needs of depth. As one little example, one of the things that we'll see later is the way that REACH uses information flow security to guarantee that secret information that is known only to go to their clients is not shared without being explicitly declassified. Now the way that we do verification is that we take the program written in REACH and we convert it into an SMT problem. SMT is one of the classic problems of computer science and there are many extremely reliable form and theorem providers like C3 that can automatically discharge through public applications. And so a major part of the way that REACH is structured is to make it so that we can automatically produce this SMT problem. Our goal is to provide formal verification without any interaction from the user during the proof process. So that means that we have to be able to discharge all of the public applications automatically. And the only way that we can do that is having a highly sophisticated approach. Now we have a lot of different kinds of properties that can be expressed inside of REACH programs. At the highest level we have basic systems level properties that should be true at all depths. Think of like if you're programming a C program, you never want to have a null pointer exception. And you don't actually need to know anything about the program that you're running to know that it should have that property. So similarly, part of REACH is to automatically synthesize properties like this to make sense for all projects. On the other hand, we also have the ability to write down particular properties of relevance for one application. In the same way that when you're writing a C program, you will have custom assertions that only make sense for your program. So we have the same logic inside of REACH. And again we'll talk about this later. Now the next thing is that as I mentioned, the REACH language provides the entire program. We use a process called endpoint projection to extract each of the individual pieces of the program out. Again I'll talk about this in a moment. So that's kind of a roadmap of where I want to go. And now let's switch and dive back into the code. Now I want to say actually one more thing, which is that REACH is the culmination of another DSL that I worked on previously. Another company making open source products called Elacris. And that other language is called Elacri. And Elacri is also available and has, we've diverged development for the last few months. And there are different features in the Elacri language as the REACH language. And I'm very happy to talk to anyone about what those differences are offline. But I want to make sure that they acknowledge the background of the project. So now what I'm doing is I'm going to switch and go over to the repository. So in the repository we're going to go into the initial directory. And this is the code that we'll be working on. Now if you open this there's going to be a lot of boilerplate stuff that's to make it so that it can run effectively. Let me just comment a tiny bit about this before we open to clarify it. So when you use REACH, to make it so it's as easy as possible for all of you to use, everything is entirely dogarized. So when you run the application, when you compile the application it compiles it into a Docker container that you can then run. That Docker container is automatically configured to connect to a test network that it also spins up and goes. So you don't need to worry about that part of testing. Similarly you don't need to download or install anything like REACH compiler. The REACH compiler is the shell size down to the bottom which is eight lines that configures a Docker instance for you. So there's a lot here that's going to make it so that those things will all sync together. But we're going to be inside of this file right here multi-sig.rsh. That's going to be our REACH program. Here's what we're going to start off as. So in the REACH language you are writing in a subset of JavaScript. So the syntax is exactly the same as JavaScript. Almost all normal JavaScript features are available and they mean roughly the same thing but there are many special things. So for example let's start by talking about what we're going to build and what the overall model of a REACH program is. What we're going to build today is an abstraction of a multi-signature wallet. The key idea of a multi-signature wallet is that many people collaborate to tool funds and then when they extract those funds other people have a say on whether or not the extraction happens. So we're going to abstract that idea to two accounts a parent and a child. The parent makes a deposit on behalf of the child and the child can attempt to make withdrawals and it must be explicitly approved by the parent. So this is not a product that when we're done today we're going to launch and become blockchain millionaires. This is an abstraction of what kinds of problems people attempt to solve on the blockchain and it's small enough that we can do it in the next 30 minutes. So the first thing that we want to do is we want to specify that this protocol involves two different participants, the child and the parent. Inside of the REACH language one of the things that you do is you specify each one of the parties and then we'll write one program down here, this main function and this main function is going to encode the behavior of all of the participants as well as all of the smart contracts. So the first thing that we'll do is we'll have the child attached to the contract. And then having the child make a publication. Now the idea of the blockchain is there's this monotonically increasing data structure of the history of all events that were added to it. In this case we think about that as being a publication to all of the other parties. So when we call child.publish we're saying that it's the child's responsibility to publish this information. Now it turns out that there's actually nothing that the child knows originally that they're going to connect with. Now every time you expect to see a message on in the protocol we have to say what would happen if the person who's supposed to do this didn't do it. What if they time out for instance. And so we always specify what will happen in the case of a timeout. And timeouts are expressed in terms of how many blocks you're willing to wait for a message. So we're going to just have this variable in our program, delay seconds, and if it doesn't then we'll fail. And the way that we'll fail is that anyone that's what this underscore means, anyone is able to submit a message. And what this message does is it will commit the transaction and then say that we have finished writing the protocol. And the reason that I'm returning this array of zero and zero is because at the end of the protocol when we're finally done we're going to return how many times the parent said yes and how many times the parent said no. So if the child times out and never joins the protocol then we're done and so no events actually happen. Now after we do this now the code has transitioned down here. And we're now inside of the contract. So at this point we need to verify anything that must be true above the publication. Now in this case nothing was actually published so there's nothing to say so we commit the transaction. And now we go back to a context where we're outside of the protocol. The idea of the reach language is that you switch between local blocks where a particular agent or many agents are simultaneously doing things. And then synchronization or consensus blocks. And in those consensus blocks all of the parties are doing the same thing and they agree on all of the information that they're getting left. Let's do an actually interesting example so after the child has joined the protocol we now want the parent to. So we're right parent dot only. So this is something that only the parent will do. Now what do we want them to do? We're going to have them run a function and so we'll specify that as a function of no arguments. And what they'll do is they'll compute what the allowance that we're going to give us. Now notice that it's a circumstance where it makes sense that at this point in the protocol the parent is always going to decide what the allowance is. But in our reach program like how do we know what you, the particular parent, are going to give to Sally before she goes on her, you know, it's a pretty great trip. How are you going to know? Well there's two ways that we can do this. The first way is that notice up here when I wrote, when I defined the parent, I said this empty object right here. So in this spot you can write initial information that every print, that that participant starts the protocol. So we could add in here knowledge of what the initial allowance is going to be. Instead what we'll do though is that we will interact with the front end. So we'll call it interact. This is a special object inside of the reach language that represents the client that will ultimately run the parent part of the protocol. So we're going to take that object and we're going to call allowance on it. Now let's return a value and we need to assert that that value is going to be an integer. This value right here we want to eventually provide it. So we'll go next and we'll say parent.publish the allowance. So we're going to publish to the rest of the world that the allowance that the child has access to is this number. Now unfortunately if we try to compile the program right now, it is going to fail. And it's not going to fail because I have this dot here. It's going to fail even if you let me fix that. The reason it's going to fail is that this program fails to satisfy the information flow security system. The reason why is that all the information that comes from the client, from the front end, is assumed to be secret information. They must be explicitly declassified. So what we'll do is we'll call declassify and now we've declassified it and we're allowed to puncture it. So good. We've made some progress. Now the next thing that I want to talk to you about is how every time we make a publication we can combine that with a unit of value that will be transferred to the client. So we'll write that by saying pay. So we'll actually pay the allowance and we'll write down the time out code. So every program, every interaction on the chain must be accompanied by what would happen if there was a time out. We refer to this property as kill safety. The idea is that your program has to be safe with respect to any participant refusing to engage in the protocol at every point going forward. So in this case what we're saying with this time out block is we're saying what if the parent never did this collaboration? What should happen? Now with these early stages of the protocol there's really nothing interesting to say. That's why they just end. But in principle as we go forward there's going to be more interesting interactions that are going to happen inside of the time out block. So now at this point we are now inside of the contract. The contract has access to the allowance and we need to go forward. The thing that we want to do going forward is we want to have a little while loop and this little while loop is going to repeatedly allow the child to ask for a fuss. So we'll write a while loop plus that we're done. Well the condition that's going to tell us that we're done is that the balance is going to be zero. When the balance is empty then the program will be over. Now while it's not some special variable we're going to have to do that. We're going to have to keep track of the balances. So we're going to say that while the balance isn't zero continue running this part of the program. So we'll define a new variable called the balance. It's going to be equal to the allowance. Now just so that we have something interesting to return what we want to do is we're going to keep track of how many times we said yes and how many times we said no running the program. Now how many times the child asked for money and the parent said no. We don't mean this isn't that important. We just want to keep track of something. And then that's the information that we're going to return at the end. One last thing that we need to do and it's actually kind of a big thing and you have a while loop. The while loop represents a point in your program where many many different things can happen. There's a version of this program that runs where you reach this point and the allowance was zero. And since the allowance was zero we never execute the code inside of here and we go right to the end. There's another version of this program where we run the inside one time and after running it one time all the balance is gone and then we exit. There's another version where we run it two times and so on. There's sometimes an infinite number of different ways to run a program that has a single while loop. Depending on how many times you go around the end. So this is a big problem for formal verification because how are we going to know what the program will actually do because the way to internalize what formal verification is is you're making a prediction about what the program will do. Now one way that we could do this is that we could automatically take the program and verify it for when we went zero times. Verify it for when we went one, verify it for when we went two, three, four, five, six, seven, eight, nine, ten, etc. What we would be doing is we would literally be like copying and pasting this code inside of the verifier over the overhand to verify each one of those different versions. That's called iterative deepening. An iterative deepening is what you do in situations where you can't figure out how to capture that into the paper. We do not do that. Instead what we do is we have a programmer specify a loop invariant. Now if you remember from your analysis of algorithms course where you use the CLRS book, this huge computer science book you probably learned a lot about loop invariants. And if you're like me, you hate it that class. It was very frustrating. Most of the time though the key idea of a loop invariant is what do you know before the loop starts and what do you know at the end? So the thing that we know is that the balance in the contract is equal to this balance and if anything that we do inside of this makes it so that that statement is false, then we'll not be allowed to compile this program. And what this is going to do is it's going to allow the compiler to verify this more efficiently. We're going to verify everything above this to make sure it establishes that invariant. We're going to verify the inside to make sure it reserves it. Then we're going to verify the end so that it also verifies it. What this means is that we provide complete verification of an infinite behavior of your program by just proving three smaller theorems. Alright so now let's go inside and do some stuff. We're inside of the context of the consensus so we have to commit the transaction and now go back to the world where the two participants can do something. And the thing that we want to do is we want the child to do something herself. Where she's going to ask for a certain amount of money. And we know that this money will start to be classified and it's going to be a number and we'll interact with the customer, sorry the front end, to request the money. And the way that we're going to do this is that we're going to tell the front end how much money is in the account so it can know how to display to the user. Sadly do you have $100 available to you? How much do you want? This interact object is not only a way to get information from the front end, it's a way to share information with the front end. So it's a two-way street. Essentially what's going on is that this reach program is specifying the API to the contract, the API to the clients, sort of the API to the back end and then we'll write on some client code afterwards. Now the next thing that we need to do is write an assertion that's going to say that how much money is going to be in the account. And it might be smaller than or equal to the balance because this program wouldn't make sense if that were not true. This Assertion function right here is one of the verification assertions that we can put in. I mentioned before that there are different kinds of assertions that we can put in. Assertions are things that always can't be true and if they're not we refuse to let you compile. Assumes are kind of like require insolidity where we actually check this property at runtime but the other thing that we do is we make sure that all the assertions later on in the program are entailed by these assumptions. So later on in the program we're allowed to write down asserts and if any assert would fail because you forgot one of these assumes then we'll refuse to compile your program. The idea is that we're guaranteeing consistency between the clients and the contracts. We're making sure that your program at runtime actually verifies all the properties that are necessary for your contract to run correctly. So now what we'll do is we'll have the child publish the amount and we'll write in the timeout code. And the timeout code will be available to the parent to run and if she times out then we'll just say that it is an automatic ignore. So it's not a yes or a no but we just continue the protocol. So what happens here is that rather than returning at the end we say that all of the variables that the loop is iterating over they stay exactly the same and then we continue the loop to the next iteration. If we want to do we can say that if the timeout happens then it like goes in favor of the child that she gets from it. It's up to us to explain what we want to do. This by the way is one of the examples that the reach language is different from my earlier project the alacrity language. Because in the alacrity language the timeout blocks are automatically generated on your behalf. You're not able to but also you don't have to specify what they do. Instead they automatically end the protocol and give all the money to the last person in the contract. So now we're inside of the contract and we will require that how much is less than the balance. So this protocol only makes sense going forward and how much is not more than the balance. Now it looks like what we're doing is we're saying something twice. We're saying it up here and we're saying it down here. And of course we literally wrote down how much less than balance two times but we did it for totally different reasons. What we're doing right here is we're saying that this protocol makes no sense unless this is true. What we're saying up here is that I am a bad client if I don't check this properly and you have to specify both of those things if you want to have a correct program because you're writing down the client and you're writing down the contract. And one of the things that we'll do in the verification process is make sure that the contract only interacts with good clients. So if we left out this line then this line will fail to verify and it will say you need to have your client check with how much is less than the balance. Because of course in the actual and like your actual front end, you don't want to submit a transaction and have that transaction fail because you failed to check it before. So then we'll commit the transaction and now we're back to a local context and we'll have the parent go find out that she is approved. In this case we'll get back a Boolean because the interact object doesn't only return numbers it can return arbitrary information. So we'll interact and we'll say we'll all approve and we'll tell the front end here's how much she asked for and here's what the remaining balances. Then what we'll do is we'll publish that and we'll have to deal with what happens if there is a timeout. And we'll do the same thing as before whereas if there's a timeout, if the parent never gets along to it then in this case we'll call that a no and we'll continue. So now we're back inside of the context for the contract and now the contract knows the balance. It knows how much money was asked for and it knows whether the parent approves. So at this point we can actually make the transaction. So we'll say if the approval is true then we'll transfer how much to the child and we'll update our state variables. We'll say that the balance is less than than how much. We'll say that there's been one additional transaction that was a yes and no no's and then we'll continue. And otherwise what we'll do is we'll say that the balance is unchanged. The okays is unchanged but there's another no. And we'll continue. And then at the end we'll need to commit the final transaction when the balance is empty and then we'll return the okays and the no's. So we just wrote 63 lines and I hope that it felt not too weird. It doesn't feel like writing solidly. It doesn't feel like writing a smart contract. It feels like writing the whole down. In behind the scenes what we're going to do is we're going to automatically synthesize the front-end code and we're going to automatically synthesize the contract. Now let's go to the terminal and see what typos are made. So the whole type make build and what it's going to do is it's going to run the compiler. Oh, I made no mistakes. So I don't know about you guys but I'm a professor and a lot of times my students make mistakes when they write paragraphs. This is why you shouldn't hire them to write your verified compilers. You should hire me to write your verified compilers because I do it right the first time. Now let's go back and look at what we wrote. Now what if we made a mistake? So obviously this would be totally stupid. But what if we accidentally subtracted how much and then added one? There's an off by one error in our program. I've never made an off by one error in our program but I've heard a bit of it. So let's try to compile and see what happens. I'm suspicious that maybe it's not looking at this file. Hmm, okay. I'm really nervous. Let me just look at a different thing. What are the annoyances with doctors and sometimes it doesn't copy things you think it's going to copy? We'll hold on to talking about that for a moment. What I want to show you right now is what we made, what the compiler produced. So here's the directory and we'll look at the salivary code that was generated. So right now the reach language can in principle produce things other than a theory but right now we only target a theory. So this is the contract that came out. So this program, this contract is certainly laborious. So it's 152 lines. You can look at it if you want. It's in the mill directory if you're running yourself. And let's just look at like one little part of it. So let's look right here at message 6. So message 6 is a message that has all these parameters. And let's try to see if what's going on. So it says right here that it must have come from v0 that the block number is less than the delay going in there. The value has to be 0. This is saying that this is one of the messages that doesn't have a payment with it. So v17 has to be smaller than v8. That's how much v8 was the balance. Then what we do is we commit that and then update the state. So with this messages, this event number 6 is the sixth thing in our program which is this step right here. This publication right here. When the child says here's how much I want then we go to the contract and we require that how much is that. I realized by the way why the compiler allowed us to comment on that line. Because I actually commented on the line that was the assertion rather than the line that made sure that the assertion was right. So I believe that if I comment on this one we'll get there. Alright now I'm really nervous that something weird is going on. Sorry. So now let's look at the jobs we've got generated. So just the jobs we've got generated is the code for the child. So we get a new file that's called child that takes as an argument that handles for the contract. We'll see this get made later. And the interact object. And then it goes through and has each one of the pieces of the program. So we just make a new window for a moment. We can compare the two of them. So for example what the first thing that the child does. The child calls request on the interact object. Gives it the balance. So the very first thing is that we publish nothing. And then we're going to wait for the parent to publish the allowance. So if you look at the code the very first thing that happens is that the child sends and then receives message one with no information expecting to receive event one afterwards. Or event two if there was a timeout. We check to see if there was a timeout. And then what we do is we continue the protocol where then we expect to receive event three. And event three comes with this information that will end up being the allowance. So this rest of the code right here is no code that a human would ever write. But it's a very straight forward output of a compiler. It has wonderful things like let B9 equal zero. Because what's B9? B9 is the count for how many times we said okay. Alright so now what we've done is we've written our programming reach. We've compiled it. Behind the scenes it's done verification for us. And we now have the JavaScript code and we have the salinity code. But this JavaScript code that we have the only thing that it does is it provides these high level, these high level functions to spin up a child and to spin up the parent. We skip down. There's the limit of parent. And then we also invent the details of the contract. Now we only have eight minutes left. So we're not going to write by hand the front end code. Instead I'll show you the front end code. So what I'm going to do is I'm going to go out of the directory and go into the minimal directory. And go look at the index.mjs file. So the first thing that we'll do is we'll import the standard library. We'll import that multi-sync program. We'll say that our starting balance is going to be 130 because we're going to test this on them now. And then we'll script a new account for the parent that has that starting balance. And that's going to deploy the multi-sync contract so that the parent will deploy. Then what we're going to do is we're going to define the interact object. And for this first version, I'm going to say that the allowance is always going to be 50 either. So I just write this function that when you get the policy allowance, I'm going to be either. Now if we're making like a real application you know I might have it pop up a web browser window. You know what I mean? Like actually do a real interaction with the user. Then we're going to write our approval function and this is a really nice parent. Their approval function is true. Because this is just for testing purposes. Then what we'll do is we'll define that we'll go off and we'll run the parent function. So we'll call a multi-sync dot parent, give it this contract object that you're going to deploy, give it that interact function, and then we'll get back a promise for the answer that will eventually come out of the parent when it's done running. We'll do something similar with the child. We'll start it off with the balance. And just because I'm lazy in this test, I made the starting balance exactly the same. So it's a personal money. But the thing is that then you have some money to provide the gas rate. Then the child will attach to the multi-sync contract. And when you attach versus deploy, you have to say what the address of the contract is and when it was created. You need to know when it was created so that you know that it's not sending things the whole time out. Now the child, it's going to say I'm agreedy-tied but what I want to do, my request is everything. And then we'll ask for the parent who will make a promise for what the child will do. We'll await those two and then we'll finish. So let me just pop back for a moment over to the caregiver here and we'll make, run, spawning up a devnet, starting to get, waiting for it to be around. Let me make this the text bigger here. It's actually running it. Really nervous for my live demo. Now it ended and it said the parent thought there was one okay and zero no's. The child thought there was one okay and zero no's. So what this code shows us is that we have 28 lines and we're able to take our multi-sync program that we wrote and write the wrapper front-end code that deploys it. So this code is the minimal amount of drop-through code that we would need to write to have something useful. You would take this structure right here and you would build your unit testing library for this particular dev based on this. Now let me show you one more version that does a little bit more interesting stuff. So what this version is going to do is it's going to be 41 lines. So it's like twice as long. And what it's going to do is it's going to print messages about what's happening. And the other thing that's going to be different is that the parent is going to say that you can have any time you ask for money as long as you ask for less than half of what's left. We'll say yes. You can ask for whatever you want as long as it's less than half. And what the child is going to do is the child is going to ask for a random amount of money that is divisible by an eighth of what's left. So why am I doing this? Just so that it will print out less than half. The child will completely ask for random amounts of money in eighths until eventually it gets down to the point where there's only I think one eighth of what's left and then it will end. So this new version of the program is going to be more like exciting to watch. But really all I'm showing you is that I'm not developing that app anymore. I'm making a user interface. I'm making a policy for what the parent does I'm making a policy for what the child does. Maybe here is an automated policy but you could have it be instead not the automated one but one that is provided by a user interface. We'll walk back to the code for a moment and we'll build in that mess. And I just love text printouts. This is going to be my favorite part of the talk. Let me make the text a little bigger so that you can really experience this. So they deploy the contract. Okay, ask for it. Put it in 50, ask for it out. Okay, look at this. There's lots of transactions happening here. And then it's running for a while. Eventually it's going to get down to the point where there's only one left. It's going to take a while. We get lots of randoms. It's so close. And then we end it. The parent said yes 13 times and no 13 times. That's the reason that's the problem. So what we did today is we wrote an entire doubt from start to finish in 30 minutes. Now I wrote it. Maybe it'll take you longer than 30 minutes. And what Rich did for us is it abstracted over the decentralized action platform. In the Rich program there's no point at which I said here's this complicated solidity idea. Did I do call or is it transfer? Maybe it's supposed to be send. Let me go look at that Stack Overflow question again. These are the kinds of things that are done that are decided for you correctly by the compiler platform. The next thing is that we verify that the doubt is trustworthy. Or at least we would if my doctor configuration was right and copied the files correctly. So if you want I'll send you. We'll post the link to the version of this walkthrough where we show the verification conditions failing and then showing how to correct it. And it ensures that the clients and the contracts are consistent. Our 40 line reach program produced 300 lines of front end job search code and solidity code. And the details of those two programs have to be meticulously connected with one another to make sure that it executes correctly. Now obviously the 40 line version produced in 300 lines that has to be right. If you wrote a real program, not this little model, clearly it's going to be much more important in this part. Now, right now we have our data that has many different, many constraints. I don't have to talk about those with me later. And we have a release plan for over the next year to expand the set of features about it. I'm very grateful for you to have come here. Please check out our website, Resatization and please look at us on Twitter and all of the social platforms. You should really check out our Instagram account. I've got a really cute cat that's part of Resatization. And finally I just wanted to re-emphasize that Reach was originally a project that I worked on with the Lackere company. And Lackere is also an available tool that's based on the same principles. And yeah, so thank you so much for your time.