 Well, welcome again. So this is part two of the Firefly demo. I talked about one thing that Firefly can do to help you out is to track and initiate token transfers. And another thing that Firefly does really well is help you connect to different chains, right? Both public chains and private chains. So very similar to the previous demo, I'm going to kind of start with private chains, because that's kind of where we started with Firefly 1.0, very focused on the enterprise use case of multi-party consortia that want to exchange data in a controlled way. And then we'll talk about the new functionality in 1.1 with connecting to public chains. So I'm going to use the same workspace that I used for the tokens demo, just a reminder that we have three Firefly nodes here. I have node 0, I have node 1, and I have node 2. And they are, on their default namespace, they are sharing a consortium. So the point of these multi-party consortiums is that you can create certain things, such as token pools, such as data type schemas, and they'll be shared with everybody so everyone can agree on them and reference the same copy of those. In this case, I'm going to go back to the sandbox and show something that you may have seen before. So we'll breeze through this quickly. But I think one of the coolest things that Firefly does in talking to private chains is this marrying of on and off chain data. So say I have a use case where I'm in a consortium and I need to tell everyone that a shipment has been received and broadcast that so that everyone sees that there's proof that I got shipment X. So I can send a broadcast message, shipment 100 was received, and then send that broadcast message. This is going to, again, be a combination of on and off chain messaging. The actual body of the message is going to go into IPFS, and then a blockchain transaction will be written to point to it. If I go to my timeline, I can see here, messages are always batched up for efficiency, because obviously the blockchain is not great at high throughput of messages. So we're going to batch a bunch of messages up if we were sending a lot at a time. Here it's just going to be a batch of one. But then that hash of the contents of that batch is going to be written to the blockchain. So here's the initiation of it. And then the message is confirmed. I can see everyone receives this, shipment 100 was received, blockchain event was written in block 18. So the hash of that message is written in block 18. And everyone can compare the contents of the message, compute the hash, and check it against the hash that was written on the blockchain. And then you know that these two pieces go together. And because this was a broadcast, everyone's going to have exactly that same blockchain event for block 18. This right here shows the block number and the transaction and log within that block. So block 18 and the same here. And of course, they all get the message confirmed that they can all see this piece of data. So this makes it really, really easy to marry the on and off-chain data and firefly guarantees that regardless of how fast or how your off-chain storage works, the events will always be delivered in the order that they are on the blockchain. So it's a really powerful guarantee. You can order your applications based on that and know that, OK, we're all going to get, if everyone's sending these different shipments that they got, we're all going to process them in exactly the same order, regardless of how reliable or slow or fast our off-chain messaging is. The blockchain is the authority for how to order and process those messages. But if I wanted to send a private message and tell just one of the recipients the contents of that shipment because they're privy to that, I can also send a private message, maybe the contents of the shipment. 100 firefly t-shirts. I think that's wishful thinking. I don't know if we even have any firefly t-shirts left. But you could always check the booth just to be sure. So maybe only org one is privy to this piece of data. So I'm going to send this one as a private message to org one. Run that snippet. There we go. I have some new events. So because I'm the sender, org zero, I see both the initiating operation and then I see the blockchain event and the message itself with the contents of that message, which again, contents of the message could be text, JSON, binary, files, lots of blobs, anything you want can go in there. They'll all be chunked and sent across off chain. Org one, because they are privy to this message, they have a blockchain event and a message confirmed. Here's my details, exactly the same. But org two, since they were not there, they get the blockchain event, but that's it. They see that something was written to the blockchain. It has a hash of a message in it, but they don't know what it means. They were not privy to the message. They are not sent the off chain portion, so they can't reconstruct that. All they have is the hash. They know something happened, but they don't know what. They don't even know who sent it to who. We obfuscate even the sender and the receiver of the off chain portion. So you cannot do anything with the hashes that are on the blockchain unless you also have the data and then you can compare to see that it was the right data. So that's one way that Firefly helps in a consortium. I'm going to show one other way to talk about consortiums, and I'm going to move to public chains as well. I've interacted with a couple different tabs here in the sandbox, and I'm going to go to the last one, and this is for smart contracts. We talk a lot about kind of the three pillars of Firefly being digital assets and on and off chain messaging flows and APIs for building applications, because obviously most blockchain applications will end up having some sort of smart contract work. Firefly has this built in single smart contract for the on and off chain messaging, but that's the only smart contract that it prescribes, and we provide an implementation of that on both Ethereum and Fabric. But you can also write your own custom contracts in Ethereum and Fabric, and Firefly makes it really, really easy to interact with those as well. So the first step with these contracts is to define a contract interface. Firefly comes with a interface format that we created called FFI, just Firefly Interface. We needed a blockchain agnostic way of describing smart contracts, what are all the methods on them, what are all the events on them. So this is the format that we use, but we also support, since Ethereum has a well-defined ABI standard, we also support Ethereum ABI. Fabric, not so much, maybe not a single standard format there, so we don't have one. But again, it's pluggable. Any other format that makes sense to support, we could take that in as well. I'm going to use the ABI format, and I'm going to use a contract called Simple Storage. You might have run into it. It's just basically a get method, a set method. You can set a single value. You can query the current value. And we've extended it, so you get events when it changes. So two methods, one event. It just so happens, the Sandbox pre-populates that, because we do demos of it so often. So I'm going to create a interface definition for the Simple Storage interface. It's going to go in. I see I asynchronously get my events to say that it was confirmed, and then everyone can see it. If I go to blockchain dash, I won't see it yet. I got to do step two. They all got the message. So they know about the interface, but they can't really interact with the interface. I do need to actually deploy a contract that conforms to that interface. I'm going to use the Firefly CLI for that. I haven't shown you live any sort of use of the CLI, but it's a really powerful tool as well. I'm going to use the Deploy Ethereum command. It's a suite of a bunch of different commands, but this one will let you deploy a smart contract to either an Ethereum or a Fabric blockchain. So my chain is called demo, and my contract is at this path. All right, so I'm going to upload my Simple Storage that has the bytecode in that JSON, and there it is. So that's been deployed to my blockchain, my consortium private blockchain, and now I can go down here and register what we call a contract API. So an API is a concrete endpoint that I can use to interact with a particular interface. And so I'm going to build this, maybe we'll do a snippet, I haven't done this yet here, so we'll do a snippet in the code editor. Just to show you how easy it is to take things from the sandbox and go directly to actually building a real application, right? So I'll do create API, not polygon. We're going to the default consortium right now. All right, so this is my code snippet. I got it directly from the sandbox. I'm going to run it as a TypeScript application. And there we go. So what that's going to do is it's going to send a message to everyone, very similar to how we did custom broadcast and private messages, but it's going to send a definition of this contract API. And if I go to each node and refresh, they are now each going to know about the API. So this is a really nice way to kind of advertise. Okay, to everyone in the consortium, here's a new API that we're going to share. This is the address on chain where you can interact with it. You can see who deployed it and you can see the interface that it conforms to. And very cool as well, you can open a generated swagger API for it. So it takes that API and it parses it into post methods. It's not really REST, it's more RPC style, but it's a really, really easy way for sort of traditional web developers to interact with a smart contract that defines whatever logic you like. I'm going to do one more step before I interact with it and that's to register a contract listener. So I'm going to say I'm interested in the changed event. I'm going to create a new topic called changes and I'm just going to add that event. So I'll get notified every time that event happens. This tells Firefly, okay, I'm interested in this event. Please catalog it every time it happens. Give me a queryable database record of every time that event happened and what the parameters were. So now that I have that in place, I'm going to go back to my swagger. I'm on member one or node two, sorry, node two here. So I'm on node two and I'm going to have him set this value. We'll set it to 55. So I do that simple REST request. It comes back accepted and it's going to kind of propagate its way through the chain. I can check the status of it with this ID if I want to but we have a pretty low block time configured. So it should be done by the time I can get back to the right tab. If I look at blockchain events because on node zero, I told Firefly, listen for change events. It's listening for change events. So it cataloged that this change event came in and came from the Ethereum blockchain and this was the output, right? From this address, value was changed to 55. So and then what you can do then in your application is add a web socket that subscribes to these and Firefly will save your checkpoint. You can hack each message, right? So it takes this complicated thing of listening to the blockchain and we put this messaging in front of it so that all you have to do is connect a good old web socket. You'll get all the messages in order as they come. Any messages you indicated you were interested in you hack each one to say that you've processed it, right? And it's just a very, very easy way to go from blockchain to business application logic. So I said I was going to do public chains as well. So that's kind of a lot of the use cases within a private consortium, right? Where I want to create these definitions. I want to share them with everyone. We all want to have access to it, right? We all want to know where these APIs are. We want to be able to subscribe to each other's events and see what everyone's doing in the network. Slightly different in a public context but a lot of the same operations apply. So I'm going to switch on my node zero only. This node has got two namespaces. He has not only the consortium namespace but he has a separate namespace that I've called polygon. We've talked a little bit about the role namespaces play in Firefly 1.1 where you can have as many namespaces as you want. They can be shared or not shared, right? They can be gateways or they can be multi-party systems. All my other nodes are only part of the multi-party system. They don't care about this public network. So I'm looking at my polygon namespace here which is again pointed to polygon.mumbi.testnet. And we're going to go ahead and deploy a contract to Mumbi. I preloaded a little bit of MATIC so I can put a contract out there and you'll see you can interact with it that exactly the same way. I'm going to do this in Postman for some variety but I'm going to start by posting. I'm going to use the layer under Firefly because Firefly is unopinionated about how you deploy contracts. It's kind of up to you if you like to use hard hat or truffle or anything else. It provides the FF tool but that's really a little bit limited to certain scenarios. But you can use things like EVM Connect which sits under Firefly and is a part of the Firefly project. EVM Connect also provides a REST based way for deploying smart contracts. So that's what I'm going to use here just to kind of give you a flavor of some of the different tools in the toolbox. I've already pre-populated this with the ABI and byte code of the simple storage contact. Same exact one that I used in the multi-party example. I'm going to, oh, that did not work. Maybe I will use a pre-deployed contract. I'll skip the deploy step and we'll use a pre-deployed contract. So I'll go straight over to the next step of defining the interface. This is the same thing I did in the sandbox for saying, okay, here's all the methods. I've got here, I've pasted it in an ABI. Just to show you, there's kind of a two-step process. There's a generator that will convert it to the FFI format because Firefly always kind of deals in FFI. That's just for consistency across blockchains. But if you start with an ABI, which I have here, I just copied this directly out of that JSON into this API call and I can do this generate. It gives me a body down here that's now an FFI format and then I can paste that back in here to do a creation. So I'm posting to Firefly on my polygon namespace to contracts slash interfaces, which is gonna define the interface. Now, it looks a lot like what I did in the multi-party system, but the difference here is there's no broadcast, right? There's no sharing. So you use the same API, but it behaves differently. It just defines it locally. It shoves it into your database and it doesn't send anything to anybody else. So that's when you have multi-party mode off, it's just a local storage. So here I have, it created this interface. It gave me an ID. I called it simple storage version one, same as I did on the other namespace. Everything's isolated, so it's a new construct. And then I'm gonna go to the APIs, right? So I created the interface. I created the API and I've pre-populated this with the address of an instance of this. This is already out there on Mumbai. So this is, I'm saying it conforms to this interface. Here's the address where I deployed it onto the public chain and I'd like you to create an API called simple storage. So there we go. It's there and if I go back to the blockchain page, I can see now, member zero in their polygon namespace knows about this simple storage that's out on polygon Mumbai. Again, nobody else would know about it because nobody else is participating in this namespace. So I can open it up, looks exactly the same. I can get the value. I wanna do a query. So query, this is a call. In Ethereum, if you do a query, it's a call. And invoke is a sending a transaction to actually be mined. This is something one of my dockers seems to have gone down. So let's, I'm gonna bring the whole stack down and restart it. I don't know. It'll take a second to restart. So while that's restarting, it'll take about a minute to restart. Any questions on the private side of it that we went through, you know, consortium-based public and private messaging, smart contracts, REST API generation, any questions on that side of it? All right, it's back up. Go ahead, yeah. You said, are you able to use a smart contract from another chain? Another chain meaning like Ethereum or Fabric? Yeah, yeah, you could definitely use, you could set up a namespace that points to Fabric, a namespace that points to Ethereum, et cetera. You can call, Firefly can call it through either way. Maybe let me come back to it because I think we're running low on time and I do wanna show this piece, but I don't wanna forget that either. And I'm afraid I'm misunderstanding the question. So we'll see, we'll give this one more try and see if the swagger works this time. So see if I can, Firefly X4, you recreate the interface and recreate the API. Now it's up and we will try to set the value. So to 10, now ETH signer is not liking something that I'm doing today. So it looks like we're not gonna be able to do the public chain portion of it. Yeah, something failed here. I don't think so, that seems wrong. Yeah, yeah, something went down. I'll try one more time to start it back up and then I think we'll be at time. So let's see what we get here. Hey, all right, it worked that time. So let's see if I can now query it. Oh, query, get. Okay, the value was set to 10. Last thing I'm gonna show you is if I create a listener. So the same way that I created a listener on, let's see, maybe I'll do it through the sandbox. So if I wanted to create a contract listener for simple storage, changed event, and I'm going to, well, I can't do it from box zero. It would take too long to come back up. Are we at time? Or do I have time to, let's see where my address is. So I'm gonna pull this up on here. This is my contract that's deployed on testnet and we'll take an index events from this block. I say I want that to be my first event. I can copy this code snippet. I can put it in here. I can run it on the polygon namespace and I should have a contract listener that starts indexing those events from the public chain. We shall see if we get them. It'll take a minute. Let's see, I think I just got one. And there I got change events. So there, that's listening to a public chain, creating a contract listener. So just the same way, it's all private to my node, right? I say these are the events I'm interested in, index them from this block and it'll listen, and I can interact with the REST API and see the events. Yes, these might be the first ones because I used this contract yesterday as well. So this one, yeah, there, set it to 10. Not sure if that was the exact one I just did or when I tested yesterday, but it's going through and it'll catch up to the head, to whatever the events are. See if this is also, that one is also 10. So yeah, this is probably the one I just did if we look at timestamp. Yeah, I think that's where we are right now. All right, I don't know if we have time for some questions. I could try to get back to your question unless there's any, you were asking about interacting with different chains? You can't, okay, I think I understand. You're asking if you can trigger a call on one contract on one chain from a call on a different chain. Firefly, it's not so much triggered directly on chain, but at the business layer, you could definitely listen to events from one contract and execute things on another contract and you would have to implement whatever layer it is that kind of ties those together. Firefly doesn't directly provide that connection. Exactly, exactly. And that is common, right? To have these two streams of information and based on something that happened over here on my consortium chain, I'm going to trigger something, this fabric chain gave me an event that means that I need to, as a business application, trigger something out on this public chain, right? And I need to roll something up or things like that. Thanks, any other questions? Well, if there are no other questions or if you think of one later, come and see us at the booth. Sorry for the slight hiccup in restarting a docker, but I think we got through everything I wanted you guys to see. So thank you very much for attending and hope to meet you out on the floor.