 Okay, you're alive. Excellent. I'm just going to grab the link for the guy that we'll be using. I'll send that out in just a minute, actually. All right. We're ready to kick off. You're good to go. All right. Thank you everybody for attending today. I'm really excited about this workshop. Looks like we have a good turnout and it looks like folks are still joining here. So let's go ahead and get things kicked off. My name is Nico Geier. I'm a software engineer here at Kaleido, and I'll be joined by Alex Schorcher and David as well. There are two other engineers here at Kaleido and also maintainers on Hyperledger Firefly. So Alex and David will be helping out with the workshop today. There is a channel in Discord that you can join if you haven't already for chat. This is going to be a very interactive, very hands-on workshop. We're going to go through things slowly, intentionally so that people can follow along and do things on their machine as we go. So just a couple of, you know, let me just share my whole screen here so I can share another window. Sorry about that. I'm just going to switch this real quick. Okay. So just a couple of things. This is the guide that we will be going through for today's workshop. I'm going to just drop this in the chat. So you have a link to it. If you don't have Docker installed on your computer, you will need that. You'll need Docker and Docker composed. So go ahead and get that set up. There's some notes and prerequisites in the, in the top of the guide here. So you can start looking through that. I do have a few slides that we'll go through kind of to kick this off, but if you just want to glance at that real quick, just to make sure that you'll be set up for when you get to the hands on part that you can go ahead and do that. The other thing is the, here's the, the channel that I mentioned. So if you join the hyperledger discord server, if you scroll down to the firefly channel, there's a firefly workshop channel here in the firefly section. This is the channel that we'll use for a dialogue during the workshop. So if you have questions or if you get stuck on something or need help post it here and I'll try to monitor this, but Alex and David will be monitoring it and answering questions in there as well. Okay. So where do my slides go here? Cool. Here we go. So just real quick, want to go through the goals of this workshop. So you know what we'll get out of it. We're going to learn how to set up firefly and connect to a public chain. We are going to deploy and configure a custom token contract with firefly. We're going to start that contract from scratch actually, and I'm going to walk you through all the different parts of that. We're going to upload NFT assets to public IPFS with firefly. And we're going to mint an NFT on a public chain and look at it on a public chain. And we'll be able to see it there. So one other thing I actually, I think I maybe mentioned, forgot to mention this in the guide. It's just now occurred to me. If you want to actually see your NFT in a real wallet app, I recommend the, I think I may have, I may have mentioned this in the, in the top of the guide here, but I recommend the alpha wallet app. You can get it here. This is something you can set up on your smartphone. It's open source. So, you know, I like to recommend open source software. But this, this app has a couple of features that we need for today. It allows you to connect to a test net, which we'll be using a test net for today, so that you don't have to spend real money in order to mint your NFT. And it also shows the artwork of the NFT in there. So when we get to the point where we actually minted our token and we want to transfer it to an address, you can use your, this is kind of an optional step, but you can, you can transfer it to your wallet address from this app. And then you can actually see it to show up there. And so that's, that's kind of like a cool bonus feature. If you want to go ahead and get that set up on your phone. You don't have a wallet app already that can connect to a test net. So that's just one of the things that we can set up. All right. For the agenda, we're going through the housekeeping stuff right now. I'm going to give a very brief introduction to hyper ledger firefly. I'm going to try to keep it to five to 10 minutes. And just to kind of give, if folks are new to the project in general, just kind of give an overview of like what, what is this thing? And, but I'm going to keep that brief because I really want to spend the bulk of the time. So we're going to have a little bit of time to get our hands on the total workshop runtime is three hours. I can't sit still for three hours at a time. So I've planned a couple of breaks in between certain sections. So we'll see how far we get. We'll kind of just. We'll be flexible. So if we, you know, this may not happen in exactly this order, but I want to give some people some breaks throughout. Cause you may need to go get something to drink or, or food depending on what time zone you're in, but we will plan on taking some breaks as we go. So here's just kind of a rough, a rough outline of the, the time and the order that we're going to do stuff in. If we have time at the end, we'd love to just kind of have an open Q and A time as well. So that is the agenda. And with that, I'm just going to check chat here. Thanks for, for posting all the helpful links in there. Appreciate that. So let's get into just a very brief introduction to what is what is Firefly. So Firefly is a platform to build web three apps. So I like to describe this to developers. I like to use a stack diagram and I think this, this picture gets at the, the immediate value to a developer and I'm a developer and I, I assume probably many of you are as well, or you're at least comfortable with code and that sort of thing. So hopefully this resonates with you as well. So what do you need to build a web three app? Well, first you need to blockchain. You need, if you're going to have public data available, you probably need some sort of off chain storage like an IPFS node. And there's lots of great open source projects for these types of things. So that's, that's great. We're not, Firefly is not trying to be another type of blockchain. It's not trying to be a DLT itself, but it builds on top of these really powerful technologies. The next thing you might need is you might need a token smart contract. You need something to manage your transactions that are going to that, that contract. You need to index events that are coming off of that contract. So you need to write some code to do that. All these yellow boxes are stuff that you have to build if you haven't picked up on that. So you probably also need to write some code to actually upload something. DFS. You're going to need stuff to manage your signing keys. You need a wallet and you need to keep track of which tokens you own versus which tokens somebody else owns based on those events that are coming off of your contract. There's going to be some coordination between data that is on the chain, you know, things like token indexes or other pieces of data that have been pinned to the chain and also data that you need to keep off the chain as well. Data that's either too large or too sensitive to put on the blockchain itself. So you need some code to link those things and keep track of them and treat them as a transaction that encompasses both of those things. Likewise, along with that, some data needs to be public. Some data needs to be private. And then finally, you start to get up into the, what we think of as the good stuff, the actual business logic or your backend API for your application, you know, what, you know, all of these things below this layer are just the things that you need to actually drive a blockchain. But then, you know, what does your app actually do? What business value does it provide? And that's where we start to get into up in these top layers. And then finally, you probably need some sort of front end for it. You need something for your users to actually use like a Web UI or a mobile app. So there's a lot of different pieces to build in a Web 3 app. So, you know, you look at, okay, there's some great open source projects here at the bottom. There may be great open source libraries and things that you can pull all together to make this, all these yellow boxes that can help you with that. But before Hyperledger Firefly, there wasn't one platform that helps you with all of these things. And so that's what Hyperledger Firefly does. It takes this whole middle section and says, hey, you know what? We have built a platform that handles all of this plumbing, all of the really hard and maybe not quite so interesting. It's interesting from a technical perspective, maybe not from a business value perspective, though, but all of this stuff that you need to drive a Web 3 application. Firefly is a common platform that provides this. It's open source. It can be extended. It can connect to many different blockchains. It can connect to private permission chains, public chains. It's modular, so it can be extended. And it's a common platform that solves all of these problems for you. So you can focus on now this really small top layer, which is your app's code. You can focus on the thing that actually drives your business real value, like the business logic, the user experience, and all this stuff. And you can use Firefly's API, Firefly's WebSocket interfaces to work with technologies that develop, that Web 2 developers are already familiar with and can pick up and use right away and really leverage the power of Web 3 quickly. So that's, I think, the real value of Firefly in a nutshell for a developer is that it takes care of this huge portion of the tech stack that you don't have to recreate over and over and over for every Web 3 app that you want to build. If you still want more control down here at the contract layer, and you want to use a custom contract like we're going to do today, Firefly absolutely lets you do that. And that's one of the things we're going to show off today. You can use Firefly's built-in token contracts if you want. You're not limited to that, though. You can plug in whatever smart contract you want. And it still gives you that if you need to go directly to the blockchain or use a custom smart contract, it doesn't lock you out of doing those things. It's really meant to complement all of those things and build on top of them. So where does Firefly fit into the picture for an enterprise? That's really what Hyperledger software is really geared toward enterprise. Firefly can connect to public chains, so it can be really useful for personal projects as well. I think it's a great fit for that as well, but it's primarily geared toward enterprise applications, and it was designed that way from the get-go. So Firefly you can think of as a Web3 gateway or in the cloud or through a hosted provider, and it is the way that they can connect to everything Web3, whether that's a consortium chain, whether it's a kind of a multi-party network, as we describe it, of other organizations also running Firefly nodes, and they've built a distributed network to collaborate using business transactions over a blockchain. Or it could be things that we tend to think of in kind of the public crypto space. Maybe they're connecting to an exchange, maybe they're connecting to a layer one chain and transferring tokens or DeFi apps. Firefly can do all of the above, and it is meant to be a one-stop shop for. Here is a platform that your organization can install, and it can connect to the Web3 world, regardless of where it is or what technology it uses. What's inside of Firefly node? It is a microservice architecture, so it has a lot of different things inside it. I've hinted at that a little bit, that it's pluggable and that it's extensible. I won't go into all the detail of every single thing on this diagram. There are already some great resources on YouTube that kind of break down this diagram about all the different components and what it is. Essentially, at the top here you have, this is the application that you can build. You can use Firefly's REST APIs. You can receive events through Firefly's event delivery mechanism, which is today web hooks and web sockets. But again, it's extensible. Firefly provides an open API swagger interface, which we will be looking at and using later today, along with the Explorer UI. We'll be looking at that as well. Those are all hosted by Firefly Core. Firefly Core is the brain of the entire Firefly node, but it also connects to a bunch of other microservices to actually execute and carry out various types of transactions. Those include a token connector, a blockchain connector, a distributed storage mechanism such as IPFS, a database, and more. There's lots of different things that all make up a Firefly node. Again, there's more material on YouTube and in the docs on what all those things are, but I just wanted to give it just a brief peek under the hood so you can see that it's not just one thing that we're running. There's a bunch of different services here. The Firefly command line interface, which is what we'll be installing and running here shortly, is a tool that is designed to run all of this in a local development environment set up on your machine, and it takes care of setting up and configuring all of these services for you so you can just run a couple of commands and be up and running. That's what we're going to run here in just a little bit to set everything up. Just a quick shout out to the Firefly community. We would love for, not plugged into the community, please join the Discord. Again, there's a dedicated channel for today's workshop in there, but you can also check out the source code for Firefly on GitHub. If you haven't, I'll just add a brief plug for, if you like this workshop, if you like the project, please go to GitHub and click on this little button and star the project. We would love to get some more stars just to drive up visibility of the project in GitHub and whatever other algorithms pay attention to that. Just a quick little advertisement plug there. That's it for slides. I tried to keep that brief. I think I kept it to 15 minutes, which was about what I had allocated it for that. Above and beyond, Nico was usual. You nailed it. I try. Let's go ahead and hit this link now. It should be in the chat. I'll just drop it in there one more time because I don't think you can see old messages. So there's, again, the guide that we're going to be going through. And we're done looking at slides. So I'm just going to close that tab. Okay. Alex or David, is there anything I should address? I'm just taking a quick peek at chat here. Any, any questions or things that I should address before? Yeah. I think there was a question around, what type of data is stored in the database in the zoom chat? Oh yeah. That's a good question. That's kind of a, just a general firefly question. I'll take that one right here real quick. But yeah. So firefly has its own database. It keeps. It's basically, so. Blockchains are not great at answering questions like, what are all, what are all, what are all, what are all of the, what are all those things that are stored here? Blockchains are not great at answering questions like. What are all of the events that have been emitted from this particular smart contract with this particular signature, such as if you wanted to know. Show me all of the token transfers for a particular type of ERC 20 token. Well, you could figure that out from a blockchain node by starting back at when that contract was deployed and going through all of the for that have been mined since then and looking for events that have been emitted from that contract. That could take a long time, depending on how long ago that was. So Firefly keeps track of, that's just one example of the things that Firefly keeps in its database. You can tell it to here index this contract and store all of the events that you see in a, right now it's some sort of SQL database, primarily Postgres is the main plugin that's most commonly used. Stores it in there in a fast access queryable way. So it's, it is, the short answer is most of the data that's in the Firefly database is data that has come from the blockchain but we want to store in a way that can be queried really quickly and searched. Or it is data that is too sensitive to put on the blockchain. And so we keep it in a private database and have a link or a pin to a hash of a transaction where that thing was pinned to the blockchain. So hopefully that was an answer to your question there. Great, thanks. There is no separate distribution for, okay, there is a build for the Firefly CLI for macOS. Yes, it should be in the downloads section there. We'll get to that here just a second once we jump into the guide. There is support for ERC 1155. The bit about the batch transfer, I'm not sure off the top of my head actually what you mean by that but maybe the answer to that question will become more clear as we get further into the workshop. Okay, let's dive in. So hopefully you've had a chance, if you don't have Docker, hopefully you had a chance to set that up. We're gonna start at the beginning now and I've actually gone and deleted my Firefly CLI binary on my machine. So I'm gonna start it up. I'm gonna install it from scratch just like you all are here as we go along. I'm gonna make this a little bigger. Is, sorry, just quick check, is the font size acceptable through Zoom to people or do I need to zoom in here? Not to use Zoom in too many ways in one sentence. Could probably be a step bigger. Better? More. Is that good? No, I'd have to take a screenshot and open it up. Okay, maybe you can go full screen with the screen share on your machine if you haven't. If I go much bigger, we're not gonna be able to fit web interfaces on the screen here. Okay, I'll switch devices. Okay. Okay, cool. So just a couple of notes for Linux users. It's recommended not to run the Firefly CLI as root. I just, I try not to run most things as root if I don't have to. So it works better if you run everything as a standard user and add your user to the Docker group. For Windows users, I would highly recommend Windows subsystem for Linux too. There is not a Windows specific binary for the Firefly CLI, but if you set up WSL, you can run the Linux binary in your WSL environment and it should work fine. And it works well with Docker desktop for Windows as well. Okay, so in this workshop, here's a picture. I like pictures to kind of just explain what it is we're about to do. So we're gonna have Firefly running on our local dev machine. It's gonna be running a Firefly core node. It's gonna be running an EVM connect blockchain connector and it'll run a local IPFS node as well. That EVM connect is going to connect to a blockchain remote RPC node running in the cloud, which I have provided a link to below in the command where we'll set all of this up. That RPC node is part of the Polygon Mumbai testnet. There are a bunch of other blockchain nodes that are all a part of this network. So down here, I have my wallet app on my phone that I've set up. I've installed alpha wallet on my phone. It has the ability also to connect to some RPC nodes. I have no idea where those ones are. It also has the ability to connect to IPFS nodes. The beauty of a completely distributed app, a decentralized app is that it doesn't matter where those nodes are running. They're participating in the same network. So this wallet app here can see things that our Firefly node is putting on the chain and putting an IPFS over here as well. So the idea is that we are going to deploy a contract to the public testnet and we're gonna mint a token on it and end goal of being, hopefully we should see that token show up in our wallet app. All right, so we're gonna go through the Getting Started Guide, the first page of it to set up the Firefly CLI. So I'm just gonna go to the docs here. I'm gonna actually open that in a new tab. And gonna go to the latest release page on GitHub and I'm just gonna grab the latest Firefly CLI binary. If I've go installed on your computer and says my internet connection is unstable, hopefully you all can hear me still. We can still hear you. If you have go installed on your computer, you can also go install. Okay, excellent. You can also go install the Firefly CLI. If you don't have go, don't worry about it. You don't need to install it for this. So I'm just gonna go here and grab the latest one. So there are binaries for Linux and for Mac OS as well. Please be sure you grab the appropriate CPU architecture. There is a difference between ARM64 and X8664. If you have an Intel CPU or AMD CPU, you probably want X8664. I'm on Apple Silicon Mac. So I'm gonna grab the ARM64 build here and I'm gonna download that one. So please make sure you grab the one that's the appropriate architecture. Otherwise it will not work. And it doesn't give you a very helpful message as to why your operating system couldn't run the binary but it won't work. All right, that's gonna download. There is a handy little command here. Really you can put this, when you extract it, you can put the binary anywhere you want. This little handy command, if you do run it with root or sudo, it will basically just extract the binary and it will move it to use your local bin for you. Assuming that it is in the downloads folder in your home directory. If that's not true, then this one liner won't work but you're welcome to just extract the TAR-GZ and put the binary anywhere you want and run that. And okay, so now I should be able to, which FF, okay, so I have the Firefly CLI installed in user local bin now. That's great. If I try to run it, Mac OS is gonna say, oh, I'm not gonna do that. Okay, I'll show you how to get around this real quick. We'll hit okay. Yes, terminal bigger understood, sorry about that. Okay, so Mac OS says, it's not signed, we didn't pay Apple boatloads of money, so it's not signed. So we need to go to system preferences and tell it that we want to run this anyway. So I go to security and privacy and I believe this is under general. So it says FF was blocked. I'm gonna allow. The next time I try to run it, it'll say, are you really sure you wanna run this? And I'll say, yes, okay, there, now it finally runs. So if you're on Mac OS, a couple hoops to jump through there, but I don't believe Windows or Linux users will have that issue, but if you're on Mac, I'll just run you through there. Okay, I'm gonna pause running through steps. Hopefully you've been able to get this or you're in the process of getting through this. I'm just gonna describe what we're gonna do next and then we'll actually do it here in just a second. So I'm gonna go back to the guide. I'm done on these tabs here and I'm gonna talk through these next couple of steps here before we actually run them. So like I said, that the Firefly CLI is a tool for creating a local development environment. So it has a bunch of different command line flags that we can get it. It has all of the, when we ran just FF with no sub commands, it listed out all the different sub commands that we can run. FF init is the, let's make this even bigger here. FF init is the command that will create a new stack for you to run that with dash dash help. The FF init command has a bunch of flags as well as well as two sub commands. I recommend using the Ethereum or Fabric specific sub commands they're newer and they have some, some of the new command line flags are on these sub commands. So if we run FF init Ethereum dash dash help, these are all the flags that we can customize for an Ethereum stack running on our machine. I'm not gonna get into what all of these are used for, but we also use the Firefly CLI to create test environments for Firefly as well. So it's used in our CI pipeline. It's used for running the end-to-end tests against and all the stuff. So a lot of these things are for creating various permutations of all the different ways you can set up Firefly, specifically for automated testing, but it's also really useful for local development and debugging as well. Okay, so for, for today, what we're gonna do is we're gonna init an Ethereum stack. I'm gonna name it workshop and I only need one Firefly node. I'm not building a multi-party network here. So that's what these first few things do. I'm gonna set multi-party mode off. I'm gonna enable public IPFS. So it's private by default. Today, we're gonna open it up to peer with public IPFS nodes though, because we want our NFT assets to be visible on the public internet. And we're gonna connect to a remote RPC node. So we're not gonna run a blockchain node on our machine. We are going to give it the URL of the blockchain node. And you may notice this URL has credentials in it. These are temporary credentials. This is a blockchain. It's an RPC gateway that is hosted by Kaleido. And these, Kaleido is the company that I work for. These credentials are temporary for this workshop only. So they will be deactivated afterward, but you all are welcome to use this one today during the workshop. We're gonna configure the chain ID for the Mumbai network. This is, I've gone and just looked that up. It's 8001 and we need to pass in a connector config. So the connector config is just, we're gonna customize a couple of settings that are a little bit different from their default value because this is a public chain. So what we're gonna do is we just need to create an evmconnect.yaml file. I probably have one already. Yep, okay. So I already have this file on my machine because I ran through this earlier, but basically just create a file called evmconnect.yaml. I just created it right in my home directory and that it, and then paste in these contents here. Now what this is gonna do is this is gonna tell it, I wanna wait for four blocks to see, to make sure that my transaction has been actually mined. I want to, and then just a couple of settings for how it computes gas prices and that sort of stuff. There's a question about the remote RPC node. It is not, no, it is not just a service returning an HTTP response. It is actually the, it actually is the blockchain node. So it is, you do need to connect to a real blockchain node running somewhere. In this case, we're connecting to one in the cloud. You're more than welcome to run your own if you'd like or connect to a different one if you have one already. But this is the one that I've tested and we're gonna use for today. So it's not something that you can just mock because that actually is the blockchain that you're connecting to. Yep, no problem. This is an infra-based node we're connecting to. This is a RPC gateway that is hosted by Kaleido. So it's not in FURA. No, this is a piece of infrastructure that my company has stood up as well. Okay, so I'm gonna copy this command. I'm gonna go over to my terminal and I'm gonna close out of them here and I'm gonna run this. That's gonna initialize a new Firefly stack. It's gonna go great. Okay, we created it. And now you can type FF start workshop to start it up. I'm gonna do that. And that will take a few minutes. So that's basically gonna start and configure all of those services that we were talking about earlier. I will, while this is going, I'll pause here to see if there are questions. I'm gonna check the Discord chat as well. Can we host the application at Kaleido? Yes, you are more than welcome to host your own blockchain node if you want to. It's a lot of work, which is why we took that. That's outside the scope of the workshop today is how to run your own public blockchain node. So it's a really fun project if you're interested in learning about that, but it's just outside the scope of today's workshop. There's a question about if we have a Kaleido account, can we use the Kaleido cloud? Great question. This is a new feature that is not yet available if you log in to self-service yet. So not at this time, but maybe someday. David, Alex, any other questions that I should address here while we're waiting for this all to start up? Nope, I think we're all good. Cool. So we'll just kind of take a... Okay, great, we're done here. Yeah, it's pulling a lot of stuff. Yes, there are a lot of Docker containers. I'll just give you a quick peek at what is currently running. So we're running Firefly Core. We're running a token connector for ERC-20 and ERC-721. There is another one for ERC-1155 as well. We're running EVM Connect. We're running a data exchange service, a signing service and the Sandbox as well. So those are all the different things that just stood up. And yeah, it's got to pull images for all those things. So hopefully you are getting close to running this as well. I'm gonna keep going through, slow here, any Docker image for FF, there's not a Docker image for the Firefly CLI itself, which is the FF command. This is the Docker image for Firefly Core itself up here. But we don't provide a packaged image that has the command line in it. All right, well, I'm gonna hop back over to the guide and talk about what we're gonna do next. So before we can do anything with our Firefly node, well, actually here, let me show you, I shouldn't have cleared that out, but it printed two URLs there. And if you don't clear your buffer like I just did, you should be able to go to localhosts5000 slash UI, and I should be able to get the Firefly UI up here. It's the Firefly Explorer. You should also get the Sandbox, which is on port 5109, and this is a really useful tool for playing around with Firefly as well. Niko? Yeah. Can you talk about the port 5000 and turning off the airplay? Oh, yes, yes, yes. Good, thank you, David, good call out. Okay, if you are, yeah, so if you're running on macOS in one of the recent versions, Apple very helpfully created a new service and turned it on for you by default, even though you didn't ask for them because Apple knows what you need. It is, I go here and then go to sharing, where is sharing? Here it is. And at the bottom here, there's an airplay receiver. Apparently, airplay also uses port 5000, which is the port that Firefly Core by default wants to bind to. It doesn't have to, you could change it. It's just easier to uncheck this box and start everything up there. So if you're getting a message about something listening on port 5000 and you're on a Mac, you wanna uncheck this box here. Okay, so yeah, so there's the Sandbox, there's the Explorer. So we've got everything up and running, and I'm gonna go look back at the guide here and just kinda talk through the next couple of steps. Before we have to do anything, because this is a public chain, we need to fund our account. So on a public chain, you have to pay a gas fee for the computational power that it takes to run your transaction. So we need to first look up what is the account address, the wallet address that our Firefly node is using. When the Firefly CLI created everything for you, it generated a wallet for you that's on your local machine and it has an address. So I'm just gonna copy this bit here and paste this in my terminal. I'm gonna, I'm just, so if you run FF accounts list and then the name of the stack, it will list all the accounts that have been created and their private key. So I'm just gripping by the address so I can just see the addresses. The private key is there. If you need it, it can be useful, but just be mindful about, I just didn't wanna leak that on the screen. So I'm just gripping by the address. And so this is my public address that Firefly generated when it set up my stack. Yours will be different. It is randomly generated. And so we will need this in just a little bit. So I'm gonna go ahead and copy that to my clipboard and I'm gonna go back to the guide here. So in order to fund this wallet, what we're gonna do is we're gonna go to, Polygon provides a faucet. So a faucet is like for a test account, for a test network, a faucet is basically a page that you can go to and put in an address and get a very small amount of the blockchain's native currency to be able to run test transactions on there. So we're gonna go open that in a new tab and hopefully the faucet is working. Okay, there we go. Yeah, so there's another question about port 5000. We just talked about that a minute ago. If you're on Mac OS, go to system preferences, sharing and uncheck AirPlay receiver here. That's probably the most likely culprit. If it's not that, then you'll need to do a little bit more to figure out what is listening on that process. But if you're on a Mac, that's probably the problem. Okay, so I'm just gonna paste my address here, hit submit. This will give me one Matic token, hit confirm. So say that the transfer is on its way, tokens will be transferred in one to two minutes. So again, it's gonna wait for several blocks to be mined and wait for that confirmation. In the meantime, we can go to Mumbai.polygonscan.com and we can go look at our wallet here. I'm gonna just paste that same address in. And so if I look at it right now, I don't see anything. I bet if I refresh this, I still don't see anything. In just a second here, it should show up. Okay, there we go. So I thought it said it was gonna give me one Matic, but it gave me point two, that's fine. That'll be more than enough. So I can see my address has point two Matic in it. There still aren't any transactions that I have run on here. There's no ERC 20 token transactions, but that's okay, that's kind of what we expect. We've funded our account, so we have the ability to do something now. So I'm just gonna do a quick time check here. I think before we dive into actually creating the smart contract and deploying it, I think we may pause here for about 45 minutes in. Maybe take a little break in just a minute. I'll pause and ask if there are questions or if people are stuck. I wanna give people time in order to make sure their stack is up and running and they've got Firefly up and make sure that they've got up to this point. I don't wanna leave people behind if we can avoid it. So yeah, great question here. Are the test net funds into the Alpha wallet or the Firefly nodes address? Great question. So I use here, I went to the command line and I looked up the address, my wallet address for the Firefly wallet. This is the signing key that Firefly will use when it submits transactions. If you installed Alpha wallet on your app, it probably, I believe you have the ability to import a private key there if you want to. I would suggest just having it generate a new wallet on your app and use a separate address and we'll transfer it to that address later. So we haven't done anything with Alpha wallet yet. We'll come to that sort of at the end of the guide if you wanna transfer it to that address later, but that's a separate address. Great question though. Check the Discord chat too. Okay, great. Just a note, there is, you're welcome to use the Zoom chat. We also have a Discord channel open which is much more rich chat. You can even post screenshots there if you're stuck on something. The other advantage is that chat will be preserved after this call ends. I would recommend using the Discord chat, but I'm not gonna say you can't use the Zoom chat either if that's just easier. Someone mentioned the faucets coming up as a blank page. It did that for me as well. And then I just gave it a second and I hit refresh and then it came up. So hopefully all 100 of us hitting it aren't hitting it with too much traffic. Maybe just try refreshing it and see if it comes up. Great, okay. Okay, there's a question in chat here. Someone use Docker compose down. That probably is, if you've done that, I would recommend running ff remove and then the stack name that will kind of clear out everything here. I'll just type this in the chat here. Besides Firefly Docker, et cetera. Yes, we are actually running an IPFS node. So if we go look at what's running here, there is a Go IPFS container that's running here as well. Just a quick note about IPFS. So at some point in the workshop, we will get to publishing an image and a metadata JSON file. I will say running an IPFS node locally, including running just the IPFS desktop app that you can download from the IPFS site. It's hit or miss whether files will actually successfully get replicated to public IPFS gateways where other apps can download them. And usually it comes down to networking problems. I'm sitting in an office right now, so I'm behind a NAT and I don't have the ability to configure the firewall. Sometimes it's able to push files to gateways and it just works. Other times the file just never ends up replicating. So that's in a production setting, you would wanna run an IPFS node in probably the cloud or a data center or not on a laptop behind a NAT. You wanna run it somewhere where you can configure the networking appropriately to expose the correct ports to IPFS so that it has nothing blocking its peering ability with other IPFS nodes. Yeah, IPFS is also running in Docker here as well. Yes, Kaleido has the ability to run IPFS nodes in the cloud. There is not currently a way in the Firefly CLI to automate the configuration of a remote IPFS node. That's something that the Firefly CLI could be enhanced to do, but it just doesn't generate the appropriate config for that today. All right, tell you what, we're 10 minutes to the top of the hour here. Let's take a five minute break. I'm gonna actually step away from my computer, go grab something to drink and we'll come back and I'll answer any more questions and hopefully folks, this will give folks a few more minutes if you're still stuck trying to catch up and we'll make sure that we get as many people caught up to this point as we can before we keep moving on to the workshop. So we'll take a quick five minute break and I'll see you at five minutes till the top of the hour. Okay, I am back. I'm gonna take a look at some questions that have come in here while I was away. An error on FF and NIT is interesting. You could try adding a dash dash verbose flag to your NIT command like this. There was a question about can we use another account instead of the Firefly default account? Yes, so we're not going to for today for the workshop, but in just technically speaking in what is possible, absolutely. There are ways to, Firefly is very flexible when it comes to key management and signing. The implementation that we have running right now is a very simple straightforward file-based wallet on the Firefly signer node that we looked at in this, one of the Docker containers that I'm currently running. But there are ways to create more keys, more wallets and also use an external signer as well. Firefly supports a lot of different features in that regard. How can you check the data stored in IPFS using Firefly? Yeah, we'll get to the data APIs in Firefly in just a little bit. But you could, IPFS has its own REST API. You can query that REST API to look up data that's stored in it just like you could if it was running somewhere else as well. Just check Discord here. Okay, cool. Let's give it two more minutes. It's about lunchtime here in the US so I actually grabbed some food. I'm gonna take a couple of bites here. We'll kick off in the next phase of the workshop here in just a little bit. But I think we're running right on schedule here right now so this is great. So hopefully everyone is able to work through any issues they have getting things started up. If you're still stuck, let us know we're here to help. Yeah, let me drop the Discord link in here again. There's the invite link to the Hyperledger Discord. And again, we're in the, if you scroll down to the Firefly section, we're in the Firefly Workshop channel down here. And this is the chat that we've got going here. Yep, no problem. I'm not quite sure I understand the question where is the mintable? Yep, we'll be, we'll get to that in just a second. That's the next part of the workshop. There was also a question in chat about event streaming and Firefly's WebSocket event delivery mechanism. It's a great topic, a little bit outside the scope of today's workshop. I would love to, it's honestly probably worth the workshop just on its own, just all about events, but don't have time for that one today. Okay, we are gonna move on. So hopefully everyone is got their Firefly stack running and their wallet funded. And we're gonna go create a smart contract now. So there are lots of different ways you can create a smart contract. I'm not here to be a smart contract development expert. I'm just here to give you a link to a thing that you can click and do in your browser really quickly for today's workshop. So don't take this as the recommended way to do it necessarily, but it, I do think generally speaking, starting from something that has been already vetted by a wide open source community and used in production and battle hardened like open Zeppelin contracts and libraries that you can build on there is a fantastic idea. Anywhere where I can leverage something that is open source that's already built, already tested and rather than writing it again on my own I'm gonna do that. So this is a great way to get started really quickly. I also think it happens to be a good way to if you really want to go deep on building your own custom token contract it's a good starting point at least. So we're gonna pop open the contracts wizard here and we're gonna today we're focusing on the NFTs. So we're gonna use the ERC 721 contract can give it a name and give it a symbol and I probably need to zoom in for this tab as well. Sorry about that. For this one, sorry. Alex just pointed out that I forgot to turn my screen share back on. There we go. Okay. So sorry about that. So here we are in this tab and all I did was I went back to our guide scroll down here and clicked on this link open up the contracts wizard in a new tab and here we are. So we're gonna give it a name. I'm gonna call mine Firefly NFTs and a symbol we'll call it FF NFT or whatever you can call it whatever you want. We don't need to put in a base URI here. You can if like, so this is where there's lots of different ways to do NFTs lots of different ways even to do ERC 721. What we are gonna do today is we're gonna set a unique URI for every token. Some contracts are set up such that there's a common base URI for all tokens and each token it has a unique index that is appended to that. That's another way of doing it. We're gonna use a unique URI for everyone and we'll set that in the contract later. When check on some features here we wanna make this mintable. We're gonna let the contract itself decide the IDs. So we don't have to tell it what token ID to mint. We just when we call the mint function it will just mint the next one available. And like I said, we're gonna turn on the URI storage option which allows us to customize the URI per token. And I believe I'm gonna just gonna double check my instructions in the guide. Here's the 721 mintable auto-incomement IDs URI storage and a cool name. Okay, I think we've got all those. My cool name is debatable but I went with something that works. This is what we need so far. So as you can see as you're checking and unchecking these boxes it's actually writing some code for you which is great. If you haven't seen it before this is Solidity. Solidity is a easy to use programming language that you can write and debug and test in an IDE and then it will get compiled down to Ethereum virtual machine or EVM byte code. And that's what we actually deploy to the blockchain node. So the easiest way to do this and this is what the guide recommends is to just do it all in your browser. Now you could hit download and you could copy the source code file to like a hard hat project or a truffle project and you could compile it locally and do all that. You're more than welcome to do that if you want to. For today I'm just gonna hit open in remix. I'm gonna try to do this all on my browser here. And we're gonna use remix to compile it. And so it'll just open it up because this handles all the dependencies and everything like that. So it's really just streamlined stuff. So I'm just gonna come over here and hit compile. And I know this is probably pretty small on the screen. Okay, so great, we've compiled it. We're gonna come back to this page in just a minute but I wanted to point out these two buttons right here ABI and byte code and then we'll copy it to the clipboard. So it basically takes the compiled output and puts it on your clipboard. That's what we're gonna go give to Firefly here in just a minute. All right, let's go back to the guide. So we are going to use Firefly now to deploy our smart contracts to the Polygon testnet. We can do this right in our browser through the Swagger UI using the contracts deploy endpoint. So I'm gonna click on that. It's gonna open the Swagger UI and automatically scroll me down to the contracts deploy endpoint. I'm gonna hit try it out. There's sort of some instructions here in the guide which we don't need necessarily all, this is gonna list all the different fields that are possible to send here. We don't need to set all those. So I'm just gonna paste that in here. These are the really the only two that we need to set for today. If our contract had constructor arguments that are required, we could list them out here but this one doesn't. So I'm gonna go back to remix. It says paste bytecode here, paste ABI here. So that's what we're gonna do. I'll copy the bytecode back to my Swagger UI and that's gonna be just a big long hex string. So this is the compiled EVM bytecode that actually is the program that the blockchain will run. It's a definition. This is where we paste the ABI here. You may notice these don't say bytecode and they don't say ABI. And the reason is Firefly works with more than just Ethereum. So we use, we sort of took a step back when we're naming things and use more generic names. So we call it contract. This is the thing that actually is the smart contract. And because not all blockchains call the compiled thing bytecode, they may call it something different. Likewise, not every blockchain uses a thing called an ABI. They may call it something different or some blockchains may not even have that concept. So we call it contract and definition. So I'm gonna copy the ABI now and I'm gonna paste that here. It's important to note this is not, this should not be wrapped in a string. This is a big JSON array that I copied. And so you wanna set, when you hit copy it will give you the whole array. And if I scroll back up here to basically the definition should be a JSON array. Okay, so that should be everything that we need. And I'm gonna hit execute. And this will take a little bit of time. So you may notice that this is set to confirm true. And so, yep, I'll show that in just a second here. So this, what confirm true means is we'll actually block the HTTP request or the response will block until the transaction is confirmed on the chain. And we told it that we want four blocks of confirmations. And so it's gonna wait for four blocks to see that the contract that it deployed is in all of them to make sure that, yep, this is the history of the chain has not changed. And, okay, great, cool. Someone asked what the difference between using Firefly CLI, FFDeploy is, and the REST API? It's a great question. FFDeploy came first and it was before we added this endpoint to Firefly. So this endpoint is newer. It is the more recommended way to do it because the transaction itself will show up in Firefly. And we'll go take a look at that in just a second. Firefly, the FFDeploy command goes straight to the blockchain connector and it sort of skips over the Firefly API. It still works, it still gets something on chain. I can't remember if it allows you, it may be less flexible than this endpoint is. So this endpoint is designed so that you can use it in production. FFDeploy is really a development tool. Okay, I think I may have gone through that a little bit too fast. What to do after compiling? Yes, so, excuse me, I went to the guide and I clicked on this link. This will open up the Swagger UI which has a list of a whole bunch of different endpoints. I think it automatically expanded this one. When you come to any of them though, there's a button over here that says try it out and you'll need to click that and that's what makes this part editable. We're gonna be doing this for a bunch of different requests here. So kind of just get used to that pattern in this interface. This is a very common interface. This is the Swagger UI that many different services used. It's a cool open source thing for interacting with APIs. So then I just copied this payload right here and I started with this and we just need to fill out bytecode and ABI here. So that's why I pasted here and I got those by going to remix copying ABI and bytecode. So hopefully that helps. Hopefully folks are caught up with that. Okay, we did get a response here. Awesome, great. And there's a lot of stuff here. Most of it is the input, but if we scroll down, sorry, that was, sorry, that was the input. We've got to keep scrolling for the output here. If I scroll all the way down here at the bottom of the 200 response body, let's see down here, there's a transaction hash and there's a contract address. This is the important thing that we will look for. The other thing that I want to see is the block number that this was deployed in. So we don't get that back in the same response, but we can go look in the Firefly Explorer now and now this refresh button has popped up here. So there's new data available. So to the question earlier of why would you use this API instead of FFDeploy, it's because now we can do this. Now Firefly itself is aware that a smart contract was deployed. So I can go look at that contract deployment transaction. I can click on it and then I can click this little button which will pop out this thing here and I can scroll all the way to the bottom here. Again, a lot of stuff and I should be able to see here's my contract address. Here's the block number that it went into. We're gonna use that in just a second. So this is a good place you can go look it up. We can also just go look this up on Polygon Scan now. So we go back and we refresh our page for our, I still have this Polygon Scan tab open. We refresh it, we'll see a transaction now from my Firefly node. And here was a contract creation. We can, oops, let's go into the transaction here and we can see like, again, all the same stuff that Firefly was just showing us. We can see on the public blockchain explorer now as well. So the two key things here that we'll need for the next step are the contract address which is right here and the block number which is right here. Now we can see that it's been confirmed at 122 blocks now. So we can either get this from Polygon Scan or from the Firefly Explorer itself. We'll need that for the next step. So actually, we'll come back to that in a couple steps here. Now what we're gonna do, so we've deployed the contract through Firefly to the blockchain. We haven't told Firefly how we want to use this contract though. So that's the next step that we're gonna do. The goal that we're working toward is we want to tell Firefly that this is a token contract and that this is an ERC-20 token contract. But we've also customized it. So we need to tell it about some of its custom ability. Looks like somebody in chat had an API call timeout. Maybe Alex or David can help look at that. I'm guessing that may have been either, may not have funded your wallet or there was an issue with the blockchain transaction itself, but you might want to double check to see what actually happened on chain to see if it made it that far. Just check Discord here. Okay, looks like, all right, just trying to keep an eye on questions and make sure I'm not going too far ahead of people here. But it looks like we're doing well. So what we're gonna do now is we're gonna, so like I was explaining earlier, Firefly has the concept of a, it's multi-chain and it's also not blockchain specific. So we wanna create an FFI, a Firefly interface which is a generic way to describe a smart contract. It's similar to the Ethereum AVI format but it is more blockchain generic. Firefly has the ability to go from an Ethereum AVI to a Firefly AVI and it's gonna basically take the AVI and wrap it in a Firefly generic format. So we can do that with the contract's interface generate API here. So I'm gonna click that. It's gonna open my Swagger UI here and I'm gonna hit try it out. And all we need to put here is, we just need an input AVI. So I'm gonna paste that here and then we're gonna go back to remix. There was a question about, where do I get the AVI and bytecode from? I see in the chat. So that's, you get it from remix and it's this button right here. It's where you get the AVI. This one right here gives you the bytecode. So if we needed that in the previous step, I need the AVI again though for this step. So I'm gonna, I'm just gonna click that and copy up. I'm gonna paste my AVI here and I'm gonna hit execute. So this is just a convenience function. You can write an FFI by hand if you want to. If you're using Hyperledger Fabric, there is not an AVI equivalent in Fabric. So you have the ability to create this FFI and define it for your contract's interface. But fortunately for Ethereum, which we're using today, there is a conversion available for that. Okay, so basically this is just a helper. So we're gonna copy this whole payload that we get from here. I think this button should copy to my clipboard. See, copy that. And then we're gonna go to the contract's interface endpoint, which is now we're actually gonna load the interface, the generated interface to Firefly. Again, we'll hit try it out and then we'll paste this whole thing here. We do need to give it a name and we need to give it a version. Those are the only other two mandatory fields. We call this, we'll call it Firefly tokens. I don't think you can put a space in the names, I just be aware of that. There's some rules about, I think letters, numbers, dashes and underscores are okay in the names, but there are some restrictions on it to make them URL safe in some cases. A version, we'll just say v1.0.0. You could put in whatever you want in these two fields, but they are required. I hit execute and scroll down, great. Okay, so we got a 200 from the server and we got a, this is a contract interface ID. So this is the important part that we'll use in our next step. Hopefully I'm not going too fast through here. If you're struggling to keep up, all of these instructions are written in the guide. So hopefully you can catch back up or follow along here. Description is optional, nope, don't need that. Name and version are the two things that are required in addition to what was generated. There's a question about FFIs and tokens for hyperledger fabric. In theory, tokens on fabric would work fantastically. Today are not any token connectors in existence for Firefly on fabric, though. So that would be a small piece of software that would need to be written. In terms of how you generate an FFI for fabric, it's a lot of JSON writing. There's really no way to automatically generate them from a fabric chain code today because fabric chain codes can be written in a variety of languages. There's no one standard for how interfaces are defined on a fabric smart contract. Cool, all right. Just looking at the time, we're doing well. I'll pause here and just see if there's any other questions or just maybe give folks a minute if they need to get through creating the contract interface. Yeah, to copy the entire response, I think on the Swagger UI, sorry, this is a request. When you look at the response body, I think this button copies at your clipboard. I'll just verify that here. Yes, it does. Okay, I'll keep moving on here. So where are we up to at this point? We have deployed the contract to the chain. We have told Firefly about the interface of our particular contract. We haven't told Firefly what to do with it yet. And we haven't told Firefly about a specific instance of this interface that we wanna start tracking. That's what we're gonna do next. So we have a few pieces of information now that we had from multiple previous steps. So we're gonna kind of combine all those. So hopefully you remember where things came from. Feel free to scroll back up in the guide if you can't remember where we saw certain things. But the things we need are the deployed contract address and the block number. So the two places we can look up those are on polygon scan. We can look up, you can either go to your account and you can look up the transactions. And I can see here, I've got, here's my contract address and here's my block number. Or you can go to the Firefly Explorer and to find it here, I think probably the easiest way is to click on this contract deployment transaction and then to go here and click this little pop out icon. And if we scroll to the bottom all the way to the bottom, here's our block number. Here's our contract address, okay? So those are two important pieces of information we need. We're gonna use the token pools endpoint. I'm gonna open, okay, here we go. Sorry, I'm starting to get too many tabs open here. Hit try it out. I'm gonna copy this payload here and that's what I'm gonna fill in here so that I can just replace all these things. Okay, so my deployed contract address. I'm gonna get that from Firefly Explorer. Copy on here and watch out because it'll wanna double quote it, block number. I'm gonna grab that from here. Even though it is a number, pass it in as a string and the interface ID. Okay, so this is the ID that we got from the previous step. So if we go back to the output of where we created the, sorry, I keep having to move the zoom chat around the screen there. We're looking at the output here from our contracts interfaces request that we just made. We need to grab this interface ID. And what this is gonna do is this is gonna link the token pool that we're creating to this particular contract interface. This tells Firefly, hey, this is an ERC 20 token but it's got some extra stuff on it because we checked all those little boxes in the contracts wizard to add features that are not necessarily in the base ERC 20 spec. So what we're gonna do is we're gonna copy that, put that right here in our interface ID and then your token name and token symbol are what we put in here originally. So I called mine Firefly NFTs and FF NFT. I actually can't remember if a space is allowed there so I'm gonna not put that there. The symbol does need to match. So it's FF NFTs is what I called mine and it's non-fungible. That was pasted in there from the template. So hopefully I didn't go through that too fast. I'll review it here before I submit it but contract address and block number. We got from Firefly Explorer by, I just went back to my Explorer dashboard. It's my contract deployment and click this pop out, scroll all the way down. Here's my block number, here's my address. So that's where I got that from, okay. Then this interface ID is the UID from the previous step that we just did which was where we posted the contract interface. So I just copied that from here and put it right in here. And then my name and my symbol is it needs to match what I put in my smart contract back when we wrote it in the open Zeppelin wizard. And the name can be something different here. Invalid character, curly brace looking for beginning of object. Make sure you don't have like a stray comma or something in your JSON that you pasted. That looks like a JSON deserialization issue. All right, so I'm gonna hit execute. Oh, okay. Remember what I said about the symbol needing to match? Well, I didn't make it match. Back here in my contract, I put FF NFT singular and here I put FF NFT is plural. So you need to get rid of that S. All right, we got a 202. So that's the server has accepted our request and it's activating that token pool. We should be able to go to the Firefly Explorer now and now we should see some new stuff here. I can see my one failure because I had that failed request because I had the typo in it. So there was my token pool that failed but now I have a token pool confirmed as well. So if I click on here, I can see that. I can now also go over to on the left side. I can go to the tokens dashboard and I can see my FF NFT pool here. Now there's no transactions on it. We haven't done anything with it, but it's here and Firefly is now tracking this token from the time that we created it on the blockchain in the original block number that it was deployed in. So that means any transaction, even if I had already minted some tokens in the past, say I'm pointing maybe this, maybe we want to use Firefly for a contract that's already been on a public chain somewhere. You put it in, point it to the contract address and the block number that it was deployed in, it will go find all of the events that have already happened on it. It's gonna, Firefly is gonna store those events in its local database. That was a question that came up earlier was Firefly put in database. Well, this is a great example. It's gonna put those events in its database so that you can query them and it can also populate this dashboard here. All right, that was a bunch of rest requests. We are through probably the most tedious and boring part of the workshop now. Now we're gonna do some fun stuff. Okay, now we're gonna upload some token assets. So before we mint a token, we want some stuff to have our token point to. One of the cool things about ERC721 is that you can give it a URI, have it point to something and have it represent something that is not on the blockchain. And it becomes a sort of a tracking identifier for that thing. I'm gonna use this little animated Firefly pixel art. You're welcome to use whatever image you want. Doesn't even have to be an image. Could be a document, could be a video, could be whatever you want. Please make sure you have the appropriate license and permission to use it. You have my permission to use my animated pixel art here. But yeah, so we're gonna upload this image. We're also gonna upload a metadata JSON as well, which will look like this. So we'll get to that step in just a minute. If you're not familiar with it. With the ERC721, it's the thing that our token will actually point out is not the image directly. It points out a piece of JSON, which then points at the image. So we'll start with the image though. All right, so I'm just gonna go ahead and close some of these extra swagger tabs now because we don't need them open anymore. Just to kind of keep things streamlined here. Don't need this, I don't need that either, yep. Okay, so we can use the swagger UI. Again, to upload some data as well. We'll hit try it out. There's some instructions in the guide on how to use, this endpoint is a little bit different because we're gonna be uploading a file. So you wanna change the default here is JSON. Cause you can just post raw JSON payloads here as well, but we won't actually upload a file. So change this to multi-part form data. And then if we look at our instructions again, it says uncheck the metadata and the validator fields as well. Trust me, bro, that's the way to do it. Okay, then we need to choose our file. I've got my little Firefly GIF here, hit open and I'm gonna execute. Okay, so right now this just uploads the file to Firefly and then it gives me an ID. Now, there's lots of different things you can do with data in Firefly. Perhaps I wanna share this piece of data privately with another Firefly node run by a different organization. Well, Firefly lets you do that. Perhaps I want to pin this to the blockchain and send a message to many different Firefly nodes that are run by different organizations. Firefly lets me do that too. In my case, I want to actually push this piece of data up to IPFS and share it with the world. Firefly also lets me do that. So it doesn't make an assumption about just because you give it a piece of data, automatically what you want to do with it. So handing the data to Firefly and then telling it what you want it to do with the data are two separate steps. So the next step we're gonna do is to upload it to IPFS. So you can actually just, so I'm gonna copy this ID. You can do it in the same tab if you want. You can just scroll down here to data, data ID, log publish, publishing it will send the data payload from Firefly itself to the IPFS node. Hit try it out. We don't need that. So we'll just put an empty body there and then we need to paste the data ID here. Okay, and execute. Great. Okay, so we got a 200 response body and we got an IPFS CID. This is really important. This is basically the IPFS hash for the data payload that we uploaded. So the guide talks about that. It's in the public field at the bottom of that request. So just to recap what we did there, we uploaded a GIF to Firefly and then we told Firefly, hey, take this ID and push it to IPFS. And it did that and it gave us the hash for that data once it landed on IPFS. Go ahead and pause here, see if there's any questions or just give folks a minute to make sure that we're up to this point in the workshop here. All right, so a couple of questions in the chat. Is it possible to use ERC 4907 in extension of 721 instead of ERC 721? Off the top of my head, I'm not familiar with 4907, but technically speaking, yes. As long as a token standard, which I think all of them do have the ability to mint, transfer and to be able to mint. So the functionality that Firefly uses for tokens is mint, transfer, approvals and burning a token. So as long as there are ways to do that in your token standard, which as far as I know, pretty much all of them have support that minimum capability. You could create a token connector that works with a different standard or an extension on that standard. If it's an extension of 721, it may just work with the existing token connector that's here already. Let's see, there's a question about uploading. Each file, if I have multilateral legal documents, sorry, I'm not sure exactly what you mean by a multilateral document, but if you had many different files and you wanted to treat them separately, yeah, you would call the upload API separately for each one of them. If there's more to that question that I'm missing, please elaborate, I'm happy to try to answer it. Upgradable smart contracts. Yeah, that's a whole topic in itself. Firefly does support upgradable contracts. I think, so actually the maintainer who is the resident expert on upgradable contracts is actually on vacation right now, but be a great question for him. I'm actually not sure off the top of my head. I think everything just works the same, but Andrew Richardson is the one to ask about that one because I know he's actually done some work on that in Firefly specifically. There's a question about what fields I filled in for the binary blob attachment. Just the ideas required, which, yes. So all I did there was, so this is where we filled out where I uploaded, I attached my file here, and then I got the ID right here. I just copied that, then I scrolled right down here to data, data ID blob publish, and I pasted that data ID in right here. You don't need any other fields in this request body, it can just be an empty, it needs to be an empty JSON object because Firefly expects it to be a JSON object, but it can be completely empty. Hopefully that helps. Let me just check Discord. There's a question about how long the Kaleido RPC node will be valid. I'm planning on shutting it off later today just because it's, I don't wanna leave those credentials floating around the internet for too long. Okay, cool. Any other questions before we move on to the next step? So now we're gonna create a metadata JSON. Now, the reason we uploaded the image first is because the metadata JSON needs to actually reference that image. So we needed to get the IPFS hash for the image because that needs to go into our JSON file. So like I said earlier are typically, like if you go look up an NFT, it's for sale on OpenSea for instance, it will, the URI for that token will point to a metadata JSON file. The, if you go look up the EIP721, this says that it's an optional thing that an ERC721 can have, where is, I probably just scrolled right past it. Yep, okay. So the metadata extension is optional for ERC721, but if you do provide it, here's what it looks like. So you can go read up on the actual standard if you want to. This is an optional add-on to it, but pretty much anybody that's doing NFTs in like a marketplace or something like that, it's, that's what people do. Okay, so we're gonna create this small piece of metadata JSON. And this is what our NFT is gonna point at when we actually mint it onto the blockchain. So what I'm gonna do is I need to create a file with this in it. I think I actually already have one on my disk already. So, because I ran through this earlier when I set it up, but you could just, you can create a file with contents like this, just a couple of things to note. If you did not use the image that I used, you will have received a different hash right here. And you need to change that. So this needs to be whatever CID you got from the previous step here in this field right here. Okay, so you can give it whatever name you want, whatever description, you can give it a different external URL, customize this however you want. This is your token that you're minting. You don't have to use the same thing that I did. This is just provided as an example. Okay, so I'm gonna go through the same two steps that I did with the GIF. And now I'm gonna do that with the metadata as well. So here's my metadata, I hit open, set that one, hit execute, I get a different ID back here. And again, I'm just gonna scroll right down and now tell it to send that to IPFS, hit execute and boom, that's my IPFS CID for the metadata. Now, in theory, if I've done this correctly, I go to, I think it's IPFS.io, which I guess it may not work. And this is I think, this is due to my NAT configuration. If I do, for some reason the GIF works fine, but the metadata JSON hasn't, which is a bummer because I wanted to actually show it to you live, but oh, you know what, that's a, that was from a different workshop. I must have copied and pasted that CID from something else. Anyway, so you can, yeah, here's the real one, sorry about that. That was from my last workshop where we did an NFT back at Hyper-Legic Global Forum, IPFS.io, IPFS.io, IPFS slash. This should be my GIF, I copied the right one here. Well, maybe, maybe not. This is again where I was talking about at the beginning of the workshop that, you know, in a production situation, you would definitely want your IPFS node to be more accessible to the public internet rather than running on a local Dev machine. But that's okay, it may just take some time. It may get there eventually, but we can keep moving on. We can actually mint the data or we can mint the token and still see the transaction on the public chain. That'll still work great. All right, so now we are finally ready to mint our token. What we're going to do now is we're going to go to the Tokens Mint API. I'm just going to click that, open it in a new tab, and that will scroll me down here, try it out. I'm going to copy this payload. So these are the only fields that we need. So amount is always one for an NFT. If this were an ERC20 or a fungible token, we could put in any amount that we wanted here if we wanted to mint like 20 of them or a million of them all at once. We could do that. NFTs are always, because of the way the transaction and the actual smart contract is written, they are one token per transaction. And that's just the way the contract works. So what we're going to mint one, we're going to put in our Firefly Wallet address here. I can go get that again by running FF Accounts List Workshop. And I get that right here. I'm going to just paste that in. And then I'm going to paste my IPFS CID here. I can go make sure I get the real one here. So this is from my metadata. I'm going to copy this. Paste it here. And I'll hit execute. Okay. And that minted a token. So now I see there's a few questions in chat. I will come, I will address those in just a second. Now if I go back to my Firefly dashboard, I should see hit refresh. Boom. There it is. It took it a second because it was still waiting for that confirmation to come in on the blockchain. But here it is. Here's my mint event. Here's my signing key that minted it. And it was two, the same key. It was a mint. So it was from the zero address. And here's the IPFS URI that I put in when I minted my token. Now I should also be able to go back to polygon scan. And I could either look at my wallet address and refresh this page. And I could see that I've called the safe mint function. Or I should be able to go to the contract address. And I can see because this was a transaction on this contract, I can see here that it was, there's that same transaction. I can go look at that particular transaction. I can see the actual data that came in with it. And all this good stuff. Okay. So I'm going to pause here. There's some questions coming in. Where do I get the IPFS CID? That was, so this, I got it from the data, data ID blob publish endpoint. I just scroll down here in the response body. There's a field called blob public. And this is the IPFS CID right here. And I had one of those for the image and I had one of those for the metadata as well. Sorry. There's a question that says, please share it here. I'm not sure what it is though. I'm happy to share it, but I'm not sure what's asking to be shared. There's a question about what here is open source versus what is part of Kaleido stack. Everything that we've used today is completely open source. The only thing that we're depending on Kaleido for, which you absolutely don't have to use Kaleido's node, is the blockchain node itself. And that's just because it's a lot of work to stand up a blockchain node and connect to a public chain. So you're welcome to use some other provider if you want. There are plenty of blockchain node providers out there that you could connect this to. But all the software that we're running on our machines is 100% open source software. It's part of the Hyperledger project. So that's really what we're focusing on here. When you have multiple images or documents, would you have multiple public responses? If you want to upload multiple files and have them each addressable as a separate file, you would have a different hash for each file. Yes. Hey, Nico. I think there's a question in Discord about how long the RPC will be available. Yeah, I did mention that earlier, but I'm planning on shutting down the credentials for it later today because I don't want them floating around the internet for too long. Yeah, so the short version of the story is running a polygon public RPC gateway is not a feature of Kaleido that's publicly available yet. So it's a feature that is available internally that we've provided just for today's workshop. I'm just reading through the questions here. Yeah, you can most certainly zip a whole bunch of files together and upload them to IPFS. They would always be downloaded together though and treated as one file at that point. Is there a way to do what we've done in batch form? So I would recommend writing some code to do what we've done if you want to do a batch of them and have your application manage what does a batch mean for your application? The, like I said, the smart contract itself is going to, like each NFT itself needs to be a separate transaction because that's the way the standard works. Each file upload itself to IPFS is going to be a discrete operation as well. And so there's lots of things that are, just because of the way the system works, are all discrete operations. The Firefly SDK, there is an SDK for Node.js that is, it's a great, if you want to write an app in Node or TypeScript, you can use that and it's a great starting point. It provides easy to use functions for all of these things that we're doing by hand. So today, the workshop is really to kind of like go through it and make the things by hand, use all the APIs. But obviously you wouldn't want to do all this by hand in production. So this is sort of like, you know, getting hands on with the APIs to do by hand what you would then go write an application to drive and automate and build that batch functionality into. Does Firefly convert API to FFI to define smart contract interface and generate the API? Yes. So there is a, there's an endpoint that we used earlier. If you scroll back up here, sorry, not that far. When we generate the contract interface, this is the endpoint that does it. That's part of Firefly Core. It's really just a convenience endpoint there to help you get started with that. Other questions about Kaleido? Yeah. So I would love to talk about Kaleido. I could talk about Kaleido all day long. That's not really the focus of today's workshop. This is a Hyperledger workshop. And where today, the focus of the workshop is the open source Hyperledger Firefly project. You know, we'd love to get in touch. Kaleido does have its own Discord server if you want to hop in there and talk about Kaleido specific stuff. We'd love to chat with you there. So let's talk about it, but this is probably not the time at the moment. But glad you're interested in it. Someone's saying their view of the sandbox does show all three columns, but not the left navigation bar. This is what the sandbox looks like. I'm not sure what the left navigation bar would be. So one thing to note when you're running in, when you've turned off multi-party mode, the messages tab will not show up here, which I don't know if that's what you're seeing, but tokens and contracts tabs are available, but messages is not when you have disabled multi-party mode. All right. So we're almost at the end of the guide here. So at this point, we have minted the token. It is available on a public chain. It's out there. And so the last step that I could do now, if I wanted to, is I can go to my... I don't have a great way to show my cell phone screen at the same time, but you could use MetaMask for this. You could use Alpha Wallet. You know, I may just use MetaMask real quick just so we can see it actually show up somewhere. Hold on just a second. While I pull that up, it looks cooler in Alpha Wallet because you can actually, if your IPFS uploads go through, like mine did not, you can see the artwork show up there. And it's pretty cool. Give me just a second here. I will... Your duplication is... I have a couple of MetaMask account set up, so I'm going to make sure I get into the right one here. Hang on just a second. Okay, cool. Let me open this and reshare my screen. All right. So I've got my MetaMask wallet here. I've got some stuff in here already. I have a little bit of Matic, some tokens from a previous demo. Cool. So what I'm going to do is I'm going to copy the address here for my MetaMask account now. And this could be... If it's your Alpha Wallet account, you could copy it from your phone. I just don't have a great way to screen share my phone and this at the same time. I know there's ways to do that. I didn't take the time to set that up ahead of time. Sorry. All right. So we scroll down here. Now we're going to transfer the token. So we've minted it, but we just minted it to ourselves. So this is an example of as someone who's defining or creating or publishing an NFT collection, you can mint stuff ahead of time if you want to. You don't have to. You could do what's called like a lazy mint or not actually mint it until someone buys it if you want. So you don't have to pay for the transaction fee. Or if you needed to for whatever application you're building, you need to have just like a pool of NFTs that are already there that someone can then transfer. You could mint all these to yourself and then have them available to transfer. So that's what we're going to do in this example. Now we're going to go to the tokens slash transfers endpoint and I would hit try it out. And we don't need all of the fields here. So I'm just going to paste this. We need the sender address and the recipient address. So sender is going to be my Firefly address. Recipient is my MetaMask address. I'm going to put that in here now. And then we need to specify the token index. So when we we minted the first token, it was just one. So we go to the Firefly Explorer. We can see there's one. And the token index was, I wonder if that should say one. We'll find out here. I may have a typo in the guide or we may have an issue in the UI there. I don't remember. I don't remember if the open Zeppelin auto index function starts at one or if it starts at zero. I think it starts at one because I think zero is sort of not set. But we'll find out here because if one doesn't exist, this transfer will not work. Invalid token ID. Okay. So it's a typo in the, that's a typo in the guide. My apologies. This should say zero right here, which that's good. That's a typo in the guide is a lot easier to fix than a bug in the Explorer. But okay. So we transferred token index zero. And if I go look at my Firefly Explorer now, I should see in just a second, it probably hasn't been confirmed yet. Yep. Yep. There it is. Now this other address has a balance of one and my Firefly address has a balance of zero. So we've transferred that token from my Firefly address, which is BB zero. Here we can see that's, that's where it originally went to in the Mint to C four one. And if we go look at MetaMask, I'm C four one. MetaMask may need me to tell, so Alpha Wallet will also just automatically find the token and it shows up there. You don't have to put the token address in. I'm pretty sure, which is great. I think MetaMask on the desktop does not do that. So if we want MetaMask to know about that, what we need to do is, sorry, this zoom screens in the way here. We need to get our contract address, copy it and tell MetaMask that we want to import it. So it automatically figured out the symbol from the contract. It went and looked up that contract on the chain, which is great. It needs a token decimal. Just put one, it's fine. Sorry, put. Otherwise it's going to look weird. I think, I think we need to put, I don't know what we need to put here. MetaMask is not the greatest. No. Okay. I don't know that's, that the balance is going to show up weird here. I guess, is it 18? I love MetaMask. This is wonderful. I did not practice this part of the demo. I should have done that. Maybe it's, I think it just needs zero. There we go. Zero. Okay. Sorry. I don't know what I was thinking. Import it and look, there's my, it says I have one of them now. Apologies for the confusion there. But so there's my token from here. I could actually, so I have this in my in my wallet. If I wanted to, I could actually send it back to Firefly now. Could copy Firefly's address and but not let me do a transaction on this. All right. Well, MetaMask has just not helped me out here. I have no idea why it won't let me transfer it. It says I have one, but it's not going to let me transfer it. Okay. So anyway, that brings us to the end of the guide. Pop up in the chat again here and see if we've got, sure there's probably some more questions here. Yeah. Thank you for all of you who are telling me it should be zero. All right. So we have another hour scheduled. We don't need to go that long. We've got to the end of the guide. I wanted to kind of go through it nice and slow so people could follow along and keep it interactive. So hopefully this was helpful. Thank you all so much for coming and just so many people for staying this long. This is a good long workshop where we really got hands-on. I'm happy to stay on for as long as people want to for the next hour if you have questions or want to still work through if you're still trying to figure out parts of the workshop. But that brings us to the end of our planned programming. So thank you so much. Yeah. So there's a question about other chains. Absolutely. If a blockchain is EVM compatible, it will work today. If it uses some other type of blockchain that's not EVM compatible, Firefly is extensible. So you could in theory create a new blockchain connector for a different type of chain entirely and do all of these same things. There was a question about access to the recording. That's a great question for either Sean or David. But I believe the recording of this will be on the Hyperledger YouTube channel. Should be there. I'll drop the link right now. The live stream link is here, but that will turn into the recording link as soon as this is over. Thanks, David. Appreciate that. Okay. I'm just scrolling back through chat here to see if there's any other things I can hit. Somebody DMed me about an error that they're getting. Okay. So to the person who DMed me about the transfer is... So the transfer is from the incorrect owner. So it's possible you flipped the to and the from address there. It's also possible the from address isn't actually the right one or perhaps you may not have actually minted that token. So a couple of things to check on there. Great question on ZK Tech. Yes, that's an area that we are actively exploring. No immediate plans that I can share about that right now. But zero knowledge is always... It's super interesting. And I think is an area that's going to be of particular interest in the future. But so it's definitely something that we're looking at. Advice for on-chain data analytics using graph databases. That's a great question. I'm not an expert on that. I think that is it's... On-chain analytics is certainly an interesting area. You could certainly build something that can create an on-chain analytics user experience with Firefly. Firefly is a thing that you could build that with. But it is not necessarily meant to be an analytics engine itself. I'm sure there are also other great open source projects out there that specialize in that particular thing as well. It's just an area that I'm not a particular expert in. Well, I'm going to check Discord here. Oh, there's a question about showing MetaMask browser wall to show the NFT. Yeah. So basically MetaMask browser, the browser wallet is really bare bones in the features that it has. This is why I recommend you use Alpha Wallet. That's... It's a lot better user experience. But basically I just went here. It says, don't see your tokens. Import your tokens right here. And then I put the token contract address in here. I can get that from PolygonScan or from Firefly itself. And I put that in there. Token decimal should be zero as we decided. For an ERC20 token or a fungible token, sometimes you'll have a number of decimal places that you have to specify here for it to show up in the UI, right? That's where I got that. That's how I got MetaMask to show that there. Any smart contract templates by business domain? Yes. I'm sure there are some out there. We have found, I think, typically many business cases can actually just leverage basically what we use today, a token contract. So Firefly comes with an ERC20 token contract and ERC721 token contract that allow you to associate data with a transfer, which is a really useful function. So in Firefly, we didn't get into this today, but in Firefly, you can send a message in a multi-party network and associate that with a transfer. We found that that pattern is really powerful and can serve many different business domains, whether it's a track and trace application, all kinds of different things. So a lot of times there's a lot that can be done with fairly basic smart contracts and the power that Firefly gives you to link data that's off-chain with data on-chain. What if you want to use your own IPFS node? Where should I set up the private IPFS address? So I'm trying to exactly understand what that question is getting at. So yes, we actually are using our own IPFS node right now. It's just running in Docker. I guess if you're saying you already have one running, where do you configure that? That goes into the Firefly core config file. You need to get the IP and port number for the IPFS API and Gateway. That goes into the Firefly core config file, I think is what you're asking there. In terms of identity, a workshop, yes, we should definitely do a workshop about identity in Firefly. That's a great topic. It's a big topic and there's lots of stuff to explore there. So I think that's a fantastic idea for a future workshop. Let's see, there was a question. Minted several images on the same token. How does this differ from the minting we did today? I'm not sure I understand what that means. If you've minted several tokens that all point to the same image or if you've minted one token that points to multiple images. And if it's the latter, I'm not sure how you did that. I guess how it compares to what we did today. We uploaded one image and we pointed one token to that. You could, if you wanted to, so like a lot of NFT collections will have, you may have, like we minted a one of one today. So there's only one, on this smart contract, there's only one animated Firefly pixel art. You could say, well, these ones are rare, so there's only five of them. And you could point five different NFTs to the same metadata JSON. Or you could say they're common, there's 20,000 of them. And you could mint 20,000 tokens and point them all the same thing. It's really up to you and how you want to define your tokens and how you want to define your collection. Someone said they got the NFT to their MetaMask wallet. Is there an easy way to transfer it to the Alpha wallet? Probably, I'm not sure why the button to transfer it in MetaMask didn't light up. Honestly, I think MetaMask is not, the browser MetaMask is just not the greatest. It doesn't have very many features. There is probably, you could probably, if you really needed to, you can export your private key from MetaMask and put it in Alpha wallet. And then it would show up there. That's another option. Or you could use a different wallet app. As long as you load that private key into a different wallet app, you can transfer it wherever you want. It's a question about hybrid cloud hosting or architecture in Kaleido. Yeah, again, we'd love to talk more about Kaleido and all of its offerings. It's just not the main focus today. But yeah, lots of different, really cool options there. And we'd love to talk about that in the future. All right, we still got 48 people in here. So I'm happy to leave the call open if people want to keep if people want to keep working through the workshop and people are still working on it. Happy to hang out if people have questions still on a dialogue. Let's see a question about integrating capabilities to connect the NFT to enterprise systems. The question is what does that mean? And that, I guess that would be my question as well. There, I guess one thought on that is, you know, we commonly, most people when they hear NFT, they think, oh, it's a GIF or it's a board ape or it's some goofy pixel art of a cat or something along those lines. And really, what an NFT actually is, like you saw today, is just a unique identifier on a blockchain that has ownership, that has provenance, and it has traceability. So it has a history of the ownership. And it points to some piece of data that may live off the blockchain somewhere. And when you think about it from that aspect, there are lots of really good business cases that you can use for that. And so one of the other challenges is in the public space, every time you transfer that NFT or perform a transaction with it, it costs that blockchain's native currency. In this case, it's cosmetic. In a private chain, you could have a gas-free system where the price of gas is free. And so that means you can make as many NFTs as you need to for your business application on a private chain. You could transfer those freely between members of an organization. Even using Firefly, you could potentially bridge those NFTs to a public chain in certain cases when that was necessary. So there's a lot of different enterprise applications to the things that we've shown here today. But, you know, most people initially think of an NFT as just an image. Well, it's actually, I would say the common use cases for NFTs that we've seen on the internet today are just the tip of the iceberg in terms of what is possible with the technology itself. So there's plenty of things that are, I think, a more useful business value that can be done with an NFT. Some other questions here about encrypting or decrypting attachments post to IPFS. Potentially, yes. I'm sure there, I know there are some projects out there that have done things with that. It's not in the scope of what Firefly does today. But it's very possible that you could plug another tool into that and use it for something that is more important than a silly picture. It's also probably worth thinking through, like, is the data too sensitive that it shouldn't even be shared even in an encrypted form publicly like that? Or within a multi-party network, if it's too sensitive to be shared with all of the members of the multi-party network, perhaps sending it directly peer to peer might be better while still using blockchain as the distributed ledger and proof of that transaction that happened while keeping the payload itself completely private. Someone asked about if S3 is suitable for this. Sure. Yeah, you could write. So, like I said, Firefly is very pluggable. It's very modular architecture. You could, so there's one plugin today for shared storage. But if you read through the code in Firefly, you don't see a lot about IPFS. It's really, we call it a shared storage system. And there's one implementation of that plugin today, and it happens to be IPFS, but you could most definitely create another shared storage plugin that leverages S3 or some other sort of distributed file share system and use that as well. All right. Any other questions? Thanks. Appreciate it. Any plans for the hybrid cloud? Yeah. So, I mean, Kaleido definitely has very flexible hosting options. If it's something you're interested in learning more about, I definitely encourage you to reach out to the sales team, and they're more than happy to talk through the different options that are potentially available there. There was a question about how to point to S3 buckets for the image URIs. Yeah, so this is also something I've seen in some NFTs where the metadata JSON goes on IPFS, but instead of that IPFS resource pointing to another IPFS resource, the metadata points to S3, and you could most definitely do that. I chose not to do that because I wanted both the image and the metadata to be immutable and distributed, so I chose IPFS for both of them. There's a question about in Discord about RPC endpoints. Yeah, so chain lists, lists, nodes that are, it's status, list, nodes that are up and available. That doesn't necessarily mean that they support all of the functions that Firefly and the EVM blockchain connector need to function. If you look at the EVM Connect Readme lists the different JSON RPC functions that it needs to actually run. Not all free public nodes support all these functions. This is why we ran one today that I know 100% supports all these functions because we're running it, but if you just do a search for free public RPC nodes, it may be up and it may support some of these. It may support all of them. That's great. You're welcome to use it, but it's sort of, you just have to have to test it and see if it actually works. All of them expose all of these functions because some of them can be more resource intensive than others. That's just something to watch out for there. I'm sorry, I thought I was sharing my screen still. Let me drop the link to that. Readme in here. All right, give it another minute or two, but if folks don't have any more questions and we can close this down here in just a minute, I think. Happy to keep chatting on Discord. Again, I'll drop the link to, let's go grab the link to the Discord there if you want to keep chatting. Happy to, I'd love to connect with you there. All right, someone finally caught up. Yay. Great job. Let's see, there's a question in chat about how we can store on S3 and maintain immutability. I don't know. That's why I didn't use S3. There may be ways to do it, but that's probably needs some really deep architectural investigation into how S3 works itself. I don't know. I don't know if that's even possible. Definitely something to explore though. All right. Thank you everyone so much for attending. There's a question about Quorum. Yeah, Firefly works with Quorum as well. Thanks everyone for attending. I think we're going to go ahead, the questions are slowing down here. If you have more questions in the future, would love to connect with you in the Firefly Discord. If hopefully this workshop was useful and informative, the guide will stay up there. You're welcome to plug in whatever RPC node you want to after today. I'll update the guide to have a note about that. But I just really appreciate all the time that everyone put into today's workshop and for taking a couple of hours here to sit with me and use Firefly and get hands on. Yeah, thanks for joining and hope you have a great rest of your day. Thanks Nico. Thanks everyone. Thank you David. Thanks for facilitating and organizing everything. Really appreciate all your help. Yeah, of course. Happy to help. Yeah, thanks everyone. Hope you got a lot of use out of that. David, do you need me to do anything on my end to shut things down? No, I'll close it in just a second. All right. Thanks so much. Okay. Bye-bye.