-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1217 from yihanga/main
feat: add BTC HDWallet
- Loading branch information
Showing
5 changed files
with
161 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
HD钱包,全称为分层确定性钱包(Hierarchical Deterministic Wallet),是一种通过单一的种子(Seed)生成和管理多个密钥对的数字钱包。这种结构使得用户只需备份一次种子,即可控制所有衍生出的私钥和公钥,极大地简化了密钥管理的复杂性。 | ||
|
||
**HD钱包的主要特点:** | ||
|
||
1. **分层结构:** HD钱包采用树状结构,根节点由主密钥(Master Key)组成,子节点为从主密钥派生出的子密钥。这种分层设计允许用户根据需要生成不同层级的密钥,方便管理和分配。 | ||
|
||
2. **确定性:** 通过相同的种子,HD钱包可以生成相同的密钥序列。这意味着只要备份了种子,就可以在任何时候恢复所有的密钥和地址。 | ||
|
||
3. **增强的隐私性:** HD钱包可以为每笔交易生成不同的地址,避免重复使用同一地址,从而提高交易的隐私性。 | ||
|
||
**HD钱包的工作原理:** | ||
|
||
- **种子生成:** 用户首先生成一个随机数作为种子,通常通过助记词(Mnemonic)表示。助记词是一组易于记忆的单词序列,用于表示种子。 | ||
|
||
- **主密钥派生:** 通过种子,使用特定的算法(如HMAC-SHA512)生成主私钥和主公钥。 | ||
|
||
- **子密钥派生:** 从主密钥可以派生出多个子密钥,每个子密钥又可以派生出自己的子密钥,形成树状结构。这种派生过程可以根据需要进行多层次的扩展。 | ||
|
||
**HD钱包的优势:** | ||
|
||
- **简化备份:** 用户只需备份一次种子或助记词,即可恢复所有的密钥和地址,避免了逐个备份每个私钥的麻烦。 | ||
|
||
- **灵活的密钥管理:** 分层结构允许用户根据不同的用途或账户生成不同的子密钥,方便管理。 | ||
|
||
- **增强的安全性:** 通过生成不同的地址,减少了地址关联性,提升了交易的隐私性和安全性。 | ||
|
||
**HD钱包的标准:** | ||
|
||
HD钱包的概念最早由BIP32提案提出,随后BIP39引入了助记词的标准,BIP44则定义了多币种、多账户的路径标准。这些标准共同构建了当前HD钱包的基础。 | ||
|
||
**注意事项:** | ||
|
||
- **妥善保管助记词:** 助记词是恢复钱包的唯一凭证,一旦丢失或泄露,可能导致资产无法找回或被盗。 | ||
|
||
- **定期备份:** 虽然HD钱包简化了备份过程,但仍需定期检查备份的有效性,确保在需要时能够成功恢复。 | ||
|
||
总的来说,HD钱包通过分层确定性的设计,提供了高效、安全且灵活的密钥管理方式,已成为当前数字货币钱包的主流选择。 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
HD钱包(Hierarchical Deterministic Wallet)通过分层确定性结构生成和管理密钥对。其核心在于通过种子生成主密钥,然后通过分层推导生成多个子密钥。这种方式使得密钥管理变得简单、安全,用户只需备份种子即可恢复整个钱包。以下是HD钱包的详细技术细节和子密钥推导过程。 | ||
|
||
### 1. **HD钱包结构概述** | ||
- **种子(Seed)**:HD钱包从一个随机生成的种子开始,该种子通过助记词(BIP39)表示。 | ||
- **主密钥(Master Key)**:由种子生成,包含主私钥、主公钥和链码。 | ||
- **链码(Chain Code)**:用于生成子密钥,是密钥派生过程中的关键成分。 | ||
- **子密钥**:从主密钥派生而来,每个子密钥都有自己的私钥、公钥和链码。 | ||
|
||
### 2. **种子生成** | ||
- **助记词**:助记词由熵(随机位数)通过哈希和校验生成。例如,一个128位的熵可以生成12个助记词。 | ||
- **种子生成算法**: | ||
- 助记词经过PBKDF2(Password-Based Key Derivation Function 2)算法与一个盐值(通常是 `mnemonic` + 密码短语)组合,生成512位种子。 | ||
|
||
### 3. **主密钥生成** | ||
- 使用HMAC-SHA512算法,以种子作为输入,和常量字符串“Bitcoin seed”作为HMAC密钥来生成512位输出。 | ||
- 输出前256位为主私钥(`m`),后256位为链码(`c`)。 | ||
|
||
**HMAC计算公式**: | ||
``` | ||
I = HMAC-SHA512(key="Bitcoin seed", data=seed) | ||
``` | ||
``` | ||
master_private_key = I[0:32] | ||
master_chain_code = I[32:64] | ||
``` | ||
|
||
### 4. **子密钥推导过程** | ||
子密钥推导是HD钱包中生成子密钥的核心过程,可以通过**标准派生**和**硬化派生**来实现。 | ||
|
||
#### a. **标准派生(Non-hardened derivation)** | ||
- 使用父公钥和链码推导子公钥,公钥和链码可以生成下一级的公钥链,但无法推导出私钥。 | ||
- 算法: | ||
``` | ||
I = HMAC-SHA512(key=cpar, data=serP(Kpar) || ser32(i)) | ||
``` | ||
- `cpar`:父链码。 | ||
- `serP(Kpar)`:父公钥的序列化形式。 | ||
- `ser32(i)`:索引值的32位表示。 | ||
- `I` 分成两部分:`IL`(左半部分)和 `IR`(右半部分)。 | ||
|
||
- 子私钥计算公式: | ||
``` | ||
ki = (IL + kpar) % n | ||
ci = IR | ||
``` | ||
- `ki`:子私钥。 | ||
- `n`:椭圆曲线的阶。 | ||
|
||
#### b. **硬化派生(Hardened derivation)** | ||
- 使用父私钥生成子私钥。硬化派生增加了安全性,不能从子公钥推导出父密钥。 | ||
- 算法: | ||
``` | ||
I = HMAC-SHA512(key=cpar, data=0x00 || ser256(kpar) || ser32(i)) | ||
``` | ||
- `0x00` 前缀用于表示该派生使用的是私钥。 | ||
- `kpar` 是父私钥。 | ||
- `ci = IR` 是子链码。 | ||
|
||
- 子私钥计算公式: | ||
``` | ||
ki = (IL + kpar) % n | ||
ci = IR | ||
``` | ||
|
||
### 5. **路径表示** | ||
BIP44引入了用于多币种和多账户的标准路径表示: | ||
``` | ||
m / purpose' / coin_type' / account' / change / address_index | ||
``` | ||
- **`purpose'`**:通常为44',表示使用BIP44规范。 | ||
- **`coin_type'`**:用于区分不同的加密货币,比如0'代表比特币,60'代表以太坊。 | ||
- **`account'`**:账户编号,用于分离不同的账户。 | ||
- **`change`**:0表示外部地址,1表示找零地址。 | ||
- **`address_index`**:地址在账户中的索引。 | ||
|
||
同时在BIP49和BIP84中也基于BIP44做了扩展,形成我们现在经常见到的BTC多个地址 | ||
|
||
#### Legacy地址 - BIP44 | ||
![Legacy:BIP44](./imgs/hd-wallets-derivation-paths-bip44.png) | ||
|
||
#### P2SH地址 - BIP49 | ||
![Legacy:BIP49](./imgs/hd-wallets-derivation-paths-bip49.png) | ||
|
||
#### P2WPKH地址 - BIP84 | ||
![Legacy:BIP84](./imgs/hd-wallets-derivation-paths-bip84.png) | ||
|
||
|
||
### 6. **ECC与HD钱包** | ||
HD钱包使用椭圆曲线加密(Elliptic Curve Cryptography, ECC)来确保公钥和私钥的安全性。公钥由私钥通过椭圆曲线点乘生成。标准加密算法如 `secp256k1` 在HD钱包中被广泛使用。 | ||
|
||
**公钥生成公式**: | ||
``` | ||
P = k * G | ||
``` | ||
- `P` 是公钥,`k` 是私钥,`G` 是椭圆曲线的生成点。 | ||
|
||
### 7. **实现细节示例** | ||
使用JavaScript库实现HD钱包的生成和子密钥推导: | ||
|
||
```javascript | ||
const bip32 = require('bip32'); | ||
const bip39 = require('bip39'); | ||
|
||
// 生成助记词和种子 | ||
const mnemonic = bip39.generateMnemonic(); | ||
const seed = bip39.mnemonicToSeedSync(mnemonic); | ||
|
||
// 从种子生成HD钱包根节点 | ||
const root = bip32.fromSeed(seed); | ||
|
||
// 派生路径:m/44'/0'/0'/0/0 | ||
const child = root.derivePath("m/44'/0'/0'/0/0"); | ||
|
||
console.log('助记词:', mnemonic); | ||
console.log('子公钥:', child.publicKey.toString('hex')); | ||
console.log('子私钥:', child.toWIF()); | ||
``` | ||
|
||
### 8. **安全性与注意事项** | ||
- **助记词备份**:确保助记词安全存储,一旦丢失或泄露,可能导致资产永久损失或被盗。 | ||
- **硬化派生的使用**:硬化派生确保公钥无法推导出父级私钥,提高了安全性,建议在生成重要的子密钥时使用。 | ||
|
||
### **总结** | ||
HD钱包通过分层结构和确定性算法,为用户提供了简单的密钥管理方式。其分层树结构和子密钥推导机制使得一个种子就能生成无限数量的私钥和公钥,极大地提高了用户体验和安全性。 |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.