(electronic chiming) – [Narrator] Let’s create a simple blockchain application using the JS library. Open up a terminal and create a new directory for the project. Then install the LotionJS library by running npm install lotion. Now let’s create a new file called app.js.
First, let’s import the Lotion library with a require statement. Then we’ll create a new Lotion app and pass in an object that contains one field called initialState, which itself is an object. For now, we’ll just have one field in the initialState, called count. This field is just going to track the number of transactions that have occurred so far. A Lotion application is usually a single function that takes the state and transaction as input and then computes the next state of the blockchain based on the transaction.
Now let’s write our state transition function. Let’s create a function called stateFunc and it takes two parameters: the state and the transaction.
Into the function, we can retrieve the current state of our app from the state variable and get the count value. We can also get fields from the transaction object, as well. For our simple application, we’ll only increment the count state if the nonce field of this transaction is equal to the current count of the app.
We’ll see where the nonce field of the transaction comes from in a second. Now we’re done with our state transition function. We need to tell the app to use this function. We can do this by calling the app.use and passing the name of our stateFunc function.
You can have more than one transaction handler functions, but we’ll just have one in our simple application for now, which is stateFunc. If you have more than one, the order in which the transaction handler functions are called is in the order you invoked app.use.
So the first one will be the first function to get called. One thing to know about the transaction handler is that it must be deterministic.
This means that given the same input, state, and transaction, the mutated state should always be the same. Otherwise, consensus could not be reached among the Tendermint nodes. Finally, to finish our app, we’ll call the app.listen and pass in a port number, which we’ll use 3000 for this example. This will start a local HTTP server on port 3000, which you can use to query the state of the blockchain, as well as create new transactions.
Let’s start the app in the terminal by typing node app.js. Now, open up a new terminal window and we can query the state of the blockchain by sending GET requests to localhost:3000/state.
You can do this by using the curl command or simply type this URL into a browser window. Either way, you should see a JSON data structure that contains the count field and it should equal to zero.
Now, to send a transaction to the blockchain, we need to send a POST request and we can do this using the curl command again, but this time we’ll use the -d option to specify the data we want to send.
In this case, the transaction data structure is a JSON object that contains one field called nonce. Remember, in our transaction handler function, stateFunc, we access the nonce field in our transaction input parameter, which is this field we specified here. Now let’s take at the return value from the POST request for this new transaction. It’s a JSON object that contains a result field which contains the height of the current blockchain and the hash of the latest block.
We’ll learn more about the check_tx and the deliver_tx data structure in a later lesson, but for now, all you need to know is it’s related to the underlying consensus and networking layer, which is provided for you by Tendermint Core.
If we query the state of our blockchain again, you’ll notice that the count value has increased to one. This is because we sent a transaction to the blockchain with our POST request and our state transition function took the previous state and the transaction and updated the state. You might be asking yourself, “Where are the blockchain-related data? And how is this a blockchain if it’s only running locally on my computer?
Shouldn’t there be many different nodes in the system?” The LotionJS library stores all the blocks and related data in your home directory under a hidden folder called .lotion. Inside this directory, we see a networks folder, for each of your Lotion apps will be under its own network directory. The network ID, which is the name of the folder, is automatically generated for you by LotionJS.
So in our example, we have a network ID that starts with f6. Inside this folder, we see just a few files and subfolders. The data directory contains various blockchain data such as blocks, and transactions, and memory pools. The two other important files we want to look at is genesis.json and config.
toml file. If we open up genesis.json file, we can see some of the information about our blockchain. For example, we see our blockchain as an ID, which says DmPY4h. We see the genesis time of our blockchain and the hash of our application as well.
In addition, we have a list of validators for our blockchain. Right now we only have one, which is the node we started when we ran our app.js file locally on this computer. LotionJS automatically creates a key pair for you. If you open priv_validator.
json file, you’ll be able to see the public and private key values. Next, if we open up the config.toml file, we can see some information of our configuration for our blockchain. The proxy_app shows the TCP socket URL that our app uses internally to communicate with Tendermint Core.
The Tendermint Core runs in a separate process as our app and they communicate over sockets.
It is also possible to run both Tendermint Core and an application blockchain interface app in the same process, but we’ll learn more about these details in a later lesson. The moniker field, which allows us to have a human-readable name for our local node, if we desire. For example, I can set it to Jack’s Computer, in order for other people to identify my computer more easily. The fast_sync option allows those that are very far behind to the tip of the current blockchain to catch up very quickly by downloading blocks in parallel and verifying them.
The db_backend allows us to choose what database to use.
The default is leveldb. The log_level specifies the verbosity of what you want to see in the output log. The RPC, or Remote Procedure Call, server, running on port 46657, is used by Tendermint Core and light clients can communicate directly with Tendermint Core through this RPC server. We’ll learn more about this in a future lesson, as well. The last option under p2p is a port we specify for other peers to connect to from our local node.
The default port is running on 46656 on TCP and the seeds field allows us to specify a comma-separated list of other peers we can connect to, if they are known. Before we finish this lesson, let’s talk about the architecture of the application we built.
When we ran our app.js file with LotionJS, underneath the hood we have a few different processes running. One is the Tendermint Core, which is responsible for consensus and networking.
One is our application, which communicates with the Tendermint Core through the Application BlockChain Interface on port 46658. The other process is the HTTP web server running on port 3000. How all this is connected together, is that when the web server receives requests, either GET or POST requests from users, it communicates with the Tendermint Core, through the RPC server, which is running on port 46657.
Then, the Tendermint Core communicates with our application through the Application BlockChain Interface on port 46658. Finally, if we had other peers or nodes in the system, they can connect to our node by port 46656, which is also running inside the Tendermint Core process.
If you want to see more videos about Cosmos, such as building your own cryptocurrency, inter-blockchain communication, and many more, go to blockgeeks.com for our full Cosmos course. Thanks for watching..