blockchain

How to Build a Blockchain App with Cosmos SDK | Jack Zampolin

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