This tutorial demonstrates how to build a name service application using the Cosmos SDK framework and extend it with IBC (Inter-Blockchain Communication) to enable cross-chain collaboration. The process involves setting up the development environment with Spawn and local-ic, creating a base application with a custom module using ProtoBuf definitions, implementing application logic through keepers and message/query servers, generating CLI commands for interaction, running local testnets, and finally extending the module with IBC functionality to allow data transfer between multiple chains using relayers and channels.
Build an Interchain App with Cosmos SDK and IBC in 30 Minutes
Added:hey everyone I'm reys and today we're going to build out a name service application using the cosmos SDK stack and then expanding that into IBC to build out an IBC module that allows for cross-chain collaboration with your module application I'm a protocol engineer at R chains we we built out the spawn protocol and this allows you to quickly build Cosmos SDK applications that bring your applications to The Interchange stack yeah so I'm very glad to be with you here today reys so I am Ollie I'm the debah lead for the interchain foundation so stewarding everything around the interchain stack uh and yeah today I know you're going to be showing me some cool stuff with spawn so I think let's just get into it let's Dive Right In so the first thing we need to actually set up our environment if you're not casually a developer so if you want to head to the installations tab within our documentation and there's a system setup so for you using Mac OS you can go down to the Mac OS section and here are the the basics that you need to have installed a lot of developers will already have these installed but anything that you don't already have you can copy paste over into your terminal yeah so I think I have most of these installed already uh it all went swimmingly so I think I am through that step but others might not be y let's head over into installing spawn then so the first thing you need to do is to get clone the repository this is going to grab the latest version for us and then you're going to move into that directory and then make install and this is going to take that that spawn source code and build it into a binary so you can execute it and build on the interchain stack the next command there is going to get local interchain this is going to install our test net tool that will allow you to run the interchain stack locally and have a test net based environment to verify that all of the code that we're about to write does indeed work and you can test it as if it was almost in produ so now you can run that that make local IC this installs the testnet runner so now that we've installed both of these let's verify that the installations were successful so if you run the spawn command we can see that that command line interface comes up ideally it does and let's verify also for local ening amazing if for some reason it shows that you get a command not found in the documentation as seen here you're able to copy paste these into your terminal and get it to work now that we have spawn and local interchain installed let's actually go build our first application so if you want to head to the year first application section this walks through an overview of what we're going to do here building a proof of stake Network we're going to then build a custom module this module will be our application and the application is going to allow for us to set a custom name to our wallet that we own and then we'll build on top of this to allow us to set it from another Network so if you want to head to the First Command the spawn new roll chain this is going to build up the base consensus of all of the formatting that we need and the structure you press enter here and spawn will begin to build up this R chain using proof of stake if you don't provide consensus and the disable Flags a pretty UI will pop up for you to select which features of the stack you want some that are not already provided here by default but this allows you to just get working with this tutorial here the new chain has been generated we can now move into that directory what did we call it we called it Ro chain and then from here we're actually going to scaffold our new name service module using the spawn module new name service command name service in this case could be any other name that you decide to choose but for this tutorial we'll use name service and just like that your module's already been created and we haven't even had to write any code yet so if you want to scroll down in the documentation we can now move over to setting the structure with this we're going to start modifying files so it may be important to open this up within your code editor so we can see the structure of the application code do there we go and perfect so we need to open tx.
prototo so just contrl p and should open this up here and so here's a Proto file think of this as the base data structure for what our application is going to interact with this just gives us a format that we can begin to plug into and have it auto jary code for us so within here below the update params on the left side of your screen you can place in the the new code there below the last update perams so if you actually want to check there's a details on the documentation you can open that up to see what does it look like that may be quite small but we post right below where update pams is and then you can paste all of that in so from here on lines 42 to 44 you're going to copy paste those up to currently line line 19 within the brackets or after actually delete that bracket and then paste it we have the bracket there there we go so now the base message service has been created we have the update prams we have our new set service name and what this allows us to do at the very bottom on line 50 a sender who will be us is going to be set and then there's a string which will be allowed for us to set a name and this can be any arbitrary value that we decide and then the response is just empty as we don't really need a response for this we're going to do the same but now for the query so if you want to open up the query file we're going to do this pretty much the same format where the resolve name RPC will be set in the service and then we have those two requests as well queries so we're we're just adding these these functions at the end yep and then if you want to pull from lines 26 to 30 that will get moved up to the service area into the service after here yep paste there and then delete that last exactly I'm going to request a wallet using the resolve name request and in response it will give me a name because I'm asking for some data we can now generate these into the go code equivalents and this is shown on the documentation using the make protoy you run this command in the terminal and it will bundle everything together using Docker into the go code the reason that we do protuff is to allow for other languages to also interact your Docker Damon is not running my Docker Damon is not so we'll need to resolve that running Docker which is also shown in the system setup and now we need to run that to ensure that we can interact with Docker to run and download that bi to compile all of our code great now try to run that command again and it should work there we go so the docker instance now it's taken all of our Proto code and it's actually automatically put that code into our application for us and connected it you don't have to know how to it just does it for you by finding other references in your app and putting that in so it's generated go code off of our Proto syntax yes go code has been generated off of the Proto and plugged into the s DK application for you that's beautiful can you run me just slightly through modules of the SDK for the sake of our audiences so a module can be thought through as an extension where the SDK gives you a base to start off of but to build your custom logic you need extensions or modules as they're called in our ecosystem from here you can build custom business logic that surfaces your users or your specific use case so for us we're building the name service others may be defi protocols or transferring some data between users or having your own application and it depends on what you really want but we call those at a generalized module okay so that gives us the power to effectively natively imp implement the business logic where many other sort of Monolithic chains you sort of deploy smart contracts on top of other existing systems exactly and the thing that's great about Cosmos is you could also deploy applications through our service called kmom which allows for you to deploy smart contracts on top of writing modules and then having those two connect seamlessly as well so this is all possible for this demo we just show the basics of modules future demos will also showcase how to use Smart contracts and how to interact together with modules or with the smart contract directly as a user great so it's the best of both worlds you can get native performance for your business logic or you can enable kmm and Deploy on top with additional contract Dynamic onchain code exactly yep Cosmos is great beautiful if you want to head back into the documentation we can now move to writing our actual application logic because we have the structure set up so the first thing we need to do is head over to this thing called a keeper in the SDK if you're coming from a a developer background this is pretty much a Singleton class if you want to think of it like other languages this is where we're going to store the base of our logic and the SDK can then read from it we have some other things you don't need to know what a lot of this does we just need to set this new name mapping so if you want to copy the name mapping line which is a map of a string which will be the user's wallet or the user's unique ID and we're going to map that over to the name so we're going to paste that into the keeper structure we just need the line that is highlighted which is below the three dots there we go and then paste that over somewhere with like under the omdb or anywhere here is really fine that base structure of a map is set which means that as we run the application this will be safe to the disk and that way as your network starts up again it can actually read from that while we have that structure we do need to set it with the new map that just gives us a base default that we can begin saving data to so we have some way to interact with it so you're going to paste this in the new keeper if you scroll down some you can add this somewhere uh below line 60 but above line 68 so if you want to paste it at the bottom and then save the file and what this does is it's a template for creating that that collections map so we have the map we're able to save it to disk but now we need to be able to interact with it with code and that's what this allows for us to do is to actually interact with it on the code side and you give me a quick rundown of the keeper uh and it's sort of memory versus like State on the Chain itself the way that the SDK works is we have the memory we're going to then save it to disk every once in a while and it will allow for us to interact with it in memory but also save it to dis where if the network goes down for some reason or you shut down your validator everything is still continued to be saved so you don't have to deal with the saving to disc the SDK automatically handles that for you and now we get to write the actual application logic so if you head over into the message server which is the sdk's way of a message is similar to an action I want to perform an action it's going to go to this action server formally known as the message server within here we have this base template on lines 33 to 35 which give you a base of where to put this code and now we can put in this this custom logic here and then paste that and then delete those those trailing lines what this is doing is it's grabbing the message server which is just an object it has the keeper inside of it so that way we have reference or we can access a keeper that previously we wouldn't have access to we're then going to call the name mapping which is that instance we just set that that saves to State we're going to set the message. sender which we specified in the prota file if you want to actually control click on that you should be able to see that where that message resides in the go code that we custom generated with using the make protogen Command and there's also the name field which is where we're going to set the text that we want for our name and we set that there as the the value to what the sender is we check if there's an error return an error there shouldn't be for most cases unless something has gone wrong on your other code side for example if you forgot to set up the keeper properly an error here will say hey you didn't set up that collection and then we return an empty type because we don't need a response the SDK will tell us that the message was successful we now have the logic for actually setting a name mapping let's now allow us to grab a name from a given address so we'll head over to the query server which allows for any user to query some data from the chain and we're going to paste in that logic there within the resolve name function that was generated for us here we grab that same name mapping it's very similar to how the message server works the only difference is we return a value in that response to the user based off of their request we're just reading directly from that name mapping and then we're resolving that name based off of that value which is what v stands for if there's an error it will return an error if not the user will get the request perfect now we're going to go configure the client because we need a way to interact with it from that binary that we've that we built which was going to package everything that we've done into a single application there's a lot here it's very scary looking but at a high level it abstracts away a lot of setup in a future demo it will showcase how to do this manually if you don't want the substracted version for this we're going to head to what the SDK calls the autoc CLI this is an automatically generated command line interface for your application and we're just going to paste in a new resolve name so the RPC method resolve name is a query which we specified in the Proto buff we called it resolve name within the message service and then we add some use cases how to use it what are the fields that are allowed into this and what's a short explainer of this the ordering does not matter here and I'm just adding it alongside the pams that I exactly so by default we give prams to all that way that you have a template for where you want to begin building out future logic with this we're going to add on top of that so now we have both prams and resolve named queries for our application the next thing is how do we actually set that well we need to just go into the set or the transaction command and we're going to set the name service using a very similar format as the query it's just going to be used for creating this transaction where again a transaction is a list of actions we've got the set name service we have the query now we can move into the next step which is actually running this test net we give you in spawn a very easy way to run this test net it abstracts away a lot of setup at a high level it is going to run the SDK chain it is going to compile it it is going to start a single validator and give you base temp base defaults for your parameters so if you want to open up a terminal and run that command within this directory now it'll begin to start and build up this test net this is going to go mod tidy which just sets up your go environment to have the latest and greatest it then also does this for a test environment for within interchain test which is full to in integration so out of the box not only do you get the cosmos SDK application but you also get a full tested environment with all of the modules that you specified for this we have some defaults that that were given we disabled kmom if you were to enable km wasm you would get testing right there in GitHub CI automatically connected for you there was a lot that just happened on the screen that was just all of the base setup this can be found in the scripts folder and you can find that within the RO chain directory we just generated ated and now we have a running blockchain application that used all of the parameters that we set and blocks are happening so if you want to scroll down now on the documentation side we can begin to interact with this test net there's this r d command which was what we just built up using make sh testet there's a transaction sub command that the SDK gives you and we're going to interact with the name service with this we are going to set our name this can be your name or by default it is given Alice and the make sh test net also sets up an SDK account for you which allows you some funds to interact with the chain uh finally at the end the -- yes just allows us to skip the prompting for do you actually want to submit this transaction so if you want to run that now in another tab it will automatically hit the test net execute that code and we will return a transaction hash or a unique ID for us to verify did our transaction indeed work and then pasting this in press enter and it's going to return the transaction hash this is always unique for a transaction and now we're going to query this to ensure did it really set so you'll use the query transaction command which is found right below and you query that and there's a lot of data here but at a high level you're looking for anything that just says error so if you scroll up through the message there's no error logs it looks like so our transaction did indeed go through from our account now let's verify that we can actually go find that on the Chain using the resolve command that we just set in the autoc CLI there's two commands here the first one we know what the address is because we could find that within the the transaction itself the other option it will pull it from your key ring which is just where accounts are stored by default so if we query this we get the name Alice which is what we set and if you run the other command it just is a prettier way if you don't know what the address is off of hand it's the same case where it's going to just fill out what that is using the key show command which is the account one which is where we set that from when where we sent that transaction with this we actually have an entire application that we built off of building the cosmos SDK and we're setting it on a single chain if you go to the next section there is a bonus where others that want to learn more of of challenging themselves there are hints and solutions for limiting input as well as resolving a wallet from a name we only did it one way how do we also do it that other way and you can walk through that there and see those different solutions this is awesome thank you so much re yes now it's time to extend this with IBC so we're doing this on a single chain we'll call this chain a but what if I want to actually set my name from a different chain that has a connection so I'm on chain a but I want to utilize it from chain B and this allows for interruptable applications across different Stacks where chain a can focus on a name service while chain B focuses on something else but through that we can send packets to actually interact with both protocols through each other so this is great from a you focus on what is important to you for your app and then others can also interact with that and utilize it in their own code so we'll head over into the applications demo section and head over to the IBC name service module this has a prerequisite of this previous tutorial we just did but we're going to build on top of this building a new module and interacting with that previous logic with this though we do need to stop that other test net so if you head over to the make Command on your left or you can just kill all with the r d that will just kill that test net so we can begin building up a future test net using IBC we're in the RO chain directory we're going to build a new module this is going to be called name service IBC and we pass the IBC module flag to provide that module logic that is different from the base module we need the IBC specific logic and your module's generated and with this we're going to now run make protogen just to get the latest to be sure that all of our name spaces match what we expect it's going to move anything over that needs to for this we haven't modified anything yet so we have an a base IBC module now we need to go set up the custom logic to actually interact with what we've just built you want to head over to the name service IBC keeper we need to allow it access to the other module that we just created so we created the name service keeper and we need now to be able to grab that so we're going to import that from within our local directory using that that import command there where's the neatest place to put this uh normally you just put it at the top at the top and that name service it will show red until we actually reference it which we're going to do in the keeper so the next line is going to be inside the keeper that way that we have reference to that so you can add this anywhere and now we're pulling reference to that keeper if you want to actually control click on the do keeper on that name service line that we just placed you can hover over that and see that is what we just wrote previously so we have access to it it all works heading back to the keeper we're going to actually allow the application a way to reference and give access to it so in the on the newe keeper line we're going to passing an argument where we'll put that that name service keeper and then we need to allow access and actually set it up to the keeper using the name service keeper there within the heaper initialization if you save on the file the application is now going to not be happy so we need to head over to the app to go set it up we're going to head over to the app.ged tick on the side scroll bar of your vs code it's saying hey we don't have enough arguments here because we need to add that line and with that that's actually going to go at the top for you since you you imported it at the top of your neweer and if there's no red lines it means that it's happy what this does is it the application as it's setting up is going to say here you go you can have this and then we can begin to use its logic in there we're all set up from the application side we have all of the base logic it's now the time to actually set our name on this IBC packet we're going to head over to the IBC module. go which is where all of the IC cross chain compatible logic is set up this has a lot of configuration you can do by default it will just work out of the box we're going to go find the handle on receive logic method this is the method where you're going to put any logic that you want for after a packet has successfully been sent and is verified and confirmed it's from a valid user we're going to then go and do some logic by default we have this example store for this we don't need that we're going to copy paste over from the documentation to set a name on that name service keeper for the name mapping so you can copy paste those lines there's also some extra verification here just to ensure that a name isn't too long which is found in one of the bonus tutorials the logic is now set up here we can now build up the application build it into a new test net which is going to use local interchain and this is going to start multiple instances this may take a minute so if you want to open up a tab and then run the make install and make local image commands make install will build the base binary this is the r d you could also run make sh test net it runs the make install under the hood run make local image this is going to build up that same binary but in a Docker image that you can then share with others or run for multiple test net compliance we'll use local interchain to start a self IBC testet this is automatically created for you if you want to find the source you can find that in the chains directory within the RO chain that we just created and there's a Json file where you can go configure it run more validators run other configurations change the parameters or change other aspects of how we connect this together we're launching chain a which is World chain we're launching chain B which is also Al rchain and then we're going to connect those using a relayer which is what IBC uses that relayer will pass the messages from chain a to chain B seamlessly without the user having to know what is going on and we do all of that through Docker so you as the developer can focus on what is important to you your application and this is also where the interchain gets exciting and where it becomes the internet of blockchains exactly so this is the core of what the interchange focus is how do we allow for everyone to interoperate together and with this we can't we actually have the image now so let's start the test net run local IC start self IBC if you don't know what chains are already given to you you can run local IC chains and that will showcase all of the chains that are in your directory I will do that local IC chains exactly and there's what we have there's a read me that you can go read about there's self IBC and testet another fun thing is that you can actually upload that to GitHub and then reference the URL and start from a URL so you can share it between other members as well that are on your team and just have a test net there that works out of the box with a local interchain also local interchain is dockerized so if you don't want to install the direct binary you can run it through Docker with this it's going to go through that configuration and begin to set up chains there's a lot of stuff happening you as the developer don't need to know it's just in the setup and you can learn about this later we're starting a chain a we're starting chain B then we're going to set up a relayer between these if you want to know Now open up a new tab and we can get ready for the next step which is actually running our first IBC transaction there's this section called import test helpers by default we give a bash instance or a shell where you can interact with local interchange very very simply you just import this into a file which is what that Cur command does that will save it to a file called source. bash and I C this straight into you just paste that right in and if you actually want to view that file you can or you can just Source it directly so it is it is Source available everything is there for you and this just adds interchain test commands that way that I can execute against it I can interact with the relayer I can do things with IBC that I typically can't do without running all of this convoluted code we as the users don't need to know that I just want to interact and so this gives a lot of helpful commands to do that with that we Source it which is going to take all of that code and run it in our terminal and now gives us access to those functions local interchain gives an API for you to interact with to run transactions to run other things that are not on your machine and so this gives us access to that via that API if you want to now head back over to the RO chains test net that is being started up we can verify that that has started and we can see that if you want to open that up you can see the base API we have documentation on this there's info there's chain registry there's other things that you can do you can upload contracts through this and just a lot of helpful methods to see our test sign is up the relayer is running behind the scenes if you go back to another tab you can run Docker PS and we can see that that is the case Docker PS is is to show all processes we've got a relayer it's running latest it started about a minute ago we have roll chain that has started 2 minutes ago and another one as well this automatically maps to your host ports so you can actually go view this in your browser using the the values there chain zero will give you the faults for what the SDK is usually giving the other ones will be randomized based off of free reports on your machine Let's actually go connect our IBC module now that we've we've generated there's a i ICT relayer exec this is going to execute a command on the relayer it's found in that source that we bashed it's going to run this on local chain one which is set in the the configuration and if you want to paste that in and press run this is going to use the connect command in the relayer between chain one and chain 2 this was automatically set up whenever we created the chain you can find this in the logs and we use a source Port we're going to specify the NS IBC module we created then on the other side because we're running the same chain twice the destination is also the name service IBC order unorder just means that I as a user can post any amount of transactions they'll come over it doesn't matter what order they happen in we're just going to send that and then we specify the version which is the NS IBC module and we just prefix that with that with a one after you run that a lot of logs will come down you may see some things that say error account sequence mismatch if you do see that it's fine the relayer will realize it and will automatically do it for you now let's verify did the channel actually create do we have a connection between both chains we can then run that Echo command to verify that it is the case we see State open unordered counterparty n sic and then there's also another state open at the bottom for the the last three lines which is is a default transfer Port that allows you to transfer tokens that's not part of this demo but there is the IBC transfer demo which will utilize this we've created a module we have the relayer the relayer has now connected together because we've told it please use my my module and now we're ready to execute our transaction across this we're going to use the transaction command that is given by default with the name service IBC module it's just called example transaction and that will allow us to execute against channel one which we saw in the query just above we have Channel id1 and we're going to send it from an account in this case account zero on local chain one so we're sending this from chain a and we're specifying yes and we want the name to be test name and the packet is then generated and we can query that using the r d query transaction command this may be different from what you see by the logs because it is using IBC under the hood there's different setups and things that can change that we can scroll through this and see all all of the logs that have that have occurred with IBC but the most important part is this packet data where we have the cender and Su data which is test name uh above the hex and so this is what we're sending and some data is going to be our name in this case for the example transaction we just said it us some data but the other side will be able to understand that and know where to pull it from let's go verify on chain two from local chain 2 that we can query the name service module to resolve the name that sent from chain a so you paste this into the terminal we resolve the name for that other on chain two and it does indeed verify because the IBC packet has sent you can also check the relayer logs by running Docker PS if you copy the port ID on that top one the 9962 you can copy that and then run Docker logs DF and then paste in that ID and if you scroll up past the the queries and you continue to go up there'll be a lot of text that specifies things are transferring here so we can see path names you can see all of the logs for what is actually happening with that packet behind the scenes that is being done for the user and for you as the developer and it just works you're able to go verify if something didn't go right here look and see is there a special reason why if not you can view all of this here you can also see it in the testet itself that as it's running it'll show you the commands that the relayer is running and those transactions we've run a relayer we have multiple n networks we've connected them over IBC and we modified a value on a chain that we are not on but we're pushing from the other chain IBC go has now worked we built our custom module and we have an application that is now cross chain usable so very very exciting stuff yeah this is absolutely awesome and it's awesome to see it with a tool that you have uh led the development on with spawn uh so yeah thanks for also showing me some something new and yeah getting this going has been pretty cool to see this is genuinely my first time running through this this tutorial and it it's really pretty pretty straightforward I'm super excited to hear that and the best part is is that this makes building on IBC even easier than it ever has been so we're excited to be bringing IBC module support to spawn and running test Nets and being able to really improve the developer experience for building cross chain applications compared to the previous stat quo so really really excited to hear and uh excited to see what others want to build on top of this using the cosmos SDK stack and IBC modules lovely stuff so for those of you who are watching this from Cosmos India we're really Keen to see what you build with this tool and we'd love to see some of you come over to cosmoverse and hackos uh particularly to participate in that hackathon as part of hackos there's some super nice prizes up for grabs and and the interchain stack track will be run by us and both Ree and myself will be there to also help you along your journey as you get building with some of these tools and creating your own chains and rollups and IBC applications and smart contracts and anything possible with the interchain stack so we're really Keen to see that thanks everyone thanks
Up Next

IBC Protocol Workshop: Interchain Accounts & Relayers
@Kryptoplanet
1.2K views•2022-09-17

Torrent File Format & Bencoding: A Technical Deep Dive
@AsliEngineering
12.5K views•2022-08-08

Operational Security Essentials: A Guide for Hacktivists (OPSEC)
@hitbsecconf
157.4K views•2012-11-26

Understanding Ethereum: A Comprehensive Beginner's Overview
@99Bitcoins
3.1M views•2018-06-26
Related Study Plans & Knowledge Roadmaps
Structured learning paths in Blockchain & Crypto









































