" MicromOne: Understanding Proof of Work, Proof of Stake, Proof of Authority, and Byzantine Fault Tolerance

Pagine

Understanding Proof of Work, Proof of Stake, Proof of Authority, and Byzantine Fault Tolerance


Blockchain networks need a way for distributed computers, called nodes, to agree on the state of the system. This process is called consensus.

Different blockchain architectures use different consensus mechanisms. Four important concepts are:

  • Proof of Work (PoW)

  • Proof of Stake (PoS)

  • Proof of Authority (PoA)

  • Byzantine Fault Tolerance (BFT)

This article explains how they work using simplified algorithms and Python examples.

Proof of Work

The idea

Proof of Work requires participants, usually called miners, to perform computational work.

The goal is to find a value called a nonce such that the hash of the block satisfies a specific condition.

For example, suppose we require the SHA-256 hash to start with four zeros:

0000a82f...

Because cryptographic hashes are unpredictable, miners must try many different nonce values.

Basic algorithm

function mine(block, difficulty):

    nonce = 0

    while true:

        block.nonce = nonce

        hash = SHA256(block)

        if hash starts with "0" repeated difficulty times:
            return block

        nonce = nonce + 1

The important property is that finding a valid nonce can require a lot of computation, while verifying it is relatively easy.

Python example

import hashlib

def calculate_hash(data, nonce):
    message = f"{data}{nonce}"
    return hashlib.sha256(message.encode()).hexdigest()


def mine(data, difficulty):
    nonce = 0
    target = "0" * difficulty

    while True:
        block_hash = calculate_hash(data, nonce)

        if block_hash.startswith(target):
            return nonce, block_hash

        nonce += 1


nonce, block_hash = mine("Alice pays Bob 10 coins", 4)

print("Nonce:", nonce)
print("Hash:", block_hash)

A possible result could look like:

Nonce: 45231
Hash: 0000c7a1f3...

The exact nonce will be different each time.

Why is this useful?

PoW makes it expensive to rewrite blockchain history because an attacker would need to perform a large amount of computational work.

The main disadvantage is energy consumption.

Bitcoin is the best-known example of a blockchain using Proof of Work.


Proof of Stake

The idea

Proof of Stake replaces computational competition with economic commitment.

Instead of asking:

"Who can perform the most computation?"

the network asks:

"Which validator should create the next block?"

Validators lock cryptocurrency into the protocol. This is called staking.

A simplified validator-selection algorithm could look like this:

function select_validator(validators):

    total_stake = sum(validator.stake)

    random_value = random(0, total_stake)

    cumulative = 0

    for validator in validators:

        cumulative += validator.stake

        if random_value <= cumulative:
            return validator

A validator with more stake has a greater probability of being selected.

Python example

import random

validators = {
    "Alice": 100,
    "Bob": 50,
    "Charlie": 25
}

def select_validator(validators):

    total_stake = sum(validators.values())
    choice = random.uniform(0, total_stake)

    cumulative = 0

    for validator, stake in validators.items():
        cumulative += stake

        if choice <= cumulative:
            return validator


validator = select_validator(validators)

print("Selected validator:", validator)

Here the total stake is:

100 + 50 + 25 = 175

Therefore, approximately:

Alice   → 100 / 175 = 57.1%
Bob      → 50 / 175 = 28.6%
Charlie  → 25 / 175 = 14.3%

This is only a simplified illustration. Real PoS protocols use considerably more sophisticated validator-selection and consensus algorithms.

Slashing

Proof-of-Stake systems can penalize validators that violate protocol rules.

For example:

def slash(validator, stake, penalty):
    return max(0, stake - penalty)


alice_stake = 100

alice_stake = slash(
    "Alice",
    alice_stake,
    20
)

print(alice_stake)

Output:

80

The idea is that validators have an economic reason to follow the protocol.

Ethereum uses Proof of Stake.


Proof of Authority

The idea

Proof of Authority uses a predefined group of trusted validators.

Instead of mining or staking, validators are authorized to participate based on their identity and reputation.

Imagine a network with:

Validator A
Validator B
Validator C
Validator D

Only these validators are allowed to create or validate blocks.

Simplified algorithm

authorized_validators = {
    Alice,
    Bob,
    Charlie,
    David
}

function validate_block(block, validator):

    if validator not in authorized_validators:
        reject

    if verify_signature(block, validator):
        accept

    else:
        reject

Python example

authorized_validators = {
    "Alice",
    "Bob",
    "Charlie"
}


def validate_block(block, validator):

    if validator not in authorized_validators:
        return False

    return block["validator"] == validator


block = {
    "data": "Alice pays Bob",
    "validator": "Alice"
}

print(validate_block(block, "Alice"))
print(validate_block(block, "Eve"))

Output:

True
False

Eve cannot validate the block because she is not an authorized validator.

Advantages

PoA can provide:

  • high transaction throughput

  • low energy consumption

  • predictable validation

  • low computational requirements

Disadvantage

The main trade-off is that the network depends on a relatively small group of known authorities.

This makes PoA particularly suitable for some private, enterprise, or consortium blockchains, where participants are known.


Byzantine Fault Tolerance

The problem

BFT addresses a different problem.

Imagine several nodes need to agree on:

"Should transaction X be accepted?"

Some nodes may be:

  • offline

  • malfunctioning

  • sending conflicting messages

  • malicious

These problematic nodes are called Byzantine nodes.

The challenge is to allow honest nodes to reach agreement despite these failures.


Practical Byzantine Fault Tolerance

One famous approach is Practical Byzantine Fault Tolerance (PBFT).

A simplified PBFT protocol has three main phases:

Client Request
      |
      v
   PRE-PREPARE
      |
      v
     PREPARE
      |
      v
     COMMIT
      |
      v
   Execute Request

The nodes communicate with each other during these phases.

A simplified algorithm is:

1. Client sends a request to the primary node.

2. Primary broadcasts PRE-PREPARE.

3. Replicas verify the proposal.

4. Replicas broadcast PREPARE.

5. Nodes collect enough matching PREPARE messages.

6. Nodes broadcast COMMIT.

7. After enough COMMIT messages,
   the transaction is considered committed.

For a classic PBFT system with n nodes, the protocol can tolerate:

f = floor((n - 1) / 3)

Byzantine nodes.

Therefore:

n = 4  → f = 1
n = 7  → f = 2
n = 10 → f = 3

This means a system with 7 replicas can tolerate up to 2 Byzantine replicas under the classic PBFT assumptions.


Simplified BFT Example

Consider four nodes:

Node A
Node B
Node C
Node D

Suppose Node D is malicious.

The honest nodes receive:

A → ACCEPT
B → ACCEPT
C → ACCEPT
D → REJECT

The network can still reach:

CONSENSUS = ACCEPT

because the honest nodes have enough agreement.

A very simplified implementation could be:

def reach_consensus(votes):
    accept = votes.count("ACCEPT")
    reject = votes.count("REJECT")

    return "ACCEPT" if accept > reject else "REJECT"


votes = [
    "ACCEPT",
    "ACCEPT",
    "ACCEPT",
    "REJECT"
]

result = reach_consensus(votes)

print("Consensus:", result)

Output:

Consensus: ACCEPT

This code is not a real BFT implementation. It only illustrates the basic idea of reaching agreement despite a conflicting node.

Real BFT protocols need authentication, message ordering, view changes, quorum rules, replay protection, and mechanisms for handling malicious communication.


Comparing the Algorithms

MechanismMain ideaResourceTypical participants
PoWComputational workCPU/GPU/ASIC powerMiners
PoSEconomic stakeCryptocurrencyValidators
PoAAuthorized identityIdentity/reputationApproved validators
BFTAgreement despite failuresCommunication/quorumsDistributed nodes

The important distinction is that BFT is primarily a family of fault-tolerant consensus techniques, while PoW, PoS, and PoA describe different ways of determining who can participate in block production or validation.


A Simple Blockchain Architecture

A simplified blockchain can be represented as:

Transaction
     |
     v
+------------+
| Validation |
+------------+
     |
     v
+----------------+
| Consensus      |
| PoW / PoS /    |
| PoA / BFT      |
+----------------+
     |
     v
+------------+
| New Block  |
+------------+
     |
     v
+------------+
| Blockchain |
+------------+

For example, with Proof of Work:

Transactions
     |
     v
Create Block
     |
     v
Mining / PoW
     |
     v
Valid Hash?
   /     \
 No       Yes
 |         |
Retry     Broadcast
             |
             v
        Other Nodes
             |
             v
       Add to Chain

With Proof of Stake:

Transactions
     |
     v
Create Block
     |
     v
Select Validator
     |
     v
Validate Block
     |
     v
Consensus
     |
     v
Add to Chain


The four concepts solve related but different problems:

Proof of Work uses computational effort to make block production expensive.

Proof of Stake uses economic incentives and locked cryptocurrency to select and control validators.

Proof of Authority uses a known and authorized group of validators.

Byzantine Fault Tolerance focuses on allowing distributed nodes to reach agreement even when some nodes fail or behave maliciously.

In a real blockchain, these concepts can also be combined. For example, a protocol can use a validator-selection mechanism together with a BFT-style consensus algorithm.

The Python examples above are intentionally simplified: they demonstrate the core algorithms and intuition, not production-ready blockchain implementations.