Hello, everyone. My name is Honor. So it's a four letter somewhat difficult to pronounce sometimes, but anyway, currently I'm located in Norway Oslo. As I said, it's like 222 a.m. right now. And it's a little bit dark, unfortunately. And Norwegians happen to like dim lights in everywhere. So I try to adjust my zoom and camera as much as possible. Currently I work at Microsoft as a front end developer. Though, throughout my most of my career, I was a back end developer. I work on the platform for, I think, for 20 years, use, use it since one zero beta. My contents with function program is actually started with another language called me merly. Maybe heard it. It was actually a fantastic language developed as a thesis master thesis in in in a Polish university. Though there was some activity and I also contributed language and I learned things like what's an option option type there. And from there I diverged to using F sharp, which actually, especially with the with the with the fable, it somehow translated allowed me to translate myself to be a front end developer, ironically. So, earlier, I tried to learn react several times and I was jump jump back. But thanks to F sharp and fable, I was able to also learn to how to do how to program and react and become a front end developer at Microsoft today. So, at work, I don't use F sharp at this job. But in my previous job in Norway, I was, I was a full time front end developer and using F sharp for content for a year. I also have some site projects.  And also I occasionally organize workshops for curious people. So, one of the reasons why I came up with this talk is that once you once you step in the functional functional programming realm. A lot of things you learn in the OP world starts not to apply you just, I mean, for example, let's say you want to do a standard credit application with with F sharp, then you immediately find yourself just surrounded with all these tools that is designed for C sharp, then you start to use again entity framework and, for example, or ends or whatever database mapping tool you use, and then you just realize it's it becomes this little pointless to you to use a function program in the first place if you're going to use the tools that is designed for non function programming languages. So, in that sense, which today's talk is about CQRS command query responsible segregation. It's actually a match made in heaven for functional programming languages because the CQRS pattern is more like a message oriented and event oriented architecture, unlike the regular conventional architectural design patterns. In that sense, it makes it makes it a very good match, but also, it's a little bit challenging how to how to how to build up all of things and integrate all of things how would you do a real life application. I feel there's some sort of courage amount of information. So this is what I'm trying to address. And say, so this talk is about a CQRS via app.net, which is a very, very opinionated way of doing things, but I believe if you're curious people, it might give some ideas, maybe they can just take the idea and apply it in a different form or I don't know. So that's that will be all up to you. So I'll share my screen, there will be some slides. During the talk, you can just stop me, interrupt me for anything you're curious. You want me to dig further. That's all fine by me. I assume you can see my slide. So, when we talk about CQRS, it stands for command query responsible segregation, and it actually has several flavors. So, I think it's awesome that it's almost like a sort of the company that develops aka.net is actually here in Houston.  Yeah, that's true. I actually met the guy here, but when he came to Oslo, NDC, I had some good time with them. Yeah, so I know about them. Yeah, and I'm pretty much in connection with them. He's doing great stuff. I really appreciate his effort doing this. Although he's trying to use a commercial business, so super valuable effort. So, as I said, command query responsible segregation comes in several flavors. At first, it's, it's there's a very lightweight form which you can just apply that if you don't want to go full blown CQRS, which is called command query segregation, CQRS, and then we'll talk about the differences, then the little bit more medium form. So you can do CQRS with or without event sourcing event sourcing is another methodology where your, your, you construct your process, your data is sort of list of events, instead of regular tables or regular persistence, whatever you're using. And then what you do is you just go to these events and maybe able to replay them and then create some sort of projection which we talk about it. And this is the, this is the flavor we'll cover and probably vast measures of time you would want to go with CQRS with event sourcing because this just it just really completes the pattern as well as it's somewhat very functional friendly, I would say. So, the talk about is just what is CQRS, why do we need it, and how do we use it, it's just you can, we can try to summarize in three steps. And then we can just talk about what is what was it before a little bit diving into into CQRS, let's just talk about the, the concepts. So, as I said, it's a, I talked about the command and query. Actually, so what we tell why what what what we try to explain my command, it's something like some sort of message that's intention to alter the state. Okay, let's say you want to order a pizza and you just say place order so it presents some sort of demand. And typically, in your in your security applications from the command you don't you don't return the state it's not it's not the, it's not the ideal way to to to fetch the state. But as a query side, it just returns the data. And you just don't touch that site and don't try to use the query side for altering the state it's just it's it's all existence is just to reading it and there's also due to a synchronicity. And it also the query side usually returns some sort of stale data, but you have to live with it, which we'll talk about that as well. So this is some sort of important chart, you can see. This represents a flow, the flow of one of the one of the ways it presents a flow of secure is where we have a command handler and demand handler. So command handler is like something that accepts a command. And it also, it's also except the state it's also somewhat gather the state, such as let's say you are you're ordering something, then the command would be a place order. The state will be, for example, could be something like a stock amount right. Then the command handler can just decide what would be the outcome, for example, if there's enough stock. For the, for the item, then you can just generate an event, such as order is placed, or we can just reject the reject the reject the command such as the order is rejected because there's not, there's not enough stock for that item. The decision maker. But eventually what it does is it just to generates the event and then that event is just going goes to the event handler. And with the current state, it just generates a new state, such as if you have ordered something then the stock amount will be reduced. It will be your newer state.  So this is a bit more, more broader picture of the architecture. So on the right hand side, you can see just as a UI, and you I can talk to your, your, your backhand via regular service interfaces. And you can see actually we tried to split the model into the command model and the query model. It's a very, very big distinction. I'll talk about the reason why we do that but just to understand why we do that. And this is actually the, it's just a CTS version of it. So there's just a single common database there, and the command model and the query model share a single data model. And once you separate the model, then you end up with the CTS part. And here's another representation of the same pattern.  And in the in the secret side, it's actually considered dashed line. On the left part, you can see, well, the application and domain it's somewhat separated from the query side again. And here's another representation and this is, this is more. This presents this actually the CQS with event sourcing. Again, on the left hand side, you can see the presentation application layer. You, you just request for action. And then what happens is, instead of your the classical tables you would just use in a crowd application. Well, there are some sort of, I don't know, orders table. You just instead of love the events what happened in the system. Okay. It's like a bank transaction book or ledger book kind of thing. So you just record what happened in the system. And there's another mechanism that runs in the back end of Scott which I tend to call a projection engine. And it just scans these events constantly, and then fulfills the data, whatever they whatever you want, it could be multiple projection engines which can then construct the redata store from that. This thing continuously runs as, as the data is feed it to the log of events. So there is, you can you can think about, well, I talk is nice but have you ever used this thing in any real project. So I work in Dubai for some time, like a three years. And the interesting bit about Dubai is that it, it's actually has the words busy airport in terms of international passenger traffic. Except like around 100 million passengers per year. And they have some sort of rules such as all government officers must be from from from the citizens which only constitutes the 20% of population. So you, as an expert you can't have such a job or just you can't attend attain citizenship or just they come they can have this kind of rules. And for that, they have a tendency to automate everything as as much as possible. So one of the projects I work on is just interested called a smart tunnel, where people just walk through a tunnel. And then while we're walking it scans your eyes, and it finds out who you are and completes your immigration process you don't show any documents for don't even stop. So, I can just briefly show the video, although it's a little bit, not technically related. Just, just, just to show how it works. Um, just, let's just just talk about the, the tunnel parts. I just want to show the video here maybe there's something, it's due to my headphone I suppose. I don't know why I can't play this. So you can see the tunnel here in the back end. And then people just walk through. So it's strange. Whatever. Okay, let's just skip this part. So it's it's some sort of tunnel and this is something I used for this pattern is something something I use in a real project. Next slide. So, one of the things. Can I ask a question. So, when you say that you use that in this tunnel. Exactly. You know, was it like moving the conveyor belt or was it the camera. Yeah. Well, it's the system so there's one one system that feeds the incoming passenger. So, typically if you think of how the system versus that. It's not possible. I mean, it's fairly fairly difficult to find out a random person who is who he or she is from their eyes. Okay. I mean, considering there are millions of people you can't just do that instantly there's no such technology. So in order to do so you need to find out who is coming so you just have to limit the people's window. Okay, so we have an integration with the airline. And then when someone checks into the counter and the airline notifies us hey someone is coming and I know their name and then we just registered the person into some sort of limited number of gallery. Okay, something like a 5000 people. And once you walk through the tunnel then it is possible it is easy to find out someone from their eyes among 5000 people. Okay, and once you pass through the tunnel, we just figured out you have passed or if your flight is off also you fly to take off maybe you don't decide to visit the tunnel, maybe you just didn't come to flight. You just removed from the gallery. And that way we always maintain a specific number of people that is registered in the gallery that could be recognized. So this whole system is just there's a passenger feeding system, and there's also a passenger consuming system. And in that sense, we utilize this pattern where there are some commands and then registering passengers and there's a system that just constructs the registered passengers table from the event logs and then once you once you go through the tunnel, it just finds that you if you registered find your relevant details and convey to the back end immigration system. That's under this kind of system. It was a very cool project I really enjoyed it. Yeah, that's wonderful.  So it's, and it may be something you you're not willing to commit everything because it requires a lot of stamina to be fair, which I'll talk, I'll tell you why it is.  Those are you should consider fragmenting your architecture vertically, not just horizontally. That is, for example, it's like a boundary context, context concept, where you have for example an application you have an authentication stuff your transactions, for example, maybe a bank transaction, and there's a contact for example, you're managing. So you can choose different architectures for for different vertical slices. For example, for authentication, you can just use a crowd level. It's all fine. And for your more valuable, where it's more, you will get more benefits from secure s, you could just commit for for example for the transactions for this for this pattern. So it's, it's, it's, it's applicable to a single slice this this is a better way to to handle the complexity. After all you don't want to spend too much time on something that's already a sole problem like an authentication, but it's all up to you. So this is just, I just tried to give a brief overview, what is it about. As I said, it's as a summary. There is some sort of commands that's feeding the system, and then you just generate a set of set of events, and there's some sort of projection engine which is just to generate it. Why should I care. Right. So I can, people came up with this idea why this is important is so several problems that is actually people don't notice which I will just talk about these problems.  When you talk to the C sharp guy. Hey, why do you use a sharper word. Why do you use function programming. It's very hard to explain, because it's just something you, you, you have this mind shift right and you know the answer but it's, it's a little hard to put on the words. So secret also it in some way it's it requires you to have some sort of mind shift. And the primary motivation to use why should I secure do security is that it is my personal primary reason it protects your domain. It's not about performance, not about concurrency, or other things you should you heard about security, but it protects your domain, and it protects your domain by separating it into two two pieces that that is the command and the query. Let's see how it does that. You develop a typical application. It's like in a crowd manner, and you have the user's table. And, well, it's a very simple table I have the user ID username and the password. And let's say your your company is going to a security audit, and somehow a new requirement came, and then your boss or manager asked you to, to answer the following query that how many times if they use your chain to your passwords. I'd like you to think about it and if you can make it make me can just talk back. Oh, you can record the state every time. Right stick in a database. Well, wait, are we confined to just that table. Like, is that the only table we have. It's up there. It's an open question. I mean, you do it like we do goodbye query on the username and you can get the frequency counts. I'm assuming that the ID is just an ID for the record ID and not the username. Would you, would you use the latest for a username and just make it make it. Yeah, but please note that there's there is no counter or something like here at this point of time right. How would you know how many times they they change. So every time the user changes password. The only thing changes the password column. Right. And how would you how would you count it. You need to count it somewhere. Every time they change it in plain text in a text file. And then you just go through with WC. I mean, you have to have a lot of people. Any time you call the change path function, you go ahead and you say a user ID in that table.  But if you do that, the world only starts when you start logging in. That's fine. But you guys aren't being creative enough. What you do is you say you can't change their password. And that is the solution. Zero. Password for it. Change data capture is never the answer until it's the answer, but it's never the answer. I'm using that capture right now. I mean, I'm assuming this table has, has the record of everything. So you just basically just do a group like where the question. But that's seriously, but change that a capture and SQL server only gives you like seven days by default. So if you were interested in the last seven days of user changing their passwords, then you're good. Well, okay. So effectively starting at the time you enable change. You make the users table, the log table. You could potentially query the SQL server logs to get all of the updates statements. Oh, that's, that's a little bit overkill, I would say. So let me just let me just wrap up. Thank you for your very creative ideas. The answer. We can send the rest of the meeting on this question. The password isn't thinking like honestly. It might be. So my new approach would be just to introduce a column just just that counts. It's a very near approach, but it would work. They just introduced a column here that is just a transfer change counts. Okay. That's not vulnerable enough. It doesn't match with three enterprise patterns. And architecture review. But once you add a column, then such a column, then the problem is you're effectively changing your data model, but also you're obligated to propagate this backwards all through all the way up to your application. That means now once I make such a change, I need to change my domain model. Perhaps, let's say I, as a, my, my name solution was to add a column. And then I, if I use something like an entry framework, in each, now I have to go to revisit my domain model, and then introduce a property that represents the change of number of number of password changes. That effectively says whenever someone wants to create something and that doesn't exist in my database, I need to, I need to change the core part of my domain. And every time you change your core, the core part of your domain, you need to make a deployment. And every deployment has the potential risk. You can introduce bugs. Well, this is this case is very naive and simple, but actually, it's what you're doing. So what's what security is trying to do is, if we can manage to separate these read concerns, perhaps we can get away with handling the subject queries, only by dealing the dealing with the change in the query part, which is non critical. Whereas you can keep your, your core domain unchanged, and which mitigates the risk. Okay. So that's the, that's the primary motivation why, why security is valuable. It protects your domain where it relinquishes. It just leaves you. Many, many times, whenever a change is happening, you can get away by not touching your core model. Okay, but so once. So are you making the argument that this allows you to keep a minimal database and push as much as possible into code. I wouldn't necessarily say database because again, let's we have to think of mentally we have the query and the command side of databases as well. And I'm, what I'm claiming is that the command side is your core model, which is more valuable, more critical. And you can get away without touching to that place where you will eventually have to touch because there's a new query you will have to touch to your query model. You will probably have to touch to your query database as well. But a mistake that would happen there, which would be far less critical that would happen in your command and query side, command, command side, sorry. So this is what does that answer your question. Yeah, yeah, yeah, that's super helpful. Thank you. So, so, as I said, this is this is the primary motive of secure as it or rather than the other benefits. So it protects your core domain. But we are not, we are not finished with this problem. So, once you add the solution, then the next question can arrive what will be the frequency. Then how many, how many times does it use a change their password within the seven days per period or just daily, something like that. Then you still can't answer that question in this name change. Well, you, you, you that you then have to resort creating another table, where it just timestamps every time a user chain, a user changes their data and then, well, and security event sourcing is actually event sourcing part of the security records everything happened in the system. Even if you want it or don't want it. And that way you never lose anything that happened to system as long as you're intended. So if there's a command change commands, sorry, password change command comes out. That would eventually yield a password change events or password change failed event for perhaps there's a policy against changing can fail or succeed. And then you will be tracking, even if you're not interested in password in this query in the first place, you will have all those events timestamped and sorted in your in your data store already. So you don't have to worry about, well, what if my boss asks me this query in the future. You don't have to think ahead. If you already record everything that happens in the system. Okay, but in that sense, it also helps you to protect your, your, your domain. So here's another example that event sourcing. And this is a little bit more different domain where you place orders in a typical crowd database we have the orders table and we can just create whenever an order is created. And in the secret event sourcing, what we, what we create is just the set of events. And I think this terminology is a little bit wrong here. You should say order place not order created because if you say created, it's in, it still leads to crowd mentality. We should use a little bit more proper naming as well. But eventually what you do is that whenever an order created order updated. So you just immediately you set you create an immediate set of events, and that just constitutes your your event low. And whereas there's again, starting from some sort of offset. There's an offset because you will system may be restarted and you just, there's no guarantee you will continue to run your system indefinitely. You record some offset and then from starting from a starting offset you just replay and I'll aggregate those events into the regular order table as we know it. So that's the event sourcing part. And that is also this is very understated when it comes to regular applications to handle concurrency. Let's talk about concurrency so concurrency represents here for example your applications are typical application and multiple users trying to access a single resource. And as I said it's a very underrated problem, and it's a very real problem. And he's actually written by distinguished engineer of Microsoft date folder which is the creator creator of sign alarm maybe you know him. And this is an example from to do in VC application. And there's something wrong with this code and it's not his fault because there was some limitation, which we talk about it. What do you think, what could good, what could go wrong with this code. What do you think. It can stop in the middle. Yeah. You're saving at the end. Okay. But assuming this is rather wrapping into into it. Well it will run into in in in a transaction. I mean, once you do that. So, let's think about a concurrency problem concurrency rate way of things let's say two people are trying to update or best for example, in one case one is one person is deleting this, this record well one is one is updating what's going to happen. So there's already a check here if you can see there's a if await TV to do and if if there's no it checks with any I think, and if there's no record there it will just return not found. Right, it's already some appears to be protected from that from some such cases, but it's actually not. So because databases work out handle the transactions in an isolated way. If consider to transaction one is trying to delete a record and then what the one is just trying to query it or save it or just insert it. So let's say you're trying to update a record. And before you update that record. Someone has deleted it. Right. And what would happen is that your, your, your update transaction will say, I suck. I successfully updated your record. That's what you get. But eventually you will have no update at all because you someone has deleted it. So it may look like a very subtle problem but even a simple crowd crowd application is vulnerable to this kind of thing. You may not worry about well. Maybe there are two few users in your system which will represent that concept. And they followed a smart guy and I talked about it and then in the next iteration he's somewhat improved as much as possible. Enter framework seven or for that different utility. And this is the same code for the. It's a newer commit for the same same code. And in this case what he does is calling the entry frameworks execute update I think instead of doing that. And most relational databases when you execute an update statement they will tell you how many rows affected the database returns that as an integer. Okay. And what this is what he's using just to just to circumvent that problem. Now, in this new version is checking if the rows affected is zero or not. If the rows affected is zero then apparently someone has deleted it. And it's somewhat helps the problem but it's still not a pure solution. Now, you can say, I have few users. Right. I don't care I'm not. I only have one user. And you may believe that you're not you're not you're not vulnerable to this kind of problem. But then think about you made a UI and then you're just user. Just click this button multiple times. And there's no guarantee which request when you work with TCP IP. There's no way you can know which request will go with the same first or second. And you can just create a very simple risk condition just by by by having a single year single single user. Well, I can disable the button. Right. It's just you I think I can prevent that problem. Then, well that means you're you're trusting your user. First of all, a malicious user can just undo this very easily I can open the HTML and then just try to corrupt your database. Maybe there is a colleague who doesn't like you in your company. There should be a web service and this time there, you have a far less control about over concurrency you're calling calling the service, and then can cause this kind of concurrency problems. Here's another problem. So when I learned about database transactions. In the first place, what I read about well we create a transaction you're transferring some amount of money from one account to another. If the transaction commits, all is good. If doesn't commit all is still good right because we are not going to since the transaction in asset database offers atomicity.  And let's say when once we're trying to transfer some amount of money we're trying to first check the balance let's say we have a hard bound rule in an environment that you can't overdraw. We are going to check if your balance if you're if your balance having a amount of money, we're going to transfer the money right. But what's going to happen when you have concurrency. Then, let's say these two simultaneous transactions are trying to withdraw money from the same same account. Both of them are checking if there's enough balance if there's $1,000 in the first account and both are checking if there's enough balance both both code will say yes, there is enough bad. There is enough balance, but there's not enough balance for both transactions and since there's the threats to transactions are isolated. These things don't know about anything about each other. They are not aware of each other and they're going to both both succeed, and you will end up with your corrupt database record. You're going to end up with I don't know depending on the condition. The transaction will say well be successful to transfer your money, but actually, only one one will succeed, right. The concurrency problem does exist. And it's it's everywhere actually in even in a simple web application we don't think about much, but it's actually, I'm not concerned about the minor possibilities and it can happen. What can we do about it. In a typical way. If you use something like an interframer crowd bay is one way is to use optimistic concurrency or pessimistic concurrency in in optimistic concurrency we decorate our table with a version or timestamp column. And then every time we make a change in the row. We check if that we do it by update statement, we check if the update statement returns at rose affected. And how we do that in the in the update statement we introduce a where condition against the version column or timestamp. So that if only the timestamp matches or the version matches the update statement with succeed, but that's the optimistic concurrency we call. But if it fails, you need to retry. And there's a pessimistic concurrency part where you would just lock the row rely on the database. The database over locking the role. And then no other transaction can just read the row even you're looking at the locking at the role level. But then this is very vulnerable to deadlocks. It really happens a lot. If you if you try to use locking over a row so do two transactions trying to read the rows in opposite order then the database gets a well both transactions are locking each other then it will kill one of the transactions. So what can we do about it. So the solution that CQS is kind of architected would offer is just let's just make a proper domain during design. Let's define our transaction boundaries per aggregate in domain during design. The concept of aggregate is just it's something that represents a transaction boundary. And it also represents an invariant. So let's what is what is our invariant here and an account cannot overdraw. Then we can we can effectively create an aggregate and transaction boundary over per account. So in typical your if you apply some things like unit of work pattern, right, you create a transaction at the beginning of request you do a lot of things.  But that's that that that creates this kind of problems, whereas what we can do is we can create a transaction boundary for each, each aggregate. But then you have to you, you have to also coordinate them. So if you're familiar with two phase commit protocol in distributed transactions, this is something we have to do. We have to check if both transactions are succeed and then follow it. Let's see in some sort of sequence diagram how this would work in a bit more secure as pattern. And this will be a simplified version of it. And also talk about a little bit more detailed version of it. So there's a customer who who who is willing to transfer money so you can, you can see the arrows as a sequence diagram their numbers, the red arrows represents the commands, and the blue arrows represents the events. So we want to transfer the money there's a command handler just forwards the accepts the transfer money, and then it issues a command to the source account and stating that well, I need to transfer some amount of money. And then source account just reserves the amounts. Okay, just doesn't commit yet, but it just reserves that it's going to commit that. And then there's some sort of state machine, which I called sagas, which is a little wrong terminology, which takes it over from that point on and then it just it just communicates to the target target account. And then target account also gives it there. Okay. And then once once both both sides reserve their amounts and then the transfer process can confirm the transaction in the first account. And then, once once they get the confirmation, it does the confirmation for the second account. This traffic this chatted thing. And then this effectively solves the problem. Because now your transaction boundaries are is are restricted into per per aggregate. The challenge with this is what happened system is crash system crashes in any of between these steps need to recover. Right. If it crashes or like, let's say that your system shut down and step four, what would you do. Another thing that they really talk about it. So we talked about the security as protects your domain, talk about handles concurrency. Also, there's another annoyance with the typical crowd, the source of truth. I'd like to ask you. In your applications, you develop applications, what is the source of truth. No, I know the answer. The source of truth is reality. No, no, that's not a joke. I'm serious. The source of truth is reality. Everything else is just a weak reflection of that. That's true. That is true. The database is actually a part of reality as well. No, a database is a record of reality. I assure you the database exists in reality. It does, but it doesn't contain the reality of We have philosophy as part of this group. Yeah. That's right into it. We have humanities people, social scientists, philosophers. Actually, the comp side people are kind of already in this group. I would say that there might be situations where you might want to keep track of certain digital things that only just the database. There's no source of truth outside the database, like the password question. You're not going to go ahead and have a real password outside the database. It's not possible. If you have a real password, that's not math, but there's a database. John, would you like to respond to the idea that all reality is in the database? No, all of reality is not in the database. Hold on. I like to respond to John's comment and he has a valid point. I think he's not joking and it's true. But the problem with the reality being the outside world is if you take that as a source of truth, then you will end up the problem with stability. Because your application won't be aware, it's impossible for your application to be aware of the instantaneous reality of reality. Change is happening in reality outside the system. It's a fundamental problem. For something to be a source of truth for our application, it also must not be a tale. That's why the reality can't be the source of truth for your application. The thing is just your application's point of view, the information is not there. There's no guarantee there. But once you talk about source of truth as a database, which everyone acknowledged, then we also know that it's source of truth because it's not tale. It is there. We accept as the source of truth. It's the reality. We assume that's the reality. We accommodate that. So, 80 years ago, a guy named Pat Helen wrote this blog post that said, This data is like the night sky. And it's actually like fundamentally really important to understand this. Like if you go and look like get outside of Houston or whatever city you're in, go out in the country, you look up at the stars. Do you know what you're seeing? Do we have any astronomers? That's the light that left those stars many years ago. Yeah, millions of years, millions of years ago in some cases, right? And so that's always true about our databases. Our databases show us the truth of the past. It's actually really important to understand if you're designing applications is to understand that your truth is in the past. I will argue, as some of you know, I will argue that this is a solved problem. It was solved some time before the year 1400 CE in Europe. It may have been solved in Korea earlier than that. But the point is, double entry bookkeeping solves this problem by accepting the fact that you can't ever know exactly what the truth at a single point in time is. Yeah. That's what you call individual consistency. Yeah. It's why you're right about everything, honestly. Like, it's why CQRS makes sense is because it's the reality is that, like, things happen. We record our understanding of those things, right? And in some cases, you know, we have to go back and correct our understanding of reality. It's just the way it is. It's like, people who think two phase commit solve their problem don't understand the problem. They really don't.  But for me, it's very pestering that I rely something like a source of truth as a database where I'm a developer, I like the source of truth to be my code. The rules that just I'm calling a lot of rules and then this is pestering me. I'm relying on the vendors. There's a database vendor. They have some sort of features in their database, they can just offer indexing, roll locking, etc. And then I somehow find it personally very, very annoying that I rely on the database that much. I'd like to reduce the database to just put it into its place to be a persistence engine, be a really persistent engine, but at least not from a developer's point of view, don't be the source of truth. So those will be really visit how this goes. But this, this, there we come the ACA dot net and the actor thing. But before we jump into the ACA dot net thing and just, I'd like to ask you another different questions, there's a functional programmers here so you just say you're developing a simple web application. And then the user submits a number and let's say five, six, and what you're doing is you need to accumulate this number. You need to do it in an immutable way in the memory, there is no database. How would you do it? Shall I repeat the question? The user submits some numbers like a five, six, seven, and what you do is you need to add these numbers constantly as the user submits the numbers.  How point to handle this. You would, you would store the number in some location and then change the variable to point at the new location so you can have it change in a comic way. Well, for example, let me just give you a little bit concise for F sharp users, you're not going, you're not allowed to use mutable keyword or you're not allowed to use any C sharp or that's a BCL level mutable collections. How would you do it? Or is it doable. You have to use mutable. It returns it. And returns it. Yeah, that's also that's supplement. That's it. It's like, you have some state. Yeah, you take a you take it, you apply it to the state. And you read. And then you have a new state that is a function that has applied the it to the state. I mean, that's the way it's done. Yeah, but how would you in practice in practice. So it's, it's, it's, it would be a shame, right. We talk about function programming, but it would be a shame if you can't do this if you can't solve this problem without using mutable variables. Right. So what, what I would do is in F sharp, there's something called a mailbox processor. Yeah. Which accepts a message. Well, I can't say it's really pure. Well, it does a lot of trading and a lot of plumbing there in the back end, but it really writes you allows you to write a recursion. And then you just listen for a message. And then you can just get the incoming number, add to the add to the current value, and then call the recursion, because it called call yourself recursively and then hold the state as the function parameter, and you will use no mutable variables. Why am I in this example because the actors actually somewhat works in a similar sense. And I could net is is is one of the frameworks that that just allows you to, to, to do this to do so. So, in a typical all object oriented programming, you have the object so an object is something like that accepts a mess, a message in form in forms of method call right there's a there's a there's an object.  Okay, but the difference is that an object is is somewhat tied into him, it's just a pile of data, and it's pinned to a memory location, even though garbage collector moves it out, it still lives in a fixed location. So as an actor is a more broader abstract. So when you talk about the actor as an object. It doesn't leave. It doesn't, sorry, it doesn't pin into particular memory location with it's a more abstract concept it's not that it's, it is not just a pile of memory. It's floating in the, in the, in the, it's a, for example, it can transparently, you can access an actor for example, transparent from another machine, as if it's, it's, it's, it's living in your own machine so you have some sort of built in mechanism, where it can restart with his own site own life cycle, it can use a different memory location but you can still access the same actor on the same place, as if it's, it's there, even though the underlying objects change with some sort of it offers and after some offers there's some sort of object like an abstraction. And one of the things that occurs that offers you in a distributed environment is which we're going to talk. There's some sort of gossip protocol. So by using an academic you can just invent a cluster. And let's say there isn't there are three physical nodes here a B and C. And of course, protocol does this. Let's say you want to introduce this B and C nodes into your cluster. And they only know about a. Okay, so you said that you know the IP address so you configure that hey, you configure be that it should connect to a as an IP address and by using a gossip protocol, academic is allowed to propagate the information of B and C to each other. Okay. Even though B and C doesn't know about each other in the first place by connecting to a, a will tell about a will tell about each other so then able tell that be that hey there's there's a there's a C in this IP address, or a will tell to see that hey there's a there's a and when then B and C we will be able to connect. So you can build, build such clusters with with our current net. That's one of the things about it. Furthermore, this is where we're going to probably use our current net which is TQRS. I can offer some sort of cluster sharding mechanism when I read about cluster sharding I told us that very advanced concept that this is required for distributed computing. So I use it for my applications is even there's even though there's a single node. I still make use of it. And in our current cluster sharding you create an entity. And that entity could be it's an abstract concept. It's not like you create an entity just like using a new keyword and starting an object but it's it just pretends as if it existed since the beginning of time. So let's say you want to send a message to an entity that you have never created. You say that well I want to create an order with this ID. But they'll make that it will it will create that actor for you if it doesn't exist and it will just start that actor and it will just receive the record and it could be distributed if it's sharded into multiple physical nodes or virtual nodes, or it could be a single machine. But the class of sharding is what constitutes the your domain level aggregates as entity. They are not going to they call it entity but actually constitutes aggregates. How does it look like an aggregate an aggregate is like an entity. Let's call it takes a message and this message takes three parameters. One is the entity ID. It's like your, for example, your order ID, the shard ID if you are sharding for example you can geographically shard it you can say that the orders from USA is sharp a orders from Brazil is sharp B. And there's the message, which is like the place the command place order command.  Okay. So, how does it not their processes like that let's say you have you have a login mechanism, then you can read the road just here represents a login command. And then the user actor just receives it, and then the size on the outcome. It could be either login succeed or login failed. This is what we did. This is what we told so far in my design pattern. There will be cases where you would start a saga.  Not every event will cause a saga start. For example, here, we have emitted the login successful event. And there, I designed a saga starter. It's another actor here, which can decide or not I mean, I mean it'll decide maybe a different saga needs to be started for this thing. So the saga do we'll we'll just visit in this next slide. So this will mean more broader picture and in a real application of how would you transfer some amount of money by using accurate net and using these, these actors. Here we have actually five actors. The saga starter is something like a global. So it exists in one once one single piece. The transaction the account sender and account receiver are three aggregates that are that constitutes our domain of it. The transaction saga is also another actor which represents the network which acts like a transaction coordinator here in the number one arrow we issue that transfer money and this this creates a transaction actor. And the next thing it just it issues it emits an event called transaction started the saga starter will say, well, okay, it will issue the third arrow. It will start it will start the saga. And once the saga started it will tell the saga saga started it started, and then it will tell the fifth arrow, it will tell the transaction entity to continue. Once we get the continue go the saga start this the the transaction will emit the sixth event that the transaction started. The transaction saga will coordinate the events. It looks like a chatty traffic but if you look at the each circle isolated way it's actually not that but chatty. On the left hand side, you can see that the transaction saga first will send the seventh arrow with reserve amount, the eight amount bill will say amount reserved, and then it will do the nine and 10 for the account reserve account receiver, it will also probably add a plus amount. And once both sides are completed with the amount reserved messages come, then you issue the complete complete to both sides, and you get the 12 and 14 messages to get that they're committed.  So, at any stage, if trans this transaction fails, let's say your process crashed, the transaction saga will book keep. What was the last number we have executed, let's say it was seven, then it will replay the replay the same message to the to the same actor, and that way, it is possible to just you can just continue the process even if the process crashes. Okay. And each of these actors just they offer their own invariance their own rule their own transaction boundaries. And then you can see all these blue arrows, whatever the message, they will land into the database as a persistent event. Okay, so you can say that well there's a transaction started. And then there's amount reserved they're completed. And then you will have a set of events that is that existing your database. So the question. Yes. Yeah, so, so every time a saga is sort of hitting the transaction saga. That's making a call to the database, or is that happening just in memory.  Okay, that's that's done by the actor and I'll show the how the code does that.  And the actor itself is responsible for persistence here. Although it's a little bit less ideal sounds of separation of concerns it works well.  So I created these actors, right in the memory now they're floating somewhere. What will happen like five hours later, will they stay indefinitely in the memory. We need to garbage collect them and I cannot offer that mechanism called passivation. Passivation is something like an if an actor doesn't receive a message for two minutes, for example by default, it will remove it from the memory. But it will do it such a way that it will handle it in a graceful way. I mean you will never lose a message. Once it's doing that. Okay, this is called a preservation and this configure well there's there's a there's a configuration here so it's by default 120 seconds. There's another problem here, let's say your process crashed, right, and then you restart it. Who would, who would restart your saga, because saga was the continuation point. There's a concept called remember entities, where if you mark and an entity as remember entities there's switch for that. It will restart those entities automatically on the boot. When you put your application and typically this ideal for sagas, it will, it will create. It will restart those sagas, it will only restart those sagas, and then the sagas will just dispatch those even in the continued process. Let's look at that from some F chef so to the talk about too much theory. How would you create an actor with F sharp. Well you can it's just a very short thing actually even this is an FSX file. And well the, the hyperion thing isn't required you just reference the link, which is a rapper and F sharp rapper over aqua.net. You create an actor system. And what you do is you create a recursive function here, just as I, as I described, and you can see there's it's wrapped into an actor computation expression. And what we do is we let bang viewers, this just like it is very it looks very similar to mailbox processor, where we just receive it for the message. In this case the message tends to be a string. If the messages stop for example we return a special token call stop, which stops the actor. Or if it's an unhandled we return a special token here called unhandled, which logs and messages unhandled. And if it's anything else we're just printing the message here and we're just recursively calling our cell. So here what is the state, what do you think the state for this loop. So the rule is the recursion, the recursing parameter is the state. In this case it's unit. So that's our state. You can say there's no state. Because the unit is the is the one we are recursing but if it could be anything it could be a real object it could be a number that whatever we are recursing would be the kept in the memory. And in the below we can see how we create the spawn anonymous for example is one of the ways to construct actor. And then you can use this funny operator. Send the message to the actor. Okay, that's, it's also type safe so in this case if you use operator you can only pass a string, you can't pass an integer it won't compile. How would we handle the persistent one. It's slightly tricky. In this case we have a real state. So our we have a counter changed, I think it's used as the message, and the counter command which we can increment and decrement the state. And then we have to get state thing. In this case our loop has a variable called state. And by default it is initialized as zero you can see that at the bottom to there's a loop zero statement. And once you see once you start that then do the message it our actor will start listening messages. Once you share command ink in the below. We will capture that command message and that it checks if it's ink, you can see that it issues a special token called persist. Once I got it gets that message, it will persist event to database. Okay, that's how persistent them. And once the persistent succeeds. It will call this event thing it will you will get another message where that will match the event part of it. So you see the first persistent message, and then we recursively call our cell and we change the state again we just add the number in the, in the loop part in the event change return loop part. And that's how it works. This is how a simple persistent actor works. We just issue the commanding commanding commanding and then command decrement, and then also we can get the state, which we don't get the state for the actors for the real for the real case. We're, we're, we shouldn't do this. So, I got that as persistent mechanism first with several databases. It first, I mean, as a lot of database it works against SQL server it works and SQL light possible SQL MongoDB Oracle my SQL I use it it SQL server SQL light Oracle myself. Perhaps, I would say most ideal might be MongoDB because what you're you what you what you're storing is like a serialized form of the event. And probably it would it would make sense to use MongoDB but the other ones also work well, you are not going to create the JSON data directly. It also supports things like Cassandra, when I know, and Azure Cosmos DB, if you go to that extent. And this is how we do how the cluster sharding works. So, I'm not going to spend much time but eventually what you do is you pretend as an entity exist and you send the message to that there's a factory of it. You specify the shard ID and entity ID, and then you can send the message to that and this is how you you work against across the sharding with F sharp. There's an important cycle. Once you message, once you receive a message, you first validate the command. For example, you get a place order command, you first validate it maybe there's enough stock or not.  Let's say there's enough stock command place, so order place three, or order rejected. You apply the state, such as reducing the stock, you persist the event, the database, then you publish the event. You follow these five steps, and all of them would would happen automatically. There's nothing will come in between because the actors are, you see that there's a message you're listening. They will not accept a message unless you will you will run through a full cycle. Okay, so this this thing will happen in a single transaction. I have some personal side project, for example, where users, for example, make a calculation. And then, typically knock it out net. This is how I model my commands and events so that's it. For example, you can add a credit consumer credit or you can just a user can log in. And the outcomes of these events are just comments is is here. So notice the difference between a command and event is command represents something a demand that can fail. And event represents something that hasn't already happened, which cannot be undone. Okay, once an event has happened, it's done, it's cannot undo it, because it's happening in the past. And this is a well it's another snapshot of how I woke the the actor which I will not talk about much. And this is how a real actor looks like in in a shot on the on the left hand side so you can see that there's an important part called recovery.  And by default, what the academic does is it plays all those events from scratch. And then you just reapply those events and then then that's how you restore the state. However, this may not be ideal. And the reason being is that if you have one million events, you don't want to replay them every time your system bootstraps. There's a mechanism for record and therefore it's called snapshot. So time to time you need to snapshot the current state, let's say every 100 message. And then it will first fetch that latest snapshot, and then replay the remaining events on top of it. This is built into a good as well. And while here's another code showing this is the apply state so once you get a get a get a new comment how would you change the thing in memory. So it's just a regular function there's nothing special about it you get the event you get the state and then you just alter the state and you just returned a new version of state. That's all about it. How does it look in the database. So you can see in the right hand side. There's the, the, the, this is how I could fulfill the database. And there's a persistent ID that looks like the, the, there's a column here persistent ID that shows actor name. There's a sequence number shows that what is the message number for this actor. There's some sort of manifest that is used for civilization. And there's a timestamp there's a payload, which is the actual stylized message. It's a shame I didn't show the payload itself. What about the read side. So in the read side. I can offer said something called Akka streams, where you can subscribe to a stream of events. So you don't need to go to database read manually.  This is, for example, I'm using a scope provider here. I get a message called credit consumed in here I go to credit stable I found a table. I just did used to credit and I just commit. When I commit. I also commit the offset number, some number that that reminds me that was the last event I purchased in the same transaction. So that whenever I restart my process, I know what was the last event I created. So this is the commit part. I'm using a sequel provider here, and it's just commits the offset value and the regular table in the same transaction. In the same thing. So the offset title looks like this for each projection engine. I have a simple single line. And for example, there's the users projection engine here. This is usually how you will have one projection engine per application, but you have multiple ones. And then you have the offset count, as well as you can see this is the regular table. This is the crop table on the right hand side. That's actually the user here. Constructing. I have some live examples. One of them is I'll just show you, I have workshop here the source code is available. This is a live demo application I created for this workshop. You can order a pizza here. This is running on this full secure cycle. So something like that. You placed order. Well, it will ask me to log in. And you can play with it. Or if you're interested in in having the workshop. You can just contact me. But that's this is my this is pretty much about my presentation. It doesn't link to one. That's it. So once I placed order. You see there's a little bit of a synchronicity here it just shows the details a bit late. And through a web WebSocket it actually based on the events it reacts actually so you can see this is moving up now right now through the WebSocket connection. Thank you for listening. If you have any question, feel free to shoot. Will the pizza actually arrive. I know it's really late there. I'm surprised you're going to make it right now. Eventually it will arrive. Questions. This is a very dense topic. I know it's going to take a while to make a pizza. I know it's really late there. I'm surprised you're going to make it right now. Yeah, yeah. Eventually it will arrive. Questions. This is a very dense topic I know it's it's fairly. It's not easy to grasp at, but at first hearing, if you're not familiar. But I just my objective was to at least familiarize with concepts. We can have their own how your own ideas, how these things work, or maybe you can develop your own framework or use something existing one. But it's, it's, it's not easy to chew at first. So you need to one need to play and experiment. And you should consider the, as I said, as a summary, the motives, what benefits you get. So I told about I talked about how it helps you to protect your domain model from your changes. You have the all events recorded in your system, and you can just get away with some of the changes in the query side. It handles concurrency very well because actors are tested by default. So you will never have two messages at the same actor in the same actor at the same time. And as well as it actually gives you gives the developer the control back to you. You don't rely on the database as as the source of truth as much as before, you will have the control in your actor you will have the code I particularly enjoy this this part of the thing. When I when I use enter framework well I have entities hydrated from database, but you don't know if it is a single if it is the only entity at that time in the memory if you have to to concurrent requests then you have you will have multiple instances of the same ID, the same ID. And just, it's a bit of it becomes a very loose concept. On the drawback side, if you see there's a chatted traffic you need to manage you need to think worry about how to handle the transactions in a distributed way. It's not for faint hearted. So it's a trade off. I do have a question. And, you know, like, I've worked with C address before, but never in a ca. So, when your domain changes over time that maybe the, you know, the meaning of a command may, you know, suddenly morph over, you know, over time.  Are you doing some sort of versioning for your commands or how are you. How are you managing that change. That's a very legit question. So, command versioning isn't so much trouble but event versioning is a big trouble. The reason is that, in particular, once your events change, you, you're trying your from your persistence, you will get the earlier grudges on your events. Okay, then is, and you have to tackle with this. How would you this or this realize them and appropriately. So the ideal approach is that So I explained the events are represented discriminated unions. So the ideally you would create a newer version of the event as a, as a, as a newer, as a, as an under step of discriminated union and new discriminated union. That would work fine. But otherwise, if you want to, if you want to do it, you can also do control the deserialization because F sharp has some offering with the option types right. Then, while deserializing you can just say that well I introduced another sum of something. And then for the older versions of those events that it will be none. And then you will have the handle. One thing you need to be careful is that you should not share these events across your application much. I mean, sharing events is something very dangerous, because you make. If you share events and those events changes, then you make things very brittle. So it's, it's all although when we can think about I, if I have a event. Why don't I share it. If you want to, if you want your application to communicate with other applications. I would recommend using a separate set of events that's outside of your security event cycle. That would be my answer. So basically I would say I would suggest you create a newer version of those events and comments, rather than missing with all ones, if you can. I was just curious. So, you mentioned that you're using a WebSocket to notify the browser. Are there any good abstractions over that I mean I've had difficulties working directly with WebSockets like SignalR or something like that or do you have any recommendations in that direction. I used, there's something called Elmish Bridge. Oh, okay. Yeah, I'm familiar with that. Yes. Okay. And to be fair, it's documentation is super confusing and how to use it properly. It took quite a time for me. But that's what I use. I feel comfortable with it. It's a very good thing. So you have this Elmish loop in the client side and there's an Elmish loop in the service side. It just really complements it very well. That sounds nice. Thanks. One thing, one thing I just wanted to comment was that, you know, I found, so when Chris and I started working on this Valero project, I found owners repo out in the wild. I thought it was, it's really refreshing to see a nice sample project with, you know, some depth to it. You know, you talked earlier about how you wanted to give like a sort of a real world example. And I think that there's, in general, but then within the F-sharp community in particular, there's sort of an alarming lack of resources of how to actually put together a real world application. And so I was very grateful to see. This is what I was trying to address and my own capabilities, at least for my own part. And this is understandable. Function programming, I think still didn't make, didn't become the mainstream. And that's why we lack of these resources. And I think no one is perfectly sure how would you develop a simple application like a CRUD in a functional way. There are different ways, different things, but there's no one standard way just like it's established in the OOP world the way it is. So in my own capabilities, I try to address this thing. Yeah. Yeah, well, it's a great resource. So I think that is the perfect place to stop our recording. And after we stop the recording, we can continue our Q&A, but I want to thank you so much. This was wonderful. And so let's give him a big applause. Thank you. Thank you so much. Thank you.


This is a classic dilemma between, do you want decentralized security with all of the delays and all of the messy that that creates? Or do you want a quick answer, even if it's the wrong one? Everything is better with blockchain, right? I'm Adam B. Levine, and this is Speaking of Bitcoin. For today's session, I'm joined by the other host of the show, Stephanie Murphy. Hi there. And Andreas M. Antonopoulos. Hello. Jonathan Mohan is out today. On today's show, we're talking about voting. How does it work today? Would adding blockchain to the mix make it better or worse? Long-time listener Jaws wrote in with some questions, and it's a discussion you won't want to miss. I think we do all this live, so I actually have no idea what we're about to say. So, getting to the email from Jaws, so he says, Hi, Adam, I'm interested in a real discussion of blockchain voting. How that could play out, what the potential issues would be, etc. I've been fascinated with the idea of voting via blockchain since getting into the space many years ago and the recent presidential election, which, no, I don't think was fraudulent, but it has certainly raised voting security conversations in general in the public space. I think about blockchain voting from time to time, and obviously the auditing and honesty truth aspects are an amazing appeal, definitely more so than the various vendor-based closed source voting machines. But the main concerns I think about are, one, how to onboard all citizens? How to essentially get everybody a private key? Do you do a national ID that also happens to be embedded with some sort of secure NFC private keys that is used to vote and then can scan the card or a public key QR on it on a home computer or phone to verify the vote? The challenge is making it usable to a large population of non-tech savvy foes. And then the other point is, what blockchain would this run on that would be most secure? Would the government run it, but anyone can run a node to help? Could that be trusted? Wouldn't a new blockchain with low incentive put up by the government be easily attacked by other stakes? Should it run on Ethereum? Could the Ethereum network sustain 150 million votes over a day or a week's time? How would foreign governments attempt to attack the Ethereum network to disrupt this? And how successful could they be? Wouldn't it be more palpable on a sharded ETH2 network? Anyway, still loving the show so much. Thanks again for your hard work, Jaws. All right, so that's a long email. A lot of questions in there. We're not going to get to all of them today. Well, I think we can simplify it. You said at the beginning of the show, Adam, that is everything better with a blockchain? Well, if you ask certain people, they would say, yes, but I don't think that I agree. So I'm going to say that this listener, Jaws, we love you, but you're overthinking this because this blockchain technology is not ready for prime time with voting for national elections. It's probably going to be used in voting in corporate situations. I'm sure various iterations of it, but for voting in national elections, no, it's not happening yet. I think the best bet is to go back in time actually rather than forward and go back to paper as much as possible and little Scantron machines. So when you start to think about voting, I think that there's all of this space to improve the way that democracy works in so far as getting more people to participate, being more inclusive about this. And so I think that people often come to technological solutions like blockchain on one side. But I mean, I recall back during the primaries this last year, there was the Iowa caucuses, right? And the Iowa caucuses are like this really, really old school way of doing politics where it's not even like a vote where everybody goes to. It's like people gather in a room. Yeah, they take a straw poll, right? Yeah. What is a straw poll for people who have never heard that, maybe international? So a straw poll is like a sentiment poll, right? And basically, instead of there being one vote where you vote and then that's the person you voted for, there's opportunities to discuss and to caucus, so to speak, to find the people who you agree with mostly and then to vote with them. And the part that's relevant, I'm not an expert on caucuses, I'm living California most of my life and I've never actually participated in one. But the important part is, is that it's a very manual person-to-person, in-person, at like community center type of thing. And what happened during the primaries last year is that an application was rolled out that was used to collect the reporting. And the application had some problems with it, but there was mass chaos throughout the system. And the mass chaos throughout the system had little to do with the software and it had more to do with the fact that you were asking literally tens of thousands of people to use an application when most of them were like in their late 60s, right? And you were asking them to change a process that they were very used to to a new process that introduces new challenges and new advantages, but which they weren't familiar with, in which they hadn't been very well trained on. The relevant part here is that the problems that blockchain is going to have when you try and put it into these situations, it's almost not about the technology like most of the things we're talking about, it's about those processes, right? And there's another part too, which is that blockchains are really good at knowing about stuff that happened on the blockchain, right? So if I send a transaction from me to you, Stephanie, then the blockchain is really good at knowing that I sent a transaction, because the thing that we were doing is encapsulated on and happens on the blockchain. But a vote isn't something that naturally happens on the blockchain. And so as Jaws correctly points out in his questions, there's all this opportunity for someone to get in the way. And really the thing about voting that it comes back to is how do you tell who is a person and who is somebody who is pretending to be a person such that they can get more than one vote, right? And this is a problem that actually we're very familiar with in cryptocurrency. It's called a civil attack. It's kind of like a third degree problem, because the first problem, the one the blockchain solve is how do you ensure that participants in transactions or the consensus mechanism are not easily civil attacked? But when it comes to voting, the vote isn't available to everyone on the planet. So simply being human doesn't make you eligible to vote. So eligibility is a form of attestation. And attestation is something that is associated with identity. So this is a second layer problem. This is not just civil attacks. This is about identity and identity because you have to first attest that specific people have eligibility to vote. And in the US specifically, eligibility to vote isn't enough because we don't have automatic registration. So you have to have eligibility and be registered. You have to in advance express the desire to vote and be registered as an eligible voter. But that's not where it stops. That's the second layer problem, which is identity, which we have not solved with blockchains yet. It's a very difficult problem. It's one of the holy grails of computer science. And it's not something that has been solved yet with blockchains. Then there's the third problem, which is great. You've got identity registration eligibility sorted out. But when you actually cast a vote, you now need to strip that identity and yet ensure that no one gets to double spend their vote. So you need to verify eligibility, but then you have to preserve the anonymity of the vote, which is a critical component of the franchise. Without anonymity, the vote becomes something that is sold, extorted, all kinds of shenanigans start once you remove anonymity.  And that somehow magically ensures that all of the voters vote for Kim Young-un, at least all of the voters that are still alive after the election. So anonymity is a pretty critical concept. And that's the third tier. So blockchains can help if you can solve first, transactional civil resistance, and second, identity attestation and eligibility, and third, anonymization after eligibility. We are very, very far from solving these problems. So the United States has an electoral system. I've heard it described as decentralized, but they don't mean like decentralized, like voting on a blockchain or something like that. They mean decentralized in that every locality, every county has sort of its own process, and every state has their own rules. And it's really like this patchwork hodgepodge of votes, but somehow they all have to vote in a common election for the president of the whole United States. So do you guys think that represents a form of decentralization? It's a very good point, which is that the federalist system that decentralizes voting, most people don't understand this, but voting in the United States is managed by the state exclusively without any question. There is no federal enumerated authority to do anything other than count the results. The federal government has no role in certifying, it has no role in verifying, it cannot even challenge, has no standing to challenge, the way elections are run. There were some brief periods where there were some implications for that, specifically the Civil Rights Act. But most of those provisions were actually repealed recently. And so the states get to run their own elections. Now this is incredibly frustrating to people who want to see consistency, homogeneity, predictability, auditability, and also because many states attempt to do all kinds of shenanigans when it comes to the voting process. But it's the other side of the coin, which is that for all of those reasons that are incredibly frustrating, this system is very, very resistant and robust to centralized manipulation. It's actually very difficult to manipulate an election across the entire country because you have to do it in 50 different states. And even within those states, the process is decentralized in voting precincts that have actual voting centers, which have independent monitoring, et cetera, et cetera. So there's layers and layers and layers of decentralization. And at each layer, there's layers and layers and layers of oversight and often competitive or contentious adversarial oversight by the opposing parties and campaigns. And this actually ends up being very difficult to compromise. So the things that are very frustrating are also the things that actually make the system robust. But they're also the things that make the system very difficult to change. So if we did see any kind of blockchain voting or any kind of technology change that's implemented in relation to voting, we would start to see it on a local level first and a patchwork of different systems. And that is what we have today. There's some states that rely really heavily on paper ballots.  And then you go to another machine to scan it. And so they do have different systems in different places. And like you said, Andres, that's frustrating to some, but also you could argue that it does add a little bit of robustness to the system because it is decentralized. A lot of robustness because failures, if they occur and when they occur, are localized. They're contained. They're not everywhere. There is no single point of failure in the electoral system. And what you didn't mention is there's also, I think, five states where voting is entirely done by mail or where vote by mail is the primary mechanism of voting. I think there's one state where it's entirely by mail. Oregon has an entirely by mail system, yeah. Yeah. And four more where it's the primary voting mechanism and you can opt out and go to a local precinct, but instead by default, it's assumed that you will vote by mail. And many other states have no questions asked, no excuse needed. Very simple mechanisms. California being one of them I voted in California under this mechanism always by mail. And it's very simple.  And can you track it? Like, can you go and check what the status is? Yes.  And you can go on a website and they will tell you if they have received and then if they have counted. It's almost like tracking a UPS package. You can say, okay, they've received it. All right, now it's actually being delivered and it has been counted. Yeah. So presumably if we were talking about like, how would that look on a blockchain, quote unquote, because that is like a buzzword, right? Put it on the blockchain. But under a blockchain based system, perhaps you would use your unique identifier or your private keys or your public keys to look up your voting transaction and, you know, what time it occurred and validate that it was actually you casting that ballot and that it's been counted and recorded in the blockchain and it happened at this time. Yeah. And interestingly enough, the whole idea of having an envelope that is sealed on the outside, the serial number on the inside, a homogeneous ballot where, you know, you've got to understand that when I send in my ballot and I've taken off the serial number off the envelope, there's a serial number on the envelope, but there is none on the ballot itself, meaning that they can track that my envelope was received and when they open the envelope and put it through the counting machine, they scan and track that my vote was counted. But of course, the ballot itself that can then be audited after the election is not related to a serial number and they can't see who voted. They only know that mine was counted and one of the ones that was counted voted a certain way, right? So in fact, in cryptography, if you want to teach someone cryptography, the idea of having a sealed envelope that you sign on the outside that leaves an imprint on the inside is one of the techniques we use to teach this concept. This is called a blind signature. And a similar concept that is very popular and has received a lot of research lately is the concept of zero knowledge proofs. A zero knowledge proof is where you can prove something is true without actually revealing what that something is. So this is a classic application of zero knowledge proofs. You could prove that your vote was counted, but no one can actually tell what your vote was, right? And so the election officials can prove to the voter that their voter was counted. You can even prove that it was added to the sums, but the election officials do not know what that vote was for. And most importantly also, the voter cannot demonstrate to someone else how they voted. And this is important because in the past, it was very common to buy someone's vote and then require proof that they voted the right way. Yeah, this could also be used for all different forms of retaliation. And so it is important to have some kind of privacy protections for the voter to keep their vote secret.  So that's a whole different question. But the point is, it is important to have some kind of privacy protections in there so that people can keep who they voted for secret, but there's still some kind of audit trail so that you can demonstrate and validate the election results later if you need to. I'd like to briefly dig into this a tiny bit more because I find this a fascinating topic. I voted in three different countries, and I've also ran an election in three different countries. I was a volunteer for the elections in Greece. I have also both voted and volunteered for elections in England. And I also have voted and volunteered. In fact, I was a precinct captain in California. So I ran a precinct and I did the audit. So I got to see kind of the mechanisms of three different countries and how they work. And I find fascinating this whole concept of the secret ballot, some brief history, until 1890, in the United States, ballots were not secret. And you're like, what? Really? Is that true? Yes, it is true. And in fact, until that time, a secret ballot was known as an Australian ballot, which blows my mind. And the reason is because Australians started using secret ballots and then that was adopted by Americans and first by Massachusetts. So then the secret ballot was known as a Massachusetts ballot. And only after 1890, did it become a secret ballot everywhere in the United States. And you see this in a lot of countries. Before that, various organizations would distribute pre-completed ballots that you would cut out of, say, your newspaper. So instead of endorsements, they would print out a ballot already voted. And you would cut it out of your favorite newspaper. And you would just drop it in the box and vote not just on a party line, but on a newspaper line effectively. And one of the things that created were situations where people were obviously pressured, bribed. But I think one of the most interesting things was the issue of the suffrage for women, the suffragettes. Because one of the things that happened when women were first given the vote in the United States was that they were pressured by their husbands to vote the way the husband wanted. And not only pressured, but they required proof. So this is a very interesting thing. Most people don't think about this, but the secrecy of the ballot isn't just because you might get chased by some opposing element down the street. In many cases, it's your own family. And I love this idea that someone can go into the voting booth screaming at the top of their lungs the husband's candidate name the entire time, and then drop a ballot for the opponent. And no one will know. I mean, that's the important part about that anonymity is that you have plausible deniability. And so it's actually something that used to exist within parts of the higher government. What was the guy's name, Stephanie? James D'Angelo? Yeah, that sounds familiar. When we were getting started with the show, he did a bunch of videos about Bitcoin. And then he left the Bitcoin space after he made this video about how the reason why Congress doesn't work anymore is because I can't remember the exact date, the 60s or the 70s. They made it so that all of the politicians who voted their votes were logged and you could see who voted for what. And his whole thing was that by removing that anonymity, it was cheered in many circles as a way to make sure that our government representatives are being held accountable. But what it did, in effect, was it removed the plausible deniability that the representatives had so that they could have lunch with lobbyists, right? And say, oh, yeah, sure, I'll vote for that thing. But then they actually, when they're making their voting decision, could vote their conscience.  And again, if you look at how the US government is set up, and this is a whole other episode that we'll have, decentralization is at the core of almost everything. Many of the changes that have been made over the last 100 years to the way that the government works have actually removed certain elements of that. It's still really decentralized. 100 senators right from 50 states, and you're talking about 400 and I think 35 representatives. Decentralization is messy. It is messy. It is inefficient. It is not the best way to do things. But it's hard to mess with. It's hard to go and compromise all of these different areas. There's just so many moving parts and they do things differently. Now, some of that difference and some of the value of decentralization can actually come out of it a little bit. If it's a decentralized system, but everyone does the same things the same way, right? We've seen a little bit of a drift towards that as voting machines have come in and other things like that. But again, as a system on the whole, it still is highly decentralized and therefore very robust against any sort of systemic disruption. Disruptions at a local level, those things happen. Systemic disruptions much harder to pull off in the decentralized system. Hey, folks. Adam E. Levine here for a quick update. Last week, along with the show, I listed our first NFT collectible in a no reserve auction and within a day we'd received a very generous bid for one ether. To be honest, it's really humbling to receive that sort of support from a member of the audience. And it's enough of a proof of concept that we're moving forward with some larger projects around tokenized collectibles, which I'm excited to share more about probably next month. In the meantime, check the show notes for this episode to find our second collectible token available in another no bid auction that, just like last time, will run from the release of this episode on Sunday, the 14th of March and end sometime between Saturday and Sunday of the following week. So if you missed out on last week's, here's another chance. And for folks who'd like to collect or patronize our show, but who can't justify the prices we've seen so far, have no fear. We're working on a less exclusive series that you won't have to compete for. But all that's in the future. For now, happy bidding to those of you who will be doing so, and thank you very much for listening. And now, back to the show. I'd like to relate this back to an argument or debate we've had about Bitcoin in the past, which is extremely relevant to this. And that is that you can have very decentralized robust transactions, or you can have cheap and fast transactions, but rarely can you have both. And one of the things that's happened, and I've certainly noticed it in the 20 years I've been in the United States with elections, has been that the influence of the TV real time bar chart pie chart reporting of election results has over the past 20 years steadily increased the emphasis on speed of closure, to the point where some people are like, what do you mean they're still counting on the fourth? When in fact, it's very, very common to still be counting ballots a week after the election. So if you want really, really fast elections that give you closure where you get a result as quickly as possible, North Korean elections achieve that. The result is already known before the election opens. It's a very efficient system. And if you want elections that cannot be compromised, that require manual auditing and recounts and have triggers that occur when things are close and they need further scrutiny, and they have layers and layers and layers of auditing and certification, well, that's going to take time to count. And it's perfectly okay to take that time. And so this is a classic dilemma between, do you want decentralized security with all of the delays and all of the messy that that creates? Or do you want a quick answer, even if it's the wrong one? And I think the emphasis here has to do with the difference between casting and counting. A lot of the efficiency technologies that have been introduced in American elections over the past decade have been about counting votes fast. And in the process of ensuring that votes can be counted fast, they've changed the way the votes are cast. Stephanie mentioned before the idea of a paper ballot that then is scanned by a scantronic machine. So for people who are outside the US who have never heard of this idea, this is also how the university entrance exams are scored. Yeah, I was going to say that if you're at least like kind of my age, this is how your teachers tabulated the results of your tests. Right. So the way this works is you have a card or single page sheet and it has some choices.  And you take a soft pen or pencil and you fill in the oval so that it's black. And once you've done that, the ballot or exam result or multiple choice test answer or whatever it is is fed through a machine. And all the machine does is it scans a barcode to know which ballot it is because there might be national, local, federal, there might be several ballots with different arrangements on them.  Or if it's an empty circle, it marks the other result. And so that's how voting happens. And the brilliant thing about that is that it solves both of the problems. You can count really, really fast because you can have a machine count it. And then if there's any doubt about the count, you can audit the actual paper balance because they're still there. And these machines tend not to be connected to the internet either. If there's concerns about malicious actors being able to access the machines through the internet, which I've heard lots of people talk about recently, these Scantron machines are a technology that has been around before the internet really. And they don't need the internet to operate. And so it's like a good old-fashioned incandescent light bulb solution that works. Yeah. The way they look, in case you're wondering, is they look a bit like a photocopier that has a feeder at the top. So you put a stack of, say, 500 ballots in the top, and it goes flip, flip, flip, flip, flip, flip, flip, and makes a lot of worrying noise. And then at the end, it just shows you a count on a screen. Actually, the last time I voted in New Hampshire, they were using a system like this, and they would put your ballot through the machine. And then if there was any problem with it, it would beep or something, and they'd say, oh, there's a problem with it. But if it went through, you knew that your vote was counted. Yeah. Now, the beauty of this, of course, is that you can go back and manually go over them. This beauty was ruined by Florida Institute's mechanism where instead of filling in the oval with a pencil, people would punch a hole through a card. The hanging chads. And they created the hanging chads fiasco of the 2000 election. Well, I mean, to be fair, there was a problem. I remember you used to have to use a number two pencil to fill out these exams. Well, the point is, there could be problems with paper ballots. There could be problems with punch card ballots. There could be problems with any system. But I mean, it's great that we have the opportunity to try out different systems in different places and have this decentralized patchwork. And I think that, yeah, probably even though there's some concerns that I have about it, states and counties will move towards more electronic voting systems. Will they be blockchain-based? Some of them, yeah, eventually as we get farther into the future. And we'll see how it works out. I think that if blockchain voting is first refined and smart contracts that manage it are first refined in corporate settings, like not public kind of election settings, that would be helpful because the kinks will be worked out basically. And private companies, I think, would be good at refining these kinds of smart contracts. And we just have to try it and see if it works, I guess. We need to be very careful about separating the motivation to count fast and give a short attention span audience the closure they want with discarding the ability to even audit these results. It's one thing if you're filling in a paper ballot that gets scanned fast. It's a whole other thing if you're tapping on a touchscreen of a Windows machine that hasn't been patched that's connected to the internet and is counting. And there's absolutely no way for anyone during, before, or after to figure out if that thing actually counted the vote and if it counted it correctly. That's a problem. And my perspective with security has always been that the number one rule with security is keep it simple.  Nothing beats paper and pencil. I will say that when I'm talking about 24-word mnemonics and people will say, no, let's encrypt it and put it online with double encryption AES and no, no, steel, punch, paper, pencil, simple, offline, manual, auditable, transparent, replicable, resilient, robust. These are important principles and some things that a five-year-old can replicate. Or a 65-year-old. Or a 65-year-old. And these voting machines that are running Windows that arguably are 90s technology or maybe early 2000s technology are already opaque, unauditable, and not transparent. Adding blockchain to that mix, simply alienates a whole new group of the electorate that won't be able either to vote in the first place or if they do vote will have zero confidence in the outcome because they have no visibility into how it works. And I think that's the wrong direction to go in. In fact, as Stephanie said, keep it simple, keep it primitive. There's no reason to rush the count. There's no reason to make elections efficient. Efficiency isn't the parameter we should be optimizing in elections. Access, transparency, motivation, eligibility, and franchisement should be the goals we should be maximizing. You know, to me, I think one of the most iconic symbols of voting technology is indelible ink that people dip their finger in after they voted so they can't vote twice. So here's the deal. This is a longer conversation. This is the end of this episode, but it is not the end of the conversation. As Andreas started to get into there, we're going to talk on the next episode about the identity challenge, indelible ink, signature verification, you know, blockchain ID, all of these different ideas that all have their advantages and also have their disadvantages, too. The other thing we're going to talk about is what blockchain could something like this go on? And, you know, again, our listener Jaws who wrote in had some really interesting ideas around that. We're going to explore those ideas on the next episode. So this has been kind of like an introduction. And I think you got the broad answer, which is that if we just plugged blockchain into kind of the system as it stands right now, would that make things better or make things worse? Chances are pretty good, it would make things worse if you didn't change anything else because the problems that blockchain is trying to solve really don't address many of the issues that are underlying problems with accessibility or, you know, the ability to validate our election system as it stands right now. But that is the next episode.