---
description: Learn module basics by writing and reading blog posts to your chain.
title: Express tutorial
---

# "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
```

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
```

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

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
```

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!