Skip to main content
Version: v28

"Build a blog" in 5 minutes

In this tutorial, we will create a blockchain with a module that allows us to write and read data from the blockchain. This module will implement the ability to create and read blog posts, similar to a blogging application. The end user will be able to submit new blog posts and view a list of existing posts on the blockchain. This tutorial will guide you through the process of creating and using this module to interact with the blockchain.

The goal of this tutorial is to provide step-by-step instructions for creating a feedback loop that allows you to submit data to the blockchain and read that data back from the blockchain. By the end of this tutorial, you will have implemented a complete feedback loop and will be able to use it to interact with the blockchain.

First, create a new blog blockchain with Ignite CLI:

ignite scaffold chain blog

In order to create a blog application that uses a blockchain, we need to define the requirements for our application. We want the application to store objects of type Post on the blockchain. These objects should have two properties: a title and a body.

In addition to storing posts on the blockchain, we also want to provide users with the ability to perform CRUD (create, read, update, and delete) operations on these posts. This will allow users to create new posts, read existing posts, update the contents of existing posts, and delete posts that are no longer needed.

One of the features of the Ignite CLI is the ability to generate code that implements basic CRUD functionality. This is accomplished through the use of scaffolding commands, which can be used to quickly generate the necessary code for creating, reading, updating, and deleting data in your application.

The Ignite CLI is capable of generating code for data that is stored in different types of data structures. This includes lists, which are collections of data indexed by an incrementing integer, maps, which are collections indexed by a custom key, and singles, which are single instances of data. By using these different data structures, you can customize your application to fit your specific needs. For example, if you are building a blog application, you may want to use a list to store all posts, with each post indexed by an integer. Alternatively, you could use a map to index each post by its unique title, or a single to store a single post. The choice of data structure will depend on the specific requirements of your application.

In addition to the data structure you choose, the Ignite CLI also requires you to provide the name of the type of data that it will generate code for, as well as fields that describe the type of data. For example, if you are creating a blog application, you may want to create a type called "Post" that has fields for the "title" and "body" of the post. The Ignite CLI will use this information to generate the necessary code for creating, reading, updating, and deleting data of this type in your application.

Switch to the blog directory and run the ignite scaffold list command:

cd blog
ignite scaffold list post title body

Now that you have used the Ignite CLI to generate code for your application, let's review what it has created. The Ignite CLI will have generated code for the data structure and data type that you specified, as well as code for the basic CRUD operations that are needed to manipulate this data. This code will provide a solid foundation for your application, and you can customize it further to fit your specific needs. By reviewing the code generated by the ignite CLI, you can ensure that it meets your requirements and get a better understanding of how to build your application using this tool.

The Ignite CLI has generated several files and modifications in the proto/blog/blog directory. These include:

  • post.proto: This is a protocol buffer file that defines the Post type, with fields for the title, body, id, and creator.
  • tx.proto: This file has been modified to include three RPCs (remote procedure calls): CreatePost, UpdatePost, and DeletePost. Each of these RPCs corresponds to a Cosmos SDK message that can be used to perform the corresponding CRUD operation on a post.
  • query.proto: This file has been modified to include two queries: Post and PostAll. The Post query can be used to retrieve a single post by its ID, while the PostAll query can be used to retrieve a paginated list of posts.
  • genesis.proto: This file has been modified to include posts in the genesis state of the module, which defines the initial state of the blockchain when it is first started.

The Ignite CLI has also generated several new files in the x/blog/keeper directory that implement the CRUD-specific logic for your application. These include:

  • msg_server_post.go: This file implements keeper methods for the CreatePost, UpdatePost, and DeletePost messages. These methods are called when a corresponding message is processed by the module, and they handle the specific logic for each of the CRUD operations.
  • query_post.go: This file implements the Post and PostAll queries, which are used to retrieve individual posts by ID or a paginated list of posts, respectively.
  • post.go: This file implements the underlying functions that the keeper methods depend on. These functions include appending (adding) posts to the store, getting individual posts, getting the post count, and other operations that are needed to manage the posts in the application.

Overall, these files provide the necessary implementation for the CRUD functionality of your blog application. They handle the specific logic for each of the CRUD operations, as well as the underlying functions that these operations depend on.

Files were created and modified in the x/blog/types directory.

  • messages_post.go: This new file contains Cosmos SDK message constructors and associated methods such as Route(), Type(), GetSigners(), GetSignBytes(), and ValidateBasic().
  • keys.go: This file was modified to include key prefixes for storing blog posts. By using key prefixes, we can ensure that the data for our blog posts is kept separate from other types of data in the database, and that it can be easily accessed when needed.
  • genesis.go: This file was modified to define the initial (genesis) state of the blog module, as well as the Validate() function for validating this initial state. This is an important step in setting up our blockchain, as it defines the initial data and ensures that it is valid according to the rules of our application.
  • codec.go: This file was modified to register our message types with the encoder, allowing them to be properly serialized and deserialized when transmitted over the network.

Additionally, *.pb.go files were generated from *.proto files, and they contain type definitions for messages, RPCs, and queries used by our application. These files are automatically generated from the *.proto files using the Protocol Buffers (protobuf) tool, which allows us to define the structure of our data in a language-agnostic way.

The Ignite CLI has added functionality to the x/blog/client/cli directory by creating and modifying several files.

  • tx_post.go: This file was created to implement CLI commands for broadcasting transactions containing messages for the blog module. These commands allow users to easily send messages to the blockchain using the Ignite CLI.
  • query_post.go: This file was created to implement CLI commands for querying the blog module. These commands allow users to retrieve information from the blockchain, such as a list of blog posts.
  • tx.go: This file was modified to add the CLI commands for broadcasting transactions to the chain's binary.
  • query.go: This file was also modified to add the CLI commands for querying the chain to the chain's binary.

As you can see, the ignite scaffold list command has generated and modified a number of source code files. These files define the types of messages, logic that gets executed when a message is processed, and the wiring that connects everything together. This includes the logic for creating, updating, and deleting blog posts, as well as the queries needed to retrieve this information.

To see the generated code in action, we will need to start the blockchain. We can do this by using the ignite chain serve command, which will build, initialize, and start the blockchain for us:

ignite chain serve

Once the blockchain is running, we can use the binary to interact with it and see how the code handles creating, updating, and deleting blog posts. We can also see how it processes and responds to queries. This will give us a better understanding of how our application works and allow us to test its functionality.

While ignite chain serve is running in one terminal window, open another terminal and use the chain's binary to create a new blog post on the blockchain:

blogd tx blog create-post 'Hello, World!' 'This is a blog post' --from alice --chain-id blog

When using the --from flag to specify the account that will be used to sign a transaction, it's important to ensure that the specified account is available for use. In a development environment, you can see a list of available accounts in the output of the ignite chain serve command, or in the config.yml file.

It's also worth noting that the --from flag is required when broadcasting transactions. This flag specifies the account that will be used to sign the transaction, which is a crucial step in the transaction process. Without a valid signature, the transaction will not be accepted by the blockchain. Therefore, it's important to ensure that the account specified with the --from flag is available.

After the transaction has been broadcasted successfully, you can query the blockchain for the list of blog posts. To do this, you can use the blogd q blog list-post command, which will return a paginated list of all the blog posts that have been added to the blockchain.

blogd q blog list-post

Post:
- body: This is a blog post
creator: cosmos1xz770h6g55rrj8vc9ll9krv6mr964tzhqmsu2v
id: "0"
title: Hello, World!
pagination:
next_key: null
total: "0"

By querying the blockchain, you can verify that your transaction was processed successfully and that the blog post has been added to the chain. Additionally, you can use other query commands to retrieve information about other data on the blockchain, such as accounts, balances, and governance proposals.

Let's modify the blog post that we just created by changing the body content. To do this, we can use the blogd tx blog update-post command, which allows us to update an existing blog post on the blockchain. When running this command, we will need to specify the ID of the blog post that we want to modify, as well as the new body content that we want to use. After running this command, the transaction will be broadcasted to the blockchain and the blog post will be updated with the new body content.

blogd tx blog update-post 0 'Hello, World!' 'This is a blog post from Alice' --from alice --chain-id blog

Now that we have updated the blog post with new content, let's query the blockchain again to see the changes. To do this, we can use the blogd q blog list-post command, which will return a list of all the blog posts on the blockchain. By running this command again, we can see the updated blog post in the list, and we can verify that the changes we made have been successfully applied to the blockchain.

blogd q blog list-post

Post:
- body: This is a blog post from Alice
creator: cosmos1xz770h6g55rrj8vc9ll9krv6mr964tzhqmsu2v
id: "0"
title: Hello, World!
pagination:
next_key: null
total: "0"

Let's try to delete one of the blog posts using Bob's account. However, since the blog post was created using Alice's account, we can expect the blockchain to check whether the user is authorized to delete the post. In this case, since Bob is not the author of the post, his transaction should be rejected by the blockchain.

To delete a blog post, we can use the blogd tx blog delete-post command, which allows us to delete an existing blog post on the blockchain. When running this command, we will need to specify the ID of the blog post that we want to delete, as well as the account that we want to use for signing the transaction. In this case, we will use Bob's account to sign the transaction.

After running this command, the transaction will be broadcasted to the blockchain. However, since Bob is not the author of the post, the blockchain should reject his transaction and the blog post will not be deleted. This is an example of how the blockchain can enforce rules and permissions, and it shows that only authorized users are able to make changes to the blockchain.

blogd tx blog delete-post 0 --from bob --chain-id blog

raw_log: 'failed to execute message; message index: 0: incorrect owner: unauthorized'

Now, let's try to delete the blog post again, but this time using Alice's account. Since Alice is the author of the blog post, she should be authorized to delete it.

blogd tx blog delete-post 0 --from alice --chain-id blog

To check whether the blog post has been successfully deleted by Alice, we can query the blockchain for a list of posts again.

blogd q blog list-post

Post: []
pagination:
next_key: null
total: "0"

Congratulations on successfully completing the tutorial on building a blog with Ignite CLI! By following the instructions, you have learned how to create a new blockchain, generate code for a "post" type with CRUD functionality, start a local blockchain, and test out the functionality of your blog.

Now that you have a working example of a simple application, you can experiment with the code generated by Ignite and see how changes affect the behavior of the application. This is a valuable skill to have, as it will allow you to customize your application to fit your specific needs and improve the functionality of your application. You can try making changes to the data structure or data type, or add additional fields or functionality to the code.

In the following tutorials, we will take a closer look at the code that Ignite generates in order to better understand how to build blockchains. By writing some of the code ourselves, we can gain a deeper understanding of how Ignite works and how it can be used to create applications on a blockchain. This will help us learn more about the capabilities of Ignite CLI and how it can be used to build robust and powerful applications. Keep an eye out for these tutorials and get ready to dive deeper into the world of blockchains with Ignite!