---
# System prepended metadata

title: 從以太坊白皮書理解 web 3 概念 - Day7
tags: [' Web 3', it 鐵人賽 30 天, ' ethereum']

---

---
tags: it 鐵人賽 30 天, Web 3, ethereum
---
# 從以太坊白皮書理解 web 3 概念 - Day7

## Ethereum: Wallet

今天要分享的主題是 Ethereum 或是說其他區塊鏈可能的一個共通名詞 Wallet

中文也許可以譯做錢包，卻跟一般概念上概念上的錢包不同，不保存直接資產在其中。

Wallet 的作用是用來產生以及保存做簽章使用的密鑰。

Ethereum 的 Wallet 是一個保存與管理私鑰的系統，並不保存 token 或是數位貨幣。

在區塊鏈上，用來做辨認交易正確性的方式就是透過加密簽章。

每個想做交易的人會產生一組鑰匙，私鑰與公鑰。

私鑰用來把交易內容做簽章，公鑰用來把加密簽章做驗證確認交易內容與簽章無誤。

由此可見，私鑰代表做交易者的身份，且區塊鏈的機制只認簽章正確性。

當私鑰被他人偷走時，對方就可以透過你的私鑰做出一個新的交易，且內容可以被驗證。

## Wallet 技術簡介

單個私鑰以及單個地址用來管理個人交易及資產是很方便。

然而，對於要做要去識別化的隱私來說卻不是一間好事情，很容易追蹤交易地址來取得所有交易紀錄。

所以，最佳的使用方式是每筆交易都使用不同的新的鑰匙，但是會造成很難管理。要在方便管理與隱私之間做到平衡就是需要一個良好的設計。

根據錢包所產生出來的鑰匙之間是否有關鏈來分類，目前最主要有兩類錢包：



### Non-Deterministic(Random) Wallet

每一個鑰匙都是從獨立隨機數字所產生出來，每個鑰匙之間都沒有關聯。

這類的錢包也被稱作 "JBOK" wallet, 是 "Just Bunch of Key" 的縮寫。

使用這類錢包，如果要維持不容易被追蹤交易，就必須要常常產生新的 key。

但會遇到管理問題，一旦沒有好好去做備份，當失去其中一把 key, 與其相關的交易將無法存取。

雖然如此，但還是有一些 Ethereum 客戶端程式設計出好的資料保存格式來避免遺失，比如 keystore 檔案格式，如下

```json
{
    "address": "001d3f1ef827552ae1114027bd3ecf1f086ba0f9",
    "crypto": {
        "cipher": "aes-128-ctr",
        "ciphertext":
            "233a9f4d236ed0c13394b504b6da5df02587c8bf1ad8946f6f2b58f055507ece",
        "cipherparams": {
            "iv": "d10c6ec5bae81b6cb9144de81037fa15"
        },
        "kdf": "scrypt",
        "kdfparams": {
            "dklen": 32,
            "n": 262144,
            "p": 1,
            "r": 8,
            "salt":
                "99d37a47c7c9429c66976f643f386a61b78b97f3246adca89abe4245d2788407"
        },
        "mac": "594c8df1c8ee0ded8255a50caf07e8c12061fd859f4b7c76ab704b17c957e842"
    },
    "id": "4fcb2ba4-ccdb-424f-89d5-26cce304bf9c",
    "version": 3
}
```

來將 key 相關的資訊做一個良好的關鏈並且保存。

keystore 檔案會使用一個 key derivation function(KDF)(密鑰推演方法) 來保護密鑰被暴利破解或彩虹表攻擊，也就是說密鑰並非是直接加密保存而已。

而 keystore 這類格式讀取方法也有在 Javascript 語言有實作的函式庫比如[keythereum](https://github.com/ethereumjs/keythereum)。


### Deterministic Wallet

每一鑰匙都會從一個主要的鑰匙或是種子(seed)所推導出來。

而這個種子(seed)是透過結合其他資料所產生出來的隨機亂數。

這類錢包中，從種子(seed)就可以還原出所有其他由種子(seed)產生的鑰匙。

所以只要備份種子(seed)，就可以還原出所有資產。

然而，這把主要的鑰匙或是種子(seed)變得格外重要。

### Hierarchical Deterministic Wallets (BIP-32/BIP-44)

Deterministic Wallet 讓所有鑰匙可以從種子(seed)推導出來。

現行最常見的形式是 HD(Hierarchical Deterministic）Wallet，是由 bitcoin 的 [BIP-39 標準](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) 所定義。

HD(Hierarchical Deterministic）Wallet 的鑰匙其推導關係呈獻樹狀結構，也就是由一把親代鑰匙可以推導出一堆子代鑰匙，子代鑰匙又可以再推導出孫代鑰匙。

![https://raw.githubusercontent.com/ethereumbook/ethereumbook/develop/images/hd_wallet.png](https://raw.githubusercontent.com/ethereumbook/ethereumbook/develop/images/hd_wallet.png)

#### HD Wallet 優點 - 組織化管理

樹狀結構，讓鑰匙呈獻組織化結構，使其具有組織上的意義。比如說可以使用不同的子代鑰匙來分開管理收入以及支出的交易。

#### HD Wallet 優點 - 可以透過Seed 產生多把公鑰

可以透過一個種子產生無數多個公鑰而不需要產生一堆私鑰來管理。

#### Seeds and Mnemonic Codes (BIP-39)

為了安全備份還有還原，目前有很多種方法可以用來把密鑰做編碼。

現在比較偏好的方式是使用一組可識別字詞透過特定排列來方式來做對應。

這個規範被定義在[BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)。

舉例來說:

有一個 HD Wallet 的 Seed 以 Hex 表示如下
```hex=
FCCF1AB3329FD5DA3DA9577511F8F137
```

透過 [BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) 中 12 個字的規範就可以編碼成以下:

```
wolf juice proud gown wool unfair
wall cliff insect more detail hub
```

相較於直接去計錄 Hex ， 由[BIP-39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)對應出的可識別字詞有較好的可記憶性。

所以為了方便使用 HD Wallet都會照著這個規範去做設計。

### Wallet 最佳範例

隨著加密貨幣錢包技術變成熟，有愈來愈多的鑰匙推導技術還有記憶詞規範。

最常見的標準有以下幾種：

* Mnemonic code words, based on BIP-39
* HD wallets, based on BIP-32
* Multipurpose HD wallet structure, based on BIP-43
* Multicurrency and multiaccount wallets, based on BIP-44


### Mnemonic Code Words (BIP-39) 介紹

Mnemonic code words 是指一序列的字詞用來編議成一個隨機數字用來產生 HD Wallet 的 Seed 。

BIP39 定義了這個轉換與還原的規範

以下分別介紹兩個流程

#### 產生 Mnemonic

| Entroy (bits) | Checksum (bits) | Entropy + checksum(bits) | Mnemonic length(words) |
| ------------- | --------------- | ------------------------ | ---------------------- |
| 128           | 4               | 132                      | 12                     |
| 160           | 5               | 165                      | 15                     |
| 192           | 6               | 198                      | 18                     |
| 224           | 7               | 231                      | 21                     |
| 256           | 8               | 264                      | 24                     |

1 根據上表，產生一個合理長度的亂數字串(Entropy)

2 先把亂數做 sha-256 再根據上表分割出 checksum 

3 把 checksum 加入亂數字串的最後

4 把每個位元均分

5 把位元對應到字典裡對應的字

6 把對應的字照順序排出就是 Mnemonic word


![](https://raw.githubusercontent.com/ethereumbook/ethereumbook/develop/images/bip39-part1.png)

#### 從 Mnemonic 產生 Seed

1 把第 6 步驟產生出來的 Mnemonic code 與 一個字首是 "mnemonic" 的加鹽文字帶入 Key stretching function。

2 Key stretching function 是透過 HMAC-sha512 做 2048 次產生出一個 512 bit 的 seed

![](https://raw.githubusercontent.com/ethereumbook/ethereumbook/develop/images/bip39-part2.png)

## 參考文獻

[https://github.com/ethereumbook/ethereumbook/blob/develop/05wallets.asciidoc](https://github.com/ethereumbook/ethereumbook/blob/develop/05wallets.asciidoc)


