Creating Custom Messages for Cosmos SDK Blockchains

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.