Creating Custom Messages for Cosmos SDK Blockchains

In this tutorial, we will create a custom message type. If you think about 1st Generation Blockchains, they were primarily built to send numbers between addresses in the form of cryptocurrency. However, Cosmos SDK chains allow you to send all sorts of data types—anything that can be encoded into byte slices.
The message type we will create is designed to register a Jedi at the Jedi Academy. (Note: This is for educational purposes only, so please don't sue us, Lucasfilm!)
To enroll a new Jedi into the academy and ensure this information is paramount and immutable, we first need to create a message type. Later on, we will learn how to edit the source code to actually update the database with this information using CRUD functionality, but for now, we will focus on creating the message.
Note: These custom messages generate a proto file that serves as a blueprint.
You should have Ignite and dependencies installed. If not, you can follow the tutorial here: Link
You can install Ignite using this command (version 0.26.1 is recommended):
curl https://get.ignite.com/cli@v0.26.1 | bash
sudo mv ignite /usr/local/bin
Next, scaffold your chain:
ignite chain scaffold JediRegistry --address-prefix jedi
Change into your project directory:
cd JediRegistry
Step 1: Create a Custom Message
What are our requirements if we want to register a new Jedi at our Academy? For starters, let's use three variables: name
, forcePower
, and homePlanet
, where name
and homePlanet
are strings, and forcePower
is an integer.
ignite scaffold message registerJedi name homePlanet forcePower:uint
Take note of all the files created with this command. The key one to note here is the tx.proto
file.
Open the proto file:
nano proto/jediregistry/jediregistry/v1/tx.proto
You can see the custom message type is similar to a struct or object variable. Note that every variable is of type string
except for forcePower
, which is of type uint
.
Step 2: Serve the Chain
Run the following command to start your chain:
ignite chain serve
Once complete, you will see your chain's binary location, addresses with the address prefix jedi
, faucet location, RPC, and REST API endpoints, all running.
Step 3: Send a Transaction
Now with our chain running, let's open a new terminal window and send a transaction from bob
. Note: bob
is a default listed in the config.yml
. We could have changed this to yoda
. In fact, let's do that. We can stop the chain with q
.
nano config.yml
Then replace all instances of bob
with yoda
.
Save the file and close it with Ctrl+X
.
Now that we have updated our config.yml
file, we can use the --reset-once
flag to reset our blockchain. Note: This wipes our chain database and starts from genesis all over again.
ignite chain serve --reset-once
Now, from a new window, we can use our chain's binary to see all of the available commands. You can view more details with the --help
flag.
Note: By using the --help
flag, we are able to see all of the parameters we need to input in order to send the custom message as a transaction.
Now we (Yoda) can register Luke Skywalker
to our Jedi Academy with the following command:
JediRegistryd tx jediregistry register-jedi "Luke Skywalker" "Tatooine" 777 --from yoda
Note: The number 777 represents Luke's force power.
Once we press enter, we will get a screen for transaction confirmation. It is good practice to verify the contents are correct before sending.
Once we enter y
and confirm everything is correct, we will receive a tx hash
, which we can use to look up our transaction in a block explorer.
Now we have succeeded in sending a transaction, but this data can be looked up by tx type, though it is not actually stored in the database. For that, we need to have our message type include CRUD functionality, which we can do with lists, and we will cover this in the next tutorial.