Build a Blockchain with Less Than 200 Lines of Go

Have you wondered if it is possible to code your own blockchain with less than 200 lines of Go? If you find this question intriguing, then you have come to the right place. What can be more effective in learning and practicing this emerging technology than developing your own blockchain? Let us give it a try!

Before we start, measure your heart rate in terms of beats per minute and then record it. We will use this figure later.

Once you have completed this article, you should be able to:

  • Create your own blockchain.
  • Understand how a hash function maintains the integrity of the blockchain.
  • Create and add a new block.
  • Understand how multiple nodes compete to generate a block.
  • View the entire chain using a browser.
  • Understand other basic features of blockchains.

However, consensus algorithms such as proof-of-work (PoW) and proof-of-stake (PoS) will not be featured in this article. Also, to make the processes of adding a blockchain and a block clearer, we have simplified the network interaction process and left out the “network-wide broadcasting” process and the likes of P2P networks.

Let’s get started!

Image for post
Image for post

Configuring the Development Environment

This quick guide assumes that you already have some experience in Go programming. After installing and configuring the Go development environment, we need to obtain the following dependencies.

Spew enables us to view struct and slice data structures on the console directly:

The Gorilla/mux package is very popular. We use it to implement the web handler.

Godotenv helps us read the .env configuration file from the root directory of the project so that we do not need to add HTTP port configurations to the code.

Next, create a main.go file. Most of our subsequent work will depend on this file. So let’s start programming!

Creating the Chain

Importing Dependencies

Import all dependency packages by using the following statements:

Data Model

Next, define a structure. Struct indicates the data model of all the blocks that form the blockchain:

  • Index indicates the position of the block in the entire chain.
  • Timestamp is the timestamp when the block is created.
  • Hash is a hash value generated by the block by using SHA256.
  • PrevHash indicates the hash value generated by the previous block using SHA256.
  • BPM indicates the number of heart beats per minute, that is, the heart rate. Remember what we mentioned earlier?

Then, let us define another structure to represent the entire chain. The simplest presentation is the slice of a block:

We use the hash algorithm (SHA256) to determine and maintain the correct sequence of blocks in a chain, which ensures that the PrevHash value of each block is equal to the Hash value of its previous block. In this way, the chain is constructed in the correct block sequence.

Image for post
Image for post

Hash and Block Generation

Why do we need hash? There are two main reasons:

  • Hash uniquely identifies the data without sacrificing the space. You can obtain a hash by calculating the data of the entire block. In our examples, we have calculated the data of the entire block using SHA256 to obtain an almost-unique, fixed-size string.
  • Hash maintains the integrity of the chain. By storing the hash value of the previous block, we can ensure that each block is in a correct sequence in the chain. Any tampering with the data changes the hash value and breaks the chain. For example, in our healthcare field, if a malicious third-party adjusts the price of “life insurance” by changing the BPM of one or more blocks to a value that indicates an unhealthy condition, the entire chain became untrusted.

Let’s continue to write a function to calculate the hash value of the given data using SHA256:

This calculateHash function accepts one block and calculates a hash value using SHA256 based on Index, Timestamp, BPM, and PrevHash values of the block. Next, let’s write a block generation function:

You can obtain the Index by incrementing the given Index value of the previous block and the Timestamp by using the time.Now() function. Also, you can calculate Hash by using the calculateHash function. PrevHash is the given Hash value of the previous block.

Block Validation

After generating a block, we need a function to help us determine whether someone has tampered with the block. View the Index value to check whether the block is correctly incremented. Check whether the PrevHash value is the same as the Hash value of the previous block, and then run calculateHash to check whether the Hash value of the current block is correct. We can write a validation function as follows:

When validating the block, we encounter a problem: When two nodes generate blocks and add the blocks to their respective chains, which one should we use? We would like to leave these details to next article. But here, let’s remember one principle: Always select the longest chain.

Image for post
Image for post

Generally, the longest chain indicates that its data (status) is the latest. Therefore, we need a function to help us replace the local expired chain with the latest chain:

So far, we have used all the important functions. Next, we need to view our chain, including the data and status, in a visual and convenient way. The best way to view the chain is on a web page on a browser.

Web Service

We are assuming that you are very familiar with conventional web services and development, so this part should be easy enough to understand.

By using the Gorilla/mux package, we can write a function to initialize our web service:

You can obtain the port number using the .env configuration file. After adding some basic configuration parameters, the web service can be listened to and served.

Next, let’s define different endpoints and corresponding handlers. For example, a GET request with a slash (“/”) enables us to view the entire chain, and a POST request with a slash (“/”) enables us to create a block.

Define the handler for a GET request:

For simplicity, we have enabled the web server to return the entire chain in JSON format. You can view the chain by visiting localhost:8080 or 127.0.0.1:8080 in the browser (8080 is the port number ADDR defined in .env by you).

The handler for the POST request is somewhat complicated to define. First, let’s define the payload for the POST request:

Let’s see how we can implement the handler:

You can use the preceding payload in our POST request; for example:

Do you still remember the generateBlock function we wrote? It accepts one "previous block" parameter and one BPM value. After the POST handler accepts the request, you can obtain the BPM value from the request body. Then, using the block generation function and the block validation function, you can generate a new block.

Besides, you can also:

  • Use the spew.Dump function to print struct and slice data to the console in an elegant and easy-to-read form, which simplifies debugging.
  • Use the chrome plug-in POSTMAN to test the POST request, which is more visual and convenient than curling.

After processing the POST request, we need to return a response to the client, regardless of whether we have created the block successfully:

Assembling All the Parts

We are almost done! Next, let’s “assemble” the functions for the blockchain and functions for the web service:

The genesisBlock is the most critical part of the main function. We can use it to initialize the blockchain because the PrevHash value of the first block is empty.

That’s it!

Let’s run it:

In the UE, we can view the log about the web server initialization and print the information about the genesis block.

Image for post
Image for post

Then, let’s open the browser and visit localhost:8080. The information about the current entire blockchain gets displayed on the web page (there is only one genesis block at present).

Image for post
Image for post

Then, let us use POSTMAN to send some POST requests:

Image for post
Image for post

Refresh the preceding web page. You will find more blocks getting displayed in the current chain. These are the same blocks that we just generated. You can view that the block sequence and hash values are all correct.

Image for post
Image for post

Conclusion

We have just completed creating our blockchain with less than 200 lines of Go. Although it is simple, it delivers the basic capabilities of generating blocks, calculating hash values, and validating blocks. Later, you can continue to learn other important things about the blockchain, for example, consensus algorithms such as PoW and PoS, smart contract, Dapp, and side chain.

The current implementation does not include any P2P network-related content. You can obtain the source code from GitHub from this link.

Find similar articles and learn more about Alibaba Cloud’s products and solutions at www.alibabacloud.com/blog.

Reference:

https://www.alibabacloud.com/blog/build-a-blockchain-with-less-than-200-lines-of-go_593852?spm=a2c41.11827719.0.0

Written by

Follow me to keep abreast with the latest technology news, industry insights, and developer trends.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store