In the first two articles of this series, we showed you how to implement a simple blockchain with refined Java code. including building blocks, validating block data, broadcast communications, and so on, this article focuses on how to implement the POW algorithm.
Everyone exclaimed about the continuing frenzy of Bitcoin, Ethereum, and other cryptocurrency, especially for newcomers to the field, who are constantly hearing Dick and Harry collect tens of thousands of or even millions of of cryptocurrency through the GPU "mining". So what is "mining"? How does it work? I believe that for programmers, there is no better way to learn than to practice the "Dig Mine" algorithm.
In this article, let's go through each and every one of these questions, and finally write our own "mining" algorithm. This algorithm, known as the Working Proof algorithm (proof-of-work), is the basis for the two most popular cryptocurrency currencies, Bitcoin and Ethereum.
What is "Digging mine"?
Crypto-electronic money is valuable because it is scarce. In the case of Bitcoin now, if anyone can "make" Bitcoins at any time, it will become worthless as an electronic currency. Bitcoin uses algorithms to control the rate of output and to reach its maximum within approximately 122 years. This slow, stable and progressive output over time effectively avoids inflation.
The output of Bitcoin is achieved by giving the "winning miner" reward, which competes between miners in order to earn Bitcoin rewards. This process is called "digging" because it resembles "gold Rush" when each gold miner finds a little gold by toiling and eventually (hoping).
how does "mining" work?
If Google had this problem, you would get a lot of results. Simply put, "digging" is the process of "solving a mathematical problem". Let's start with some knowledge of 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 generates illegible output (ciphertext) through a mathematical function. The nature and complexity of such functions or algorithms vary. The more complex the algorithm, the more difficult the reverse engineering is.
Take the popular SHA-256 algorithm as an example. This site [5] allows you to calculate the output of any given input, which is the SHA-256 hash value. For example, let's enter "Hello World" to see what we Got:
By constantly trying to calculate the hash value of "Hello world". You'll find that the results are exactly the same every time. This process is called idempotent.
One of the most basic features of cryptographic algorithms is that it is very difficult to solve the input by reverse engineering, but it is very easy to validate the output. For example, you can easily verify that the SHA-256 hash of the given input "Hello world" is correct, but it is difficult to determine what its input is by the given hash value. This is why this type of algorithm is called one-way encryption.
Bitcoin uses Double SHA-256, which computes the SHA-256 hash value as input SHA-256 the hash value evaluated. To simplify, we only use SHA-256 once.
Digging Mine
Back in cryptocurrency, Bitcoin is the "digging" process by allowing participants to use such cryptographic algorithms to solve a hash value that matches a particular condition. Specifically, Bitcoin requires participants to calculate a hash of "leading 0" over several bits by using the double SHA-256 algorithm, and the first one to solve is the "winning miner".
For example, we ask for the SHA-256 hash value of the string "886":
As you can see, there is a "leading 0" hash value of 3 bits (the first three bits are 0).
Recall the "one-way Encryption" feature we mentioned earlier:
It is easy for anyone to verify that "886" produces a 3-bit "leading 0" hash value. But in order to find such a 3-bit "lead 0" input (the "886" here), we do a lot of tedious calculations: from a large set of numbers and letters to calculate their hash value and determine whether the above conditions are met. If I was the first person to find "886", the other person would be able to judge me by proving that I had done such a lot of tedious work. The process in Bitcoin and Ethereum is called a proof-of-work algorithm.
"If I was lucky, the first time I tried, I found a qualifying (input) value?" "--this is very unlikely, you can try to enter some letters and numbers at random.
The actual algorithms and constraints in Bitcoin are more complex and, of course, more difficult (requiring more bits of "leading 0") than is required. It can also dynamically adjust the difficulty, with the goal of ensuring that bitcoins are produced every 10 minutes, regardless of the number of people involved in mining.
Almost ready to go.
Having learned enough background knowledge, we then use the Java language to encode the work proof (proof-of-work) algorithm in practice. It is recommended that you read the previous series, as the following work proves that the algorithm section involves the previous code.
Proof-of-work
You need to complete the "proof of effort" process before creating a new block and adding it to the chain. Let's start by writing a simple function to check if the given hash value satisfies the requirement.
The hash value must have a "leading 0" for positioning
The number of digits in "leading 0" is determined by the difficulty ( difficulty
)
Can dynamically adjust the difficulty ( difficulty
) to ensure that the proof-of-work more difficult to solve
Here's isHashValid
the function:
/*** Verify the legitimacy of the hash * *@paramHash *@paramDifficulty *@return */ Public Static BooleanIshashvalid (String Hash,intdifficulty) {String prefix= Repeat ("0", difficulty); returnhash.startswith (prefix); }Private Staticstring repeat (String str,intrepeat) { FinalStringBuilder buf =NewStringBuilder (); for(inti = 0; I < repeat; i++) {buf.append (str); } returnbuf.tostring (); }
We define the prefix
variable, which represents "leading 0", then checks whether the hash value has a "leading 0" that satisfies the condition, and then returns True
or False
.
We modify the function that generated the block before generateBlock
:
Public StaticBlock Generateblock (Block Oldblock,intVAC) {Block Newblock=NewBlock (); Newblock.setindex (Oldblock.getindex ()+ 1); Newblock.settimestamp (NewSimpleDateFormat ("Yyyy-mm-dd HH:mm:ss"). Format (NewDate ())); Newblock.setvac (VAC); Newblock.setprevhash (Oldblock.gethash ()); Newblock.setdifficulty (difficulty); /** The For loop here is important: get the hexadecimal representation of I, set the Nonce to this value, and pass in the Calculatehash to compute the hash value. * Then through the above Ishashvalid function to determine whether to meet the difficulty requirements, if not satisfied to repeat the attempt. The calculation continues until the Nonce value of the request is obtained, and the new block is added to the chain via the Handlewriteblock function. */ for(inti = 0;; i++) {String hex= String.Format ("%x", i); Newblock.setnonce (hex); if(!Ishashvalid (Calculatehash (Newblock), newblock.getdifficulty ())) {System.out.printf ("%s do more work!\n", Calculatehash (Newblock)); Try{Thread.Sleep (1000); } Catch(interruptedexception e) {logger.error ("Error:", E); } Continue; } Else{System.out.printf ("%s Work done!\n", Calculatehash (Newblock)); Newblock.sethash (Calculatehash (Newblock)); Break; } } returnNewblock; }
With limited space, I've posted the full code on GitHub and can get it from here.
run and look.
Start the program, Access it in the browserhttp://localhost:8080
It then sends a request with the VAC data via Restclient POST
. We look at the command-line window, constantly calculating the hash value, and if it does not meet the difficulty requirement, continue to retry until Nonce
it finds the hash value that satisfies the requirement and
You can see that the last hash value meets the difficulty level we set (1-bit "leading 0"). Let's refresh the browser:
You can see that the second block was created successfully and added to the chain, which Nonce
is calculated by Proof-of-work to meet the difficulty requirements of the value.
Next Step
First of all, congratulations, the contents above are very valuable. Although our example uses very low difficulty, in essence, the working proof algorithm is the important component of Bitcoin, Ethereum and other blockchain.
For the next step in which direction the blockchain should be, we recommend learning how to access large files via IPFs and get through the blockchain. [IPFs]
In addition, compared with the proof-of-work,proof-of-stake algorithm is getting more and more attention and favor, you can also learn how to change the PoW algorithm of this article to implement PoS algorithm.
Write one of your own blockchain-3 mining algorithms with only 120 lines of Java code