
What is a Proof of Work?
The next method that we are going to add to our blockchain data structure is the proofOfWork method. This method is very important and essential to the blockchain technology. It is because of this method that Bitcoin and many other blockchains are so secure.
Now, you must be getting curious about what a Proof of Work (PoW) actually is. Well, if we take a look at our blockchain, every blockchain is pretty much a list of blocks. Every single block has to be created and added to the chain. However, we don't just want any block to be created and added to the chain. We want to make sure that every block that is added to the chain is legitimate, has the correct transactions, and has the correct data inside of it. This is because if it doesn't have the correct transactions or the correct data, then people could fake how much Bitcoin they have and essentially cause fraud and steal money from other people. So, every time a new block is created, we first have to make sure that it is a legitimate block by mining it through PoW.
A proofOfWork method will take in the currentBlockData and the previousBlockHash. From this data that we supply, the proofOfWork method will try to generate a specific hash. This specific hash in our example is going to be a hash that starts with four zeros. So, with the given currentBlockData and the previousBlockHash, the method will somehow generate a resulting hash that begins with four zeros.
Now let's try to understand how we can do this. As we learned in the previous sections, the hash that is generated from SHA256 is pretty much random. So, if the resulting hash is pretty much random, then how can we generate a hash from our current block that starts with four zeros? The only way this can be done is by trial and error, or by guessing and checking. So, what we will have to do is run our hashBlock method many times until we end up getting lucky one time by generating a hash that has four zeros at the beginning.
Now, you might be wondering that the input to our hashBlock method are the previousBlockHash, currentBlockData, and nonce parameters. How will these three parameters that have been passed in once and possibly generate multiple different hashes, when, in actual fact, we're always passing exactly the same data? Furthermore, as we know from the previous section that whenever we pass in a specific piece of data, we are always going to get the same resulting hash generated from that data.
So, how can we alter this data in a way that does not change our currentBlockData or the previousBlockHash, but we still get a resulting hash that has four zeros at the beginning of it? The answer to this question is that we are going to constantly change the nonce value.
This might all seem a bit confusing right now, so let's try to clarify it by knowing what actually happens in a proofOfWork by breaking it down a little bit.
Essentially, what is happening in our proofOfWork is that we're going to repeatedly hash our block until we find the correct hash, which will be any hash that starts with four zeros. We'll be changing the input to our hashBlock method by constantly incrementing the nonce value. The first time that we run our hashBlock method, we are going to start with a nonce value of 0. Then, if that resulting hash does not have four zeros at the beginning of it, we are going to run our hashBlock method again, except this time we are going to increment our nonce value by 1. If we do not get the correct hash value again, we're going to increment the nonce value and try it again. If that doesn't work, we'll again increment the nonce value and try again. Then we'll continually run this hashBlock method until we find a hash that begins with four zeros. That is how our proofOfWork method will function.
You might be wondering how this proofOfWork method actually secures the blockchain. The reason for this is because in order to generate the correct hash, we're going to have to run our hashBlock method many times, and this is going to use up a lot of energy and computing power.
So, if somebody wanted to go back into the blockchain and try to change a block or the data in that block – perhaps to give themselves more Bitcoin – they would have to do a ton of calculations and use a lot of energy to create the correct hash. In most cases, going back and trying to recreate an already existing block or trying to re-mine an already existing block with your own fake data is not feasible. On top of that, not only does our hashBlock method take in the currentBlockData, it also takes in the previous BlockHash. This means that all of the blocks in the blockchain are linked together by their data.
If somebody tries to go back and re-mine or recreate a block that already exists, they would also have to re-mine and recreate every single block that comes after the first one that they recreated. This would take an incredible amount of calculation and energy, and is just not feasible for a well-developed blockchain. A person would have to go in, recreate a block by using a proof of work, and then recreate every block after that by doing a new proof of work for each block. This is just not feasible for any well-produced blockchain, and this is the reason why blockchain technology is so secure.
To summarize this section, what our proofOfWork method will basically do is repeatedly hash our previousBlockHash, our currentBlockData, and a nonce until we get an acceptable generated hash that starts with four zeros.
This might all seem overwhelming and a little bit confusing right now, but don't worry – we are going to build the proofOfWork method in the following section, and then we're going to test it with many different types of data. This will help you to become much more familiar with how the proofOfWork method functions and how it is securing the blockchain.