---
# System prepended metadata

title: 比特幣 白皮書解析

---

# 比特幣 白皮書解析

原文連結：[bitcoinn: A Peer-to-Peer Electronic Cash System](https://bitcoin.org/bitcoin.pdf)
`(本文參照白皮書內文書寫)`

如果你是初學者，可以搭配我拍的講解影片：[比特幣核心技術解析](https://youtube.com/playlist?list=PLps5WYftESWp1_q0BR6o43uQcmV1SDLoT&si=5nVaCyng206VlPfs)

## 前言
> 這篇文章是在介紹比特幣是怎麼運作的。

> 歡迎對本文章提出指正，直接留言即可，或是可以寄信到我的信箱`ytwhyer@gmail.com`

會想要介紹比特幣，主要的原因是因為，一陣子之前，我也想學習比特幣的技術，但網路上的資源大多都只是在討論比特幣的價格，而不是比特幣的技術，而繁體中文的資料中，更是難以找到關於比特幣、區塊鏈技術的介紹。甚至許多人有買比特幣，但卻從來都不知道，他是怎麼運作的。所以我再自己學習後，決定和大家分享比特幣這個美妙的技術，希望能讓大家更輕鬆地上手。

當然，我不會講一些大家可能早就在新聞上看過的話題，例如：
1. 比特幣就是抗通膨啦
2. 比特幣就像虛擬黃金，礦工可以挖他獲得
3. ~~比特幣就是龐氏變局~~

如果你進階一點，你可能知道：
1. 比特幣是去中心化的
2. 比特幣高度透明
3. 比特幣由眾多節點維護
4. 比特幣的帳本是不可篡改的
5. 比特幣是可信的，不需要信任單一的第三方

總之如果你真的完全不知道，你可以先稍微了解一下最基本的再回來看，今天我打算藉由當年中本聰的白皮書，把你可能有的零零散散的認知，全部接起來，讓你知道，比特幣是怎麼運作的。內容可能會涉及一些專業知識，但不用擔心，我會提供你關鍵字，你也可以一邊學一邊看，我的目標是讓國中生也看得懂（前提是你真的有興趣啦）。

## 1. Introduction
>為什麼我們需要比特幣？

<details>
<summary>📘 關鍵詞解釋（點我展開）</summary>

- **double-spending（雙重支付）**：指同一筆比特幣被嘗試用於兩次以上的交易，是數位貨幣必須解決的關鍵問題。
- **peer-to-peer（點對點）**：一種去中心化的網路架構，使用者之間可以直接通訊與交易，無需透過中介伺服器。

</details>

用一個例子來說，假如你今天要賣一台二手電腦，你賣出並且寄到消費者手中，但他卻故意說你的電腦有問題，申請退款。這樣怎麼辦？你可能會說，就去申訴啊，但問題是就算你最終拿回了錢，你也浪費了一堆時間，以及額外的錢。而有些商家可能也為了怕顧客亂來，所以為了這個原因，而要求提供一些個資。但其實，假如今天是在菜市場買菜，付現金不就完事了，你把現金交出去就不能撤回了，你也不用因為買個高麗菜就報上自己的名字吧？而比特幣呢，就是想要在電子世界中擔任**現金**這個角色，這裡就點題了：**Electronic Cash** 比特幣－電子的現金。
而且我們目前的線上交易，甚至是紙鈔，我們都是透過一個可信的第三方才得以完成交易，這樣的問題是，假如那個可信的第三方失去信用了，我們可能會因此產生損失。例如你能確保你使用的網路銀行他們不會偷改你的餘額數字嗎？但比特幣可以，因為比特幣是由**peer-to-peer**網路組成，所有節點都擁有一份帳本，不用信任單一個節點，且有人偷竄改，也會馬上被發現。

## 2. Transactions
>比特幣是怎麼記帳的？擁有比特幣是什麼概念？


<details>
<summary> 📘 關鍵詞解釋（點開查看）</summary>

- **UTXO（Unspent Transaction Output）**：尚未被花掉的輸出，是你可支配的「餘額」。
- **公鑰（Public Key）**：代表比特幣接收方的身份，相當於「收款地址」。
- **私鑰（Private Key）**：用來產生數位簽章，證明你擁有某筆比特幣的秘密資訊。
- **數位簽名（Digital Signature）**：用私鑰對交易簽名，讓他人能用公鑰驗證你是合法擁有者。
    
</details>

我們先討論一個情況：
今天小明起來，媽媽先給他100塊，他花其中50塊買早餐（給了早餐店阿姨），後來早餐店阿姨下班回家，花15塊做公車回家，假設除了媽媽原本有100以外，其他人原本都沒有錢，你會怎麼記帳？

先整理一下交易：
1. 媽媽 →（100塊）→ 小明
2. 小明 →（50塊）→ 早餐阿姨
3. 早餐阿姨 →（15塊）→ 公車司機

我猜你可能會這樣記帳，把大家的交易整理成表格統計：

<div style="display: flex; gap: 10px; flex-wrap: nowrap; justify-content: space-between;">

<!-- 媽媽 -->
<div style="flex: 1; min-width: 200px; background: #f9f9f9; padding: 10px; border-radius: 8px; border: 1px solid #ccc;">
  <h4>📗 媽媽的記帳本</h4>
  <table>
    <thead>
      <tr><th>對象</th><th>金額</th></tr>
    </thead>
    <tbody>
      <tr><td>原本</td><td>100</td></tr>
      <tr><td>小明</td><td>-100</td></tr>
      <tr><td>結算</td><td>0</td></tr>
    </tbody>
  </table>
</div>

<!-- 小明 -->
<div style="flex: 1; min-width: 200px; background: #f9f9f9; padding: 10px; border-radius: 8px; border: 1px solid #ccc;">
  <h4>📘 小明的記帳本</h4>
  <table>
    <thead>
      <tr><th>對象</th><th>金額</th></tr>
    </thead>
    <tbody>
      <tr><td>原本</td><td>0</td></tr>
      <tr><td>媽媽</td><td>＋100</td></tr>
      <tr><td>早餐阿姨</td><td>-50</td></tr>
      <tr><td>結算</td><td>50</td></tr>
    </tbody>
  </table>
</div>

<!-- 早餐阿姨 -->
<div style="flex: 1; min-width: 200px; background: #f9f9f9; padding: 10px; border-radius: 8px; border: 1px solid #ccc;">
  <h4>📙 早餐阿姨的記帳本</h4>
  <table>
    <thead>
      <tr><th>對象</th><th>金額</th></tr>
    </thead>
    <tbody>
      <tr><td>原本</td><td>0</td></tr>
      <tr><td>小明</td><td>＋50</td></tr>
      <tr><td>公車司機</td><td>-15</td></tr>
      <tr><td>結算</td><td>35</td></tr>
    </tbody>
  </table>
</div>

<!-- 公車司機 -->
<div style="flex: 1; min-width: 200px; background: #f9f9f9; padding: 10px; border-radius: 8px; border: 1px solid #ccc;">
  <h4>📕 公車司機的記帳本</h4>
  <table>
    <thead>
      <tr><th>對象</th><th>金額</th></tr>
    </thead>
    <tbody>
      <tr><td>原本</td><td>0</td></tr>
      <tr><td>早餐阿姨</td><td>＋15</td></tr>
      <tr><td>結算</td><td>15</td></tr>
    </tbody>
  </table>
</div>

</div>

---

然而，比特幣是這樣記帳的：
只記輸入(誰花了多少)和輸出(誰得到了多少)

### 帳本

<div style="display: flex; flex-direction: row; flex-wrap: nowrap; gap: 10px; justify-content: space-between; align-items: stretch;">
    
<!-- 箭頭 -->
<span style="font-size: 2em; display: flex; align-items: center;">➡️</span>

<!-- 區塊 #1 -->
<div style="background:#f5f5f5; border: 2px solid #bbb; border-radius: 8px; padding: 10px 15px; min-width: 220px; box-shadow: 2px 2px 5px rgba(0,0,0,0.1); flex: 1;">
  <h4>⛓️ 區塊 #1</h4>
  <ul>
    <li><strong>輸入：</strong><br>100 元 ➝ 媽媽</li>
    <li><strong>輸出：</strong><br>100 元 ➝ 小明</li>
  </ul>
</div>

<!-- 箭頭 -->
<span style="font-size: 2em; display: flex; align-items: center;">➡️</span>

<!-- 區塊 #2 -->
<div style="background:#f5f5f5; border: 2px solid #bbb; border-radius: 8px; padding: 10px 15px; min-width: 220px; box-shadow: 2px 2px 5px rgba(0,0,0,0.1); flex: 1;">
  <h4>⛓️ 區塊 #2</h4>
  <ul>
    <li><strong>輸入：</strong><br>100 元 ➝ 小明</li>
    <li><strong>輸出：</strong><br>50 元 ➝ 早餐阿姨<br>50 元 ➝ 小明（找零）</li>
  </ul>
</div>

<!-- 箭頭 -->
<span style="font-size: 2em; display: flex; align-items: center;">➡️</span>

<!-- 區塊 #3 -->
<div style="background:#f5f5f5; border: 2px solid #bbb; border-radius: 8px; padding: 10px 15px; min-width: 220px; box-shadow: 2px 2px 5px rgba(0,0,0,0.1); flex: 1;">
  <h4>⛓️ 區塊 #3</h4>
  <ul>
    <li><strong>輸入：</strong><br>50 元 ➝ 早餐阿姨</li>
    <li><strong>輸出：</strong><br>15 元 ➝ 公車司機<br>35 元 ➝ 早餐阿姨（找零）</li>
  </ul>
</div>

</div>

這邊稍微想一下，你就可以發現，如果站在中心化的角度去想，第一種方法直覺，且紀錄方便。但注意，比特幣是去中心化的，用第二種方式，每一筆交易只需要記錄「我花了誰給我的錢，轉給了誰」，不需要知道整個人的帳本狀況。這種方式可以分散儲存、獨立驗證，而且所有節點只要確認交易輸入對應的輸出存在且未被花掉，就能保證記帳正確。
所以你讀到這就可以知道，用有比特幣到底是什麼概念了，不像銀行一樣，會存說你有多少錢，就代表你有多少錢，而是你可以去鏈上查看，曾經有人給你多少比特幣，來得知你擁有多少比特幣。
當然看到這你心中肯定還有許多疑問，我們雖然利用數字簽名（我的例子裡沒有特別提到）確保是本人控制自己的資產，但仍然無法解決雙重支付的問題，而解決的辦法就是，公開整條鏈的資訊給所有人看。



## 3. Timestamp Server
>透過hash，我們能建立不可逆的順序，並確保資料無法竄改。

由於**hash**實在是太重要了，所以我決定先介紹一下什麼是hash，其中比特幣會用到的hash叫做**sha-256**:
簡單來說，hash就是有以下特性的function:
1. 可以給任意長度的輸入，會有固定長度的輸出
2. 就算輸入有微小的差別，輸出會有很大的差別
3. 很難反推（幾乎不可能）
4. 幾乎不可能找到，兩個輸入擁有一樣的輸出（雖然理論上可行，但機率小到不可能）
> 如果你有興趣，你可以在原始碼中`sha256.cpp`看一下，他怎麼算hash值的。

啊這個能做什麼的，在這裡最大的用途就是看資料有沒有被竄改，建議大家可以實際去網路上找sha-256實際感受看看。
阿他能幹嘛能，簡單來說就是可以檢查一個東西有沒有被改過，例如你有一篇作文好了，可能有十萬字，你複製了一份，你想確認兩個是否一樣，你就把兩份都取哈希對比即可，不用一個字一個字比對。而在區塊鏈上，這可以省空間。

那這章原本的內容其實就在說，我們把每份交易內容和前一個區塊的 hash 值一起 hash，這樣除了能確認順序，也確保前後區塊緊密連結，無法竄改。
![截圖 2025-04-29 晚上9.43.20](https://hackmd.io/_uploads/r13FP8Ryxx.png)
（引用比特幣白皮書中圖片）

## 4. Proof-of-Work
>那這條鏈上的區塊，到底由誰來加到鏈上？

簡單來說，就是大家來比賽吧，前面說要找區塊鏈的hash值，那我們就在區塊內，除了原本的資料外，再加入一個**Nonce**，礦工可以調整該值(除了Nonce也有其他值可以改)，大家來比賽，誰能先hash出一個值，該值很小(通常會規定前面要有幾個0)，就贏得了記帳權。
其實`PoW`就類似用CPU算力來投票，而不使用`ip`地址來投票是因為創一堆`ip`地址太容易了。擁有一堆CPU算力相對來說難很多。
而比特幣設計當初，也有考量到大家的算力會越來越高，所以這個難度是動態調整的。
另外，節點還要達成一個共識就是**大家都要相信最長的那條鏈**。我們可以站在攻擊者的角度想，假設你想要修改鏈上的帳本，你一定是修改了之前的某個原本已經被大家承認的區塊，然後你要自己做一條更長的鏈假鏈，讓大家去相信這條假鏈，這基本上很難做到，因為這就等於你與所有人為敵，但這是真的不可能做到嗎？答案其實是否定的，這就是**51攻擊**，有人掌握一半的節點，就有可能。所以你也不難發現，比特幣是當越多人使用時，越安全。

## 5. Network
>你是比特幣節點的一員，你需要做什麼？

1. 有新交易的話，廣播給所有人
2. 所有人把新的交易寫進區塊中
3. 開始`PoW`看誰先找到
4. 如果你找到了，就廣播給所有人這個新區塊
5. 如果你收到別人找到的區塊，確認無誤後（檢查有沒有雙花），接受這個區塊
6. 你表達接受的方式，就是透過使用該區塊的哈希值，去尋找下一個區塊，以此延續下去

這樣其實不難想像，整個鏈就能不斷的被增長維護，且大家都維護共同的、不可篡改的帳本。
另外，白皮書中還提到下面件事：
**如果有兩條鏈剛好一樣長怎麼辦？** 
別擔心，就選一條延續下去，一條先留著，反正最後一定會有某條比較長，就再改用那條就好。
**如果某個節點漏接了新的區塊怎麼辦？**
不用擔心，他遲早會發現了，因為如果他中間少收到一個區塊，他收到新的區塊之後，就會發現，那個區塊的哈希值怪怪的，他再去跟其他節點補齊即可。

## 6. Incentive
>如何讓大家有動力去`PoW`，讓礦工消耗資源去記帳

先說，礦工的獎勵來自於兩點：
1. 區塊獎勵
2. 手續費

我們前面知道，一個區塊裡面會有許多筆交易，被礦工打包後接到鏈上，那怎麼給礦工酬勞？很簡單，就是每個區塊的第一筆交易，就是給礦工的獎勵，這筆錢不需要由誰來給，而是直接給礦工。從最一開始是一個區塊`50`個比特幣，大約四年減半一次(準確來說是算區塊數)，如今我寫文章的當下，一個區塊的獎勵是`3.125`。
到這邊大家應該就能很清楚的知道，礦工怎麼挖礦，怎麼記帳並得到比特幣的吧。
>可以看原始碼中`validation.cpp -> GetBlockSubsidy() ` 看看比特幣是怎麼減半的

你看原始碼會發現，或者光用想的就知道，減到一天總會少到沒有吧，沒錯！大概減半30幾次就全部挖完了。
但別忘了礦工還可以賺手續費，而手續費其實不是固定的，如同我們在交易(#帳本)那個章節提到的[帳本模型](#帳本)，只要輸入大於輸出，剩下的就是手續費。舉例來說，我花50元買早餐，但我輸入60元，那10元就是礦工的手續費。所以手續費不是一個定價，而是付錢的人自己決定。但別當礦工是笨蛋，每個區塊大小是固定的，能放的交易數量是有限的，所以礦工會優先挑手續費高的放，所以當比特幣網路很擁擠時，你付太少錢可能你的交易就無法被確認，嚴重可能導致交易失敗，所以這也是為什麼手續費越高，交易速度越快。

## 7. Reclaiming Disk Space
> 怎麼節省空間

我們前面知道了，我們防止雙花的辦法就是公開整條鏈，但對應的代價就是，所有人都必須儲存整條鏈的資訊。而現在，我們就來講怎麼節省空間。
一筆交易合不合法，取決於之前是否有人給過他這筆錢，我們只需要確認這筆輸入是否對應到某筆尚未花費的輸出（UTXO），而不需要一直往上追溯每個來源。所以一筆交易其實在經過足夠的方塊後，是可以被刪除掉的。
但為了不影響區塊的哈希值，比特幣做了以下設計：

![截圖 2025-04-30 晚上10.42.55](https://hackmd.io/_uploads/rJjgvn1gee.png)
(引用比特幣白皮書圖片)

而設計的方式也是利用`hash`將交易紀錄兩兩取hash，不斷地直到剩最後一個，我們稱之為`Root Hash`，並把它存到區塊頭中。這樣已經不重要的交易，我們就可以透過剪枝的方式剪掉，如圖右邊，刪掉交易細節，只留下哈希值。

## 8. Simplified Payment Verification
>就算你不是全節點，你也可以確認單筆交易是否成功

![截圖 2025-05-01 晚上7.41.09](https://hackmd.io/_uploads/SJgJARggxg.png)
(引用比特幣白皮書圖片)

如果你的交易資訊是`Tx3`，你只要把你的資料和`Hash01`以及`Hassh2`（其他人的交易細節對你來說不重要，拿他們的hash值只是為了驗證）自己hash出一個`Merkle Root`確認是否和鏈上的值一樣就可以。這方法只要當全網是由誠實的節點控制，最長鏈是可信的時候就可行，但如果是是交易頻繁的人，就會建議還是要自己運行全節點。

## 9. Combining and Splitting Value
>記帳的方式

其實這章節的內容，為了方便理解我已經提前在[第二章](#2-Transactions)講完了。我就補充一個重點：一筆交易是由多比輸入和兩筆輸出組成的，輸出其中一個是你要轉給誰多少錢，另一個則是給自己的找零，透過這樣，每一比輸入其實就一定來自於之前的某一比輸出。

## 10. Privacy
>隱私

我們前面說了，為了防止雙花，我們必須公開所有的交易紀錄，但這樣就等於你花了什麼錢大家都知道，很沒有隱私。那防止的方法就是，區塊鏈上紀錄的是公鑰，只要保持公鑰的匿名性，也就是說大家雖然看得到錢從哪個地址轉到哪的地址，到事實上不知道那個地址真正屬於哪一個人的。

## 11. Calculations
>用數學的方式說明比特幣很安全

這個有興趣的話，直接看原文就很清楚了。

## 12. Conclusion

講了這麼多，我們終於得到了這樣一個電子交易系統——比特幣。它不需要依賴對任何第三方的信任。
整個系統的架構從數位簽名開始，確保了資產的所有權與轉移權是由使用者自己掌控的。
接著，透過點對點網路（P2P）、工作量證明（Proof-of-Work），以及公開完整區塊鏈的設計來防止雙重支付（double-spending）。

這套系統既簡潔又強大。節點之間幾乎不需要互相信任，只需盡可能地廣播自己知道的訊息，因為訊息的傳送不需要指定對象。
節點可以自由加入或離開網路，他們透過貢獻自己的 CPU 算力來延續區塊鏈，藉此表示對某條鏈的「認可」；反之，若拒絕貢獻算力，則表示「不認同」。
最終，整個網路中的規則與激勵機制一起維護了這個去中心化的共識體系。講了這個多，我們得到了一個電子交易系統-比特幣，它不需要依賴信任某個第三方。整體構造從數位簽名開始，我們確保了貨幣所有權的控管。再來透過p2p網路、PoW以及公開整條鏈來防止雙花。整個系統簡潔而強大，節點只需要少量的合作，不用驗證對方，因為訊息不指定傳到哪，只要盡量的散播就可以，每個節點也可以隨時加入退出，他們花費自己的CPU算力，用繼續延長鏈的方式表達接受，拒絕工作表達不接受，所有的規則和獎勵都在維護著這個共識。








