How do blockchains work?¶
A blockchain is a type of distributed system called a distributed ledger. What does this mean?
A distributed system¶
A distributed system is a computer system that runs across multiple computers. An example is LHC@Home, a distributed system that powers research in physics. You could download it to run as a screensaver, and it would use your spare CPU time as your computer is idle to solve physics problems:
flowchart TD TaskServer((LHC@Home computer, Inventing tasks)) --> |Sending work| ComputerA((Your computer, running a screensaver)) TaskServer --> |Sending work| ComputerB((Another computer, running a screensaver)) ComputerA -->|Sending completed work back| TaskServer ComputerB -->|Sending completed work back| TaskServer
This is a situation where a central hub sends work to many computers, then reconstructs them on its server. This is an example of a classic distributed systems pattern, where a “leader” server (the LHC@Home server) is sending work to “followers”, which do the heavy lifting, which the leader then aggregates and organises. If LHC@Home were to go offline, then the system would be crippled in this example.
Imagine another system, where a group of microcontrollers in a beautiful and luscious greenhouse monitor incoming solar power and soil quality. Each device has an energy efficiency mode that simply aggregates data from the various signals they’re connected to. Once a day, somehow, an email is sent to an administrator with information from each device. A central system, a leader, aggregates measurements it receives, and sends the email with the info.
Each device is scheduled to start once a day to report on information received from its sensors. Normally, devices contain a quartz crystal, which vibrates at a frequency when voltage is supplied, and the devices use this as a way to know when to wake up from their low power state. Unfortunately, heat influences the vibration frequency of the crystals, and each device wakes up with latency (or too early).
As such, the leader must be online at all times (or at least around the time of the wakeup moments for the other devices), so as to receive messages without issue. To save costs, the developers have elected to build this system to be run as a distributed system. You might imagine that a single system indicating to each connected device when to operate is a lot more cost efficient than everything running at once in this example. One of the three (or variable number) of devices is the leader, and the rest are followers. This affords the followers the opportunity to sleep until their moment.
In the example below, Device A is the current leader:
flowchart LR DeviceA[Device A]:::crowned DeviceB[Device B]:::bottomLeft DeviceC[Device C]:::topRight SignalA((Sensor)) --> DeviceA SignalB((Sensor)) --> DeviceB SignalC((Sensor)) --> DeviceC DeviceB --- DeviceA DeviceC --- DeviceA classDef crowned stroke:#333,stroke-width:2px,font-weight:bold,font-size:20px;
Device A fills the role of leader by the process of an election.
An election is held if it disappears. In the distributed system of LHC@Home, a clear leader is responsible for everything: LHC@Home themselves. In this example, at a given point in time, any of these devices could become the leader. So, if water were to fall and damage a device, and it would become inoperable, then it would be replaced quickly by another device. You might imagine how this is useful in many given environments, for example a swarm of devices taking advantage of proximity to each other to aggregate and solve problems (there will always be a bottleneck where a leader is needed), inside a computer network to power a distributed file system, etc, the list goes on.
Returning to our example, how does an election take place? In the Raft example (Raft is one the most popular distributed system consensus protocols), in the simplified form, once the followers determine that the leader is unable to be accessed, they wait a few seconds at random, then declare to each other that they’ve become the leader. Devices that receive this message then go on to become followers of the new leader.
There are a few advantages to randomly having followers self declare they should become leaders, the main being that it’s very easy to reason about, and that randomness prevents a situation where two devices simultaneously attempt to become a leader. Randomness in distributed systems generally speaking is “unfairly efficient”, it generally makes systems more reliable. One of the many bizarre elements of reality.
So, a leader election could look like the following:
sequenceDiagram Everything is fine ->> Knocked offline: Device A, the current leader is offline. Knocked offline ->> Devices randomly sleeping: Each device randomly begins sleeping. Devices randomly sleeping ->> Device is done sleeping: A device stops sleeping. Device is done sleeping ->> Device declares it should be leader: Device messages everyone it should be leader. Device declares it should be leader ->> Devices become followers: Devices become followers of the new leader.
So, a device is knocked offline (by nature or by other reasons), every device waits, then it notifies every other device in the network that it is the leader. This works well if every device trusts each other to do the right thing! But what if they don’t?
A distributed ledger¶
What differentiates a distributed ledger from a distributed system? A distributed ledger implies each follower (and the leader) of a distributed system maintains a shared view of history. You might think of a basic spreadsheet:
Time |
Description |
Credit |
Debit |
---|---|---|---|
9:30 |
Silver daisy bush bouquet |
$18 |
$0 |
9:45 |
Garlic Lily seeds |
$20 |
$0 |
9:56 |
Bee hive removal for backyard |
$0 |
$200 |
As is often the case for this poor business, unexpected fees are really the greatest cost driver. You might imagine a distributed system in this context being a cash register with a screen for info on the purchases of the day, and a server on the internet that collates this view for a business owner:
flowchart LR Employee -->|Enters purchase details| CashRegister((Cash register)) -->|Tells server about every payment| Server((Income, inc))
In this normal situation, the (follower) cash register notifies the (leader) about purchases made using it. It does so virtually immediately.
In South Australia on Kangaroo Island, a hardware failure might bring down the 3G in that area. In that situation, what’s the cash register to do? It becomes a leader of sorts, forming its own informed opinion about purchases made that it sends off once the internet comes back:
Time |
Description |
Credit |
---|---|---|
10:00 |
Lavender bouquet |
$50 |
10:23 |
Kathy’s sandwiches |
$0 |
11:39 |
Grevillea bouquet |
$30 |
This forms an internal ledger of actions taken within its system. Now imagine that our server (Income, inc), is connected to by multiple cash registers at a time, perhaps by a franchisee business (the floral industry on Kangaroo Island is really booming)!
This poses an interesting challenge inherent to distributed systems: what to do if the networked devices disagree with each other when they sync histories? Assuming it’s important to the server that information is linearly stored from the way that it came in (maybe Income, Inc really needs to know accurately within hourly windows, maybe to target visitors with special advertising?) This might seem trivial in this example, but this is a real problem for certain environments. For example, fighting games – one fighter goes to land a floor kick when the other is squatting, but the kicker’s simply had a brief moment of lag, and the squatter is not on the floor anymore – should that blow technically connect? You might advise the game developer to simply make the game pause in situations where a disconnect takes place, but this happens so often at a micro level (ie, a second latency), that that’s simply infeasible.
In this example, the cash register informs its own view of history, and when circumstances allow, it reports to the server, which tells it what it should believe by updating its local representation of reality. This forms the basis of what’s known as a merge conflict: an outside source has bundled many things together that can’t be reliably merged into the view of reality. This is why a broad technical distinction for a distributed ledger exists apart from a distributed system – distributed ledgers have their own set of novel problems.
Thankfully, there is a whole group of thinking in this department, notably in the realm of Conflict-free Replicated Data Types, and Operational Transformations. While this is interesting, let’s stop here: this book is not to teach foundational distributed systems.
Problems with distributed systems and ledgers¶
The problem with distributed systems and distributed ledgers in a way that’s relevant to our discussion is twofold:
A device could intentionally sleep for a second and become the leader.
Deception could take place maliciously by submitters lying about time to the leader (or the leader itself lying) when they sync.
These are two major issues! The first kind of problem is known as being applicable to distributed systems that are not Byzantine Fault Tolerant.
What’s Byzantine Fault Tolerance?¶
In the classic example, let’s study the War of the Roses in England. During the famous Battle of Bosworth Field, Richard the Third of the Yorkists side fought Henry Tudor of the Lancastrians. During this famous battle, Richard depended on the neutrality of the knight William Stanley, a knight whom previously previously had fought on the side of the Yorkists in the English civil war. How does Richard guarantee collaboration with William?
I have bad news for Richard: in his hour of need, William betrayed the Yorkists, ultimately leading to Richard’s demise at the hands of Henry. This event led to Henry becoming King Henry the 7th. William would, much like the theoretical problem at the crux of Byzantine Fault Tolerance (that there’s no way to guarantee cooperation in a hostile environment), fail to cooperate.
Byzantine Fault Tolerance is a statement about a conceptual problem titled the Byzantine Generals Problem. The Byzantine Generals problem is exactly like the plight of the Yorkists during the War of the Roses, two entities seek coordination in an adversarial environment to succeed in a battle. How can they coordinate and be sure everything will go ahead correctly?
Unfortunately, there is no solution for the classic interpretation of the Byzantine Generals Problem. Does this mean we’re in trouble as an industry? No! Though there is no solution for this problem in theory, we can make statements about systems that are susceptible to the Byzantine Fault Tolerance problem by using a degree of certainty with probabilities and economic infeasibility.
Pop quiz for those of you who’ve used Ethereum (or any public blockchain for that matter): what do you think those confirmations are for?
The second kind of great issue inherent to the classic distributed system is the problem of followers (or anyone with a line of communication to the leader for that matter) to lie to the leader. This might also arise if the leader lies itself to its followers.
This is an interesting problem, since technically in any circumstance involving a truth external to the system (including basic things like, what’s time in the real world?), someone could lie. But as we’ll learn in this book, there are approaches to mitigate this issue.
How does a blockchain work?¶
For the two aforementioned issues: there are solutions. These are including, but not limited to, Proof of Work (PoW), Proof of Stake (PoS), Zero-Knowledge Proofs (ZKPs), Verifiable Delay Functions (VDFs), Multi-Party Computation (MPC), Threshold Signatures, etc. Most of these technologies are associated with distributed ledgers, specifically a form of that, blockchains.
For purposes of discussion, what’s an archetypical blockchain? While you might argue none such concept exists, for purpose of discussion and clarity, we will consider Bitcoin.
Bitcoin features a conservative development culture, a relatively simple mechanism of building trust (with a technology titled Proof of Work, which we’ll explain later), and a simple smart contract language – users can only send Bitcoin to each other, write notes to each other, or lock Bitcoin up for a period of time.
Bitcoin’s conservatism owes to its philosophical standing as a formally leaderless collective united around a goal of becoming the world’s global reserve currency (or the only currency, for that matter). It envisions itself as the simple layer to underpin a plethora of technologies, remaining largely unchanging, so as to enable a broad range of usecases without compromising on simplicity and security.
Mail-in voting systems¶
Imagine a mail by vote service in a city. Each citizen owns a special stamp illustrated with their insignia, which they use to stamp their name on the letters they send with their voting preferences. During each election, citizens post a letter to a mailbox near their home with their preferred governor for the current election. At the post office, each submission has the insignia in the letter verified.
Each election, each mail in vote is tabulated and verified to be legitimate based on the insignia attached to the letter. The tabulation takes place with a computer that any citizen can run at home, but most of the citizenry are lazy and choose not to do this. This computer scans the vote written on the paper, and includes a photo of the insignia attached. It then reports the votes. Only politically interested citizens of the city have a proclivity to run the machine, and most do not have access to the post system’s mailboxes to collect the letters anyway.
To run these computers, a great amount of energy is needed. Post office workers run on a great treadmill to keep the system running. This takes a great amount of great amount of effort.
Unfortunately, in this cosmopolitan state, social fractures are common. At any time, a growing discontented portion of the community expect to have the right to audit every mail in vote at the drop of a hat. If their needs are not met, they will go full anarcho-tyranny and break away from the city to form a commune living in a remote society. But, it’s hard for an authoritarian despot to lie to the city’s society.
Citizens of the city are hopelessly pragmatic: money talks. A would-be dictator seeking to insert their guy as unfairly elected for the span of a month might have to spend a lot of money coercing members of the post office to do their bidding. This combination of pragmatic ruthlessless mixed with the appetite for succession might be considered a perfect state in some worlds, or a perfect nightmare for others.
Our city’s voting system looks like the following:
flowchart TD Citizen((Citizen)) -->|Posts mail with insignia attached| Mailbox((Mailbox)) -->|Collected by the post office| PostOffice((Post office)) -->|Verifies insignia| UpdatesPostalRecord((Voting record)) -->|Tells citizen who is the current governor| Citizen
This is an analogy for Bitcoin, with a Transaction being the equivalent of sending mail:
flowchart TD Signer((Signer)) -->|Shares transaction to a shared pool| Mempool((Mempool)) -->|Transaction picked up by a miner| Miner((Miner)) -->|Miner verifies transaction is legitimate. Includes in a block| Block((Block)) -->|Transaction becomes a part of Bitcoin history| Signer
Transactions and signers¶
A Signer is the equivalent of a voter with their mail by vote insignia: they stamp (sign) their proclamation using a kind of cryptography called public-private key cryptography. This proclamation is what’s called a Transaction.
A Transaction is the structured equivalent of a proclamation in our mail by voting system – where the classic mail by vote system is simply stating who your preference is, a Transaction includes information like “who the recipient of this note is”, and if we were to count all the instances I voted, what number is this vote? A vulnerability in the mail by vote system of before is if a post office worker were to simply replace a past vote of a citizen with their current vote, assuming their preferred candidate was voted for in the past. A Transaction includes the count of votes in the past (the number of the vote) so as to mitigate this line of issue: an office worker can’t simply reuse what someone declared in the past.
Quick intro to public-private key cryptography¶
Transactions are signed using public-private key cryptography (asymmetric cryptography as a technical term). Public-private key cryptography is a tool that lets you encrypt data for a recipient, and prove that someone produced data by a process called signing. This kind of cryptography comes in pairs: a private key is used to create a public key, and to decrypt information encrypted for the public key it created. The public key is shared around, but the private key is held privately.
With this approach of signing using a private key, we can prove using cryptography that the holder of the private key produced data, what we call a message. This is useful in proving, reusing the example of the mail in voting system, that someone actually voted, and it wasn’t intercepted somewhere in the supply chain of sending the mail and receiving.
sequenceDiagram Private key ->> Public key: Creates. Signer ->> Encrypted blob for public key: Encrypts something for a public key. Encrypted blob for public key ->> Private key: Decrypts using the private key for the public key. Private key ->> Signed "digest": Signs a blob proving the public key produced some blob. Signed "digest" ->> Public key: Can be used to get the creator of the signed digest.
A specific kind of cryptography that we use in the blockchain setting works by taking a random number, and using it to derive a number on a “curve” – a range of numbers generated by a function specific to the cryptography function in use. This type of cryptography is known as Elliptic Curve Cryptography (ECC),
An Elliptic Curve from Wikipedia.¶
With ECC, the random number that you chose is your private key. This is combined in practice with a number called the Generator point, a pair of numbers (the x, and the y), that’s fixed for the type of Elliptic Curve algorithm you’re using. This is used to derive your Public key:
To be specific:
With d being the private key, and G being the generator point.
For context, the Generator point for Bitcoin’s use of ECC, the secp256k1 curve, is x 79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798, and y 483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8.
This type of math is known as modular arithmetic over a finite field.
Note
The following is included as background. Thankfully for us, we won’t need to implement any of this ourselves. So if you find yourself lost or glazing over the math, that’s okay! Continue without stressing, and it will become relevant and obvious in our code examples for each blockchain, and we’ll even reiterate these topics when they come up.
Encrypting messages for another¶
Note
Encrypting won’t be needed for operation for the chains we’re going to explain. But it’s interesting to share for a first time user of public-private key cryptography, so I’m explaining it here.
If you, someone filling the shoes of an encryptor, were to encrypt a message that only the holder of a certain private key would be able to decrypt, you would first pick another type of cryptography you intended to use alongside this process, as you will be intending for the recipient to utilise something titled Symmetric cryptography.
Symmetric cryptography is unlike asymmetric cryptography. Public-private key cryptography (asymmetric cryptography) is based on public and private keys, and the process of verifying provenance of data as well as encrypting for a recipient. Symmetric cryptography is the process of decrypting information with a shared key, like a password for example.
You, the encryptor, in sending for the recipient of your message (the decryptor), would follow the process of creating a random number (r), then computing R, a number to send alongside the encrypted blob (the ciphertext). R is a point on the ECC curve. With:
Remembering that G is the Generator point. Then, you would create a “Shared secret”, a bit of information that the recipient (the decryptor) that holds the public key needs to create itself, based on the number R, which it received alongside the blob:
With this, the decryptor would take the shared secret, which is now functioning as the key (or, the password) for some symmetric cryptography. The suite of symmetric cryptography algorithms include Advanced Encryption Standard (AES), a combination of multiple steps that XORs text if you know the key, to produce intelligible data that can only be decrypted if you know the key.
Armed with the shared secret, the decryptor can now decrypt the information the encryptor sent, by utilising the cryptography algorithm the encryptor chose.
This way, it’s possible to implement the Public-private key cryptogaphy we discuss. In web3 parlance, the private key/public key combination forms the basis of a wallet: your view of the Bitcoin (or any asset for that matter) that you’re entitled to.
Signing messages and proving you produced a message¶
Signing is the process of taking something called the signature, which is produced for the digest of a string which the user wants to sign, then verifying properties of the signature.
A digest is the fixed size checksum of a string a user wants to sign. It’s the result of using a one way hashing function: these include functions like sha256, sha512, blake2, blake3, and more. In sha256 and sha512’s case, hashing a string is the process of breaking your message up into chunks, then repeatedly expanding and XORing the message, then finally compressing and concatenating it together. It’s necessary to make a digest of a message for correctness reasons: ECC algorithms are designed for fixed size inputs, and not doing it this way breaks them.
You might use a digest in a database to store a user’s password. This way, if your database gets hacked, the user’s password doesn’t get leaked. [1]
So after taking a digest of what we want to sign, we create a random number. This is called the ephemeral key. We need to calculate R, a point on the curve again. We do this the same way as the encryption function, but we refer to the random value as k:
Once we have this, we can calculate the x coordinate on the ECC curve from R. This is where the modular arithmetic on the finite curve math comes into the picture. This way, we can create r:
This is the equivalent of accessing the x field from the value R.
Following calculating our point on the curve, we can start to calculate s. s is used to validate that the signature that we create is associated with the private key that we used. To calculate s:
AKA:
With k being the random number, or the ephermeral key, z being the hash of the function (aka the digest), and r being the x point of the value R (that we just calculated). d is our private key, and n is the curve order.
What’s the curve order? The curve order is the number of points on the elliptic curve. For ECDSA, 115792089237316195423570985008687907852837564279074904382605163141518161494337 is that number.
Now that we’ve computed r, and s, we have enough to reconstruct whether a public key signed something. In Bitcoin’s case, it always includes the public key alongside every transaction on-chain.
This is enough for someone else to verify using r and s whether a public key signed a transaction. To do this, we need to calculate multiple functions, starting with the modular inverse of s mod n:
We need w (the modular inverse of s mod the curve order – n is the curve order) for what we’re about to do:
Using the first scalar (u_1), and the second (u_2), we can then compute the elliptic curve point:
Where G is the generator point, and P the public key.
Finally, we take x’ from R’:
r’ is a recalculated version of r. At this point, we can check if the public key that we have the r and s for is actually the public key that signed this transaction by simply comparing:
And that’s how we verify signatures!
Bringing it together¶
So, we’ve established that Transactions are the equivalent of a signed proclamation with an insignia in our mail-by-vote town.
That a Transaction includes a field which says the number of times the signer (the creator of the transaction) had previously created a transaction, a destination, and a note.
That the number of times that the transaction has been used previously is to prevent someone from lying about a signer by resubmitting what they already submitted for voting. We haven’t explained what a note is: think of it simply as a arbitrary piece of information relevant to whatever the user wanted to convey with their vote.
We’ve established that the transaction includes a destination, and we’ve also established that Bitcoin transactions include a public key so everyone can verify whether the transaction is legitimate.
Putting all these things together: you might imagine how in our town where citizens like to mail by vote, that one of our big problems in distributed systems – someone lying – is something we can address using cryptography. Obviously, we can’t control the theft angle, what if someone were to steal the private key that our citizens could use as an alternative to their voting by insignia method, but it’s an effective alternative!
So for problems one and two, that someone might lie and take the place of the leader, and that someone might simply edit everyone’s preferences when they mail their vote in, we can address the second issue in our system.
So let’s return to our first issue. Returning to our example of the town voting with their mail by vote preferences, in the first issue, someone could approach the post office, bribe all the operators, and ensure that they selectively censor the posts from the citizens, even if they vote using cryptography.
This problem stems from the byzantine fault tolerance issue: there’s no way to guarantee coordination amongst the postal workers. The adversarial element is their need to make money in this hostile landscape, they don’t care for things like morality.
Proof of Work, blocks, and miners¶
The solution in this situation is what’s called Proof of Work (POW). In a PoW system, unlike a device stepping up and taking over the leader role until they’re knocked offline, the game of leadership becomes a game of musical chairs. A new leader is elected to complete their governance task, then a game is played, and the winner gets the right to become the leader.
Imagine in our city, if when votes are delivered from the post system, that anyone has the right to enter the room where the letters are kept, and to record them on computers to tabulate the votes themselves. Obviously, this is a challenge not for the faint hearted, but you might say that there’s an incentive for some people to do so. There will always be a incentive for someone to act honestly: a governor put in illegitimately leaves a lot of disenfranchised citizens in their wake.
At any time, a member of the citizenry could step into the room where the letters are held, decide the current consensus of the state is wrong (somehow), run the computer themselves, tabulate the votes, then tell everyone what’s the case, and create a parallel state in the wilderness. In this insane example, no-one physically prevents someone from entering the room, or from leaving the society.
Returning to the virtual world: Bitcoin, miners exist: miners are agents that collect Transactions together, then bundle them together into a collection titled a Block. A Block is a collection of Transactions. A Block is an addition to the ledger of the distributed ledger on a blockchain. When blocks are added together, they become a blockchain.
At any time, users can look at the details of a block, and decide if it’s legitimate or not. They can do so by looking at the public key verification cryptography contained within in each transaction, and they can also do so by the rules of the system that the block was created for. If we were to transition our mail by vote example literally to the blockchain, the rules of the system would be ensuring that a candidate exists, and that a voter hasn’t voted twice in one voting period.
flowchart LR Signer((Signer)) -->|Shares transactions| Miner((Miner)) -->|Bundles transactions into a block| Block -->|Miner shares the block to everyone that it can find| Everyone
You might be wondering: why would they do this? With Bitcoin we introduce a currency intrinsically tied to the network: Bitcoin, abbreviated to BTC. For someone to make a transaction and to have it be included in the history of the blockchain distributed ledger, they must offer an incentive for miners to collect their transaction, and include it in a block. They do it by offering a fee. The fee is an amount that the transaction signer and sender is willing to pay for the transaction to be included in a block. The transaction fee is in the native currency itself.
In Bitcoin, as an implementation detail, we don’t directly modify people’s balances. When you think about banking, you might think of a savings account that you own. In your savings account, you have a balance of $100 dollars. Logically, it makes sense to consider that with Bitcoin we’d have the same practice right?
We leverage this concept called UTXOs. UTXOs are either inputs (think of this like a credit in traditional finance parlance), or an output (equivalent to a debit). An input is the equivalent of having the right to spend money, and an output is the act of you spending it. You receive outputs from other people that become inputs, which you then yourself dilute down in the process of sending to others. Then when your computer reconciles the facts of what happened on-chain (on the blockchain) it tells you you have X amount of Bitcoin.
Why use UTXOs? It has to do with state managaement. The Bitcoin blockchain can prune any spent UTXOs from history in the form of compression. Also, it has benefits for parallelism and privacy in some contexts. We’ll muse about a reproduction of this as we discuss the Solana blockchain later.
For your computer to interact with the Bitcoin blockchain, it needs to trust something called a Node. A node is a program that ingests blocks constantly from Bitcoin, which it then presents to local software you might run. That local software is called a Wallet, and it’s the user experience that you plug into when you interact with Bitcoin.
For technical reasons, we’ve been referring to a signer as a separate concept. A signer is typically bundled with a wallet application. So for all intents and purposes, a wallet = signer.
So if you were to use Bitcoin to send money to your friend, a wallet would first look at how many inputs you have and what they sum to. Your wallet would “spend” these inputs by splitting them into smaller inputs then making outputs, and record that you decided to do so. Your wallet would decide to how much to offer a miner to include your transaction in a block so that it may become a part of the blockchain – it would do so by looking at the recent blocks using the node. You would then use Public-private key cryptography to sign a message of this, which your computer would then share to everyone it knows about in Bitcoin. Nodes may or may not be bundled with wallet software.
Once a miner makes a block with your transaction, they share their block with everyone that they possibly can, because in doing so their block derives utility, and if other people consider the block as canonical in this system, then the user was able to derive value for supplying it to them. And then the Bitcoin fee that they earned becomes real, and the block becomes a part of the history to trustworthy miners (and every downstream user who cares).
So Bitcoin becomes a perpetual motion machine motivated by belief. Someone derives utility from it, which incentivises them to keep using it, and with demand for it, the more Bitcoin would be used by people, incentivising the flywheel to continue! The economics of Bitcoin starts to take shape!
What if a miner decided to start censoring everyone else’s blocks by ignoring them and considering only itself canonical? This would be totally unsustainable for them. Because Bitcoin blocks can only be created with a significant amount of computing power to solve each Proof of Work problem, other miners would likely eclipse them with the power they have access to. If the miners are unable to (maybe this particular miner is super powerful and backed by a government), transaction submitters could start to ignore the powerful miner if they censor their transactions.
If the miner started flat out lying, then other miners that believe that for their Bitcoin to derive the maximum amount of value is to play the game fairly, then those miners would just ignore them. This would cause a situation called a Fork, where there is a divergence in the history of the blocks.
When a fork happens, miners consider the longest history of blocks that’s free of abuse the “canonical chain”, and the other chain the forked chain. Most platforms that realise your Bitcoin in the real world elect to wait a number of blocks before considering history real. To my understanding, this can be in the ballpark of 10 blocks or so today. These platforms run a “node”, a piece fo software that ingests the blocks.
Let me show you what I mean…¶
How does this all tie together in practice? Simple! Let’s actually go through the process of creating a Bitcoin transaction to send money to my friend.
…
Recap¶
So to recap:
flowchart LR Miner((Miner)) -->|Miners tell everyone they can about every block they create.| Node((Node)) -->|Provides information to your wallet about blocks it sees| Wallet((Wallet)) User((User)) -->|Interacts with to submit transactions and to see balance.| Wallet Wallet -->|Sends transactions to.| Node Node -->|Sends transactions it wants included in blocks.| Miner Miner -->|Miners tell other miners about blocks.| Miner
A glossary:
Term |
Description |
---|---|
Signer |
Signs transactions with public-private key cryptography. |
Transaction |
A signed instruction with a destination, UTXO inputs that are spent, and a public key for the sender. |
Public-private key cryptography |
Either encryption or signing with cryptography probably based on the ECDSA curve (in Bitcoin). |
UTXO |
Either a credit (a UTXO input) or a debit (a UTXO output). Sort of like a IOU. Needs to be reconciled to be used. |
Block |
A combination of transactions, with fees paid to a miner who produced it. |
Miner |
Someone who collects transactions together into blocks to be paid, then shares it with everyone. |
Node |
A program that listens for data from miners and other nodes to reconstruct what’s happening in the blockchain to present to a wallet. |
Fork |
A miner disagrees with the history another miner has created and has created their own incompatible version of blockchain history. |
Wallet |
A user-facing application that likely manages signers on behalf of a user. It also figures out fees to pay for transcations. |
Fee |
A fee paid to miners to include a transaction in a bolck. |
Proof of Work |
A cryptographic challenge solved by a miner with economics designed to prevent abuse from bad actors this way. |
User |
You! |