If these posts are interesting to you, please subscribe:
and share!
Also, feel free to follow me on twitter: @azakmay
The Blockchain and Proof of Work
Until recently, and maybe still, I fell into the majority camp of people who didn’t understand blockchain that well. I knew a couple things: that it’s a distributed ledger containing transactions; and that to verify the ledger you had to solve a math problem.
But what does that mean…?
No clue!
I find there’s no better way of figuring something out than by writing about it, and when I was doing the research for this piece, I had trouble finding a resource that summed it all up in a neat way. Hopefully, this is a clear description of how a blockchain that relies on ‘Proof of Work’ functions. We will start at the transaction level and work our way up to defining Proof of Work (PoW). This will not be a perfect explanation but will get at the core concepts. So, what are the main components of a PoW blockchain?
Transaction between two parties or P2P payments
Distribution of transactions
Ledger verification (Proof of Work)
Longest connection of blocks forms the blockchain
With that, let’s begin. As defined in bitcoin’s whitepaper, it is “a purely peer-to-peer version of electronic cash [which] would allow online payments to be sent directly from one party to another without going through a financial institution”. In other words, I should be able to send my friend currency without using a bank.
Let’s start where the whitepaper begins: A person wants to send money to another person, and for the transaction between the two parties to be recorded and verified. The ledger records all the transactions that occur and is known as a ‘block’ in the blockchain world. I will use block and ledger interchangeably. In the image below “CC” stands for Crypto Coin, the currency that we are tracking via the ledger. For instance, a block with two transactions might look like the following.
To understand how a transaction occurs in the blockchain world, let’s use the first transaction in the block above: “Jenny sends David 100CC”. With this simple case we already run into a few issues. One obvious issue is:
How do we know that it is Jenny who is sending the money to David and not someone fraudulently doing so with Jenny’s funds?
To prove this is indeed Jenny, we need Jenny to sign the transaction. On a paper contract, this is typically just a signature. In the digital world, a common method for verifying things is by using a private and public key.
Jenny, along with anyone transacting on the blockchain has two keys: a public and private key.
Private key: Also known as a secret key because this should not be shared with anyone. You use this key to generate a signature on every transaction. If someone knows this key, it is the same as someone having a key to your home while you’re out of town, entering and turning off all the security systems. The house is now theirs to take what they wish - really bad!
Public key: this is known to all and is what others in the network use to verify that a transaction really came from you.
Now that we know what a private and public key are, we can use two keys and a function to sign and verify transactions.
First, let’s quickly define a function because this concept is important for understanding multiple steps in the blockchain: A function is anything that takes an input and produces an output.
f(input) = output
If we have
f(x, y) = x + y
Then we get
f(1, 1) = 2
This is important for understanding the signing and verifying of transaction. In our transaction system we might have two functions that look something like the following:
The perform_signature() function is special type of function known as a one way function. This is a function where the output is easy to compute, but it is extremely difficult to go in reverse and compute the input from the output. This is good because you don’t want anyone to be able to take the signature produced above and figure out your private key. Under the hood, this function is using a technique known as SHA 256. This is a cryptographic hash function and is the crypto part of crypto currency. For all intents and purpose, what this means is: your private key is safe. No one can take the signature output and determine your private key.
In our transaction scenario, Jenny would have her message: “Send David $100” and private key: XXXX. This input would then produce a signature others could use to check that the transaction is valid.
This transaction is then broadcast out into the network and since everyone knows Jenny’s public key and the signature they can quickly verify the transaction by running the function perform_verification():
Since perform_verification() returned “True”, we know this to be a valid transaction and we can add this transaction to the ledger. Jenny has now sent David $100 and it is valid. If perform_verification() is “False” the transaction is not included in the ledger. For transaction to only occur once and not be copied, there is a unique transaction ID associated with each transaction.
On the left, the transaction could be copied endlessly to make David really rich, and knowing David, he would likely do just this! On the right, the unique ID at the start of the message prevents this from happening. That covers how we verify valid transactions and leads us to our next complication: how do we make sure someone has the funds to cover their transaction? What if Jenny doesn’t have a $100 to pay David? If Jenny is sans funds, this should also be an invalid transaction. But to answer these questions, we need to talk about where the ledger lives and how it gets distributed.
When a transaction occurs, it is broadcasted out to the network (using something similar to a gossip protocol) where nodes are listening for events. A node is just a computer running the blockchain protocol. You can kind of think about a node like a rain gauge, similar to how a gauge hangs outside waiting to tell you how much it has rained, a node sits on the internet waiting for transactions to come in so that they can tell you other node about the latest transactions. Basically, nodes will see the transaction, add it to their ledger and pass that transaction onto other nodes in the network. All these connected nodes form what is known as a mesh network, which is just a term for a bunch of connected devices. The process looks something like below and is one big notification system for transactions.
What this means is that every node on the network sees every transaction and records it in their ledger. Instead of one central entity recording all transactions, everyone has a copy of the ledger. This is what makes the system decentralized and removes trust from a central location.
Back to our main concern of Jenny having the funds: this solves that scenario because the network knows every transaction and the starting amounts as a ledger should.
Now that everyone has the ledger and decentralization is established there needs to be a way to validate the correct ledger. This is where PoW comes in. We need PoW because there must be a way to establish what the correct ledger is; we need David to be able to spend his 100CC he just received from Jenny. The method that Bitcoin came up with and that Ethereum currently uses is PoW - although, Ethereum is moving to Proof of Stake imminently.
PoW forces compute to be done on a block to verify the transaction. We can think of the block as a file that is our input in the SHA256(block) function. Remember SHA256 is just an extremely secure one-way function to produce a signature. If we use Bitcoin’s PoW protocol, we must find a number such that “block + random number” creates a hash with a certain number of leading zeros. The only way to do this is to try every number until you have a hash with the predetermined number of zeros.
Example: Pretend we need to find a hash with two leading zeros (e.g., 0010010101010). The work might look something like this.
SHA256(“Block + 1”) = 10101
SHA256(“Block + 2”) = 11111
SHA256(“Block + 3”) = 10101
SHA256(“Block + 4”) = 11101
SHA256(“Block + 5”) = 01101
SHA256(“Block + 6”) = 00101
It is not until guess 6 that we find a hash that satisfies the condition set by the Bitcoin protocol. Once we have this hash, it is super easy for others in the network to verify. They simply run the SHA256 function with the “Block + 6” as the input and will get the same hash generated with the brute force technique. To generate a hash with two leading zeros, we have no choice but to do the work and expend the compute / electricity via a brute force. This goes back to the property of one way functions: you can’t go in reverse. Since all numbers are just as probabilistically likely, we just start at 0 and count up. The “solving a math problem” you hear about in discussions of crypto is really just guessing numbers / counting until you compute the right id to generate a hash with the correct number of leading zeros for the protocol.
Here is a gif of computer searching for a number that satisfies different leading zero inputs.
The gif starts by looking for a hash with 2 zeroes and is solved almost instantaneously. When the computer tries to find a hash with 6 leading zeros – it takes a long time and never happens. As you can see, as the requirement for the number of leading zeros increases the longer it takes the computer to solve. We can show why this is the case with some simple probabilities:
In SHA256, there are 16 possible outputs for each space: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f
The likelihood of randomly guessing the correct input on the first try that produces output with a single leading zero is 1 / 16. At worst, you’ll find the correct input with 16 unique guesses.
The likelihood of randomly guessing the correct input on the first try that produces output with a two leading zero is (1 / 16) * (1/16) = 0.0004. At worst, you’ll find the correct input with 256 unique guesses.
And so on, and so forth.
Hopefully, this shows the exponential difficulty of solving the hash function as the leading zeros you must find increases.
Once we have the hash, we can submit the block to the blockchain to be verified by the network and added to the chain. Solving the block takes time because the expected number of attempts for a computer to find the right number is in the trillions, but once this number is found others can use this same number and verify the integrity of the block is instantly.
Once verified, the block is added to the blockchain. The way that other participants in the blockchain determine which block is correct is by using the longest block. Whichever block has the most blocks in its chain are the one you will add the next block to.
Why would anyone pay for the electricity associated with performing this compute?
The miners, those who expend compute to search for the random number, perform this function because they earn rewards for verifying and thus securing the network. These rewards are called “block rewards”. In our example the block rewards would come in the form of certain number of Crypto Coins. This is the only way coins are produced and are supposed to make it worthwhile for the miners to maintain and secure the network. If you're a miner, you must believe these coins are valuable because there are costs, in the form of electricity, for being a miner. Now are the coins valuable? Well, that is a discussion for another time 😶.
The Actual Chain
Now that we know how transactions and the block are secured and verified, we can talk about how the blockchain maintains security. At all times, everyone agrees that the longest chain is the accurate chain. The way this stays true is because of the hashes previously calculated for each block. It’s hashes all the way down!
Here is an example blockchain with their solved hashes.
Everything looks good and all hashes have the appropriate number of leading zeros. Now, notice what happens when we change a transaction in the first block.
We see the first transaction’s hash no longer meets the requirement for leading zeros, so this is not a valid block. The network sees this and does not accept this new history and keeps the current chain. The only way for this new chain to become the valid blockchain is to solve every block at a faster rate than the longest chain. This means starting at the fraudulent block, you need enough computing power to solve the hashes for Block 1, 2 and 3 and then any other added blocks to become the longest chain. This is where you need 51% of the networks computing power for enough time to catchup and have the edited chain win. This is unlikely but would allow for fraudulent transactions to occur on the network.
We made it! I will leave you with this tweet. If this joke makes sense, I did a decent job explaining the blockchain.
Resources / Learn More
https://ethereum.org/en/developers/docs/intro-to-ethereum/
Ethereum site overall has amazing resources
Zero Knowledge podcasts
Which is an awesome channel in general.
Love this! Best explanation so far