 All right, so welcome to this Hyperledge Sweden Meetup. My name is Roland and I'm your guest for today's session. And in today's session, we will have, I think a really cool session because we will see how we can create the chain code with no cheers. And this session today is part of, I think a longer experiment. So I try to compare the no cheers chain code with the gold chain code and try to understand what is better. So in case of performance, in case of development and so on. So and today's session, we will start with a simple chain code use case. And first we will look a little bit at the use case. And then I have developed a small guideline how you can get started with the no cheers development. So because today we will see a little bit from the deaf Docker deaf network. So for the peer deaf modes, we have used in the last sessions. And then we will develop this chain code and we will see how we can pin from scratch this chain code and test it during the development process. And then when we have finished this, we will install this chain code in the test network. And that's very easy because the new network script it gives us a single command line. And with this single command line, we can create the network and install this chain code as well. And then we have a situation where we have two organizations with two peers and then we can test this chain code. And finally, I have prepared a small passion script where we can test how fast my test machine is and how many transactions per second we can create with this chain code. Next in the upcoming sessions, we will compare this with the same use case in the goal length, for example. And then we can compare is this faster, is this slower and also in terms of peers. So I think that's an important question is a network slower when you have more than two peers, three peers, 10 peers, 20 peers, for example, and which impact has proper endorsement policy. And yeah, so that's a little bit of an ongoing work from my side and small parts of that I would like to show you with you. And I have created a small example. I call this commission statement because it does a little bit of calculation that calculate a fee for a recommendation and the fee for an revenue. And we have two organizations. We have a producer and we have a seller. So we can also test this with other JavaScript examples or Node.js examples for example, for how you can connect to the network and how we can use a little bit on permissions. So something the seller could see and what which information the producer can get from this example. And yeah, here the links as every time. And I have also updated the GitHub repository with all the source codes from this session and so you should be able to follow this session today. But the session builds a little bit on last sessions and the first session. So yeah, here are two important links. Here we have a link to the fabric chain code repo. So this is a good starting point to learn a little bit and read a little bit about the Node.js implementation of the chain code. So short overview about my use case. So this is a simple situation. So we have two organization. This is a fit to the test network example. So we can imagine organization one is the producer and organization two is here, the seller. And we say when the producer gets a recommendation from the seller, then the seller should earn 1% of the revenue and when the producer have a closed sale from this revenue, then the seller will get 10%. So that's only for testing. But that's also a good example for later when we say that when it comes to discussion what is the smart contract and what is the chain code. So and I would like to explain this that in the permissioned situation, in the permissioned blockchain network, then we have the companies have to come to an agreement. So the companies from organization one and organization two, they must come to an agreement that they say, okay, I accept your 1% or I accept your 10% for a closed sale. So it is a smart contract. And this smart contract must be done by the companies, by the manager, by the managers and CEOs from these two companies. And the chain code is the programmer interpretation of this written smart contract between the organizations. And what happened when we have to change this parameter here when we say, okay, now I gave you so much recommendations and yeah, I want 2% or 3%. And then we can test with this use case the upgrade process. So how we can upgrade the chain code in a running network. And this is also a good example, which we can do later and see how we can upgrade this chain code. And then today we will implement this in with Node.js and later we will see it also the same in the Golang and then we compare it. We compare it here in the container image size. This is one key parameter. For example, so that we can see how large is this Node.js container when it's running and how large is a Golang container. Is it larger? Is it smaller? For example. And then we will test a little bit to the performance in the test network with the default configuration with the default block size with the default endorsement policy. And this is also a good way to see in my test case with I think it's one CPU and two gigabit RAM or so I don't know, I have to look. But in reality I reach to nine transactions per second in this situation. So and with this we can analyze the system and then we can see how many, how strong must our virtual machine must be to come to the certain transactions which we want. And we can test this, we can extend this analysis also with some other components like the endorsement policy, how many endorseers you will have in your network. So is there an impact if you have 10 endorseers in this network or not? So makes it sense to have more endorseers or not? So yeah, this is some, this are some facts which we can analyze here in this scenario. And the asset here has four, five values. So and this is a little bit constructed so that we can see some special things. So we can see the transaction ID so we can get the transaction ID from the chain code then we can store a string then here we store a date. So that's an interesting part to store a timestamp or a date in the asset itself in the state of the asset because this is maybe a problem or a mistake which someone could do because with JavaScript you can create a new date, a new timestamp very easily with the new date command. But if you do this in the chain code and then you will have a problem because in the execute the face then you will, because the decline send the chain code to endorser one and then this endorser creates the asset or this object and then a new date is created. And if this is done also with the second endorser then another date is created and because also when there are only milliseconds between this request then we will not have the same asset and then your transaction will fail. So that's an important part that when we use dates here then we have to give the correct date to the chain code here. Then we have here two numbers here. And then we will implement two simple methods. We will implement the methods to store these commission statement asset and then we will query this. And for this I will use a so-called composite key and this is a way we use only the level to be database and the level to be database has only a key to store. And then we can normally we can only query the key. By key range or this compost key. But when we do this in a certain way when we have a situation where we say, okay we want all very news by year by the year 2020 then we can query this in this way or we can query this when we say we want all very news for 2020 and the month, March for example then we can do it as well. But we can extend this also for the day but I haven't this here. And when we add the transaction ID then we will get the single revenue. So this is an example to understand how we can use a composite key in a special configuration like this use case. So this is not useful for every situation. So this is useful because I say I don't use couch to be here I won't only use the level to be because this could also be have an impact on your performance and on your security and so on. So and for this situation I want to query all revenues per year, per month or the particular revenue transaction. So that's the use case. And a short overview what we are going to do now. So for this example we need here in the last box we have this Docker environment for the local testing. So I use the setup from the session in the end of January, so and then we use we try to install this in the test network. And this is the material from the beginning of the session. So on the beginning of October last year. So this is built on this part. And then in the middle here we will use the favorite contract API in the Node.js implementation to build this particular chain code. And we will try to run this here during the development. So that we see, okay, when we do this step then we can check if this is running or not. And but we can in this death mode we cannot test the problem what we have seen but I have mentioned earlier with the date. So because in this peer death mode scenario we have only one peer and then we will not have a problem with the date. So that's key is to keep in mind. And yeah, so the final test in the test network but this test could be done very easily because this in the favorite 2.2 the network script can make this with a single command line, the installation and the whole approved process and so on. So it's very easy to do this. And with in this, and then we can test this chain code. Yeah, so and this is our lab what we are going to do today. Okay, so now let's start. So, okay, here I have used the Visual Studio Code and here I have the fair examples. And in this fair examples I have created this Docker death network and this is the same setup which we have used in this session. And here we would like to create a new folder and we call it CS1 and we need the index.js file. And this is here our backing directory. But I will work a little bit also here in the terminal. Roland, can you make the font just a little bigger? It's kind of hard to see. Yes. Thank you. So, yeah, that's a bit better. Yeah, so, so fair examples and here the death network. And yeah, so and in this death network I've here my chain code folder and in this chain code folder we have here the Node.js folder and this new CS1 folder. So, and we need this index.js to die. So, to get started with this so we can call, we need an npm project. We call the npm init command. So we can say yes to this. And then we have here, you should have here a backup JSON file and in this backup JSON file we will have, we need two dependencies and important is here the script object because here we have to put our start command that the Node.js chain code will start later when we deploy it. So, but we need first this and it's important that the index file, the start file is called index.js file. And then we need two packages. We need, I'll do this here. So, we need, we can install this with npm install. We need the fabric contract API and the fabric shim package. So, these two packages we need and we can install this with the npm install command and we save this to the package file, package JSON file. So now we have this node models folder and in our package JSON file we have this two new dependencies here. And then we need this, what's this? And then we need a structure, a small structure. So we create and folder maybe lib and we have to export two elements here for the chain code. So, and here we have our chain code. So, and then the slip folder we create another file. So maybe CS01.js and this file will contain our chain code logic. And then we have to export a contract, this contracts property within a way of, we can have different contracts. So, and this is the contract here. And then we have to export also an object here and property here with the contract object here, which we have included here. So, and this is what we need here in the index.js file. And in the lib file, in the lib folder, this file. Okay. And here we will create our chain code. And the first thing what we need, we have to include this fabric contract API. And then we have to create a class which extends the contract. So, and in this contract we need the constructor and we can call here a name or not. So that's not important. But I think it's useful for logging. So we can here, we can set here a name which identifies this contract. And then this constructor we can, I have here the transaction ID because I need it on several times. And then we can make here, oops. And then we will have two functions here. And this function is a function called before transaction and after transaction. So we don't have to use this, but when we use this, then we can use this for certain things or for logging, for example. So when we need the transaction ID from this transaction. And then we can say, okay, before the transaction happened, before we're in the main process of the transaction will come. Then we can grab this transaction ID and we can start us in this property here, in this. And this before transaction has here one variable. So this CTX is called the context and this context has another object and this is this stop contract, this stop object. And I think most methods are way-label over this stop object. And one of them is this get transaction ID. And then we will get the unique transaction ID from this particular transaction here. And then we can store it here in this property. And then we can do a logging, for example. And the same is for after transaction. And after the section is also called when the transaction is finished. And so, and with this, yeah, so. And when we have this in place, then we can try, we have to export this and then we can try if our test network will work. We can start our test network. So, and then, so in this definite back here. We, the first thing to start the definite work is that we have to export the fabric config path. And this is the path to the sample configuration. And here we have the sample configuration. This is what we need. And then we have to create first in your Genesis block for this. This Genesis block is here in the artifacts folder. You can see it here. And then we need the channel create transaction. Same. Also in the artifacts folder on the up here for the channel one transaction. And then we have here the Docker composition from the last session here. And the important part here is that we start the node with this option peer chain code dev through. And this gives us the possibility to start the chain code by hand and start and stop, start and stop the chain code. So, and in this way, we can reload the modified chain code very soon. So, and then we can say Docker compose up. So, okay, this works. And then the second terminal, we have to create and join the channel. And this is also done with the standard commands here. And then we can join the channel. And then we can install the chain code. And first we have to package the chain code. And here the important part is that we use here this option length with node. And then we have a label. The label is the same like in the go version. And the path here is linked to this CS01. And then we should have here and tie the set package with the pack with this tar archive and with the chain code inside. And then we have to install it with P install. If this is done, we need these identifiers here. We can query this also when we also command be a live cycle chain code query installed. Again, it's also this identity package identifier here. And yeah, so I export this and store it in an environment variable so that I can use it a little easier. And then we can start this. And this is the command to start and stop the chain. So to start the chain code. So we have to stop, we can stop the chain code with control C or we can kill this process. But the important part here is that we use here the node models pink fabric chain code node command here. And this is the reason why we have to install this fabric shim package in the package JSON. So when we install the fabric shim package here, then we will get this program here. And that's the program we need to stop the chain code. No, sorry, follow the directory. Okay, so we have to switch into the chain code program. And now we have a running chain code here. But the next step is that we have to approve it. So to start this, it's a little bit, yeah, there's a small effort to do this. But if it's running, then we only have to start and stop it. So we need the backup ready again and then we have to approve this chain code. So, yeah, there's nothing special in this command. That's the same command which we have used in the past. Then we can check also the readiness of this chain code. Then you'll see here, or in this sample organization one has approved this and then we can come up with this chain code. And you see we have a valid transaction here. And yeah, I think now we are ready to test our chain code. So, and to test our chain code, maybe I'm not really ready for this now. So I think we should implement the store method first. I will copy this. And here we have this store method. That's very easy to understand. So the important part here is we have this context. So this CTX variable here and with this CTX variable, we have access to this stop implementation. And then here we have the possibility to create this composite key and also to store the new state with the boot state command here. And so the first part here is simple. So we have the commission fee, we have our revenue and we import here our timestamp. This timestamp is a simple JavaScript date. And then we have here a small case where we can say, okay, when we have this record type, then we calculate here 1% of the revenue and then we have 10% here. Otherwise we have 10% and then we have a commission of 10% from this revenue here. Then we can create here a short JavaScript object as a model. So we say we store the revenue, we store this commission, the timestamp, the type and the transaction ID. And then we say, we want a new key and we have the possibility to create a so-called composite key. And that means that the key is not a single number, a single string or something like that. So we can have a combination and we can define a combination like we want with this tilde, the limiter here. So we say the first is the year, month and the transaction ID. So the call is here as index name. So here I don't, the only thing I do here is, so here I have this error in place here, that's good. Yeah, so and then here we create the string and then we can create this composite key with the index name here. So with the string here, this is the key. So, and here we have the values of these keys. The year is a string, the month is a string and the transaction ID, this is a string. And then this method creates us these new key. And then we can use this new key as a key and we store the model here, the created model as a buffer object and that's it. So, and with this, we can create a new key and we can query later this key when we say, when we give only the year, then we will have all transaction from this year for this month and then we can say, okay, we want this particular transaction, then we have to use the whole combination here also with the transaction ID here. And then we can save this state to the lecture here and that's it, I think. And then we can compose here the return value. So I say, okay, I want to know the year, the key. So I will give here the unique key that we can use it later to query and to see what is stored into the lecture. But this is also depends on your example for it, if you want. Yeah, and we wrap this in a trial block. So then if there is an error, then we can catch this error and throw here a message, how we want. And yeah, that's it. And okay, then let me put also the query. Now let us test it. So, okay, now we have now changed the chain code. So we have modified this file and then we have, and when we try now to test this, then we can stop this container here in this chain code and we have to start it again. And now we have loaded this new chain code and we don't have to repeat to improve the install step and to approve and commit step here. We can only start and stop this container, this chain code in this terminal here. When we stop it here with control C and then we started again with the command with the favorite chain code mode start command here. And then let us try invoke this chain code here and we do this with the command line, be a chain code invoke. So the other address, the channel, the chain code name. So in the C option here has our arguments and we say, okay, we call the method store CS, then we have a value of 100 and here we will have a time stamp. So that's the fixed string here. And then we have this type and is in it is only because it's the first transaction here in the network and it works. So we have your chain code invoke successfully and we say here we can do a logging. And you see here the before transaction statement and you see here the after transaction statement. And now we can try to change this. So when you try to invoke this now, okay, we don't need it. Then you see the log command is the same like before. And to change this, we have to stop it and we can start it again. And when we try to invoke this, then you see here you have a new chain code version. And in this way, you can develop your chain code and you can test it. And you don't have to do the whole install and approve process. And I think that's an easy way to see if your chain code here is working, especially for a small in a small test. And now let us implement the query method. So this is this get chain, get CS per year and month. We have also here the CTX too. And here we use, I use another example. So in the first version here, we say, okay, we have a revenue, we have the revenue timestamp and we have the CS type. And then we can use this variable here in our function. But when we have here a lot of parameters or we don't want this, we can have this also with this get arcs method here. And this get arcs method gives you exactly these parameters here, all parameters, which you have to get to them during the call. So when we try to query this, we will use something like that. And you see you have here the function. And then we will use here only one parameter, for example. And we try to separate this here with this tilde, but you can use every delimiter if you want. So it's only in my case here. And with this arcs command, we will get this information. And here we will receive two, we will here, here we will receive an array with two fields. And then the first field, we will have the function name. And then the second field, we're starting with the second field, we have here the these parameters here. But we have only one parameter here. So, and then we can grab this parameter and split this with this delimiter. And then we will have here another array, which we can use for each loop, for example, to push the elements to a keys array. Yeah. And then we will have this keys array here. And this keys array is used here in this method, get state by PartitialComposite key, which is also delivered through this CTX step object here. And yeah. And the only thing what we have to do here is to query this, we have to say, okay, how is our key compost? So with this year method and transactionality. And then we have to deliver here an array with elements in this, in the correct order. So, but the good thing is when we only deliver the year, then we will receive all transactions from this year. When we deliver the year and the month, then we will receive all transactions from January, February, and so on. And when we deliver also the final transaction ID, then we will receive the exact transaction. But this will only work in this order. So you cannot say, I want only the, I want all transactions from every year in the month of October, for example. So we have to use the, we can say prefix, I think it's like this one. So you cannot say, give me only the, give me the transaction regarding this transaction ID. If you want a function like this, then you have to create here a new function, which does this, yeah. And this works only in this order. So you can leave, you can leave transaction ID, you can leave month, yeah. And yeah. And this will receive an iterator function. And then we can loop through this iterator function with this, with a while loop. So this is, this snippet is also from the official documentation. So for me, it's a little bit, yeah, strange to use here while loop. But I copied this from the documentation. So this is also called the old way. And then the documentation, you will find a new way. But in my case, and in the time I could spend to do this example, it doesn't work. So I switched back to this version to finish this example here. But in the documentation, you will find another way with a for await loop. And, but I think this hasn't worked here, my example. But Roland, you have a couple of questions in the chat, just FYI. Oh, let us look. So it's not, I have to say sorry because I have to look. So function star C returns key. Where does it get stored? Can we access it? Yeah, it's stored in my, in my lecture, in my demo lecture here. And you can access this with query here, with the chain code query, your chain code query function. And we have to implement this function. And that's what we are talking now. So we have to implement a function to query this information from the command line. And when we don't want the command line, then we have to use the node shares SDK, for example, to connect to the network and make client application and query this, this lecture. But this is another step. So in this example, we see, we use the only the command line option here, but there is no, there is from the chain code side, there is no difference between this version here to query the chain code. And if you use the node shares SDK, that's only here how you pass this parameters here and how you query this. And stored, is it here in this network here? So we have a test network here. This is the DEF network. In my slides, you find the date for, in the GitHub paper, you find the documentation from this. And here we have a Docker composition. So in this test network here, we only have a single order. This is a solo order, I think, or not, I don't know. And we have only a single PR. And on this PR, the data is stored. And the data is stored here in this lecture data. And that's where your lecture lived. And here you see, you can see it here. Look at here, can look here also. So I, and this is the storage from the PR. And in this folder, you will have, so all the lecture data, yeah. So, and so on. So in this demo network, you have a real hyperlature fabric network in the, with a level to be implementation and the single order. And here is the data stored. So you have persistent data here. So you can stop this and you can start it again, this network, and then you can use the lecture again. So that's not the mock data, something like that. So this is a mini, mini, a fabric network. And this is all, and this node starts here with the PR chain code def mode. So this is, I think this is made for this situation. And you find this documentation for this here in the, and you see here in this links. So, but be careful. This is not explained in this release 2.2. So we have to switch to release 2.3. And there you have, starting start, node, tutorials. So here, you have one in chain code in development mode. And this scenario is here descriptive. So, but to be honest, the description here is not what I have used. So in this description here, you use the native version of a peer and then order. And this is a different. So we are here in a session, peer def mode comparison. You have here one, this network in two different modes. So I call this the binary mode. And this is the setup, which is also the scripted. But you need one terminal more. You need four terminals to run this, but you don't have to use Docker for this. So you can use a favorite without Docker because in since the 2.2 version, I think we can run a peer and the order also in a native version. And, but you can also a Docker version of that. And this is the network I have used today. And this is the explanation. So, and when you follow this guide, then you can create this and start the network. So you see here, this is our starting example. And this is the example for the go chain code here and not for the node shares chain code. But the steps are basically the same. But what you have here is you have a running favorite network. So I hope this makes this a little bit clearer. And you can follow here on my GitHub repository, all the sessions. And that's why I have put here some dates. Let me say here session from 29 January. Then this is the reference to this meetup here. And here you can find the guide for this. And here is also a guide when you start at the beginning. And then you have to install favorite at all. And we have, I have set up here a guide from the beginning. So from the preparation and I use here and digital ocean grow blade 1 CPU. And that's also the same what I have used here for this scenario. And you will see this not so fast. We can have only nine transactions per second with the setup, but it's enough to test this. And yeah. And here the test network installation is also the scripted on the beginning of October last year. So this is this session. So this is the first session here. Okay. Yeah. What is the mode of storing certification? Is positive demonstrate storing of cells or using software? No, today not because this is an example we have to provide to prepare. And then I can show it maybe in a further in the upcoming session that we can show how we can use a soft HSM. Okay. So another question to this. And okay. So, okay. Let's go back to this. Okay. So now we have implemented this get data function. And here we can query the last state of this, of this of this transfer of this asset. So it's important to understand a use here several times the term transaction. So, but we don't store a transaction here. In general, we store an asset. And if there is an asset, then an asset has a state. And then when we update this asset, then we change the state of the asset and the transaction is only the container around this. So, but we don't have transactions here while we store transactions. It's better to know that we store assets. And we have an asset could be any object. So a name, a football team, whatever. And then we change the asset, the state of this asset. And when we modify one attribute here, so when we change to revenue, then we change the asset. And we have a second version of this asset. And this is triggered to a transaction. And this transaction has a transaction ID. And yeah, but this is also an important part. So when we are talking about the key, so what should be the key? And the key could be the car, for example, like in the top car example, a marble name, like in a marble example, but the key could also be a transaction ID. So you can use this here. You can say that's an auto increment key. So like you use it in the in a MySQL database, for example. And you get this key here in the before transaction phase. And then you can use it here as a key. And it will also work. And then you have an auto incremented unique key. And this key is unique in this channel. So yeah, and that's also important to know. So, but this is a long number. And it's not easy to query this key. So let's look here. So we see this is the transaction ID here. And you see that's a long number. So maybe it's not so comfortable to query this, but it depends on your use case. In our scenario here, we don't have any update. So think of a logging. So when you try to log some results or some other informations, then, and you have only one state, then you can use this transaction ID as a unique identifier for your key. And then it's difficult to query, but when you make a here and in combination or a composite key, then you can think of a situation like this. And if the situation makes sense in your example, then it's good to go. Okay, so now let's try if query works. So the rest here is, I think this is important to know is that this gate state per partitial composite key or gate state by range will give you always an iterator here. And we can walk through this iterator with here in this next, with this next method. And when we receive an object which has the done property here, then we can close this iterator. And that's why I have here this console log elements. And then we will see that if we are on the last asset here, then we will see this done here. And then we can close this iterator and return all the assets which we have pushed here to this all assets, all results area. Okay, so if this is ready, then we can stop our chain code and start it again. And then, for example, and now let's test this. So, okay, let's test this. So, okay, so, and then we have an error. Why we have an error? Because we get this, yes. The metric minus one, and you see, we receive three transactions or three assets. So in our scenario, three revenues with 100. And all of this is in February here, let's see. And then we try to modify this and we call this again. And you see, we have here this revenue from 2000. And then we try to use this tilde with two. And then you will see here the March. Why March? March has here three and we have here two. So that's why the date starts with zero and not with the month one. January is zero and not one, so. But this is something what you can improve in the chain code that this number here is the same as the calendar months. But I think everybody who is using JavaScript and Node.js knows this. But the important part is here that we say, okay, now we have only the three. And that's a very cool thing, I think. Because now we can query with the composite key here, we can query our blockchain with leveled B. And in leveled B, we only can have a unique key as an identifier. And that's important to see here. So we have only key and value. And the key must be unique. The key is unique. So, yeah, and the key would be T1, T2, for example. And this will deliver only a single result, not a multiple result. Because you can only have a key, a single key, a unique key. And with this combination here, then we can make a key which delivers multiple results. And when we say, okay, we want this one here, and then you have the single key. And this is possible through this composite key. And yeah, so, and this depends really on your use case what you would like to query here. And then you can compose an index, yeah, a key like your use case. Yeah, and here you'll see some login here. And here you'll see the, where is the done? And here you'll see the login for that. Inside value store, okay. I want to see the done, console, console lock. Now we do this. Let's start it again. And then this, and you see here the true. And that's the way how you can use a composite key to query level to be database and to receive more than one results for a key. Okay, so this is, so I need to pop up. Okay, it's, we have too much time for this. Okay, so now our chain code is ready. So let us skip this. So there's some logging in. Okay, let us test it again. And then, and let's check it. And you see here our equal, no, we need three. Okay, so, and you have here our last example. Okay, so now I think that is working. And now we would like to install this as a final step here in the test network to test if this is really working in the real environment. And for that, we stop our test network here. So, and now it's important that you are sure that no corrupt container is running, no volume is running, is available more. So let us check it Docker PS. Then we can see there is no running container. Docker PS option A, there is no excited or corrupt or whatever container. And we should also check the volume, Docker volume LS shows here we have here some volumes. Okay, then we can burn it. And now we have a clean network. We can also know Docker network LS. So, okay, that's also the default configuration for that. And now we'll switch to the test network. The test network is part of the fabric samples. And you can say that's a reference implementation. Okay, so, and now we would like to install this chain code here in this official test network. And this test network has two organizations. Organization one and two has a build, has a raft order, has a TLSN, is TLSN enabled and has all the defaults configurations which fabric camps that default. And the first thing is that we set our config, fabric config path. So because we have to change it. So in the, for the test network, the config path is one in the parent directory. So if you don't know, it's looking. So, and the important part here is the core YAML file. So, and the config TX YAML file. So these both, and of course the order YAML file. So these three files are the important configuration files for your fabric production. And fabric needs to know where this is, where the files live. And this is done with this fabric config path variable here. Okay, and then I have, as I have mentioned, we can install and start and create the network with a single command. That's pretty cool. But I will show it a little before. So, so, and we can, in fact, there are two commands. The first is the network create channel command. So we say, okay, we create a channel with the name channel one. And we use the create channel option here. And this is the first step. And then all the crypto material, the organization feed TLS, and also the connection profiles for the Node.js client application. All this will generate that from this command here. And if this is ready, then we can deploy the chain code. So, and that's new here, I think. So, because when you deploy a Go chain code, you don't have to use so much options here. And one important part here is that, okay, we say we deploy a chain, we deploy a chain code. Then the channel where we have to deploy a chain code. And then the name. So this is the chain code name. And then the language. So, and you see, we use JavaScript. And when we look back to the package command, when we do it by hand, we use the lang node. So, I don't know why this is so, but when you use here node for Node.js, it will not work. So you have to use here JavaScript and you have to use here node for Node.js. And then here we have the chain code version. Okay, that's the chain code version. That's a number. So you can say always name number one. And then we have this sequence number. And this sequence number is important because every change on this chain code, if you have an upgrade to this chain code, then you have to increase this sequence number to two, three, four and so on. But the chain code version could also be the version one, version 1.1, 1.2, 1.3, whatever. And could also be the same here, but the sequence number is the number which you have to increase when you do a chain code upgrade. And that's why I've said in the presentation here, so what happened if we try to change this when you say 2% or 20% whatever, then we have to upgrade the chain code and the chain code sequence number here is the key for that. And yeah, and then the path to the chain code. And that's it. So if this is all in place, then we can wrap this to a single command with the double end. And let us try this and see if all this will work. Oops, no. So just take some minutes. Yeah, but I think that's also a very fast way to test your chain code in there under a real situation. So here now we have the second command, the chain code install command and the chain code deploy command. And you see here also the improved process is now here. So chain code install is installed on both peers. So on peer one on our organization, one peer zero organization one and peer zero organization two. And you see here the improved process, every steps we have to do by hand could be done in a single line here. And you see here the sequence number here, sequence one, so important to recognize this. Okay, so then let us look. No, we have, ah, we have an error. Okay, one important step we have missed. I have mentioned this step, but I have forgotten this step. So in the package JSON file, in our development scenario, we have started the chain code by hand. But when we use this in the real environment, then we need a way, so a fabric need a way to start this chain code. And this is done with the start option here. And I have forgotten to set the start option here. So we don't need a test here, we could remove it. So, and this is also an important step here. So in the chain code folder here, at the beginning we have called the npm init command and with this npm init command, we have received this package JSON file with this configuration here. And when we do the deploy chain code command, then a new container is built and in this container, all these fabric dependencies will be installed. And also the start command is important here. And, but that's not a problem because so, but now it's important to know, okay, so we have a running network here, but when we look at Docker PS option A, then we see here also the started chain code container, but they have failed. And now it's important to switch back to a clear setup. So the first step what we do here is we are not Docker compose now, so we can use the network script, network shell down and then we stop the network. And this network script deletes all the chain code container, the volumes and so on. And then we should have Docker PS empty, this is also empty and Docker volume is also empty. So now we have a clear state and we can start from the beginning. Okay, now let us try again and the command is the same. And yeah, so this could be a little bit nerfing, but yeah, with this second version of fabric, I think in this new network script, it's very easy to make your test network to create your net test network and also to install your own develop chain code of a very easy way, so. And okay, just take some time and then we can say here, we'll cross this, then you will see, and you see here PS0 of an organization one and PS0 of an organization two is running and also the other is running. And then we should see the two chain code containers from the Node.js site. So we receive two chain code containers because we have two, you see here, now it should work. So all right, and you see here, this left here, zero arc two, this is the Node.js chain code container from organization from PS0, organization two, and this left here, zero arc one chain code container is you see here the chain code name CS01 chain code. And now you see this is running here. And now you have installed your test network with your own Node.js chain code. I think that's pretty cool. And now we can test it. So the next step is that we can equate. So, and then we have to do some final steps. Yeah, so all the containers here are running in the background. So maybe it's a good idea to see the locks. This could be done also with a single command. We can use the Docker compose command here. And we have to say, we have to set the position from the Docker compose YAML file here. So, and then the test network in the test network, there's a folder it's called Docker and there we have different YAML files and the default YAML file for the test network is this one. So, and then we can say, okay, we want the locks. Then we see the locks. And then we use this F option. Then we have, when we call this without this, then we receive all the locks and the process ends. So all the locks for this moment. But with the F option here, then we have, this is called a follow up. And then we will have a continuity. So here the terminal, the program is not blocked and then where it's blocked. And then when we see some debug messages or log messages, it will be printed here to the terminal here. And then, but we can skip this also with control C, but in the background, the blockchain, the fabric network is still running. So, and then, okay, to communicate now with the test network, we need some environment variables. And the test network came also with this, has also this preparatory task. And this script, what we need is this environment var script here. And this, you can find also in this folder, in this test network folder under scripts. And we have to call this file. So, no. This is in the test network. And then we have the possibility to call a function. And this function is also useful. So it's called setGlobals. And with setGlobals one, we set all needed environment functions, which we need to communicate from the terminal as an admin user from the organization one. And when we change this to setGlobals two, then we have all environment variables in place to act as an admin user from organization two. And that's also a very cool feature. So now we are using organization one, but you can check this when you use the ENF command, then you set grab core. And you see here, all these environment variables. So we need the local membership service provider ID. You need the peer address and the part. You need here the TLS certificate certificate here. And also the membership config path brother admin user has its membership service provider credentials and public and private keys. And here, because the test network is per default, TLS enabled. So that's the option for it. And when we switch back to organization two, then you can see here, you have organization two in place. You have a different part here. And you have also here the correct path to the admin of the organization two. And it's also very useful to do this here. Okay, so now we are using organization one. And yeah, and then I have prepared the small script to test this, but let us do it by hand for the first time to copy this, it's a long command here. I will do it here. So, okay. Now, so, okay. This is the first invoke command here. Be a chain code invoke. And you see it's the same like in a test in a development network, but it's longer. And the reason why this is longer is because we have here the TLS enabled. So we have here the TLS path to the time file. Then we have the channel here. That's the same, we have a chain code name. Okay. But here, that's important. We have a peer address from the local host and the TLS rule certificate from this host. And we have here another peer address. And then we have here the C option with the R one. And that's this also there. So this order TLS host name override. This is all configuration stuff for the TLS to be TLS enabled. But important to know is that in our, in the test network, so the peer chain code invoke command here, this is declined. So the terminal is declined. The environment variables say, okay, I'm declined. And this peer chain code invoke, use this environment variables to do the invoke. And this is not a client call. And the default installation has an endorsement policy. And the endorsement policy is per default, the maturity. And that means that the maturity of all organizations have to approve, have to check if this transaction is correct. And with two organizations and the maturity, that means that we need both, we need at least one endorsement peer from organization one to have a valid transaction. And we need one endorsement peer from organization two. And these are the address. And that's the reason why we have to set up here two peer addresses. And that means that the client here, this is client command here. And this represents the client here, that this client sends the invoke, the execution from this chain code here to this both endorsement peers. And when this both endorsement peers gave the same answer, the correct answer, and then the transaction will be delivered to the order and so on. And that's a little bit different here. When you compare it to the def mode scenario, which we have used earlier. And that's the reason why this command is here longer. When you do this with the Node.js SDK with the client, you don't have to take care on this peer addresses and so on, because that's the job from the Node.js SDK. So when you have in place the Node.js SDK as a client application, as a Node.js client application, then it's very easy to query the data and you can focus on the creation of the client application on your SAPI and so on. So you don't have to care on all this certificates and all this peer addresses. Because the Node.js SDK checks what is the endorsement policy and knows through the gossip protocol that we need, oh, we need this local host, we need this peer, we need this peer, or we need another peer and so on. And that's the advantage from the Node.js SDK. Okay, so now let us query this. So let us try this. So, okay, store down, this is the value. This is the, we have six, so, and then we have record, so, okay. Let's try this and see what happens. Yeah, it works successfully. And you see here, okay, we have a key and here's the key. And then we can try to track the query. So, trend one, but, and here you see another difference. Okay, so let's meet this and we don't do this. And you see the peer chain code query command is much smaller, because invoke command is sent to the other one, yeah. And you need the, and the fabric needs a improvement from the majority of all endorsement is from all organizations. But the chain code query command, yeah, here is only sent to the local peer. And to the peer from the organization one, from the environment variable. And that's the reason why the query is, the query is doing here is much smaller. Okay, so now then try this. And you see we have an error here. Okay, we have the wrong name. Okay, I have to fix this in the documentation. Of course, I will do this. We need this name. Okay, this works. And you see the same. Okay, and now let's make a small stress test. And I have here created a script here. This is script. And here, this is a simple page script where I tried to invoke the chain code in, we say in February, yeah, or in March, so. And we say, okay, I read 1,000 transactions. I stored the start time and the store the end time here. And then I calculate the difference. And then I do a small med that they said, okay, I would like to calculate your transaction per seconds. And I calculate here the maximum number of transactions divided to the elapsed time in seconds. And then we can see how performant is this. And here you can, here I have a random revenue between 1,000 and 10,000. And then this is here. So this is also maybe a little bit tricky. So if you are not so super familiar with Pesh scripts, then it's a little bit difficult to set and Pesh variable under single dots and double dots here. So under double dots, it's no problem. So then you have this situation. You have double dots here and you can use this Pesh variable here as like a string, for example. But this will not work when you have here single quotes. And in this scenario here, we have to use the single quotes because we have to, this is a JSON string here. This is a JSON string. And for the JSON string, we need the double quotes here. Yeah, that's a valid JSON string in the sense of fabric here. And that's the reason why we have here, we have to use your single quotes. And then when we use here this Pesh variable, then we have to close this here, the single quotes here and here. And then we have to open here the single quotes. So, but that's only as I'm sure most of you know this and but for me, it wasn't really clear why this is so must be so complicated, but now I have figured out. Okay, so and that's it. So when we try to start this, so make 10 transactions now very fast to see if this will work. Okay, so now let us see an H-stop for example, so that they can see a little bit about the performance from the system. And we see here, we have a single core machine and we have two gigabyte round here. And so the test network. So we can see docker ps size, I think. Yeah, so and you see here one, you see, okay, the checkup container they use here and virtual amount of space from 300 megabytes here. And you see here, you can, I don't know if this much or not. So, and that's part of this exercise here to understand is this much in comparison with Golan, for example. So what is the number here and what is the number here? And okay, so to start the script, the only thing we have to do is, yeah, stop the script and you see we are done. We have here 10 invokes, it took 1.13 seconds. So it leads to eight transaction per seconds in this configuration. When we say, okay, we're like 500 here to have a little bit more. And you see here, now we have reached 100% CPU, so, yeah. But we have enough memory. So the memory is not increasing here, okay. But we are limited with the CPU. And I don't know if this is a proper way to test it. So, but I think it gives me an impression how the system performs. And yeah, so, in the next couple of sessions we will improve this a little bit. And once I'm ready with the Golan code, then we can compare this with the Node.js version and then we will see what is the difference. And then we can play a little bit. So we can play with the endorsement policies when we have an or and then and so on when we have two or three more endorsers, how these effects the system. And of course we can use also country to be in this. So, and then we can see is the system a little bit faster in the invoked process or slower. So we can learn more about the system, how the system works and how the performance is, how you can see the performance and which configuration you really need at the end of the day for a real scenario. Okay, so I think I'm an answer. Oh, and I know seven persons online. So thanks for participating until the end. Someone raise the hand. Yeah, this is Kali's one. Yeah, thank you so much for this wonderful session. Like this is a session like, you know, very useful. Thank you. And one more thing like in the Linux foundation recently they recalled support for Java language. They're only supporting for Node.js. Is there any reason for that? I don't know. So, I mean, I think that's a problem or that's a question because that's, I think that's Fabric is plug and play. So they call it plug and play. And when they have enough people which contribute to the Java project, Java chain code project, then they will increase this. When they have enough people for the GoLan or Node.js project, then this project will work. So this is, I think that's not, that's community driven. And I think it depends how the community contribute to each part project and in the end some, I read something about RAS for chain code. So, and when there are enough people who contribute to this project, then I think we will see RAS there's another chain code language. And, but that's, I think I'm not the right person to answer this question because I have this, I think I have the same information like you. Nobody talked to me and say, okay, our plans for the next future is to improve the Java chain code version or the Node.js. And it's also, for me, it's a little bit confusing that when it comes to the Linux foundation in terms of the certification. So the chain code, the developer certification has started last year, I think, and in the 1.4 version. And you have, you could choose between the Go version for the chain code and the Node.js version for the chain code. And on the client side, there was the Node.js version. And then they have stopped the certification. And now two months or one month ago, I received an email that in March they will resume this process again, but only with the Node.js. So they resumed the certification with the Node.js on the chain code side and also on the client side. That's a little bit the reason why I have focused me a little bit on the chain code side for the Node.js for the chain code development. And maybe it helps someone who is going to try the exam, the developer certification in March, April or this year. And yeah, but I don't understand why they don't have, maybe they don't use the Golang also for their certification because the Golang is, I think... Native support. Native support. And that's also, I wrote some articles about, from guys, they said, okay, Node.js is so, it's not performant, it's slow and it took so much storage. The chain code container took so much storage and so on. And I said, why? And that's also the reason why I tried to analyze this and do a small example like this, what you have seen today and compare this with Node.js and the same with the Golang. And then we have, we see it clearly what is how this performs and what is better for that. And that's the reason why I focus a little bit now on this Node.js chain code development. And I think when you know all these steps here, then you will recognize that it's not so difficult to write so a standard chain code for a standard implementation. So it's not so difficult, I think. When you know these steps, when you know how you can test this, when you know that you have the package chasing, the start command, when you know that the start command will be installed through this very shim package. So these are some hard-learned facts. So I have invested a lot of time to figure that out. And that's also the reason why I put this online and write this down. So because it took a lot of time to figure this out and make and development and joint development process like today in nearly two hours. So yeah, but I don't know why they skipped the Java for chain code, but in the documentation I think is it already named. Okay, so why I asked this question because I'm from the Java background and I just wanted to, last year I registered for an exam, but in the middle they recalled the Java support. Yeah, anyway, from the bottom of my heart, like this almost two hours session, entire my throughout my entire my career, I don't see such a session. You know, you have given a great session for this small group. I really, really appreciate for your effort and the time you have invested for these sessions. Thank you so much for this. Thank you, thank you. Any other question? Okay, if not, then you can give me support. No, not support, you can give me a feedback. So if you want, and if you want to try my examples and on the GitHub here, and this session is recorded and I think tomorrow it will be available and then I will send, I will post this on the Meetup, this Meetup thread and then you will receive also the link to the slides, to the slides here and also in the slides you will have here this GitHub repo and you find here a step-by-step guide. So it's important for me to know if you can work with this guide. So if somebody of you try this guide, try to follow these guides here. So when you try to test the Docker DevMode here, then you can follow one of these guides here when you see the Docker edition. So, and then it would be a cool if you try this and say, okay, I can work with this, this tutorial will work or not. And this would be a nice feedback for me to see if this is also, this works for another person, not only for myself. All right. Okay, so thank you for your attention and your time. And I hope we will see you on the next session. And on the next session, we will focus a little bit more on the Node.js part. So I will go a little bit through the last session through the requirements for the certification. So we can extend, we can work a little bit of couch to be. So that's a little bit different. And also we can use the attribute-based chain code. So that could be a small site step to FabricCA. And then we can make a little bit more, or we can use a little bit more from the permission side. So we can say, if this user, this particular user is from the marketing department, then you can use this chain code or you can use this function, for example. And this is also very interesting. And then you can see a little bit from the FabricCA. And with the Fabric 2.2 network script, we can start this also very easily. And that's the reason why I show you this network script every time, because when you know how this is working, then you can test a lot of different configurations in without any effort, I think. So you can use couch to be, you can use FabricCA and so on. You can use free endorsement peers, whatever. So it's really a good way to test them, to see and to learn how Fabric works. Okay, so, thanks. Where to send feedback? Yeah, you can send, that's a good question. You can send feedback in the Slack channel, of course. I will share this link here. I think you find this link also on the Meetup page. On the Meetup page, we have this Slack channel. Ah, no, sorry. On the Meetup page, there is only the text that you... I wish maybe if I find it here, I can give me a minute, hope this link will work. So I think that must be the correct link to the Slack channel. Will there be any session of soft horizon? Yeah, maybe I will, I can prepare something like that, but not in the upcoming sessions because I want to focus a little bit more on the chain code side and on the client side because for myself, I'm going to try the developer certification. And that is part of my learning process now. And all the examples are part of this learning process. And that's the reason why I have focused for the next upcoming sessions on this part. So, but if this is ready, then we can switch back to this topic and then I can prepare such a session. But this is an open Meetup session. So if someone of you want to make a session, then come, connect me and then you can do a session by your own. You can show also your examples and what you have learned. So that's not a cause or something like that. That is a session from the community for the community. And every contribution is welcome. So, if you would like to open also a topic for that, so you can make a part of this presentation and so on or show what is your problem, then we can see how we can fix this and make it. So it's not the school here, it's from the community for the community. And everybody of you can take part of this session here. Okay. So, Link is here and I think you have also connected. Yes. Yeah, so thanks for your attention and see you next time.