 Okay, Sam. Yeah, let's go ahead and get going. So I'll start introduction. Thank you everybody for joining this virtual Hyperledger meetup today. We have Samuel Vinze from Go Ledger, and today he's going to speak about building Hyperledger Fabric Chain Code better and faster with the CC Tools Lab. So with that, Sam, take it away. Thank you, David. Hello, everybody. So as David mentioned, today we're going to talk about these lab called CC Tools, and how we can use it to build chain codes better and faster. So before we get into that, just introduce myself. My name is Samuel. I'm the CTO at Go Ledger. Go Ledger is a Brazilian company specialized on blockchain and Hyperledger technologies. We work with Hyperledger Fabric and Basel, and also some of the tools that come together with both of those frameworks like Cacti, Caliper, and a bunch of other projects. I've been working with Hyperledger Fabric since 2018. Back in the day, I was certified as Hyperledger Fabric Administrator, which is now extinct certification, and I helped with the Hyperledger Fabric certified practitioner certification that just came out last year. And more importantly, I am one of the core maintainers of the CC Tools Lab. So what is Hyperledger Labs? Hyperledger Labs is a way that the Hyperledger Foundation found to encourage innovation in blockchain and DLT technology. Basically, Hyperledger Labs hosts experimental projects or labs related to various aspects of blockchain. Those projects are maintained fully by the community, and the whole structure of Hyperledger Labs presents a easier entry point to new projects into the foundation, and successful projects may be integrated into the Hyperledger ecosystem at some point. And what is CC Tools? CC Tools is a package that provides a relational-like framework for programming Hyperledger Fabric chain codes. CC Tools will implement tools that work with Go chain codes, mainly with features for assets, data types, transactions, and events. Here on this meetup, I'm assuming most people are familiar with the concepts of chain codes. But for those that are not, chain codes are basically the smart contracts, how Fabric calls smart contracts, and they will provide the business rules for registration into the ledger, basically. So a brief history of CC Tools. When, as developers, we strive for reusability of code. So it's a good practice to attempt to reuse code as much as possible. And in the beginning of Go Ledger, Go Ledger was founded in 2017. But in 2018, we were getting started with a lot of chain code development. And I remember developing some chain codes and having to take code from one chain code that we had just developed and put it onto another chain code for another customer. And when you're starting with the development, you learn a bunch of good practices as you go. So we were getting a lot of code that could not be reused amongst a bunch of chain code that we had. So one of the first things that we tried to do was getting all the common things that we implemented for all these chain codes. And we started pulling those features into a separate project called template CC. And that was, let's say, the template project that we would use for any other project that was going to get started. So instead of getting other projects and getting common things like property validation and things like that, instead of going to those other projects and pulling the things that we needed to new projects, we started to adding those features into template CC and actually starting a project with the current version of template CC. At some point, we actually realized that we could just take all these features that we were implementing and put it into an external package. So that package was when we started calling it CC tools. So this is actually one of the actual commit on template CC where we transitioned from using local files for those features to the CC tools package where we could just iterate and maintain and just update the version of newer chain codes. In June of 2021, we released the package, the CC tools package, as an open source project along with an example repository called CC tools demo. And that was the first, let's say, open source version of the project that not only Go Ledger could use, but every other developer that wanted to develop chain codes could use it for chain code development. And from 2010 to one until last year, CC tools was maintained and used in production as a Go Ledger project. And last year, September of 2023, CC tools was approved as a Hyper Ledger Labs project. So before we get into CC tools, we have to talk a little bit about standard chain code development. And for those of you that are developers here in this call, you probably know there are infinite ways one could implement a chain code. Basically, for chain code development, you can use general purpose languages. You can use Go, you can use Node.js, you can use Java. Actually, you can use JavaScript, right? And there are many ways you could structure a project and validate or create complex business rules for your chain code and all that stuff. Usually, you're going to use something like the Fabric Contract API. In this case, I'm going to be talking about the Go tools because CC tools is made for Go chain codes. But basically, that would translate to the other one. So you have the Fabric Contract API. And at the time that CC tools got started, chain codes actually use Fabric Chain Code Go directly. There was no Fabric Contract API. But generally, developers will basically do a get state or a put state in a transaction. So you're going to do some validation on something that you received as input. And you're going to put a state into the blockchain or you're going to get a state into the blockchain or you're going to do both. So that's standard chain code development. So this is what it looks like. This is taken from the Fabric samples repository. This is one of the examples that has a transfer basic chain code. So you basically have a, for example, a ghost truck that's going to act as your asset definition. You're going to create this as a variable. Then you're going to marshal this into some JSON bytes. And then you're going to essentially put the state, those JSON bytes as a state for a particular key, in this case, an ID. So this is pretty standard. So simple chain codes can be easily implemented this time away. Implementing multiple simple chain codes might present the issue of copied and pasted code. So for example, if you get a particular function for validating some strings in a way that is, for example, you can pass parameters and validate by those parameters, you might find yourself doing like we did in the beginning, taking those functions and copying and pasting it to neural code just to reuse them. But when you get to more complex chain codes and implementing actually multiple complex chain codes, it can take far too long. And that was our experience in the beginning to developing chain codes. So how to actually build better and faster? So CC Tools is the result of five years of chain code building experience that we have at Go Ledger. The main features that we observed in our daily development were implemented as to make the development easier. So for a moderately complex chain code in the beginning, developing in a standard way, we would take about three months, give or take. And with CC Tools, the same level of complexity we can actually implement in less than a month, usually three weeks. So those features that we observed that we were using constantly, we actually put it all into this package that can be easily used by any developer. And those are basically related to assets which are well-constructed and actually provide more functionality, allowing referencing between assets. So you have the relational-like feature that we mentioned earlier. Basic transactions like rate, rate, update, and deletes, they are built into the chain code for every single asset. So defining an asset, if you want to just perform just basic transactions on it, you don't have to actually code any transaction. Everything is already built in. You have custom data types, which can be extended from primary data types. We're going to see what does that mean a little bit. And of course, you can create custom transactions that will leverage range of CC Tools functions. Let me see if we have some questions in the chat real quick. OK, we're good. OK, so the CC Tools project has three parts, three rappels. The first rappel is Hyperledger Labs slash CC Tools. It's a core library which is imported into projects. So this is where the actual library is implemented. We have the CC Tools demo rappel, which is a template of a working project, which we're going to explore further today. And we have the CC Tools doc, which is the read-the-docs repository for the library with tutorials. And we're going to see what it means in a bit. OK, so let's get into the real deal here. So for Hyperledger Labs CC Tools demo, let's start with the things for those who want just to use it. So let's say you want to make your development faster and you think that CC Tools might help solve your problem. Let's see how we can use CC Tools to actually make your work easier. So what I want to do now is five things, basically. We're going to see the rappel structure. We're going to see how assets are defined. We're going to see how data types are defined and used. And we're going to see how transactions are defined. And finally, how it all comes together in the end with an actual working example of it. So what I'm going to do now is actually share my whole screen. Just give me a second. OK, hopefully you can now see my whole screen. And here I have the CC Tools demo rappel opened on a browser tab. So let's get started here with the structure. If you scroll down to the readme, you're going to see our director structure here. The main three directors are slash fabric, slash chain code, and slash CC API, where the fabric rappel is going to provide all the tools for a fabric network for a test environment. Here it is mentioning 2.2 version of fabric, but this also works with 2.5. We're working on a release for upgrading this network. And this actually, CC Tools has been tested with 1.4, 2.2, 2.4, and 2.5, OK? We have the chain code directory with chain code and related files. This is where the implementation happens. And we have the CC API, which is an API that we're going to use to interact with our local environment for this chain code, OK? So I'm going to move to VS Code now. This is the clone rappel on the main branch. So basically the same thing that I was showing you. And the first thing that we wanted to actually see is how we can define our assets. So we can actually open our chain code directory. And I know we have a bunch of directories and scripts here. I'm going to get into this on the fifth point that we have on the slide. But first, I wanted to show you how we create the asset. So opening the chain code directory, we have a structure here with asset types, data types, event types, tests, transaction definitions, and other files here. On the asset types directory, we have the implementation of the assets that we want. So what are assets for those that are not used to the naming convention, let's say? The asset is a you can think of it as a table on a database. Basically, it's the definition of a certain type of data that you want to actually store with its properties and data types for its properties and whether it is required, whether it's not, things like that. So the asset is going to be the abstraction that makes that registration on the ledger more structured. So for CC tools, I'm opening here the definition of a book. So let's imagine that this chain code, example chain code, will implement a, for example, a library, OK? So this is the definition of a book. We're going to have our import here. So we're importing the CC tools package, actually the assets package of CC tools. And for the assets package, we have the asset type definition, which will provide a bunch of fields that we can feel to define our asset. So we're going to have a tag. This is going to define the asset uniquely on our blockchain. We have a label. This is useful. We're going to see how this is useful, but this is useful for when you want to, for example, assemble a front end that is dynamic and you want to not use a tag but use a label that's a pretty string. And that's description, which is just book in this case. And here we have our props. OK, our props are properties of the asset. And if I expand this, we're going to see that we have a list of asset properties. And this is where we actually define each of our fields of this asset. So our book is going to have a title. It's going to have an author. It's going to have the current tenant, the person that is currently possessing this book because it's a library. We have genres. We have published dates. And we have book type. And one thing that is interesting is that instead of creating a ghost truck and just getting the name of the property and its data type, we can have so much more. We can actually say if it's a required property, we can make this property a key, which I'm going to explain how CC2s do with that in a little bit. We can say that the data type is a string. And we can actually, we can reference another asset. So this is interesting because now I have a relation to another asset that is already registered on the blockchain. And this is validated for consistency. I can also do lists. So I can do a list of strings. I can do date time. And I can do custom data types. So for example, this book type, it is a custom data type that it is expended upon the primary data types that we have. So this is an example of a book. So let's check person. I'm reference person here. Let's check how person is defined. So for person, I have also my tagging label. I have my description. And I have my properties. So a person is going to have a tag called ID. This ID is specifically a CPF, which is a Brazilian ID. And the data type is actually CPF. And we're going to see how we work with that in a little. We have also a name for this person. And one interesting thing is that I can provide a validating function directly on the asset definition. And whenever a person asset is registered on the blockchain, all these properties are going to be validated by their data type and their validate function. So this is pretty much checking that the string is non-empty as an example. But you can pretty much add any validation that you wanted here. And one other thing that is really cool is that you can provide a default value for your property. So for example, the height of the person is not a required property. And I can fill this automatically with a zero when this property is not passed. I can also change this to provide, for example, like 100 or whatever. This is basically free for the developer to decide. OK, so this is one of the ways that we define the assets. And I already showed two assets that I use in custom data types. So how do we define those data types? I can come here to this data types folder. And you can see that I have book type and CPF here and a data types.go file, which is going to list my custom data types. But let's check for CPF, for example. So remember that CPF is an ID number for basically Brazilian ID. So every data type that is registered here is going to have at least these two properties. So this is also imported from CC Tools. And we are going to tell CC Tools what are the accepted formats for this data type. In this case, it's a string. OK, in this case, it's a string. And we're going to provide a parse function. And this parse function is going to receive the data as an interface. Basically, it's going to receive a generic data. And it's going to return the string representation of this data, the actual interface, and an error. So in this case, we are receiving as a string. And we are providing below all the codes that validates this to be a valid CPF. And if it's not valid, we're going to return the error. So if it's valid, we're going to return the string representation and the actual representation. This is useful for, for example, date times, where you want to return, for example, a time dot time here and the string representation of time in the first return value. And then once this is listed as a custom data type, you can use it for any property that you want in your chain code. So this is really good because the validation for data type for any asset that you have can be the same logic. And CC2 takes care of that validation automatically. And for book type, we have a sort of different type of data type. This is actually a enumeration for the type of the book. So if it's a hardcover, if it's paperback, or if it's an ebook. So this implementation uses the iota to make this an enumeration. So book type hardcover is going to be 0. Paperback is going to be 1. And ebook is going to be 2 type, which is going to use the book type and check if it's one of those three, if it's not an invalid type. And then here, we have the parse function, which will take a data. And here, we take the data, which is an interface. But we kind of check if it's a float64, if it's an integer, if it's an actual book type, or if it's a string, and we parse it accordingly. And then we check that if the type is actually valid and then return it. So one more thing that we have is also these dropdown values. And this is going to be really useful for something that I'm going to show you later, which is an interface that actually assembles the registration of assets automatically. And these dropdown values are going to provide the information for these frontends to be assembled correctly. OK, so I think I have a message on the chat. OK, we're good. OK, so continuing. So we've shown asset types. We've shown data types. And now we have transactions, which are the actual logic of our chain code. So for example, let's start with a simple one. Let's start with a create new library transaction. This create new library transaction, as the name suggests, is supposed to create a library asset. So the library asset is defined right here. It's not that complicated. It's going to have a name. It's going to have a book collection, which is a list of references of books, which is pretty cool. And it's going to have an entrance code, which is a reference for secrets that we are going to tackle later. What is the secret? Because it's related to private data. So create new library is going to be really simple. It's just going to take the name of the library. The library is going to be created without any books on it. And here we have the definition for tag, label, description. This method is going to reference the HTTP method that can be used on an API. This is really useful, again, for some of the dynamic front end that we assembled for it. These colors, we're going to talk more about permissioning later, but the color is going to restrict what organizations can call this function. And we have the most important part of it, which are the arguments, which are really similar to the properties. But they are actually the inputs for the transaction, in this case just a name. And the routine, which is actually the logic for the registration of this asset. So here for the routine, we have a function with the following signature. We have a function that we will receive a stub object, which is a stub wrapper. We're going to speak more about the stub wrapper later. And we're going to receive a request, which is a map string interface. And this will represent the arguments that we receive on our transaction. And those arguments can be accessed using their tags. So for example, if I'm going to access name, I just use the tag name that is provided here on the args part. And in this case, I make a type assertion because it's an interface to name. And then I can use this to assemble my asset object. So here we start to get into some of the functions that CCTools provides for us. So one of those functions is this new asset function. This new asset function, and when you start using CCTools, you're going to realize that all of the functions in CCTools are they have comments on it. So if you're using an IDE, you can just hover your mouse and see what the function does. So the new asset function is going to construct an asset object from a map of properties. So that's what we are doing here. So we are creating a library map. We are saying that the type of this asset is a library. This is referenced to the tag of the asset. And then we are saying that the name assets is actually the name that we received as an argument. And then we are passing this to the new asset function. What this will do is it's going to return us an assets.asset object, which is going to have a bunch of useful functions for working with this asset. Here we are doing a simple registration on the blockchain with the put new function. The put new function, it's going to insert the asset in the blockchain. And it's going to verify if it exists. And if it does, it's going to return an arrow. So that's basically what the put new does. And after we do this put new, we just take the assets, assemble it as a JSON. And then we return it here for our client application, which is calling this transaction. Here in between, we actually create a log message for events that we're going to talk a little bit later. But that's basically the anatomy of a simple transaction using CC tools. And what is really cool is that if you get a really complex asset with a bunch of validation on data types, on references, and all that stuff, the new asset and put new functions are going to solve all that for you. So it's going to be the same complexity for you to register an asset with a bunch of different data types and a bunch of references as it is to register a simple asset type like library. OK, so we moved through basically the three main parts of these CC tools. And now the thing that we want to do is see how it all comes together in the end. So for that, we're going to get into how we make this actually work on our machines and how we can actually develop and iterate on it. So for this, there are a bunch of scripts that are auxiliary for a developer to deploy their own network in their machine. The one that we are going to use is the start dev one in the upgrade CC. The start dev is going to create a local development network. And the upgrade CC is going to upgrade the chain control code for the network that is already up on our machines. So I'm going to run start dev here. I have two options here. I can run just start dev. It's going to deploy a network with three organizations. Or I can run a network with only one organization for a more light setup. For this demo, I'm going to run it with three organizations. And we're just going to have to wait a little bit until it deploys everything for us on Docker. So I think now we have some message on the chat. Some questions from YouTube. Can we use MongoDB instead of CouchDB? As far as I know, the peer only supports level DB and CouchDB. I think if you were to use MongoDB instead of CouchDB, you'd have to actually port the peer and add the support for it, because there's no official support. OK, how to debug running chain code? OK, so CC2 does not deal with the remote debugging of the chain code. We're going to see how to make tests on the chain code. And we can actually run debug on some of the tests that we're going to show here today, but not all of them. OK, so how to run chain codes locally? OK, so what I'm showing right now actually is running the chain code locally with a local test network. This test network is heavily inspired by the test network on fabric samples. So that's the way that we're running locally. Now, if you want to run chain codes outside of a network, you probably would have to create your own runner for it. OK, what about creating our own consensus mechanism? OK, so this presentation is actually on the chain code level of things. Consensus mechanism on fabric is a whole other thing that's going to be related to peers, or there is in the transactional flow. So we're not going to cover that, and that's probably a question for another time. Can we make public key? Sam, sorry to interrupt. Just on that last question, sorry to interrupt. There's actually a meetup next week that's going to be about fabric consensus. I just dropped a link to that in the Zoom chat. Perfect. So can we make public key storage using CC tools? I'm not sure what you mean about public key storage. If you can make this question a little bit more detailed, I can answer it. And we have public keys and private keys. But do you want to register public keys and private keys on the chain code? Is that what you're asking? OK, yeah, you certainly can. But I would say that you might not want to restore private keys on the blockchain. You might not be the best of ideas, but it probably depends on your use case. So there's one big one here. How easy is to go beyond the base crude operations, like implementing customer organization access rules, putting part of the data into private data collections, having trained in feuds, in the transaction or purge private data, querying data in an efficient way, like using composite indexes? Yeah, we're going to cover all that. Yeah, I'm going to cover all that. So we have a couple more. Do they also support private collections? Yes. I'm going to move to that just in a little bit. Is it possible to run chain code Java instead of Go in CC Tools? Not at the moment. CC Tools is implemented for Go chain codes. Can I deploy it on AWS managed blockchain? Yes, yes, you can. This is standard chain code. You can deploy in every fabric network that you might want to deploy on. So let's move on and I'll keep the questions for later. So now we have deployed our local network, and I'm going to show. So we have a bunch of containers here. We have three organizations. So you can see that we have R1, R2, and R3. We have the dev containers for the chain codes. So this is where our chain codes are actually running. And we have the CC APIs, which are the chain code APIs that we are going to use to interact with it. So we don't have to use CLI and none of that. And we have CC APIs, one API for each organization. This is a client application for each one of these organizations. And you're going to be using client certificates for the respective organizations. So we're going to have R1, R1 using certificates for R1, R2 for R2, and R3 for R3. So we have now, there's one thing that we really like to use when developing, which is an interface that can be run with this script, RunCCWeb. I'm going to run it now. And what this is going to do is going to provide me an interface so I can connect one of the APIs and actually see what's going on the chain code with the assets and with the registrations that we have. So I'm going to open my browser here and I'm going to access my localhost 8080 where my interface is located. And this is connecting me directly to organization one. If I want to change the API that I'm connected to, I can just change the localhost from 80 to 980, which is organization two and 1080, which is organization three. Okay. For now, we're going to stay with organization one. And here we have, actually we have our assets. We can see that we have the assets that I just showed you. We have person, we have book, we have library. You might notice that we have assets read write and assets read only. And we're going to see just in a little bit, why is that? And here below, we're going to have the active transactions and we're going to have also non-callable transactions and we're going to show how permissioning works on CC tools as well. For now, we can just go to person and we can see that we have a table which is empty and we can now create a person. And for that, I'm going to use a sample as CPF here. I think that's the one. I'm going to put my name on it. Let's say I was born today. And this interface is assembled dynamically based on what is defined on CC tools. So I can just submit and remember that my person's height is not mandatory. I can just submit or I can click curl and have the actual call the curl command for creating this. And we can see that it's calling this create asset endpoint with this payload. So I'm just going to submit this. So now we have a person registered. If I come back to the table, we're going to see that my new person has been created. And just as we said previously, the person's height is 0 because that's the default value. So that's one way you could use it. The API that is provided is also a swagger. So if you access the API port, you can actually see the swagger for the operations. And one thing that is really interesting about the API and the way that CC tools is structured and how those connect together is that it is a generic API that's going to work for every transaction that you define and for every asset that you define. So you can mess around with your same code and you don't have to mess around with the API if you don't want to. You can obviously create specific endpoints for assets if you want. But in the development case, we chose not to. OK. So we have our network. It is up and running. And now what we want to do is actually explore a little bit more. So as a next step for it, we are going to see how we can do asset permissioning, chain code transaction permissioning, chain code events. We have a feature that is called Dynamic Asset Types that we're going to show it in a little bit and automated tests. OK. So you might have noticed that I didn't mention during the asset presentation, for example, for a book, that we have this property called Writers on it. And this Writers property is really interesting because it's going to allow us to define which organizations. And these are the organization MSPID. So which organizations are going to be able to write on that particular property? And it's really nice because it's, how can I say this? It's granular enough that you can make it for properties instead of the whole assets. So for example, in this book, example, we have R2 being able to write for the property title and for the property author. And also, we have just the org. This is for the network that is a single org. But for the network that we deployed, which are three organizations, this is what's going to make the difference. And if I take this and if I define the writers for properties that are key values, this makes it impossible for other organizations to create new assets with those values. Because when you create a new asset, it is mandatory for you to write a key for it. But this actually allows for organization to create a book and for another organization to change any other property for a book that already exists. So for example, in this case, if I come back here to our interface, you might notice that our book is under assets only. And I cannot create this. And if I actually could call the create assets transaction, it will return an error. So if I point this to the organization to API, now I can, the create button is available and I can just create a book. So let's say that I'm going to create The Lord of the Rings by J.R.R. Tolkien. Let's say it's a fantasy. And now we're leveraging the use of listing on CC2. So remember that, generals, they are a list of string. So if we go back here, you can see that this is a list of string. And this front end is going to assemble this directly for you. So it's fantasy. And let's say it's about fantasy and fiction, let's say. OK, I don't actually remember the published date. So let's say it was like two weeks ago. And the book type is, let's say it's a hardcover. And we can create this. So this is going to create a book as organization two for us. And then we can see that our book is actually created here. And if we go back to organization one by changing this back to port 80, we can actually see the registration here. We can see the history. This is calling another built-in transaction to see the history of an asset. We can see the transaction that's been called by clicking on the curve button. And it's to read asset history. This is one other limitation that's built into CC2. And this is the payload that is being sent. And you can see that it's been created by organization two at this timestamp. So coming back here, as organization one, we can actually edit this because nothing that Chincode is saying that we can't. So we can just click Edit. And for example, let's say that there is a current tenant, which is the person that we just created. This is that CPF that we created for myself in a couple of minutes ago. So I can just update the book and create this and update it. So now it's referencing the current tenant, which is an asset. If I click here, I can actually see that the asset is being referenced. And I can also come back to the history and actually see that org one made a change to this particular key. The particular key that we are talking about is actually this one. This is the key is made out of the tag of the asset and a UUID identifier based on the properties that are keys. So if the asset has the same keys, the UUID is going to be the same, basically. OK. So this is an example for the usage of writers. Another example that would be analogous, but for transactions would be the user of colors. So this is going to pretty much do the same. The colors is going to allow us to call this transaction as org three. One interesting thing is you might have no info in front. This is because this also supports rejects. So you can actually create organizations that have a particular prefix or something and use rejects to allow all of them to use to call this transaction. And this will not be callable by any other organization. If both writers and callers are empty, it's basically allowed for you by anyone. OK. Right. So this is part of permissioning on writers and callers. And we have another kind of permissioning on assets, which is private data. How do we work with private data on CC tools? So for private data, you probably all know that you have collections, private data collections, and you create those private data collections between the company, the organizations that you want to have access to it. And that will basically create a new policy, a policy for accessing those private data. And also remember that private data does not go into the ledger. Only the hash off of the key and the value goes into the ledger. And the private data is actually exchanged amongst the companies that are in the collection using gossip. So how does CC tools leverage that? So for CC tools, we leverage that, creating assets that are private. And for assets that are private, we have on the level of the asset, we have a reader's property. So for example, this secret asset is a secret between R2 and R3. We have org here for our example of a network that is with a single organization. But this is essentially a secret between R2 and R3. And all assets that are created, all secret assets that are created using this definition will go into a collection between R2 and R3. This cannot be standalone. So for this work, we actually have to define the collections JSON, which is defined here below. And it's used during instantiation of the chain code. So for this collection, we have a collection that is the same name of the asset with a policy that is going to allow R2 and R3 to access it. And CC tool is going to take care of the rest. So whenever an asset, this asset is registered, CC tool is going to actually default to using the function of putting private data instead of the actual put stage that's going to go into the ledger. And one other interesting thing is that, for example, when you create an asset using the beauty and create asset function, if the asset is private, the create asset is going to get the inputs from the transient data that is sent during the transaction call. And this is all done on the API that I can show you in a little bit. But let's do an operation to check how is it working. So I have Word 1 here. You can see that we have secret as an unreachable asset for organization 1. So if I create here, it's going to return me an error. I don't have access to it, basically. So I can go to organization 2, for example. And now my secrets is on the read, write part of the assets. And I can pretty much create this secret here. And let's say the secret is my new secrets. And the actual secret is hyperledger labs is awesome, which is not a secret, by the way. And I can submit this. And now we have a private data registered here. You can see that I don't have the option to see the history, because private data does not generate history, just the hashes of the value of the private data. And this is also accessible by R3. So if I change this to organization 3, I can actually come into secrets, which is, for organization 3, it's really only. And I can actually see that hyperledger labs is awesome. OK? So I think we have a couple questions here. Does the name have to be secret for you to later identify it? No, the name can actually be any name that you want. We used secret in this demo repo to actually become clear that this is an implementation of private data. You can actually have any assets to be private. You just have to go into the asset, for example. You can make book a private data. You go into the asset, you provide a readers set, and you create a collections for it with the name of the book, with the name of the tag of the asset. In this case, it is book, OK? And then CC2 is going to take care of the rest. If you want to use collections for multiple assets, you can just use like you would in any other chain code by using the put private data function that is exposed by the fabric chain code go tools, OK? How would you implement having an attribute that is confidential to a subset of orgs while the asset list and its other associated attributes are visible to all? Yeah, so this is a really good question. What I would do is actually how it's actually defined here. So for this example, we have the library, which is an asset that can be seen by everybody. But it has an interest code, which is a secret that can only be seen by a subset of organizations. So what we do is we actually reference the private data in the public accessible data. So you can create an asset that references its secret properties, and you can have multiple references for multiple different kinds of secret assets that you want. So how do you define that it is private data? OK, yeah, so the readers and the json, yeah, exactly. How about private data objects? I'm not sure what you actually mean by private data objects. If you can clarify that, I might be able to answer it better. OK, so we've seen now asset permissioning, transaction permissioning, and private data is included on that. And now we have chain code events. So CC2 also provides a way to use private data. No, I'm sorry, to use events. This was just recently implemented. And under the chain code folder, we have the event types. And the event type is going to create an event object imported from the CC2 structure. And this one is a simple one as an example that's going to log in the API, the creation of a library, for example. So in this case, we're going to have a tag. We're going to have a label, a description, just like every other CC2 implementation. We're going to have a type. OK, so types can be event log, event transaction, and can be a custom event. The base log is going to be a new library created. And we are actually defining which are the receivers of this event. And this is really useful because when we deploy our APIs, our APIs, they have the client certificate for the specific organizations. And we have this listener on the API that's going to register to all the events that they are receivers from in the chain code. And this is pretty straightforward to use. Once you define it here, you just use it in one of your transactions. So for example, the create new library transaction is actually going to take a, it's going to actually create a log message with the new library, make it into bytes, and send this to the call event from the CC2's library. And informing that we want to call create library log with our log message. And then our APIs can receive that. This is pretty simple because it's just a log, but our APIs, the APIs that we have implemented here, they actually support you actually creating an event that's going to serve as a trigger to call another transaction. And this is actually done by this other type event transaction, which you can inform another transaction from the chain code that you want to call. And then once the event is issued, it's going to trigger another call to the chain code. So you can actually create workflows together with the API to do multiple steps and multiple transactions at once with one call, I mean. Cool. So let's see if we have more questions. No, I don't think so. OK. So now we have dynamic asset types. This is a specific implementation that we did for CC2's, which in my opinion is pretty neat because we actually took the definition of an asset, which is based on this, is based on tag label and properties. It's on tags, keys, and whatever not. And we actually created a way for assets to be defined once the chain code is already deployed. So you don't need to actually create a new definition on the source code for your assets and then upgrade your chain code. You can use the dynamic asset types feature and define those asset types directly on the chain code and actually have their definition live on the ledger. This is done with, for this to be enabled, it has to be enabled on this particular object. And if it's enabled, it's going to allow you to create asset types and it's going to allow you to choose which organizations are administrators of new asset types. So you can actually make permissioning based on that. So what does that mean? I'm going to show you now. So my dynamic asset types feature is enabled. So I can come back here to my interface. I'm going to connect to organization number one. And here I have a great asset type operation. When I click here, you can see that I have the same options as it provides me for creation on our source code. And I can create a new asset type basically just by filling this out. So for example, let's say I want to create a company asset. So I'm going to create a tag. I'm going to create a label. This is going to be a description of a company. And let's say my company has a name, which I'm just going to have a tag name. I want it to be a required. I want it to be a key. And the data type is going to be string. I don't want to add any writers right now. And I don't want to add a default value for the name. So I can click on Add. So name is now here. And I can submit this. And now I have a new asset type that can be worked with just like any other asset type that is defined on CC Tools. So if I click here to reload my application, I can see now that I have a company asset here. And I can edit the type if I want. Or I can create one. So I can say let's say I'm going to create Google Azure. And now this is actually an asset that leaves on the blockchain. And I have my asset here. It was created by Organization One. And it has its own key. And all that was defined without you having to actually mess around with the code of the chain code. And you can create multiple asset types just by transacting on the CC Tools blockchain. Sometimes this is not ideal. Of course, sometimes you want to have a certain assets to be predictable. That's why you have the asset admins. Because if they are admins, you're basically saying that they are the ones that have authority to change the chain code. But if not, you should disable this and upgrade your chain code with new definitions and go through the chain code lifecycle with the approving orgs just as usual. This has some use cases. But I see that not all use cases are perfect for this. OK, so I have some questions here. Let's see. Do you happen to have any transaction performance measurements of this demo at Google CC Tools? I don't have it right now. We've done some performance benchmarks with Caliper using CC Tools, but for another chain code for one of our clients, one of our customers. So not for this particular demo one. But maybe if you want, we can actually work together and create those measurements. If you want using Caliper, that one tool that we use already here. OK, so when would it make sense to use CC Tools event management versus something like Sawtooth or Firefly? I don't think I can answer that with a lot of certainty because I don't have that much experience with Sawtooth and Firefly. I know that the event management that we created suited our needs for eventing on chain codes and actually allowed us to create those kind of workflows that we wanted with a transaction triggering an event that triggers another transaction that's called by the API. Are those definitions stored anywhere once they are created dynamically? Yes, they start on the ledger. So if I go back here to our interface, I can actually see that there is a asset type list data here, which if I visualize it here, I can see that we have the list of the assets that we have, including the company here. And the company asset can be accessed with a read dynamic asset transaction. That is built into CC Tools. But yeah, they're starting the ledger. Let me see. I think I have a few more questions. Does CC Tools provide any validation while creating dynamic asset types? I'm not sure. No, they are not starting the code repo. No, they're starting on. There's no way for it to be written on the code because the code is actually compiled by the peer. So they're starting on the ledger. OK, so any validation while creating dynamic asset types? I'm not sure what you mean by validation. There is validation based on the tags and stuff like that. But basically any label that is valid string is available. There is validation on the data types that you have. So the primary data types are going to have validation. But you can also, if you're asking about the data types that are used by the dynamic asset, those are validated just as like any other asset in CC Tools that work exactly the same. OK, so yeah, so we've gone through dynamic asset types. If there are any more questions, I can answer them later. And now we have automated tests. So for automated tests, CC Tools implements a few, let's say, types of automated tests. And we are actually reworking some of them right now. But the main ones are the unit type tests. So below here, I'm going to expand this a little bit. You can see that there are three files called txtfs, name of the transaction, underlying tests. These are unit tests for each one of the transactions that we have here in CC Tools. And how can we make unit tests with chain codes here? CC Tools implements a mock, which is basically a mock stub, which is going to work as a mock stub to register states and to get states. So this is what basically we can do with the mock stub. We can use it to create unit tests for any transaction that does not use queries on the lecture. Because queries, if you're using rich queries and stuff like that, you're going to be using CouchDB. And if you're using range queries, it's some whole other things. But this will allow you to test most of the logic that you might have for registering an asset. So this is an example for the create new library. We are defining here an expected response. We marshal that, and we actually create a mockingvoke. So we do a stub.mockingvoke, where they create new library assets with our request bytes. We take the timestamp of this transaction, and we actually put into the expected response, because that's one thing that CC Tools we register in the asset. And then we can use reflect dp equal to see if they are equal or not. And this will actually, if I run this, I can run this. I see it's OK. I can see coverage. I can have a whole package and see all the coverage of this. And this is where we can debug the chain code. So we can use the debug test off go and actually debug this function that uses a mock stub. This will also work for get states. They are different from queries, right? So we set up the state of the blockchain by actually doing some put states before, and then calling our mockingvoke to get the, in this case, get the number of books from a library, which is going to use get state based on the state that was set up by the test. And then we can check if the response is actually the one that we want, just as we might expect. So this is one of the types of tests that we have. We are currently working on probably going to merge this pretty soon. We have Godoc tests. And if you don't know what Godoc is, Godoc is a tool that works with a code to create BDD, behavior driven development, like tests. So you can test this on a network that is actually up and running. So let me see. So yeah, under the tests directory here, we have some features that are implemented as gherkin type of syntax in which we can actually create using almost natural language scenarios for our test. So create a new library. We can say that given there is a running test network, I make a post request to our API on part 8080. This is one of the things that we're going to correct. With this payload, and then the response should be 200, and the response should have this response. And then we can actually run this as one of the automated tests when we either commit to the RAPL or when API is made and anything like that. So this is another type of test that we have. This one is with a network actually up and running. So this will support get queries. And it's going to be just the same because there's a network running. OK, I think we have some questions. So CC2s will be like a modern day hyperledger composer. That's actually a really cool comment because in the beginning of Go Ledger, we actually used Composer. We had a lot of trouble with it at the time. And short after we started using Composer, Composer was actually deprecated. And then that's when we started to figure out how we can do our chain codes better and faster. That's why we created CC2s. So yeah, you might say that, that not being able to use hyperledger composer is what made us start to figure out how to create CC2s. OK, so now we move through pretty much everything that I wanted to do in CC2s demo. And now for those want to go deeper, I can show you a little bit of the implementation of CC2s itself. And I promise you that we are almost done. So bear with me a little bit longer. For the CC2s repo, I can show you here. We have another repo that is actually the package itself. And this is where all the implementations are actually done on CC2s. So if I move here to my actual local repository, we can see that we have some packages that are related to the features that I just showed you. So we have an assets package. We have a transactions package. We have events package. We have a mock package. We have the stub wrapper package. And we have a bunch of tests here. And I'm going to try to show you all of them. More detail. So for assets, we have a lot of things here. And I want to go into the more important stuff. Most importantly, we have the asset type, which is actually the definition of the asset that is used when we are implementing. And here you're going to see that we have the tag, the label, and all of the, we have all of the, all of the, all of the, all of the assets that we have all of the descriptions for each one of those. And, and when this is a, someone asked me about where is the dynamic asset register. When the dynamic asset is registered on the ledger, it is actually sign node as a dynamic asset with this, with this pull property here. And the asset type is going to have a lot of, it's going to have some functions that we can use to, for example, get the keys of the assets, to get the sub assets, if they have references, check if an asset has a property, things like that. But this, this is actually not the most, most useful stuff when we're developing. The most useful stuff when we're developing is right here on the asset.go package. So when we create a new asset with that new asset function that returns us a asset object, this is what it's returning us. So this is returning us an object that we can actually use for actually interacting with its properties and with its, and with the ledger itself. So this is the function new asset. This function actually is going to perform some validations. It's going to generate a key for this asset based on the properties that are keys. It's going to validate the props. So if you have a prop that is not valid, for example, you're using a string when it's supposed to be a number, this is going to get you an error. And it has also some private functions here to inject some metadata into the asset. So you have that at asset key, you have the at asset type at key and a bunch of other stuff relating to what transaction wrote the asset last, what organization called the transaction that wrote this asset last and all that stuff is going to be available in the asset itself. Although it's not shown on the interface, I can show you in a little bit how does that translate. We can check if it's private. We can get the key. We can do a lot of stuff here. And this is for anybody that wants to know the inner workings of CC tools. This should be one of the best resources. This is also documented into a group package. So you can access all of these functions and their comments in the package itself, which is available. There's a link for it that some, I can put it on later. This is the link here, go reference, okay? So if you go to the repo, you can just see the reference for everything that we're talking about here for the code. Okay. We have the same thing for transactions where we have not only the transaction definition, which is the one that we already saw about like tags, colors, labels, descriptions, arguments and all that stuff. But we also have the implementation for the transactions that are built into CC tools. For example, create assets. The create asset into CC tools is implemented just like any other transaction, but this will work for any asset. So we have a special way of receiving these assets. For this transaction, we can receive a list of assets. In this case, the asset's gonna be validated against its format, like having the asset type property and stuff like that. And what it's going to do is actually just use put new for every asset that was received and return all of that as a response. So this is where it's implemented, okay? Including delete asset, including read asset, all that stuff is here. So I think somebody asked me about queries and I haven't touched on it yet. Yeah, we have, there is a search transaction which we receive a query string according to a CouchDB specification. And if it's a private data asset that you want to query, you actually can send the collection. And if the asset has references, you can send a bullion to make it resolvable, to resolve this recursively. And this will actually use a built-in function in CC tools, which is called search. That can be used by any other transaction, by the way. And this will actually use the normal iterator, the stub get query result for this particular file vector string that was sent. One more thing that I wanted to show here besides the transactions is actually the stub wrapper. The stub wrapper is pretty interesting. There is one feature that I didn't mention that it's one feature that's, you can see that on the fabric documentation that when you make a put state, you cannot make a get state and get the state that you've just put in the same transaction, because the state has not been committed to the ledger yet. So what we did, we created the stub wrapper, which wraps the actually the stub interface from Fabric Chincode Go, but also provides a write set and a private write set, which is a map that's gonna relate string to bytes where string is the key, and the byte is gonna be the actual value that's being put. So when this happens, the one interesting thing is that our put state done by the stub wrapper uses the put state that is implemented by Fabric itself, but then it puts the object in the write set of that transaction. So your transaction can actually read the write that you've just made, and that create no consistency issues, because if you write to that key again, the put state's gonna reflect that no issue at all, because the state has not been committed. And so when you get the state, you can actually check if the state is on the write set, and if it's not, it's gonna get the committed state, which is just a proxy for a normal get state, okay? Yeah, okay, so I think we have some questions. Yes, this meeting's being recorded, it's gonna be available later on YouTube if I'm not mistaken. Okay, so we've seen assets package, transactions package stub wrapper, and now we can move to the last one, automated tests. So for automated tests, there are two things that I want to touch on. One is the implementation of the mock stub for the automated tests made on the chain code implementation. This is what it does. The mock stub is gonna implement all the properties of a normal stub and the actual functions that the normal stub would implement. And this will allow you to create, and we have more like mock transaction start, mock transaction end, and this will allow you to test your chain code with unit tests. So that's one. And the other one is actual tests of the chain code here in CC2s. So we have a package of testing that's gonna test everything on CC2s. All the functions on CC2s are tested. And one of the things that I'm gonna talk about in a little bit is about contributing. So if you want to contribute with this, you can see basically how everything is implemented and how is the usage of everything and follow the lead basically. And last but not least. Okay, so we have a question from YouTube. My application is entirely on Java Spring Boot, including both the chain code and the SDK client. Will CC2s be implemented in Java as well in the future? We don't actually have plans for it, but as this is a project, like community project, if it's interesting enough for you, we can collaborate on creating CC2s for Java and making sure they are consistent between versions. But no, from our side right now, there's no plans for it. Okay, so how to get involved? One of the things that I would say is a great start is actually joining Hyperledger Discord. There's a CC2 channel on it, which CC2s was just accepted as a labs project. So we don't have many activities going down. In that Discord, but nonetheless, that's a great way to start and it's a great way to reach out to us. Goledger also has a Discord and that's been going on longer because we have CC2s as an open source project for almost three years now. So there we have a bunch of people that are already using CC2s and that they have doubts, questions and they talk to us there. And of course you can start developing with CC2s. So I suggest you check out the docs. So the docs here, let's see if I can open them real quick. So the docs is a read the docs link in which we have getting started with download and setup environment configuration. We have a tutorial writing your first application where it's going to explain to you everything that's happening with implementation and you have basically information on assets, data types, events, transactions, everything that we talked about here, including testing. So this is going to be a great resource for those that want to start developing. And of course, if you want to contribute with the project itself, there are three repos. Those are Hyperledger Labs CC2s, Hyperledger Labs CC2s demo and Hyperledger Labs CC2s doc. And you can contribute with your PRs or your feature requests, just creating new issues or bug reports and all that's gonna make us really, really happy and to get more people involved. And I would say that's it. I think we might have some more questions. So let me see if I can answer them. Okay, let me just drink some water. Instead of using normal chain code running environment, you wanted to run in fabric private chain code in Go. You would only need to change the stub wrapper. I mean, that is the code that actually calls the fabric contract API, right? I'm not sure, I'm actually not sure because I'm not that familiar with the fabric private chain code structure. But if you can make a chain code, just a standard chain code work, CC2s should work as well because all of the structure of CC2s is based on just normal chain codes. All that I showed that is a library can be, in the past, actually it was all implemented in the single chain code structure. So everything is just compatible with just normal chain code development. The only thing that we did is move this to a separate library and start to expand it. But everything is just a standard chain code with a bunch of features that are implemented for the good of the developer. Do you have any more questions? Okay, if not, I think that's it. If you have any more questions, feel free to reach us at the CC2s.com on this channel on Discord or the Golagzhar channel on Discord as well. If you want, connect with me on LinkedIn and feel free to reach out. We expect to get more people involved in using and contributing to CC2s. Yeah, thank you everybody. Thank you for your patience and I hope this was informative at least. Yeah, this was great. Thanks, Sam. Thank you everyone. Yeah, thank you.