Back

How Bitcoin works

Have you ever sat there reading about Bitcoin and how it's "decentralized" or "permissionless" and wonder But how does this actually work? Well this post is for you!

The goal is to give an overview of how Bitcoin acts as a permissionless and decentralized ledger.

We'll start off with a quick explainer on private vs. public ledgers. Then go into how Bitcoin manages to implement a public ledger.

Private vs. Public ledgers

Let's say you're a bank and you have people who own accounts with your branch. In typical fashion, we'll have our three culprits: Alice, Bob, and Cliff. Each of them has an account and want to be able to transact with each other.

There are 3 transactions that we want to process.

#SenderReceiverAmount
1AliceBob$10.00
2BobAlice$15.00
3AliceCliff$20.00

There are a few problems that can pop up and we need to solve with ledgers to make sure they are operating correctly.

  1. How do we know the people who initiated the transaction did so?
  2. How can we make sure an account doesn't spend money it doesn't have?
  3. How do we maintain the security of the ledger?

A bank solves each problem by virtue that it's a bank and having control over the ledger. Only it has the permission to do so and by that nature, it's centralized.

What Bitcoin (and most blockchains) does is turn this ledger public, meaning there is no third-party that maintains the ledger. Instead, the public maintains the ledger, in this case, it's permissionless and decentralized.

So how do we solve the same problems as we have above?

Signing & verifying transactions

Problem #1 uses public-key cryptography as a solution. It allows users to sign transactions with a digital signature that only they possess and anyone can verify belongs to them.

Account holders have two keys:

  • Public key: this key is visible to everyone
  • Private key: this key is only known by the account holder — it is critical that the holder never reveal this to anyone else

We use these two keys to sign transactions and verify transactions. The private key is used to sign a transaction, while the public key can be used to verify that the key was signed using the corresponding private key.

Using your private key, can sign a transaction indicating it as valid. Anyone else can use your public key to verify you signed it with your private key.

Using public-key cryptography, it's easy for anyone to both sign and verify transactions by themselves and others. In most cryptocurrency applications, the account holder's public key is their account address and their private key is their seed phrase.

The timestamp server

In a private ledger, the maintainer (e.g. a bank) will keep it under lock and key to make sure there are no unverified or unauthorized transactions added to it. If the ledger is public, how do we make sure that the ledger is both valid and has not been tampered or changed by a bad actor?

To do this, we use something called a timestamp server. The server is maintained in a peer-to-peer fashion and works by taking a block of transactions, creating a hash of it, and publishing the hash to everyone. That way, we can prove that the data is accurate and truthful.

Using hashes, we can take a set of transactions and create a chain we can track and verify using the hashes.

Below is an example of a block of transactions. Try grabbing one and moving it around - notice how the hash changes.

Block example
Grab a block and move it around, notice how the hash changes.
1
Alice
Bob
$10
2
Bob
Alice
$10
3
Alice
Cliff
$20

This is how we can ensure a block hasn't been tampered with. If you sent these transactions to anyone, they could easily verify whether the set (and order) of transactions they have is correct.

In the example above, we're only changing the order of the transactions. In practice, if anything from the sender, receiver, amount, and time the transaction was sent are changed, the hash changes drastically.

So hashes protect us from modifying transactions, what if someone were to modify an earlier block? To solve this, we use the previous block's hash as an input for the current block. This effectively creates a chain of blocks - or blockchain.

Using a chain of hashes, we make sure our previous block is included in the next hash to protect from anyone modifying older blocks.

Our next problem though, is how do we know the hashes received are correct? What if we receive different hashes at different times. This is where we use a neat tool called a consensus mechanism.

Consensus mechanisms

Above we mentioned a potential problem with a timestamp server and what if we receive different hashes, both which could potentially be valid.

To summarize, our goal is two-fold:

  1. Be sure that the chain (truth) has not been tampered with
  2. Achieve the above in a distributed permissionless fashion

What the second point above means is that since the ledger is public, we need some way to have everyone agree on the ledger at any time. If we only simply use hashes, a potential bad actor could submit a fake block with bogus transactions.

In order to do tackle this, we use something called a consensus mechanism. There are many out there, but for scope of this post, we're going to stick to Bitcoin and its consensus mechanism: proof of work.

Proof of Work

This consensus mechanism works by having everyone do computational work. This materializes as calculating a difficult hash. What does that mean?

Above we spoke of hashing functions that accept some input and give an output. With Bitcoin, we calculate the hash of the transactions, but then we add an integer called a nonce. The goal is to find a nonce for a given block that gives an output with N zeroes at the front of the hash. Since it's basically impossible to work back from a hash, we really need to guess numbers until we find a nonce that results in a hash with a set of leading zeroes.

Once you've found a nonce, that is known as a proof-of-work — you have proven that you have done the work to generate a difficult hash. This entire process is known as mining.

Let's look at an example where we need to compute the nonce for the transactions above. Click on the "Mine block" button and it will increment the nonce until it finds a nonce that gives us a hash that starts with two 0s. Then try to swap around the transactions, you'll see that the nonce is no longer valid.

Nonce example
Invalid hash
1
Alice
Bob
$10
2
Bob
Alice
$10
3
Alice
Cliff
$20

Oops! The hash doesn't start with "00". Mine a valid nonce below.

Note that we're starting from zero in the example above and the nonce it calculates is just one of many valid nonces.

Why exactly do we use nonces? We want to make it hard to generate a hash, yet easy to verify one.

By computing a nonce and use the previous hash and nonce as an input, we make it much more difficult to attack the network.

We make it hard to generate a hash so that if someone manipulates or changes the transaction history (e.g. bogus transactions) we force them to recalculate the hash since the old nonce will no longer be valid. Further, it's easy for anyone to verify a set of transactions with the nonce published.

Let's look at an example of a chain of blocks. First, compute all the nonces until you have three valid blocks. Then see what happens if you change a block. Start with the first block and work your way down.

A blockchain
Calculate the nonces first, then try moving the blocks around.
Invalid hash
1
Alice
Bob
$10
2
Bob
Alice
$10
3
Alice
Cliff
$20

Oops! The hash doesn't start with "00". Mine a valid nonce below.

Invalid hash
4
Bob
Cliff
$15
5
Cliff
Alice
$32
6
Alice
Cliff
$14

Oops! The hash doesn't start with "00". Mine a valid nonce below.

Invalid hash
7
Cliff
Bob
$5
8
Bob
Alice
$25
9
Alice
Bob
$36

Oops! The hash doesn't start with "00". Mine a valid nonce below.

You should have seen that changing any transaction in the earliest block immediately makes any subsequent blocks invalid.

With the process of chaining blocks together and requiring nonces, we make the chain much harder to attack since the further up the chain an attacker attacks, the much harder it is for them to generate new nonces to broadcast to everyone.

The network

Finally, let's take the principles above and put them all into practice with a full network.

In practice, Bitcoin is managed by many nodes — these are known as validators. Validator nodes do the following:

  1. Collect transactions that have broadcasted to it into a block
  2. Filter out any invalid transactions (i.e. where users might have tried to double-spend)
  3. Calculate a proof-of-work (difficult hash with a nonce)
  4. Broadcast the block to the rest of the nodes when it finds a valid nonce

The rest of the nodes will then verify that the nonce and hash are valid, then continue along with the received block being the previous valid block (i.e. use it as the previous hash for the next block).

Wrapping up

We've gone over some slightly technical explanations of how blockchains (particularly Bitcoin) works. There is a bunch that hasn't been touched on in this post, such as:

  • How would an attack on the chain work?
  • If an attack occurred, how would that play out?
  • How do miners get compensated?

Perhaps I'll tackle these in a future post, but for now I'll leave it here.

Other videos or explainers to check out

Huge shout out to Grant Sanderson on his Bitcoin explainer and Anders Brownworth's interactive video and site. Please check out their work as its been the inspiration for this post!