Blockchain

從零開始建立你的區塊鏈

·#區塊鏈開發#密碼學雜湊#共識機制#智能合約

嘿,你一定聽過「區塊鏈」這個詞吧?它聽起來可能有點像科幻小說裡的東西,或是只有金融專家和電腦天才才懂的複雜技術。新聞和網路上充斥著比特幣、NFT 等等讓人眼花撩亂的名詞,很容易讓人覺得這東西遙不可及。

但如果我告訴你,區塊鏈的核心概念其實非常簡單,甚至有點優雅呢?如果我再告訴你,讀完這篇文章,你不僅能徹底明白它,還能親手用幾十行程式碼,從零開始打造一個屬於你自己的、迷你但功能齊全的區塊鏈呢?

區塊鏈基礎概念

什麼是區塊鏈?一本共享的數位筆記本

想像一下,我們有一本很特別的數位筆記本。這本筆記本不是存放在某個中央伺服器(例如銀行的電腦)上,而是被複製了成千上萬份,分送給網絡裡的每一個參與者,每個人手上都有一模一樣的完整副本 。

這就是「區塊鏈」最核心的概念:它是一個分散式帳本(Distributed Ledger)

  • 帳本(Ledger):就像傳統的帳本一樣,它按時間順序記錄著一筆筆的資料。最常見的資料就是交易紀錄,例如「A 付給 B 5 元」。
  • 分散式(Distributed):這本帳本不是由單一機構保管,而是分散在整個網路中。你可以把它想像成一個 Google 試算表,它被分享給網路上的所有人,每個人都能看到所有內容,但沒有人可以單方面竄改它 。

這種設計從根本上改變了我們信任和儲存資訊的方式。傳統系統依賴一個可信的中心機構(如銀行、政府),而區塊鏈則透過數學和網路共識來建立信任。

區塊鏈的核心特性

正是因為這種「共享數位筆記本」的架構,區塊鏈才得以展現出它革命性的三大特性。這三個特性環環相扣,共同構成了區塊鏈的強大之處。

  1. 去中心化(Decentralization) 因為每個人都有一份完整的帳本,所以我們不再需要一個「中心管理者」來告訴我們哪個版本才是正確的 。當有新的紀錄要被寫入時,需要網路上大多數的參與者達成共識,同意這筆紀錄是有效的,它才能被加進去 。這移除了中間人,使得交易可以直接在點對點(Peer-to-Peer)之間進行,理論上可以更快速、更便宜 。
  2. 安全性(Security) 這本筆記本有著特殊的魔法保護。每一頁(我們稱之為「區塊」)都經過了嚴密的密碼學加密 。更神奇的是,每一頁都和前一頁緊緊地「鎖」在一起。如果你想偷偷修改前面某一頁的任何一個字,這個鎖就會被破壞,而且後面所有的鎖也都會跟著斷裂。這種密碼學的連結機制,讓任何的竄改行為都變得極其困難且容易被發現 。
  3. 不可竄改(Immutability) 一旦有新的紀錄被寫進筆記本的某一頁並被大家確認,它就幾乎是永久性的,無法被刪除或修改 。如果你想「更正」一個錯誤,你不能擦掉舊的紀錄,而是必須在最新的一頁上寫下一筆新的紀錄來沖銷它,例如「B 還給 A 5 元」。這創造了一個透明且完整的歷史軌跡,所有事情的來龍去脈都一清二楚 。如果有人試圖竄改他自己那份筆記本中的舊紀錄,他的版本會立刻和網路上其他所有人的版本產生矛盾,從而被整個網路拒絕。

這三大特性並非各自獨立,而是相輔相成的。正是因為「去中心化」的架構,才使得網路有能力透過比對來發現惡意竄改,從而保障了「安全性」;而強大的「安全性」機制,最終實現了紀錄的「不可竄改」。

區塊、雜湊、鏈接的概念說明

現在,讓我們把這本數位筆記本拆解開來,看看它的基本構成單位。

  • 區塊(Block):區塊就像是筆記本中的「一頁」。它是一個資料容器,裡面打包了一段時間內發生的多筆交易紀錄、一個時間戳(標示這頁是何時被建立的),以及一些其他的技術資訊 。
  • 雜湊(Hash):雜湊可以被理解為這個區塊的「獨一無二的數位指紋」。它是一個透過密碼學函數(例如 SHA-256)計算出來的、固定長度的字串 。你可以想像有一個神奇的果汁機,你把整個區塊的所有內容(所有交易、時間戳等等)都丟進去,它就會產出一串獨特的代碼。這個過程有幾個關鍵特性:
    • 唯一性:任何微小的輸入改變,哪怕只是改動一個逗號,產出的雜湊值都會完全不同 。
    • 不可逆性:你無法從雜湊值反推出原始的內容。
    • 確定性:同樣的內容輸入,永遠會得到同樣的雜湊輸出。
  • 鏈接(Chain):這就是區塊鏈真正的魔法所在。當一個新的區塊被建立時,它的內容不僅包含自身的交易資料,還必須包含前一個區塊的雜湊值 。這就像在筆記本的每一頁頁尾,都寫上了前一頁的「指紋」。

    這個簡單的設計產生了驚人的效果:所有的區塊透過這種方式,像鍊條一樣一個扣一個地串連起來,形成了一條「鏈」。如果有人試圖竄改鏈中間的任何一個區塊(例如第 50 塊),那麼第 50 塊的內容就會改變,導致它的雜湊值(指紋)也跟著改變。如此一來,儲存在第 51 塊裡的「前一塊的雜湊值」就對不上了,這條鏈就從這裡「斷掉」了。這種連鎖反應會一直傳遞到鏈的末端,使得任何竄改行為都會立刻被整個網路偵測到 。

區塊鏈的運作原理

區塊如何串接

我們再複習一次這個至關重要的概念。區塊鏈的串接是一個線性的、按時間順序的過程 。它就像一條單行道,只能往前走,不能回頭或插隊。

  1. 假設區塊 A 被成功建立。它包含了它自己的交易資料,並透過雜湊函數產生了它獨一無二的指紋,我們稱之為「雜湊 A」。
  2. 接下來,網路開始準備建立區塊 B。區塊 B 會打包新的交易資料,並且,它會把「雜湊 A」也一併記錄在自己的區塊內容裡。
  3. 當區塊 B 的所有內容都確定後,它會被整個拿去計算出自己的指紋,也就是「雜湊 B」。
  4. 然後輪到區塊 C,它會打包新的交易,並把「雜湊 B」記錄進來,再算出自己的「雜湊 C」。

這個過程無限地持續下去,形成了一條由密碼學保證的、不可分割的歷史紀錄。因為每個區塊都包含了前一個區塊的「DNA」,所以它們的順序是固定的。你無法在區塊 A 和區塊 B 之間插入一個新的區塊,因為那樣會破壞區塊 B 中記錄的「雜湊 A」。這種只能在尾部追加新紀錄的特性,被稱為「僅可附加」(append-only)。

什麼是創世區塊(Genesis Block)? 萬物的起源

既然每一條鏈都必須指向前一塊,那麼問題來了:第一塊要指向哪裡?

答案就是創世區塊(Genesis Block)。它是鏈上的第一塊,通常被編號為區塊 0 。它非常特別,因為它是唯一一個沒有「前一塊」的區塊。在它的「前一塊的雜湊」欄位裡,通常只是一個固定的值,比如 "0" 。

創世區塊是整個區塊鏈的基石和共同起點,它被直接寫死在區塊鏈軟體的程式碼裡。這樣可以確保每一個加入網路的參與者,都從同一個、公認的歷史開端進行同步 。

創世區塊不僅僅是一個技術上的起點,它往往還帶有濃厚的象徵意義。最著名的例子就是比特幣的創世區塊。它的創造者,化名為「中本聰」(Satoshi Nakamoto)的神秘人物,在其中嵌入了一段文字:

"The Times 03/Jan/2009 Chancellor on brink of second bailout for banks."

這句話是 2009 年 1 月 3 日英國《泰晤士報》的頭版標題,內容是關於英國財政大臣正準備對銀行進行第二次紓困。這被廣泛解讀為中本聰對 2008 年金融海嘯後,傳統中心化金融體系弊端的一種無聲批判,也揭示了比特幣被創造出來的初衷:建立一個不受中央機構控制、更加透明和公平的金融系統 。

因此,創世區塊就像是這條鏈的「出生證明」和「使命宣言」,為整個專案定下了基調。

工作量證明(Proof of Work)簡介

我們知道區塊要一個接一個地加上去,但下一個問題是:在一個去中心化的網路裡,由來決定下一塊的內容,並把它加到鏈上呢?如果大家都可以隨便加,那不就亂套了嗎?

為了解決這個問題,區塊鏈需要一套規則來讓大家達成共識,這套規則被稱為共識機制(Consensus Mechanism)。而其中最著名、也是比特幣所使用的,就是工作量證明(Proof of Work, PoW)

你可以把 PoW 想像成一場全球性的數學競賽 。

  • 競賽規則:想要贏得「記帳權」(也就是添加下一個區塊的權利)的參與者(我們稱他們為「礦工」),必須解決一道非常困難的數學謎題 。
  • 謎題內容:這道謎題並不是什麼複雜的微積分,而更像是在暴力破解一個密碼。礦工需要不斷地嘗試不同的數字(這個數字被稱為 "Nonce"),將這個數字和準備打包的區塊資料合在一起,然後進行雜湊運算。他們的目標是,找到一個能讓最終產出的雜湊值,恰好滿足某個特定條件的 Nonce 。
  • 勝利條件:這個特定條件通常是要求雜湊值的前面必須有一定數量的零,例如「找到一個 Nonce,讓雜湊值以 10 個零開頭」。由於雜湊的特性,這個過程沒有捷徑,只能靠不斷地猜測和計算,直到碰巧猜中為止 。

這個謎題的設計有一個非常巧妙的關鍵點:它極難解決,但極易驗證。一個礦工可能需要動用強大的電腦,進行數萬億次的計算才能找到正確的 Nonce。但是,一旦他找到了並向全網公布,其他任何人只需要進行一次雜湊計算,就能立刻驗證他的答案是否正確。這就確保了網路可以在不信任任何單一個體的情況下,快速地對勝利者達成共識。

挖礦與安全性

這個解決 PoW 謎題、爭奪記帳權的過程,就叫做挖礦(Mining),而參與者就是礦工(Miners)

那礦工們為什麼願意投入大量的電力和昂貴的硬體來做這件事呢?答案是獎勵。第一個成功解決謎題並添加新區塊的礦工,會獲得兩部分獎勵:一部分是系統新生成的加密貨幣(這也是新幣發行的方式),另一部分則是這個區塊裡所有交易的手續費 。

正是這個挖礦過程,賦予了 PoW 區塊鏈驚人的安全性。這種安全性不僅僅是密碼學上的,更是經濟學上的。

想像一下,一個駭客想要竄改區塊鏈的歷史,比如修改第 100 塊中的一筆交易。他需要做什麼呢?

  1. 他必須重新計算第 100 塊的 PoW 謎題,找到一個新的 Nonce。
  2. 由於第 100 塊的雜湊值變了,儲存在第 101 塊裡的「前一塊雜湊」就錯了。所以他必須接著重新計算第 101 塊的 PoW。
  3. 然後是第 102 塊、103 塊……一直到當前最新的那一塊。
  4. 最關鍵的是,他必須在誠實的礦工們產生下一個新區塊之前,完成所有這些工作。也就是說,他的計算能力必須超過網路上其他所有誠實礦工的總和(這就是所謂的「51% 攻擊」)。

這需要耗費天文數字般的電力和計算資源,其成本遠遠超過了攻擊可能帶來的任何收益。因此,對於一個理性的參與者來說,誠實地參與挖礦、賺取獎勵,是遠比試圖攻擊網路更划算的選擇。PoW 機制巧妙地將所有參與者的經濟利益與整個網路的安全性綁定在了一起,讓大家自發地去維護這個系統的穩定和誠實 。

動手打造簡單區塊鏈

現在,就讓我們把這些概念轉化為實際的程式碼。你會驚訝地發現,一個最基礎的區塊鏈,其實並沒有想像中那麼複雜。

所需工具與環境

我們的專案非常輕量,你只需要準備兩樣東西:

  1. Python 3:請確保你的電腦上安裝了 Python 3。如果沒有,可以到 python.org 官方網站下載並安裝。
  2. Flask:這是一個小巧而強大的 Python 網站框架。我們將用它來建立一個簡單的 API,方便我們與自己建立的區塊鏈進行互動。你可以用下面這個簡單的指令來安裝它(打開你的終端機或命令提示字元輸入):
    bash
    pip install Flask

就這樣,我們的開發環境就準備好了!我們還會用到 Python 內建的 hashlibdatetime 函式庫,但它們不需要額外安裝 。

區塊(Block)資料結構設計

首先,我們要定義一個「區塊」長什麼樣子。在我們的程式碼中,一個區塊將會是一個 Python 的字典(Dictionary),它包含了我們之前討論過的所有關鍵資訊 。一個區塊的結構看起來會像這樣:

python
block = {
    'index': 1,
    'timestamp': 1672531200.0,
    'transactions':,
    'proof': 35293,
    'previous_hash': '00001a3b5c7d...'
}

為了讓程式碼更清晰,我們會將所有與區塊鏈相關的邏輯都封裝在一個名為 Blockchain 的類別(Class)中。

雜湊函數實作

接下來,我們要實作那個神奇的「數位指紋」產生器。我們將使用 Python 內建的 hashlib 函式庫,並選擇 SHA-256 這個廣泛使用的雜湊演算法 。

我們的雜湊函數需要接收一個區塊(字典格式)作為輸入,然後回傳它的雜湊值。這裡有一個非常重要的細節:為了保證對於同一個區塊,我們的函數總能產生完全相同的雜湊值,我們必須確保輸入的字串是穩定不變的。如果字典中鍵的順序不同,轉換成的字串就可能不同。因此,我們會使用 json.dumps 並設定 sort_keys=True 來將字典轉換為一個標準化的 JSON 字串,然後再進行雜湊 。

建立創世區塊

每一條鏈都始於創世區塊。在我們的 Blockchain 類別被實例化(也就是被建立)的時候,我們就要自動產生這個區塊。我們會定義一個方法,在 __init__ 建構函式中呼叫它,來建立一個索引為 1、previous_hash 為 '0' 的創世區塊 。

新增區塊與驗證流程

這是我們區塊鏈最核心的邏輯部分。

  • 工作量證明(Proof of Work):我們需要一個 proof_of_work 方法。這個方法會接收前一個區塊的證明(proof)作為參數。然後它會進入一個迴圈,從 1 開始不斷嘗試新的證明數字(nonce)。在每一次迴圈中,它會根據一個簡單的數學問題(例如,新證明^2 - 舊證明^2)計算一個雜湊值,然後檢查這個雜湊值是否滿足我們的「難度」要求(例如,前四位是否都是 '0')。一旦找到符合條件的證明,迴圈就結束,並回傳這個證明 。
  • 新增區塊(挖礦):我們需要一個 mine_blockcreate_block 的方法。當我們想新增一個區塊時,就會呼叫這個方法。它會:
    1. 取得鏈上最後一個區塊。
    2. 呼叫 proof_of_work 方法,傳入最後一個區塊的證明,來找到新區塊的有效證明。
    3. 計算出最後一個區塊的雜湊值,作為新區塊的 previous_hash
    4. 最後,將所有資訊(新的索引、時間戳、交易資料、證明、前一塊雜湊)打包成一個新區塊,並將它附加到鏈的尾端。
  • 驗證流程(Validation):為了確保我們的區塊鏈沒有被竄改,我們需要一個 is_chain_valid 的方法。這個方法會從頭到尾遍歷整個鏈。對於鏈上的每一個區塊(從第二個開始),它會做兩項檢查 :
    1. 鏈接檢查:檢查當前區塊儲存的 previous_hash 是否真的等於前一個區塊計算出來的實際雜湊值。
    2. 工作量證明檢查:檢查當前區塊的證明(proof)和前一個區塊的證明,是否真的能解決我們設定的 PoW 謎題(也就是計算出來的雜湊值是否滿足難度要求)。

    只要其中任何一項檢查失敗,這個方法就會立刻回傳 False,表示這條鏈是無效的。如果所有區塊都通過了檢查,它才會回傳 True

實作完整區塊鏈類別

現在,讓我們把上面討論的所有邏輯,整合到一個完整的 Blockchain 類別中。這個類別將會是我們整個專案的核心。

操作實例教學

理論和設計都完成了,現在是見證奇蹟的時刻!我們將展示完整的程式碼,並教你如何執行它,親眼看看你創造的區塊鏈是如何運作的。

完整程式碼展示

底下是我們完整的 Python 程式碼。它包含了 Blockchain 類別的全部實作,以及一個使用 Flask 建立的簡單網站伺服器。這個伺服器會提供三個網址(API 端點),讓我們可以方便地進行「挖礦」、「查看整條鏈」和「驗證鏈的有效性」。

我已經在程式碼中加入了詳細的中文註解,幫助你理解每一部分的功能 。

python
# 匯入所需函式庫
import datetime
import hashlib
import json
from flask import Flask, jsonify, request
import requests
from uuid import uuid4
from urllib.parse import urlparse

# --- 第一部分:建立區塊鏈 ---

class Blockchain:
    def __init__(self):
        """
        建構函式,初始化區塊鏈
        """
        self.chain =
        self.transactions =  # 儲存待處理的交易
        self.create_block(proof=1, previous_hash='0') # 建立創世區塊
        self.nodes = set() # 儲存網路中的節點

    def create_block(self, proof, previous_hash):
        """
        建立新區塊並加入鏈中
        :param proof: <int> 工作量證明找到的證明
        :param previous_hash: <str> 前一個區塊的雜湊值
        :return: <dict> 新建立的區塊
        """
        block = {
            'index': len(self.chain) + 1,
            'timestamp': str(datetime.datetime.now()),
            'transactions': self.transactions,
            'proof': proof,
            'previous_hash': previous_hash
        }
        self.transactions = # 建立區塊後,清空交易列表
        self.chain.append(block)
        return block

    def get_previous_block(self):
        """
        取得鏈上的最後一個區塊
        :return: <dict> 最後一個區塊
        """
        return self.chain[-1]

    def proof_of_work(self, previous_proof):
        """
        工作量證明:找到一個數字 new_proof,使得 hash(new_proof**2 - previous_proof**2) 的前四位為 '0000'
        :param previous_proof: <int> 前一個區塊的證明
        :return: <int> 新的證明
        """
        new_proof = 1
        check_proof = False
        while check_proof is False:
            # 謎題的設計可以很簡單,但要不容易找到解
            hash_operation = hashlib.sha256(str(new_proof**2 - previous_proof**2).encode()).hexdigest()
            if hash_operation[:4] == '0000':
                check_proof = True
            else:
                new_proof += 1
        return new_proof

    def hash(self, block):
        """
        計算一個區塊的 SHA-256 雜湊值
        :param block: <dict> 區塊
        :return: <str> 雜湊值
        """
        # 確保字典被排序,以獲得一致的雜湊值
        encoded_block = json.dumps(block, sort_keys=True).encode()
        return hashlib.sha256(encoded_block).hexdigest()

    def is_chain_valid(self, chain):
        """
        驗證整個區塊鏈是否有效
        :param chain: <list> 一個區塊鏈
        :return: <bool> True if valid, False if not
        """
        previous_block = chain
        block_index = 1
        while block_index < len(chain):
            block = chain[block_index]
            # 1. 檢查區塊的 previous_hash 是否等於前一個區塊的 hash
            if block['previous_hash']!= self.hash(previous_block):
                return False
            # 2. 檢查每個區塊的工作量證明是否有效
            previous_proof = previous_block['proof']
            proof = block['proof']
            hash_operation = hashlib.sha256(str(proof**2 - previous_proof**2).encode()).hexdigest()
            if hash_operation[:4]!= '0000':
                return False
            previous_block = block
            block_index += 1
        return True

    def add_transaction(self, sender, recipient, amount):
        """
        新增一筆交易到待處理交易列表
        :param sender: <str> 發送方地址
        :param recipient: <str> 接收方地址
        :param amount: <float> 金額
        :return: <int> 將包含此交易的區塊索引
        """
        self.transactions.append({
            'sender': sender,
            'recipient': recipient,
            'amount': amount
        })
        previous_block = self.get_previous_block()
        return previous_block['index'] + 1

# --- 第二部分:透過 Web API 與區塊鏈互動 ---

# 建立一個 Flask Web 應用程式
app = Flask(__name__)

# 為這個節點建立一個獨一無二的地址
node_identifier = str(uuid4()).replace('-', '')

# 實例化 Blockchain 類別
blockchain = Blockchain()

# 建立 /mine 端點,這是一個 GET 請求
@app.route('/mine', methods=)
def mine_block():
    # 執行工作量證明來得到下一個證明
    previous_block = blockchain.get_previous_block()
    previous_proof = previous_block['proof']
    proof = blockchain.proof_of_work(previous_proof)

    # 計算前一塊的雜湊
    previous_hash = blockchain.hash(previous_block)

    # 挖礦成功,給予礦工獎勵。
    # sender 為 "0" 表示這是一個新鑄造的幣
    blockchain.add_transaction(sender="0", recipient=node_identifier, amount=1)

    # 將新區塊加入鏈中
    block = blockchain.create_block(proof, previous_hash)

    response = {
        'message': "恭喜你,成功挖到一個新區塊!",
        'index': block['index'],
        'timestamp': block['timestamp'],
        'transactions': block['transactions'],
        'proof': block['proof'],
        'previous_hash': block['previous_hash']
    }
    return jsonify(response), 200

# 建立 /chain 端點,用來顯示整個區塊鏈
@app.route('/chain', methods=)
def get_chain():
    response = {
        'chain': blockchain.chain,
        'length': len(blockchain.chain)
    }
    return jsonify(response), 200

# 建立 /transactions/new 端點,用來新增一筆交易
@app.route('/transactions/new', methods=)
def new_transaction():
    values = request.get_json()

    # 檢查請求的 JSON 中是否包含必要的欄位
    required = ['sender', 'recipient', 'amount']
    if not all(k in values for k in required):
        return '缺少必要欄位', 400

    # 建立一筆新交易
    index = blockchain.add_transaction(values['sender'], values['recipient'], values['amount'])

    response = {'message': f'這筆交易將會被加入到區塊 {index}'}
    return jsonify(response), 201

# 建立 /valid 端點,用來驗證鏈的有效性
@app.route('/valid', methods=)
def is_valid():
    is_valid = blockchain.is_chain_valid(blockchain.chain)
    if is_valid:
        response = {'message': '太棒了!區塊鏈是有效的。'}
    else:
        response = {'message': '糟糕!區塊鏈是無效的。'}
    return jsonify(response), 200

# 執行伺服器
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

執行結果與解析

現在,讓我們來實際操作一下。

  1. 儲存程式碼:將上面的完整程式碼儲存成一個 Python 檔案,例如 my_blockchain.py
  2. 執行程式:打開你的終端機或命令提示字元,切換到你儲存檔案的目錄,然後執行它:Bash

    python my_blockchain.py

    如果一切順利,你會看到類似這樣的訊息,告訴你伺服器已經在你的電腦上(127.0.0.10.0.0.0)的 5000 埠號上運行了:

    • Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
  3. 與區塊鏈互動:現在打開你的網頁瀏覽器,我們來跟它玩一下!
    • 步驟一:查看初始狀態 在瀏覽器網址列輸入 http://127.0.0.1:5000/chain。你會看到區塊鏈的初始狀態,裡面只有一個區塊,就是我們程式自動建立的「創世區塊」。
      json
      {
        "chain": [
          {
            "index": 1,
            "previous_hash": "0",
            "proof": 1,
            "timestamp": "2023-10-27 10:00:00.123456",
            "transactions":
          }
        ],
        "length": 1
      }
    • 步驟二:挖第一個新區塊 接著,在網址列輸入 http://127.0.0.1:5000/mine。你的電腦會開始進行工作量證明的計算(可能會花幾秒鐘),然後你會看到一個 JSON 回應,告訴你成功挖到了一個新區塊!
      json
      {
        "index": 2,
        "message": "恭喜你,成功挖到一個新區塊!",
        "previous_hash": "a1b2c3d4...",
        "proof": 533,
        "timestamp": "2023-10-27 10:05:00.654321",
        "transactions": [
          {
            "amount": 1,
            "recipient": "your-unique-node-identifier",
            "sender": "0"
          }
        ]
      }

      注意到了嗎?這個新區塊(索引為 2)包含了一筆交易,這是系統給予你(礦工)的獎勵。

    • 步驟三:再次查看區塊鏈 現在,再次回到 http://127.0.0.1:5000/chain。你會發現,你的區塊鏈變長了!它現在包含了創世區塊和剛剛挖出的新區塊。而且,新區塊的 previous_hash 正是創世區塊的雜湊值,它們完美地連結在了一起。
    • 步驟四:驗證鏈的有效性 最後,讓我們來檢查一下我們的勞動成果是否穩固。在網址列輸入 http://127.0.0.1:5000/valid。你會得到一個令人安心的回應:
      json
      {
        "message": "太棒了!區塊鏈是有效的。"
      }

      這證明了我們建立的鏈,其內部連結和工作量證明都是正確且一致的。

如何新增資料到區塊鏈

在我們的範例中,除了挖礦獎勵,我們還建立了一個可以新增自訂交易的功能。這需要使用能發送 POST 請求的工具,例如 Postman、Insomnia,或是用 curl 指令。

假設你想記錄一筆「Alice 付給 Bob 10 元」的交易。你可以向 http://127.0.0.1:5000/transactions/new 發送一個 POST 請求,並附上以下 JSON 資料:

json
{
 "sender": "Alice",
 "recipient": "Bob",
 "amount": 10
}

伺服器會回應你,告訴你這筆交易將被加入到下一個區塊(例如區塊 3)。這筆交易會被暫時存放在 transactions 列表中。當你下一次訪問 /mine 端點成功挖出區塊 3 時,你就會在區塊 3 的內容中看到這筆交易,以及系統給你的挖礦獎勵。這就模擬了真實區塊鏈收集交易並打包進區塊的過程 。

驗證區塊鏈的有效性

/valid 這個端點和它背後的 is_chain_valid 函數是區塊鏈安全性的核心體現。它就像一個自動化的審計員,不斷地檢查帳本的每一筆紀錄是否前後一致、是否符合規則。

你可以做一個思想實驗:如果你能暫停程式,手動修改 self.chain 列表中的某個舊區塊的資料(比如把一筆交易金額從 10 元改成 100 元),然後再訪問 /valid 端點,你得到的結果將會是「區塊鏈是無效的」。因為你的修改破壞了那個區塊的原始雜湊值,進而破壞了整條鏈的連結。這個簡單的檢查,就體現了區塊鏈「防竄改」的強大能力。

第五部分:延伸討論

恭喜你!你已經成功建立並運行了一個中心化的區塊鏈。但要讓它成為一個真正的、像比特幣那樣的系統,我們還需要討論幾個更進階的話題。

如何讓區塊鏈去中心化

我們剛剛建立的區塊鏈,所有程式碼都運行在一台電腦上。這是一個中心化的系統。一個真正的區塊鏈,是一個由成千上萬台電腦共同維護的去中心化點對點(P2P)網路

要實現去中心化,我們需要做什麼呢?概念上,它包含以下幾個步驟 :

  1. 節點(Nodes):網路中的每一個參與者(每一台電腦)都需要運行我們寫的這份區塊鏈程式。每一個運行的實例,就是一個「節點」。
  2. P2P 網路:這些節點需要一種方式來發現彼此並直接通訊,而不是透過一個中央伺服器。它們會形成一個網狀的 P2P 網路 。
  3. 廣播(Broadcasting):當一個節點新增了一筆交易或成功挖到一個新區塊時,它不會只存在自己的電腦裡。它會把這個新資訊「廣播」給所有與它相連的節點。
  4. 共識(Consensus):其他節點收到這個新區塊後,會獨立地進行驗證(檢查雜湊和工作量證明)。如果驗證通過,它們就會把這個新區塊加到自己本地的鏈上。
  5. 解決衝突:有時候,可能會發生兩個礦工幾乎同時解決謎題並廣播了不同的新區塊,這會導致鏈產生短暫的「分叉」。在這種情況下,網路需要一個規則來決定該跟隨哪一條鏈。比特幣採用的規則是「最長鏈原則」—— 網路會繼續在更長的那個分叉上工作,最終較短的那個分叉會被拋棄,整個網路恢復共識。

實現一個完整的 P2P 網路相當複雜,超出了本篇入門教學的範圍。但如果你有興趣深入,可以研究一些 Python 的 P2P 函式庫,例如 p2pnetwork

pyp2p ,它們能幫助你處理節點間的底層通訊。

從我們這個簡單的程式碼,到一個真正去中心化的系統,中間的鴻溝在於解決複雜的「分散式系統」問題,例如網路延遲、資料同步、衝突解決等。這也正是比特幣和以太坊這類專案的偉大之處,它們在規模龐大的全球網路上成功解決了這些難題。

進階應用與未來發展

區塊鏈的潛力遠不止於記錄簡單的交易。當區塊鏈變得「可程式化」時,一個充滿無限可能的新世界就此打開。

  • 智能合約(Smart Contracts) 你可以把智能合約想像成一段運行在區塊鏈上的程式碼 。它就像一個數位世界的自動販賣機:你投入正確的金額(滿足合約條件),它就一定會掉出你想要的商品(執行合約動作),整個過程自動執行,無需任何人為干預,也無法被竄改 。智能合約是區塊鏈從一個單純的「資料庫」進化為「世界電腦」的關鍵。
  • 去中心化金融(DeFi) DeFi 就是利用智能合約,在區塊鏈上重建一套傳統的金融體系,例如借貸、交易、保險等,但完全不需要銀行或金融機構這樣的中心化中介 。例如,你可以透過智能合約,將你持有的加密貨幣抵押出去,自動獲得一筆貸款,所有規則都由程式碼強制執行,公開透明 。
  • 非同質化代幣(NFTs) 如果說比特幣是「同質化」的(每一個比特幣都一樣),那麼 NFT 就是「非同質化」的。每一個 NFT 都是獨一無二的數位資產,代表著對某個特定物品(如一幅數位藝術品、一首歌曲、一段遊戲裝備,甚至是房地產)的所有權證書 。這個所有權紀錄被安全地儲存在區塊鏈上,公開可驗證,無法被偽造 。

這些進階應用的共同點,是利用了區塊鏈提供的「可信任的、可程式化的價值網路」。智能合約的出現,是區塊鏈發展的「寒武紀大爆發」,讓開發者能夠在這個去中心化的基礎上,創造出無窮無盡的應用。

常見問題與解答

在探索區塊鏈的過程中,你可能會遇到一些常見的疑惑。這裡我們整理了幾個問題並提供簡潔的回答。

  • 問:區塊鏈和比特幣是一樣的東西嗎? 答:不是。區塊鏈是一種技術,而比特幣是這種技術的第一個、也是最著名的應用。你可以把區塊鏈想像成作業系統(像 Windows),而比特幣是運行在這個系統上的一個應用程式(像 Word)。
  • 問:區塊鏈是絕對安全的嗎? 答:它非常安全,但並非無懈可擊。它的安全性來自於密碼學和去中心化的結合。然而,風險依然存在,例如建構在區塊鏈之上的應用程式(如智能合約)本身可能存在程式碼漏洞;用戶也可能因為社交工程攻擊而洩漏自己的私鑰。理論上,「51% 攻擊」也是一種威脅,儘管對於大型網路來說,執行的成本極高 。
  • 問:為什麼聽說區塊鏈很慢又很耗電? 答:這主要指的是採用「工作量證明(PoW)」機制的區塊鏈,例如比特幣。這種「慢」和「耗能」是為了保證安全而刻意設計的。許多新一代的區塊鏈採用了更節能高效的共識機制,例如「權益證明(Proof of Stake, PoS)」,它們的速度更快,能源消耗也大幅降低 。
  • 問:我可以在區塊鏈上儲存像圖片或文件這樣的大檔案嗎? 答:技術上可以,但實際上非常不推薦。因為在區塊鏈上儲存資料的成本極其高昂且效率低下。更常見的做法是,將實際的檔案儲存在其他地方(例如去中心化儲存網路 IPFS),然後只將該檔案的雜湊值(也就是它的「指紋」)記錄在區塊鏈上,以此來證明檔案的存在性和完整性,而不會被竄改。

結語

我們一起走過了這段旅程,從最基礎的概念,到親手打造出一個能運作的區塊鏈。希望你現在不僅理解了區塊、雜湊、鏈結、挖礦這些名詞的意義,更重要的是,你親眼見證了這些抽象的概念是如何透過程式碼轉化為現實的。

學習區塊鏈,不僅是學習一項新技術,更是學習一種新的思維方式。它融合了密碼學、資料結構、網路理論和經濟學,創造了一種全新的、無需信任中介的協作模式。

相關資源推薦

如果你想繼續深入這個迷人的領域,這裡有一些非常棒的學習資源推薦給你:

  • 線上課程
    • Coursera - "Blockchain Basics" by University at Buffalo:由大學教授主講的優質入門課程,涵蓋了扎實的理論基礎 。
    • edX - "Blockchain Technology":由 Linux 基金會開設,深入探討區塊鏈技術的商業和技術層面 。
  • 互動式教學
    • CryptoZombies:一個非常有趣的互動式遊戲,透過編寫一個殭屍遊戲來教你學習以太坊智能合約的程式語言 Solidity 。
  • 必讀書籍
    • 《精通以太坊》(Mastering Ethereum) by Andreas M. Antonopoulos:被譽為以太坊開發的「聖經」,深入淺出地講解了以太坊的每一個技術細節 。
  • 新聞與資訊站
    • Coinbase Learn:提供大量關於加密貨幣和區塊鏈基礎知識的優質文章和教學 。
    • Binance Academy:幣安學院,同樣是學習區塊鏈概念和術語的絕佳去處 。