In the first two articles [1][2] of this series, we showed you how to implement a simple blockchain with refined Go code. Including generating blocks, validating block data, broadcasting communications, etc., this article focuses on how to implement PoW algorithms.

Everyone is amazed by the continued craze for Bitcoin, Ethereum, and other cryptocurrencies, especially those new to the space who keep hearing about “mining” their Gpus to amass tens of thousands or even millions of cryptocurrencies. So what exactly is “mining”? How does it work? For programmers, there is no better way to learn than to practice the “mining” algorithm. In this article, let’s go through each problem one by one and finally write our own “mining” algorithm. This algorithm is called proof-of-work [3] and is the foundation of bitcoin and Ethereum, two of the most popular cryptocurrencies.

What is “mining”?

Cryptocurrencies are valuable because they are scarce. In the case of Bitcoin today, if anyone could “make” it at any time, it would be worthless as an electronic currency. Bitcoins use algorithms to control the rate at which they are produced and reach their maximum number in about 122 years. This slow, steady and gradual approach to output over time effectively avoids inflation. Bitcoin is produced by giving prizes to “winning miners,” who compete with each other for their bitcoins. This process is called “mining” because it is similar to the “Gold Rush” [4] when each Gold miner toiled and eventually (hopefully) found a bit of Gold.

How does “mining” work?

If you Google this question, you’ll get a ton of results. Simply put, “mining” is the process of “solving a mathematical problem.” Let’s start by learning a little bit about cryptography and hashing algorithms.

A brief introduction to cryptography

One-way encryption takes human-readable text (plaintext) as input, such as the string “Hello world”, and a mathematical function to produce an illegible output (ciphertext). Such functions or algorithms vary in nature and complexity. The more complex the algorithm, the more difficult it is to reverse engineer. Take the popular SHA-256 algorithm as an example. This site [5] allows you to compute the output of any given input, namely the SHA-256 hash. For example, let’s type “Hello world” and see what we get:

By constantly trying to compute the hash of “Hello World”. You’ll find that the answer is exactly the same every time. This process is called idempotency. One of the most basic properties of encryption algorithms is that it is very difficult to reverse engineer the input, but very easy to verify the output. As in the example above, you can easily verify that the SHA-256 hash of a given input “Hello world” is correct, but it’s hard to tell from a given hash what its input is. This is why this type of algorithm is called one-way encryption. Bitcoin uses Double SHA-256, which takes the hash of SHA-256 as input and recomputes the SHA-256 hash. For simplicity, we will use SHA-256 only once.

dig

Back in the case of cryptocurrencies, bitcoin is “mined” by letting participants use such cryptographic algorithms to solve hashes that meet certain conditions. Specifically, Bitcoin requires participants to use the Double SHA-256 algorithm to compute a hash value with a leading zero of more than a few digits. The first participant to solve is the “winning miner.” For example, let’s find the sha-256 hash of the string “886” :

As you can see, is a 3-digit hash with a leading 0 (the first three digits are 0). Recall the feature of “one-way encryption” we talked about earlier: anyone can easily verify that “886” produces a three-bit “leading 0″ hash. But to find an input that produces three leading zeros (” 886 “in this case), we did a lot of tedious computing: hashing a large set of numbers and letters one at a time and deciding whether the above conditions were met. If I’m the first person to find “886,” then everyone else can verify that I’ve done a lot of tedious work. In Bitcoin and Ethereum this process is called a proof of work algorithm. “What if I get really lucky and find a valid [input] value on my first try?” — This is very unlikely. You can try typing random letters and numbers. The actual algorithms and constraints in Bitcoin are more complex and certainly more difficult than the above requirements (requiring more leading zeros). It can also adjust the difficulty dynamically, with the goal of making sure bitcoin is produced every 10 minutes, regardless of whether there are many people involved in the “mining”.

Almost ready to go

With enough background, we then coded the proof-of-work algorithm in Go.

I encourage you to read the previous article series implementing your own Blockchain with 200 lines of Go code, as the working proof algorithm section below will cover the previous code.

Proof-of-work

A “proof of work” process is required before a new block is created and added to the chain. Let’s start by writing a simple function to check that a given hash value meets the requirements.

  • Hash values must have a “leading 0” for positioning

  • The number of “leading zeros” is determined by difficulty

  • Difficulty can be adjusted dynamically to make proof-of-work harder to solve

Here is the isHashValid function:

func isHashValid(hash string, difficulty int) bool {        prefix := strings.Repeat("0", difficulty)        return strings.HasPrefix(hash, prefix)}Copy the code

The Strings package of the Go language provides convenient Repeat and HasPrefix functions. We specify the prefix variable, which represents a “leading 0,” then check if the hash value has a “leading 0” that satisfies the condition, and return True or False. We modify the generateBlock function that generated the block earlier:

func generateBlock(oldBlock Block, BPM int) Block { var newBlock Block t := time.Now() newBlock.Index = oldBlock.Index + 1 newBlock.Timestamp = t.String() newBlock.BPM = BPM newBlock.PrevHash = oldBlock.Hash newBlock.Difficulty = difficulty for i := 0; ; i++ { hex := fmt.Sprintf("%x", i) newBlock.Nonce = hex if ! isHashValid(calculateHash(newBlock), newBlock.Difficulty) { fmt.Println(calculateHash(newBlock), " do more work!" ) time.Sleep(time.Second) continue } else { fmt.Println(calculateHash(newBlock), " work done!" ) newBlock.Hash = calculateHash(newBlock) break } } return newBlock}Copy the code

Create a newBlock, newBlock, where the PrevHash contains the hash of the previous block, Timestamp is the Timestamp, BPM is the heart rate data, and Difficulty is the aforementioned Difficulty, whose value determines the number of “leading zeros”. The for loop here is important:

  • Get the hexadecimal representation of I, set Nonce to that value, and pass in the calculateHash to compute the hash value. Then use the isHashValid function above to determine whether the difficulty requirements are met. If not, repeat the attempt.

  • This process continues until the desired Nonce value is evaluated, and the new block is added to the chain via the handleWriteBlock function.

Space is limited, but we have posted the full code on Github, which is available here [6].

Run and see

Start procedure:

Go run main.go Go to http://localhost:8080 in your browser

A POST request containing heart rate data is then sent via Postman.

We then look at the command line window and continuously calculate the hash value, and if the difficulty requirement is not met, continue to retry until we find the hash value and Nonce that meet the requirement

You can see that the last hash meets our difficulty requirement (1 bit “leading 0”). Let’s refresh the browser again:

You can see that the second block is successfully created and added to the chain, where Nonce is the value calculated by proof-of-work that meets the difficulty requirement.

The next step

Congratulations to you, the above content is very valuable. Despite the very low level of difficulty used in our example, proof of work algorithms are essentially an important part of blockchains such as Bitcoin and Ethereum. For the next step in the blockchain, we recommend learning how to access large files through IPFS [7] and connect to the blockchain. In addition, proof-of-stake algorithm [8] is getting more and more attention and favor compared with proof-of-work. You can also learn how to change the PoW algorithm in this paper into PoS algorithm.

Refer to the link

[1] Write your own blockchain with only 200 lines of Go code!

[2] 200 lines of Go code implementing its own blockchain — block generation and network communication

[3] https://en.bitcoin.it/wiki/Proof_of_work

[4] https://zh.wikipedia.org/zh-cn/%E6%B7%98%E9%87%91%E6%BD%AE

[5] http://www.xorbin.com/tools/sha256-hash-calculator

[6] https://github.com/mycoralhealth/blockchain-tutorial/blob/master/proof-work/main.go

[7] https://github.com/ipfs/ipfs

[8] https://en.bitcoin.it/wiki/Proof_of_Stake


Related reading:

Write your own blockchain with just 200 lines of Go code!

200 lines of Go code implements its own blockchain — block generation and network communication

A beginner’s guide to blockchain and Bitcoin

Special recommendation:

Bitcoin, Ethereum, ERC20, PoW, PoS, Smart Contracts, Lightning Network…

Want to learn more and discuss these topics? High availability architecture has created a blockchain learning group in knowledge Planet (small tight circle) to learn blockchain including cutting-edge technology of digital currency. Please click the link to join us.

Blockchain learning group

Translated by Wei Jia, Coral Health Please indicate the source, original technology and architecture practice article, welcome to submit through the public menu “contact us”.

Highly available architecture

Change the way the Internet is built

Long press the QR code to follow the “HA Architecture” public account