1. 程式人生 > >以太坊HD錢包開發 二 —— BIP協議介紹

以太坊HD錢包開發 二 —— BIP協議介紹

以太坊HD錢包開發 一 —— 錢包概念介紹
https://blog.csdn.net/bondsui/article/details/85780452

以太坊HD錢包開發 二 —— BIP協議介紹
https://blog.csdn.net/bondsui/article/details/85780675

以太坊HD錢包開發 三 —— 程式碼實現
https://blog.csdn.net/bondsui/article/details/85780940

文章目錄

4、BIP協議

BIP:Bitcoin Improvement Proposals 比特幣改進建議

BIP32 通過一個隨機種子,提出的為了避免管理一堆私鑰的麻煩提出的分層推導方案。HD錢包(Hierarchical Deterministic Wallets)

BIP39 通過定義助記詞讓種子的備份更友好。

BIP44 BIP32的分層增強了路徑定義規範,同時增加了對多幣種的支援。

ganache錢包示例,如何備份?

Available Accounts
===
=============== (0) 0xfef3d415f66464c3b38e10fd5f31edbead7be44b (~100 ETH) (1) 0xfc26f518d2f7091667dbdd81ee04d1f17d122359 (~100 ETH) (2) 0x5e7363aa3c0669083a554dde5ed548a8ec90ff12 (~100 ETH) (3) 0x57060a8a16bff2615769282eb83d1b50891f04a9 (~100 ETH) (4) 0xc1f109c747e70bbc85371bcb6fbdc8fe23219da9 (~100 ETH) (5) 0x3d25841411dd7917c123d980f4dd33cad101cc31
(~100 ETH) (6) 0x9b477be361d60597e24dd7838d29f706396a3fa1 (~100 ETH) (7) 0x8adffcabe036474de3a6d6f513bfd6df19fbcc1f (~100 ETH) (8) 0x2394c966264c3794247136637e0dc9924dfad3d7 (~100 ETH) (9) 0xbf513ae069d7a58eb4d0f8c6e17402dbe2cc1bee (~100 ETH) Private Keys ================== (0) 0x7c70eaea87e3d568bfcc8758ef9038b2ec640bc86130742a9a5154c5487bb033 (1) 0x7591240850e02d42f00f967aa836bf80c85a8022549a3a37fdc45efdc07db310 (2) 0xd29e3e156168928940d2f2f15a30821b4513919ec0d46aeb3df6c9eb98039ba3 (3) 0xfeb9ea90fe450517044c3d36d199aa2ee8fb81814fce1e1b9f470ebbe7a4fbb0 (4) 0x34c8c7173a5ef0b723aae65a6819aff5c740a8d73a47f1beba8b6e6a31529cc2 (5) 0xfa1cc9d7fd124bfa67b5efc59ef8563139690a634af1e74434902d604228aec8 (6) 0xb98ec5a0902400cc3248046fd869f6e533ec9e05af63f72ca98d2618c6d92b58 (7) 0x3d18f2267377dbafa797aa2e59382e60bee47368c234b5e14e4c3cab40b2adce (8) 0xc09ceed4ddb30bffe0626c1c2663fe5acf80e0f1eb9fa8eeed09172b84c00faa (9) 0xcd2d8a951d2d94c264ba8ad86e23d4751a3ede513131bf19b5c7f566443d8af0

HD &BIP32 提議

BIP

根據一個隨機數種子通過推導方式得到n個私鑰。儲存僅需一個種子就可以推匯出私鑰

https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki

協議名稱:Hierarchical Deterministic Wallets-HD

  • 更好的保護隱私性

  • 多賬號備份麻煩,如果錢包100個賬號

hd錢包推導過程

image-20181226235743427

BIP39-助記詞

https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki

BIP32 避免儲存一個使用者的多個私鑰,可以僅儲存一個隨機種子,而隨機種子為一串16進位制資料,進行冷備份不變。

BIP39 :使用助記詞通過演算法生成種子,這樣使用者只需要記住12個單詞即可(12-24個)

隨機種子

b052ba6a0f2212a003c6b59739ddfff1ee54031041a30a341ab7f26c7319807ca12233e1cc0f8948573e9a83f4e3bd89313627de852f41f719b481af69bb0adb

助記詞

disorder timber among submit tell early claw certain sadness embark neck salad

回顧 我們已經用過的,啟動ganache-cli命令

ganache-cli -m 'disorder timber among submit tell early claw certain sadness embark neck salad' 

回顧 小狐狸匯入賬戶

匯入成功

image-20181227034143356

助記詞流程:

  1. 生成一個128位隨機數
  2. 對隨機數做的校驗4位
  3. 隨機數+校驗碼=132位數
  4. 按每11位做切分,得到array[12]
  5. 助記詞表中查詢
  6. 得到12個單詞為助記詞
  7. 通過助記詞+salt(mnemonic+可選密碼)
  8. 進行HMAC-512雜湊
  9. 得到512bit的隨機種子

單詞表(支援中文

https://github.com/bitcoin/bips/blob/master/bip-0039/bip-0039-wordlists.md

demo

BIP39協議-js

https://www.npmjs.com/package/bip39 6個函式

npm install --save bip39

demo-01bip39.js

const bip39 = require('bip39')

var wordList = bip39.wordlists.chinese_simplified

// 生成助記詞
var mmic = bip39.generateMnemonic(128, ctypto.randomBytes, wordList)
console.log("生成的助記詞為:", mmic)

var mmicHex = bip39.mnemonicToSeedHex(mmic)
console.log("生成的助記詞為:", mmicHex)

// 通過助記詞生成種子
var seed = bip39.mnemonicToSeed(mmic, "your password")
console.log("隨機種子:", seed)

var validate = bip39.validateMnemonic(mmic,wordList)
console.log("合法?", validate)
console.log("修改後合法?", bip39.validateMnemonic(mmic + " ",wordList))

// 助記詞轉換
if (validate) {
    var hex = bip39.mnemonicToEntropy(mmic,wordList);
    console.log("加密後的助記詞:", hex)
    mmic = bip39.entropyToMnemonic(hex,wordList)
    console.log("轉換後的助記詞:", mmic)
}

執行結果

生成的助記詞為: 絲 卵 呼 礙 載 快 賴 邦 權 個 督 吾
生成的助記詞為: 589044554643555c78b40c7b4aa756f018f03e16d4b2bf5bb1af5a8799b512cec350b129fa60186267478ebcc462cefbb3bba5e7273017465cd15bf3
隨機種子: <Buffer bf 87 c9 21 49 8a 06 c6 8b eb 0d 96 87 66 ff a1 cf af 14 49 cb 21 99 2d 83 45 53 da0 21 21 4b f7 17 9c 89 68 a3 6d 4c b0 e2 15 39 20 f1 11 a9 d3 ... >
合法? true
修改後合法? false
加密後的助記詞: 589991cf5cd56671383566256039c5f6
轉換後的助記詞: 絲 卵 呼 礙 載 快 賴 邦 權 個 督 吾

BIP39協議-go-瀏覽即可

  • bip32 分層確定性錢包 建立賬號
  • bip39 助記詞 備份賬號
  • eth賬戶匯入匯出的功能
  • go語言編寫,基礎回顧

BIP32相關函式

// 生成隨機數種子
seed, _ := bip32.NewSeed()

// 生成 masterkey
masterKey, _ := bip32.NewMasterKey(seed)

// 通過masterkey得到privatekey
childIdx = 0;
privateKey, _ := masterKey.NewChildKey(childIdx)
//通過childkey 得到publickKey
publicKey := privateKey.PublicKey()

demo-bip32.go

/*
@Time   :   2018-12-27 01:32
@Author :   suibingyue
@File   :   demo-bip32 分層確定性錢包
*/

package main

import (
	"fmt"
	"github.com/tyler-smith/go-bip32"
)

func main() {
	// 隨機種子
	seed, _ := bip32.NewSeed()
	// 生成 masterkey
	masterKey, _ := bip32.NewMasterKey(seed)
	fmt.Println("masterKey:", masterKey)

	accounts0 := genAccountsFromMasterKey(masterKey)
	genAccountsFromMasterKey(accounts0[0])
}

// 根據種子生成賬戶
func genAccountsFromMasterKey(masterKey *bip32.Key) []*bip32.Key {

	// 儲存賬戶key
	var privKeys []*bip32.Key
	var pubKeys []*bip32.Key

	for i := 0; i < 3; i++ {

		// 得到childkey
		privKey, _ := masterKey.NewChildKey(uint32(i))
		//通過childkey 得到publickKey
		pubKey := privKey.PublicKey()

		privKeys = append(privKeys, privKey)
		pubKeys = append(pubKeys, pubKey)
	}

	fmt.Println("\n Public keys,深度為", pubKeys[0].Depth)
	for index, key := range pubKeys {
		fmt.Printf(" %d %x\n", index, key.Key)
	}

	fmt.Println("\n Private keys 深度為", pubKeys[0].Depth)
	for index, key := range privKeys {
		fmt.Printf(" %d %x\n", index, key.Key)
	}
	return privKeys
}

bip39相關函式

	// 生成隨機數
	entropy, _ := bip39.NewEntropy(256)
	// 生成助記詞
	mmic, _ := bip39.NewMnemonic(entropy)
	// 根據助記詞密碼生成種子
	seed := bip39.NewSeed(mmic, "suibingyue")

demo-bip39.go

package main

import (
	"fmt"
	"github.com/tyler-smith/go-bip32"
	"github.com/tyler-smith/go-bip39"
)

func main() {
	// 生成隨機數
	entropy, _ := bip39.NewEntropy(256)

	// 生成助記詞
	mmic, _ := bip39.NewMnemonic(entropy)
	fmt.Println("生成的助記詞 ", mmic)

	//根據助記詞密碼生成隨機種子
	seed := bip39.NewSeed(mmic, "")
	fmt.Printf("生成的 seed %x \n", seed)
	// 根據隨機種子生成主key
	masterKey, _ := bip32.NewMasterKey(seed)
	fmt.Printf("生成的 masterKey %x \n", masterKey.Key)

	fmt.Println("===電腦不安全,寫進我的日記本里====")

	fmt.Println("匯入的助記詞 ", mmic)
	seed2 := bip39.NewSeed(mmic, "")
	fmt.Printf("匯入的seed %x \n", seed2)

	masterKey2, _ := bip32.NewMasterKey(seed2)
	fmt.Printf("匯入的 masterKey %x \n", masterKey2.Key)
}

執行結果


有了masterKey,我們就可以使用BIP32協議,根據mastKey建立HD分層賬號

同一個包下,執行失敗?

image-20181227045454070

原因分析:go檔案編譯執行過程 build -> run

image-20181227045730313

解決辦法 進入到根目錄,執行*go build .go,執行完成後,會生成兩個可執行檔案,執行即可

或者*go run .go

注意,同一個包下只能有一個main函式

➜  gowork cd src/go6eth錢包 
➜  go6eth錢包 go build *.go
➜  go6eth錢包 ls
demo-bip32             demo-bip39助記詞.go
demo-bip32.go          go6eth錢包
➜  go6eth錢包 ./go6eth錢包 

BIP44 規範

為分層確定性錢包定義的一個邏輯層次結構規範,大部分幣種,基於BIP32

https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki

Path levels:

m / purpose' / coin_type' / account' / change / address_index

有了HD分層錢包,錢包備份就無需備份多個私鑰,只需備份一份隨機種子的檔案即可。