The Cosmos SDK is a modular framework for building blockchains that abstracts away the underlying consensus and networking layers (handled by Tendermint), allowing developers to focus on defining application-specific state transitions through modules. Each module contains keepers (state management functions), handlers (message processing logic), and queriers (read operations), enabling developers to create custom functionality like name services while leveraging the SDK's built-in modules for account management, staking, and token distribution.
Build a Blockchain App with Cosmos SDK: A Developer's Guide
Added:before we get my my name is Jack I'm the product manager on the cosmos SDK over tender mint I've been there for a little while and obviously we've been focused quite a bit on launch here so just a show of hands to kind of level set here who has worked with any of our products before tinder mint cosmos the cosmos SDK ok cool who's who else is developed on top of other blockchains aetherium folks primarily bitcoin cool awesome so good good journal level of blockchain knowledge in here so what I'm going to be talking about today is how to use the cosmos SDK to make a replicated state machine or a blockchain as we'll call it at a high level the so what is our initial state that's a question we're gonna have to answer as we're building this replicated state machine where does it start from what are the possible state transitions how can that state mutate and then is it Byzantine fault-tolerant ie the nodes that it's living on are they able to resist malicious actors so at a high level the cosmos SDK sits on top of tender mint which is a Byzantine fault tolerant state machine which takes care of a lot of the kind of magic the p2p stuff all of the persistence the creation of the blockchain network and the addition of new blocks is all taken care of in ten Derman itself and that communicates with your application via something called a BCI your application blockchain interface in all of your state transitions and other state mutations will all be defined within this application we're building so what does this allow you to do it allows you to take a step back from the underlying internals and really focus on what you want the user interface of your app to be ie what actions do we expect users to perform and how do those app actions mutate State so there's this focus on the application you can think of Ruby on Rails for blockchains it's also proof of stake so in Prior generations if you were looking to build your own blockchain you'd probably fork Bitcoin or port depending on how adventurous you are and use one of these proof-of-work currencies to create a blockchain we're really the first SDK that allows you to do this in a proof of state system and as I mentioned earlier tinder mint for consensus and networking I'll also pause right here if anyone has any questions during this presentation please just shoot your hand up I'd be happy to answer those yep so what are we building today if any of you are familiar with the history of the blockchain space you'd be familiar with some of these blockchain naming systems the ahkam folks over there are building one for IOT devices this is an active area of research and an active area of development for many of these blockchain systems so the etherium naming service handshake both both run on top of etherium were examples of this they essentially map a human readable identifier to a public key very similar to the domain name service the earliest example of this was named coin that eventually became a company called block stack I actually spent a couple of about a year at block stack and helped them raise their I co2 so this is near and dear to my heart yeah so as I mentioned earlier at the beginning here's the github if you want to download the tutorial and follow along with the code that's probably the best way to get the most out of this and at the end I've got a node spun up with the network and we'll be able to bid on some names and steal them from each other and hopefully it's fun okay that's that's at least the game plan but in this what we're creating you'll be able to outbid somebody for a name so if somebody pays let's say five tokens for a name and you bid six for it you become the new owner or so a fun little bit of more can develop so if we're talking about the SDK at a high level it's this modular framework and what do we mean by that so if we go back to this idea of a replicated state machine and we're defining these state transitions that users can make there are groups of these state transitions that are kind of thematic so in the SDK we give them we give users the staking module this defines some advanced staking in slashing behavior so a couple of folks were talking about downtime slashing or when the validator double signs or presents some malicious behavior towards the network will penalize that validator by taking away their tokens so that's that's one example of a module distribution another example of a module in the hub software we have inflation that rewards folks who stake tokens with those in those newly minted tokens and they're distributed to all the validators evenly so that's that's a module the ability to use tokens and we'll see a few more examples in the core of this tutorial is building our own module which is just going to be a group of state transitions any questions there all right so the modules in this tutorial off so this is the cosmos SDK by default is an account based blockchain so you can think of something like a theory 'm rather than aut excel based blockchain like something like dogecoin or a Bitcoin obviously the first one and then there's Bank which is closely paired with off so keeping track of the amount of tokens obviously when we're talking about the state machine in a starting state there might be a starting state with some number of tokens in it money money money and then our name service is the other module that's gonna be in this and we'll build this and this is essentially maps a name to some data so in the DNS service that's a zone file in it's gonna be roughly the same thing here so staking I spoke about just a few seconds ago that's one of the major modules that we have in the hub you could add it to this tutorial I've omitted it for clarity and lack of complexity but this would give you that sort of advanced staking logic and what's interesting is without staking the cosmos chain is kind of this private permission chain where you need to know somebody on it to join as a validator our staking module in the hub the one that's publicly available is designed to be a public staking module so that it's this permissionless staking system and you can build both of those with tender mint in the SDK and then another one that is not in there is governance if you guys have been following the project at all lately you know that we've got a couple of governance proposals up to upgrade the project so that's that's how we're doing governance in the chain and if anyone has questions on those I'm having the answer them at the end as well so modules control state and you define messages in those modules so at a high level when we're thinking about the cosmos SDK there I mentioned that there's the application that kind of lists on top and then there's tender mint below it there's a piece of the SDK that governs communication between tender mints and your application and that's called base app in the store that it has on disk is something we call the multi-store and it just has a bunch of different key value stores so you can think of like a name to value mapping just very simple stuff or in the case of validators and the staking module there's a validator to the amount of power it has and these simple primitives with that you can build up much more complex applications it's just a key vkv store unlike any other database any questions they're cool and then the state balances in Bank which accounts exists and then domain names so pretty simple state here we're not going to really dig into the details on accounts and balances but we will dig into the details on the domain names so what will be storing in this store that we've created for this name service we've got three mappings here one from name to value what is the name resolve to ie it's the zone file or the I mean just like in a record it would come out to some IP address so I think that's the example that we show is it resolving to an IP address but it could be a fully RFC compliant zone file pretty easily it's just a string another mapping is named to owner ie what name is owned by what wallet and then we're gonna use a public key there and then another mapping is from the name to the price so how much was paid for the name and I was talking about this bidding component to this so that's obviously important as well now one other way we could do this if you'll notice they're all named to something mappings you could have name to complex object mapping that contains all of the other data that's left as an exercise for the user if you guys want to modify the tutorial that's a pretty easy refactor that helps you understand the code a little bit better so in the SDK we have transactions in each transaction that goes into a Cosmos SDK application can contain many messages so when we're talking about these user facing methods that are gonna be called we're talking about messages messages are routed through handlers handlers hand those messages to keepers this is the sort of like higher-level object hierarchy within the SDK they hand those two keepers which control access to the the Cavey stores and the underlying blockchain and when I was talking about that component that talks to ten Derman the keepers have very direct access to that and the keepers update the state so we'll see this flow quite a bit if there's any questions please please feel free to ask them I do know that the terminology can be a little daunting at first so what messages are we going to define in this module we're gonna creating people need to be able to do two things they need to be able to buy a name you can buy a name that's already been bought and that's like bidding more for a name but that's the exact same messages buying a name and then once you've bought it you need to be able to set the value of that name ie what does this name resolve to when I call who is doesn't give me 8.8.8.8 for Google's DNS or does it give me foo and we need to be able to set that so these are the two messages that our name service is gonna have so again for this general flow here and kind of how these messages will flow through the application and we'll see this in code in more detail here in a second a transaction contains messages tender bit nodes so once the transaction comes in with the messages that those transactions are sent down to the tender main node which will include them in blocks and that's passed down through the a BCI interface which is the application blockchain interface it if anyone has any specific questions about that we can we can dig into that afterwards but one of the real beauties of the cosmos sdk is that it it abstracts the need to deal with this interface away from you it's very low-level but it does give you everything you need to build complex state machines the decoded those so they're passed to a BCI and then when they come back when they're included in blocks they're decoded as messages and routed to the correct module to be persisted in state and for those state transactions to happen to them and those state transactions are called handlers so when the message is handled the state is modified and the handlers call these keepers which are sort of the abstraction that's at the core of the module to modify that state any questions here I'll just pause for a second cool yeah and I would note if you want to take a peek at where this code is in the application modules are by convention held in the slash X directory at the root so all of these underlined things here will have their own named dot go files and we'll dig into those in more detail throughout this tutorial as well so how does this whole application come together there's all these components we've got these modules we have this base app thing we've got ten Derman a bunch of stuff that I don't know what it is we need to stitch it all together so by convention in cosmos applications you do that in a file called app dot go and this is where you wire everything together and it does logging authentication database management so within the cosmos ecosystem we have a specialized encoding format to do persistence as well as over the wire and APCO is where you'll deal with a lot of the encoding formats stuff basically it's a lot of boilerplate where you're wiring together the different pieces of your application so if we start an app go we're importing a bunch of the tool chain basically so if you can see up here we're gonna import some stuff from tinder meant so some logging utilities this is a module from the cosmos SDK so as I mentioned earlier that X convention their modules are stored under X and this is the off module so obviously if we need to counts it's one of the first things we need to wire up because the name service module that we're going to create later needs accounts in order to make these named two value mappings because names need to have owners and then for the ability to have tokens you need to have the accounts to use the bank module so that's one of the first things we need to import and then base a p-- and then the database manager so if you're following along in the tutorial there's a in the SDK application tutorial repository there's a slash tutorial folder and it's got a bunch of markdown files in there there's a first app go or something like our first app dot MD or something like that that shows you the the basic app dot go and that just all it does is instance instantiate space app ie your connection with the underlying tender mint data store and allows you to wire up additional modules to it so it's it's just very basic so once we've got that let's step back and start talking about our name service module so modules go in the directory called slash X and if you're following along you can see X slash name service in that SDK application tutorial and inside there we're gonna have a bunch of go files named after things we've started talking about already handler that's where the messages are gonna be handled and we'll define our state transitions there keeper dot go this is where the core of our module lives in where we will define the getters and setters for the most basic pieces of state update querier this is where so the handler handles transactions the querier will handle queries so for querying this custom state you might need to write custom rod custom logic to return lists let's say you want a list of all the names all of that stuff is gonna go in query or go messages go we'll define the different messages that our handlers will handle which is just essentially the JSON structure of the transactions that users will submit here codec go is a little bit of housekeeping and then the SDK has nice hooks to generate rest routes and CLI stuff and hook that into a nice CLI experience very easily I'll pause here any questions am I going too fast pardon I don't know that's a great question I don't I don't know it's I've seen it in other projects and I know it's like short for something that I can't think of right now no it's just like modules go and slash axons okay yeah I don't have a great answer for you there I'm sorry yeah so the first piece that you're gonna want to think about here and obviously is it's kind of the most low-level and it's the most fundamental representation of your module is the keeper these are the getters and setters on the database essentially and your handlers are gonna call these keepers in order to mutate state so this is this is the base of the application here if any is anyone written JavaScript before any JavaScript folks in here anyone familiar with redux okay cool so keepers are like reducers in redux or mutations and view X and then handlers or like actions if that makes any sense the handlers actions piece I totally get the reducers keeper thing is a little bit fuzzier for me that's just me personally so we talked earlier about the value mappings that this keeper will take care of for us in the first is name two value ie what is the value of the name when we resolve it that's gonna be a key in each of these value mappings in the database we'll have a key that gives access to it and this prevents this is how you can give delegated access to other modules to access functionality in this module without giving all of the functionality of the module so you can really precisely give permissions to different modules within your application and then there's the owner store key so there's an account address to name mapping what account owns what keep it what name and then the prices store key how much does the name cost and then as far as getters and setters if you're following along in the code this is an X slash name service slash keeper dot go so what we need to do here we need to resolve a name that's get a name we might want to answer if a name has an owner because there's gonna be some custom logic we want to do if it does and there's gonna be some other logic that we want to do if it doesn't we also want to be able to get the owner and the price so these are our getters here they're all basically get X except the has own or one which is just a boolean operator for convenience and then this setters this is writing data to the database set names set owner and set price pretty pretty simple so let's let's look at one of these here so this get price here we're gonna pass in the context so the SDK comes with a lot of nice tools for working within this framework here obviously it wouldn't be an SDK if it didn't so let me just talk through a couple of these objects here the get price function takes context as an argument context has all kinds of useful information on it like block height all the chain parameters from Genesis like a bunch of useful stuff for you where you are within the block there's this concept of begin block at the beginning of the block you want to call a handler as you're including transactions you want to call a handler at the end block you want to call a handler the context has where you are in that flow along with a lot of other useful things I would encourage you to look at the go Docs for that if you're more interested we have links on the SDK in the name so obviously if you wanna get the price for a name we need to give it the name so first we're gonna check if it has an owner and if it doesn't we're gonna return the base price which is one coin obviously it says my coin here but that can kind of be parameterised out and given whatever denomination you'd like pretty easy to work with that code there so once we have the name we need to get the store so we're gonna create a new Cavey store with our key there and if you pass the key into this Cavey store constructor anywhere in the code it will give you access to that on desk and then we're gonna get the name from the store unmarshal it and I talked about the codec earlier so this is an example of us using the codec to do some on marshalling and then we're gonna return it as a specified type and that type is SDK dot coins so the coin is just a value denomination pairing pretty pretty simple but there's a lot of functions on there where you can do addition subtraction on coins multiplication all sorts of fun stuff and then setting the price so that's a getter and then the setter we're gonna pull that store again and then we're gonna set the name equals to the marshaled coins price any questions they're good pardon that's eight okay so that's a great question so that is a query but it's a method on the keeper does that make sense so this is ghost syntax for we're defining a method on this object so the get price method you need to have the keeper in scope to call the get price method and to get price method takes two arguments the context which gives you all this useful information about where you are in the SDK and the name to pull that out and then we've got the the types that I just talked about does that make sense yeah the queries are for returning user facing data so this is like low-level stores getters and setters and maybe we need to use the get price the get name and the get owner in return all of that data at once for just a generalized query so we would stitch all those things together in a query or and return that to the user and we'll see that in just a minute might they're fading it does okay so I just needs to get updated thank you for the heads-up there I appreciate that shouldn't be updated too much should it a little bit okay thank you well well I'll check that out in just a second yeah so trust what's in the repository don't trust my slides yeah so now we're on to messages and handlers now that we've got the keeper we can get and set all of our values let's create this user facing interface that we're going to offer so messages trigger handlers these are like user initiated events you can think of it this is a click in redux handlers call keepers again like actions and then reducers so just that same thing keeping this in mind here's the interface that every message needs to satisfy who's familiar with interfaces and go okay those folks for those who don't know an interface just defines what methods an object must have in order to be included in a specific piece of code so here we need a type this type in route or used to route the message within the SDK to the proper handlers base app pulls the type off gives it to the module and the module pulls the route off and puts it to the specific handler validate basic so any simple validation that doesn't require access to state like if you can check that the person who signed it is the person who is supposed to own the name that's something easy you can do invalidate basic and we'll see a couple examples of validate basic functions in this but these are stateless checks of validity of the message and they will return an error get signed bytes so this is the byte representation of the JSON that you need to sign over and then get signers will return all of the signers for an individual message obviously multi-sig implementations you can sometimes have multiple signers so this is it returns an array of addresses again our two message types so we probably don't need to talk about the first two they just return strings it's pretty easy but validate basics so this is a great validate basic example if the owner is empty then they can't buy it like you need to submit an owner with your by name message message set name so if there's no owner on the name then there's something wrong and you're not able to set it and if there's no name or there's no amount of coins in the message then obviously we want to reject that as well so stateless checks on the validity of a message invalidate basic yes and this is called so this gates this is something you never really need to call in your code the sdk calls it under the hood and will reject transactions like at the CLI level if they don't pass this so it's just it gets called under the hood in the sdk and it helps you make sure that you're sending valid messages to the state machine so let's think about how we need to handle this name and again the code may be different here but this is the gist of it so if the message owner so okay just stepping back here somebody owns this name and we're setting the value on it so let's say I got jacked ID and I want to set that value to Jack sampling comm because that's my website so I would say if message owner is not equal to and we're gonna pull the owner of that name then we want to return unauthorized because that that person doesn't own the name they can't update it that's an error and the SDK so that SDK dot that is the cosmos cosmos SDK slash types package this contains many of the common utilities for working with the SDK including errors that return proper results along with logs that will be appended and stuff so this is kind of the canonical way to do that but if the owner is correct then we want to use the keeper to set the name and state and then return an empty result so this is just a very basic handler any questions they're awesome so we just talked about handlers now we'll talk about some queriers so the two queries that we want to have is we want to accept a name and return a value and we want to return all the data about that name the value the price and the owner and we'll define two queries for this so that second one is the most the more complicated one the first one is just gonna call that getter as you mentioned and then return that data essentially so really kind of a wrapper method but again more complex logic is possible in these queriers so queriers will generally take the format of having the context is an argument the path which is just like that type and route in the message interface queriers have a similar thing bass app will route them to the module first and then the module will route them to the query handler and that's done in the past thing and they the ABC I request query this is some additional data that would come along and then you also need to pass in the keeper so that you have access to that underlying data and it returns bytes in an error so you'll see in this code here we use the keeper to pull each of the different things for a given name and then we've got a struct that we've defined down there and we marshal it and return it so pretty simple one of the nice things is all of the code within each of these abstractions four basic things is extremely simple it does give you the flexibility to add much more complexity within each of these steps but just following this basic thing if you need to do pretty simple mappings like this it's not overly complicated which I think it's quite nice and it makes for very readable code so this is the codec here so this you only need to register with the Kodak things that will be serialized into storage so the only things that we're serializing into storage are these get name by name and set name all of the other Struck's in the tutorial including that who is we're not really putting into storage we're essentially just JSON encoding and decoding them so we don't need to don't need to deal with that but suffice it to say all of your messages need to be registered this way it's kind of boilerplate and it lives in a code echo file all of our modules within the SDK you'll see this exact same pattern if you want more information on Amino please check out the github comm slash tinder mint slash go - Amino repo there's a lot more information about the encoding format there but suffice it to say it's essentially protobuf with a couple of prefix bytes to tell you what the message is and then it's protobuf encoding after that there's some alternate implementations in JavaScript if anyone's got any questions about that I'm happy to answer those later so now that this is like these are the core interactions we have this querier we have the messages if all I want to do is use the tinder mint RPC port which is 2 6 6 5 7 I could manually construct via JavaScript or whatever messages and queries that would work with this state machine what we're doing now is just niceties for a user debugging via CLI or someone who needs to use a standard rest interface and this just comes nicely out of the box the CLI I'll show you is very similar to the gaya one like we built it with the SDK so I tried to make it nice and modular so that you can swap these modules in and out add queries and new message types pretty easily with the minimal of code we use the cobra library that's pretty common and a lot of large golang projects if you're familiar with things like kubernetes or any of the hashey core projects there's a lot of projects that use this Cobra CLI library you'll probably probably recognize it so we're gonna create a couple of files here obviously our user interface here is these queries and these transactions that we've created so we're gonna create a client folder CLI and then a query in a transaction go and then the rest server would go and client rest rest go there's an abstraction within the sdk called this module client and this allows you to export all that functionality from the module in a way that's easy to wire up at the end and we can see that and I'm happy to dig into details there because I wrote that code and once we've done that we got to stitch it all together in alko so we need to import and initialize this module that we've created and hook the module in with the auth and that's really about it it's not a whole lot there is some complicated code in there for the net chain that code I don't really explain super in detail in the tutorial basically what it does is it takes this Genesis file which contains the initial application state including parameters and brings it into the application I'm happy to go through with anyone who's interested and talk through that code there's also some additional code in app code that talks about exporting state so this would be how you would dump the state from the application and restart from a specific block height that logic we haven't packaged up nicely so that it's really easy to write like the rest of the SDK that's definitely on the roadmap and if folks have questions about that I'm happy to answer those but if you guys are familiar with the way that we did the hub launch all of we had this long list of addresses where people had donated for the fundraiser and we also had folks from game of stakes come in and you put it all together in the genesis file and that bootstraps the application so not really gonna get into detail on that here but having to happy to talk about that a little bit more and then finally we need to build our binaries so with go the convention is binaries would be in the CMD folder and we've got two of them we have an NS D which is the daemon that runs our name service module and then we also have the in a CLI which is the CLI that you use to interact and we talked about building that there and then we've got the make file we're currently using DEP for go dependencies we've just switched the SDK over to go mod and all of the rest of it will be going with go mod in the future this is a go dependency minimal issue probably no one's interested there but yeah so happy to dig into more detail there but first let's go to everyone can go to talk shot talk the talk shop dot name and I've got a server running there that has a main coin chain running and you can use the faucet if you run make install I believe from the root of the application repo you should be able SDK application tutorial repo you should be able to build these binaries just build off of master and the commands that you can run are here if you'd like to use NS CLI config to preset some of these config things like node or chain ID here you can do that as well and I'll just go ahead and pause here for questions I have the repo loaded up I'm happy to dig into any individual piece of the code I kind of didn't really did go into detail on the CLI stuff towards there towards the end because it is a lot of boilerplate but I'm happy to show that and sort of talk through the flow there as well so the CLI uses the rest interface on tinder meant to query all this data the rest server itself is gonna aim to be a full light client eventually and the CLI will have some light client features currently the we're undergoing some changes on the tenorman side on how we're returning those to clients and we've we haven't updated the SDK right now so that's something that within the next couple of months we should have available within the CLI and the rest server any questions here so you need to build the binaries locally and I believe it's make tools which will download depth for you and then it's make get underscore vendor V and dr underscore depths which will download all the dependencies for you so there's a number of go dependencies it's like it's fairly heavy and then if you run make install if you have your go path properly configured you should have NS d and NS CLI in your path and all you really need is NS CLI to do these queries or you know buy a name and if anyone needs some tokens there's a faucet here if you want some more tokens I can find a way for you guys to send me addresses and I have access to a false that is the faucet wallet as well so happy to send those let's just say has anyone bought a name yet all right well this updates every five seconds I'll leave it here while we're while we're chatting details so as far as those core components they're the keepers the handlers and the messages does anyone have any questions about that piece of it I won't stay here so I mentioned the the CLI so this is kind of what the general shape of the CLI is within cosmos config will allows you to set configuration parameters there's a lot of common flags across the different commands this allows you to set default values for those very easily and you would just say key value and then config just writes it back to you so as I mentioned there's the queriers and the handlers in the CLI that is kind of broken down in a query and transaction so you would say in a CLI verb module so TX ya can't type TX and then all of the different modules we have here auth and Bank don't have a prefix because they export very little functionality sign essentially but name service contains the messages that we just defined here so by name and set name and let's say I want to by name so the name let's say Jack ID and the amount I think the coins here are name tokens so I think I'm going to say one name token and then I need to pass it a from need to get that error message fixed and included in a block and there's my name now to set that name to arguments we need a name so Jack dot ID and I'm gonna just put in my my website here from would be what key we're using to sign this message so I have the Jack key here we do want to broadcast that all right and now it's got the value of my name on there is anyone having issues getting the CL eyes built or connecting with the server at all oh journal next winter winter so if I wanted to buy me Reynolds name I would say in SEL ITX name service yeah I need to all right and if you'll notice the address there should switch to the new owner yep there we go awesome cool
Up Next

Build a Cosmos Blockchain with Ignite CLI in 10 Minutes
@ignitehq
6K views•2022-09-19

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

How to Set Up a Cosmos Validator Node: Full Guide with Sentry Architecture
@CosmosProject
10.1K views•2020-07-10

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


































