 Hi, I'm Jeremy, co-founder of Funfair. We've spent the last 18 months building a platform that uses state channels, which is now live on Mainnet and has been for about a month. So, realistically, I'm going to talk to you today about our experiences that we've learned over the last 18 months doing this. So, what is Funfair? Funfair is a casino platform which allows a wide variety of games to be run in real-time, but the gameplay is backed on the chain using state channels, as we will be talking about today. So, I'm going to blast through this. We have a fairly specific form of state channels that we've developed for our application rather than developing something massively generalised. So, we have a two-party bi-directional channel and we support a fully generic state machine. So, we will support state machines that pretty much can do anything. As long as it can be expressed in a contract hall that can be executed on the chain, I'm going to talk about that in some detail. We also provide an integrated RNG into this, which is a form of a complex commit reveal scheme using hashes. It's deterministic but not predictable, and we feed essentially one random number into every state transition that's available for the state machines to use. It's optimised for our use, for casino games. Unlike a lot of the examples that people talk about when they have chess people taking one move and then another move and then another move, we advance the state with an action from both players at the same time. So, it's more like rock paper scissors where both people are doing this at the same time and we combine that together with the random number to produce the next state in the sequence. This actually makes writing the state machines themselves a lot simpler as there's only really one function to advance the state, but it does make dispute resolution quite a bit harder. So, all of our disputes which can come from various reasons, timeouts, network problems, incorrect state transitions, just general software problems, we reduced to a single statement which is that the other party is not following the protocol of a state channel. And state channels, it's really important to understand, are a protocol. They are a series of statements by which the state is advanced. Those are the rules that need to be followed. So, if that actually happens, then the person makes a claim on chain using the previous cosine state that both parties have agreed to and what they think the next one should be. And the contract validates that that's a valid state transition. And if that is correct, then we raise a dispute. And then the counter party can do a number of things. They can go, okay, that was a problem, right, I better do something about this. And they can provide the next state transition and if that's done and validated on chain, then we have a great side effect which means that we can actually carry on from that point off chain and complete the contract. This is a really, really powerful thing. The counter party can say no dispute, as in, well, you know, yeah, probably that's my fault and we just close the channel where we are. The counter party can do nothing if their laptop is blown up or if they've gone on holiday. The channel times out and the claimant can close the channel subsequently to that with a penalty to the party that timed out. Or they can challenge with a later cosine state. Now, in various implementations of that, there's penalties or not, whether or not someone has maliciously tried to close a channel with an earlier state. We think that is malicious, especially because we're treating the casino games here. So we treat that as a penalty to the person that put the earlier state on the chain because of the variance. So building a customer-facing DAP is hard, I think most people know that. Using state channels does not make this any easier. If you want to build an automated system that interacts directly with a blockchain, it's even harder still. So this is really a talk about what we've faced while we've done that, with experiences from the team, quite a few of which are here today. So let's start with the topic de jour. So customers are non-boarding. So fun fact, we really aimed our initial product to at least people that had some crypto somewhere, right? Or vaguely knew what was going on. Most people, he says hand-wavingly, hold crypto in exchange is relatively few have actual wallets and interact with the chain directly. But we need to take people through this. So the usual stuff that you have to explain to people, gas price, gas limit, what happens if you get them wrong, if you get transactions stuck that can't be mined, we have to take people through this process to be able to get them in front of the state channel. We didn't really want to roll out our own wallet. We wanted to be wallet agnostic with this. So anyone that's got a wallet of any shape or form, you can use that. Lots of people are working on wallets. So why do work that other people are doing? But relatively few of these are out of beta or with these properly support arbitrary apps. And even then, we are at the mercy of someone else's code for our entire platform to function at all. In the month we've been live, Metamask have broken our app four times, which is really not particularly helpful. This particular, the first error, is happened the day we launched when you asked it to make a transaction to the chain. It made a transaction to the chain and then reported an error saying that transaction had not been made to the chain. So this does not help writing automated code. Also, it's very unclear what customers are actually signing when they open a channel. I mean, this is just like some data. What does that actually mean? That's the raw data for part of an open channel. You might get to see something like this. Why would I press that button? I don't really know. We've got some, right? What does that do? So, but we've got to encourage our users to do that. So we've got work to do here. Also, this is another entertaining thing. We managed to get into this situation, trying to open a state channel using a ledger with 16 button presses going through random streams of hex digits, not particularly custom friendly. So I know that people are working on this a lot, but where we are today is not good enough to get in front of customers. So realistically, we need to wait for it to get better. That's the lazy approach. Roll our own solution or collaborate with people that are doing this. And I know lots of other people are doing it. We're here on a mission to find a partner to help us with this. So if you've got anything interesting to say, please do get in touch. But it's certainly our biggest short-term problem as a customer-facing live application at the moment. Finally, it's hard to explain to customers what's going on and why it's fair. It's hard enough with this blockchain in general. But to try and talk to them about state channels, you don't get very far without having to explain what a hash function is and why it's important. And to really prove that a channel is fair, you need to be able to understand and read contract code. You need to be able to validate the signatures of each state transition. And you need to be able to validate that the state transitions were correctly executed by both parties, which basically no one's going to do. So we need to work on that a little bit. I think there's some interesting stuff along the lines of witnesses or watchtowers, and Patrick's going to talk about that later today. And I think that might be able to provide some sort of a help here. But it's just in terms of getting customers to understand what they're doing. So we put up a nice screen. I don't know if you can see that. So, yes, everything was fine, the signatures were validated, the smart contract validated at all. But what does that mean? It doesn't mean a huge amount. It means that we said that that's the case. If you want to do it yourself, you've got to go and look at this lovely piece of Jason and try and submit it to the chain, which also isn't going to work. So we need to try and bring those two things together so that we can really get our customers to understand and believe that state channels are actually secure and work. Which they do. Right, quick one on liveness. So state channels require participants to be live as in you have to always be there to respond to the messages to advance the state. If you go away, the channel can't advance. So it's fairly obvious in itself. But if you go away, how long do you go away for before you do something about that? If you just turn your computer off and walk away, you have violated the protocol of a state channel. So the longer the channel is expected to last, the longer your timeouts need to be. I think that's probably self-explanatory. But timeouts need to be short or long. There's a period in the middle where it makes no sense for the timeouts to be. So what situations are you trying to cover? If the user just closed his laptop and walked away, well, you know, then you can probably close the channel fairly quickly. But if it's important enough and there's enough value in that channel that if they've broken their laptop or they've gone on holiday and they've forgotten about it, the risk to them of losing all of their funds, you have to really understand and think when you're building a channel what values you want to choose for your timeouts. Right, automated blockchain transactions I need to crack on. We have written some headless service processes that interact with the blockchain to provide the casino end of this casino game. They don't really have any decisions to make themselves. They just need to follow the protocol. But turns out this is quite hard. There are hundreds of different situations that can occur. And failure to deal with any of them is a protocol violation and penalty. Anytime an automated process interacts with a blockchain, you have to really watch this. If you don't notice a transaction, has been mined or an event issued, that's a protocol violation. If you try and mine a transaction and it doesn't get mined, that's a protocol violation. So you need to make very careful assumptions about gas price and you need to react if it looks like a transaction that you put into the transaction port is now no longer going to get mined because the gas price has changed. We have issues with event feeds but so we just triple check everything that every single way we possibly can. And this is a quick one on uncalls and reals. I mean, how long do you want to wait? I mean, we definitely, there are people in this room that would say that we don't wait long enough. I'm fully aware about that to open a channel but regardless of that, not noticing a chain reorganisation is a protocol violation. So you can have interesting situations where both parties in the channel want to raise a dispute separately. They both do it in the same block. One of them gets mined before the other one so this one throws because you can only have one dispute on a channel at a time. Then you have a chain reorganisation and they happen in the other order and we've got to have automated code that can spot that and react to that and continue and not crash or do the wrong thing. And that's just one example of many of the things that need to happen. And the client code needs to do that as well because you can't have your users try and work out manually what's going on when the chain's been reorganised. I will say that if anyone's actually developing this stuff, we moved on to the main net from the various test nets way too late in the process and it's very, very different main net from any of the other test networks. So if you're trying to do anything automated on the blockchain, get on main net as soon as you can. All right, state machines, the kind of meat of this. Sorry, we're trying to not do everyone's implementation of a definition of a state machine but a state machine is code that implements this function which is a function that takes a state and an action on that state and returns a new state. And it has a function that has no side effects so it's entirely self-contained. All state machines which represent the individual games, the slot machines, the roulettes, black-aroud, blackjack, all of that stuff are written individually in solidity and we deploy these to the chain in advance. There are people here that would say that there are other ways of doing that but we do it primarily so that it's there in advance and you know what you're getting into when you start a contract. It leads to some interesting challenges though. Each state transition has to run in less than a max gas for a block otherwise you can't advance the state easily but they still need to be cheap regardless as in a dispute both parties have to execute this code. It's causing some unexpected design decisions for when it comes to writing generic games as we've done over the years. You end up doing things like using complex lookup tables rather than just a very simple mathematics calculation to get that stuff cheap. You confront this cost to the deployment of the contract. Some of our original contracts had several multi-million gas transactions to be deployed on chain because of the size of the lookup tables but we've made significant progress with that. The EVM is interesting to traditional developers when you're writing non-crypto code which this isn't really the game these state machines. Limited stack size is a pain in the ass but we can get around it but it turns out that it's also it's cheaper to store static data such as pay tables in actually in code rather than in storage but then you end up like with some stuff like this. This code should never be written by anyone ever but it is the best way of doing it currently in Solidity if you want to get at this stuff done cheaply. Right, also this is a new problem for state machines. State machines can't really throw. I mean they're not supposed to have any side effects so there's nothing to undo but they have to always work. If you can reach a position where in a state machine is in a given state and the next state transition will cause that state machine to have an overflow or even throw or some sort of exception or something that causes a transaction to fail you cannot resolve that dispute and this is actually exploitable. So we have various validate calls that we do to make sure that you can't bet on 37 on roulette or minus one or something right which could cause problems but this code has a whole new set of vulnerabilities different to other Solidity vulnerabilities that you would experience writing generic blockchain code and you need to think about this very, very carefully. Debugging, I'm going to probably skip through this it's debugging hard on the blockchain that's just really simple when you run in private nodes with the black boxes they crash they go down they take ages to restart the test nets depending on what day the week it is sometimes work but they're not particularly representative of mainnet remixed debugging when it works is actually quite fun I'd love to stepping through individual transactions on mainnet and what our customers have done but it's all pretty hard just be aware of that I'm doing good, good time So packing and unpacking we are ultimately preventing that the state channel is an interface that lets the state the state advance but it calls out into the state machine to actually advance the state so this thing has to deal with lots of data that it doesn't understand you don't want the state channel to be able to know what in meaning of the actual state is beyond the actual balances of each individual participant so we end up passing around blocks of binary data which the state machine can use freely but that then means that you end up having to pack and unpack this data fairly regularly so we ended up writing a full code generator for packing and unpacking data people say it's like Google's protobuf site wouldn't necessarily know that generates code for solidity typescript and C-sharp so that all three languages can actually unpack and unpack in a consistent way and so the code that needs to understand this can and the code that can't doesn't need to I think that makes sense so I'm very much looking forward to the day when the experimental ABI encoder version two is no longer experimental and for ABI decode in solidity 0.5 and I will say if you're doing any sort of state channel you should be looking forward to that too it's going to make life significantly easier for packing and unpacking arbitrary data inside solidity contracts upgrading contracts so yeah again I mean that's obviously hard anyway you have to build in upgrade ability to most of the things that you're doing on the chain right now but you might have a channel that's open so your client software needs to be able to make sure that it can run both versions of channels at the same time but the most important part of this is that state channels involves signing stuff off-chain and putting it on-chain so you don't get any of the natural replay protection stuff that a regular transition transaction would make so you have to be very careful about replay attacks it's very very easy to get that wrong I mean a simple way there are many ways to get stuff is to ensure that the contract address of the code that's verifying the signature of the data is actually stored in the data and it's not the only way of doing it but it's a simple way of not making too many mistakes but if you have data that's validated over here and then pass on to other contracts that's not necessarily the case trust some blockchains are trustless as a result of decentralisation and consensus mechanisms state channels are fundamentally trustless through the protocol so the protocol defines a trustless system but how do you create a trustless implementation of a state channel and this is a problem for DAPS in general it's all very well saying that stuff is secure but who wrote the typescript code that's running in my browser this is a problem that DAPS in general will face again there are people looking at solutions to this stuff but we've got plenty of work to do here to prevent the various attack vectors right okay good so I just thought of a couple of pages of some actual real stats for you guys based on what we've discovered over the last month so our channels are designed to be short lived so a few hours really is the longest we would expect although we've had longer than that we're seeing an average of 200 state transitions per channel but we've had one that did nearly 5 000 back at the envelope calculation would suggest that this channel would have cost one and a half billion gas or nearly three thousand dollars to run on chain it took 60 cents so this stuff does work this stuff really does work and it does achieve a scalability and the cost-saving reductions so people say it does approximately 5% of those channels end in a user time and out 50% of those are ragequits which is people just closing their laptop because they have limited value in the channel and there's more effort for them just to turn the laptop off and to actually close the channel but actually you know I'm two and a half percent I'm taking that as a good number actually that's a lot better than we thought it was going to be and a significant number of the others are basically people getting bored trying to wait for the channel to open put the wrong gas value in or whatever we need to work on that as well but once you're in the channel things seem to work pretty smoothly ish so these two things I am actually very proud of even the first one we've had one failure of our automated casino system to correctly advance the state now that's a bug that's fine though these things happen but the protocol worked all right player raised the dispute and claimed the dispute and they got paid and the casino did get penalised and actually this is good for the players this is the system actually doing what it's supposed to do we need to write less bugs it's fine but it's good and it really worked and I'm really actually proud that it paid out and then we've had two channels that actually had a dispute resolved it on chain and come off chain and continued and you know that's the thing that very very proud of that that's worked and two minutes go we're done thank you very much I didn't think I'd get through that in time so I've got two minutes so I can probably take one question if anyone's got anything otherwise we'll crack on yeah so just a quick question regarding the main net and testnet your observation what's what's the main difference what's the what's your what do you mean by that main net okay so the the key point on that one although my guys here can tell you more about it is that most of the testnets don't real I mean on a regular basis you don't see you don't see uncle blocks we see a lot of uncle blocks on the main net that make it into you know we've seen that transaction we've started to do things or tell the user that that's happened but then it's gone away and it's and you have to real we've had to do you know do something else and if you don't catch that if you don't spot that it's happened that's the main that's the main one that's out of there obviously it's a bit slower sometimes and the different consensus mechanisms from the testnets behaviour of somewhat differently but that's the main one it'll help you see uncles and then find out what you need to do about them cool one and a half minutes I was going over here you wanna come to the microphone okay, thanks so did you decide like not to wait for confirmations or we do wait for some right but we actually vary it based on I don't know if this works but someone had the crazy idea of waiting for using the first derivative of the rate of change of the rate of change of the gas price and if the gas price is changing you are more likely to get uncle blocks I don't know that if that's actually true or not but we use that as a metric to work out how much longer we should wait okay what do you deal with the user experience on the setting up the site channel well I mean we built a reasonably complex UI in front of this right so we've spent a lot of time on our UI to try and talk people through exactly what's going on so this stuff is all live by the way you can see demo version of it on thumbfair.io and we have our first casino is live for those of you in the limited number of jurisdictions that it's available for but you can you can go and see what we do with that but we talk people through the process we create the transactions we show them nice spinny things waiting for the block to be mined and then when it's all done the game the game launches and stuff so we put a lot of effort into that at least anyway cool I think that's it thank you very much