1. HD錢包簡介
Hierarchical Deterministic wallet (簡稱 "HD Wallet"),是目前最常用的分層確定性錢包,BIP32是HD Wallet的核心提按。確定性錢包特點是可以通過一個主私鑰可以推導出多個子私鑰,各個子私鑰可以獨立使用且互不影響。這樣就能簡化系統中地址管理的問題,無需大量備份私鑰,只需要備份主私鑰即可。
2.相關提案
BIP32是 HD Wallet的核心提案,通過種子來生成主私鑰,然后派生海量的子私鑰和地址。
BIP39是通過算法將種子轉化成方便記憶的助記詞來保存,也可以將助記詞轉化成種子,通過BIP32來找回私鑰和子私鑰
BIP44是對BIP32路徑的一種規范,用於擴展和支持更多幣種,五層建議路徑如下:
m/purpse’/coin_type’/account’/change/address_index
3.錢包創建過程
- 生成一個助記詞
- 將助記詞使用 PBKDF2 轉化為種子
- 把種子使用 HMAC-SHA512 生成根私鑰
- 通過根私鑰導出子私鑰
- 通過子私鑰推導出子公鑰,並生成地址
4.PHP實踐
1. 項目依賴
bitcoin-php bitcoin的php實現庫,用於創建助記詞和生成私鑰
ethereum-util 以太坊常用函數php實現庫
composer require bitwasp/bitcoin
composer require web3p/ethereum-util
2. 創建助記詞
<?php
require_once './vendor/autoload.php';
use BitWasp\Bitcoin\Bitcoin;
use BitWasp\Bitcoin\Crypto\Random\Random;
use BitWasp\Bitcoin\Key\Factory\HierarchicalKeyFactory;
use BitWasp\Bitcoin\Mnemonic\Bip39\Bip39Mnemonic;
use BitWasp\Bitcoin\Mnemonic\Bip39\Bip39SeedGenerator;
use BitWasp\Bitcoin\Mnemonic\MnemonicFactory;
use Web3p\EthereumUtil\Util;
// Bip39
$math = Bitcoin::getMath();
$network = Bitcoin::getNetwork();
$random = new Random();
// 生成隨機數(initial entropy)
$entropy = $random->bytes(Bip39Mnemonic::MIN_ENTROPY_BYTE_LEN);
$bip39 = MnemonicFactory::bip39();
// 通過隨機數生成助記詞
$mnemonic = $bip39->entropyToMnemonic($entropy);
echo "mnemonic: " . $mnemonic.PHP_EOL.PHP_EOL;
3. 助記詞產生主私鑰和主公鑰
$seedGenerator = new Bip39SeedGenerator();
// 通過助記詞生成種子,傳入可選加密串'hello'
$seed = $seedGenerator->getSeed($mnemonic, 'hello');
echo "seed: " . $seed->getHex() . PHP_EOL;
$hdFactory = new HierarchicalKeyFactory();
$master = $hdFactory->fromEntropy($seed);
// 私鑰
echo "master private key: " . $master->getPrivateKey()->getHex().PHP_EOL;
// 公鑰
echo "master public key: " . $master->getPublicKey()->getHex().PHP_EOL.PHP_EOL;
4. 批量生成主私鑰生成子私鑰、子公鑰和地址
$count = 5; // 生成以太坊賬戶數量
$util = new Util();
for($i = 0; $i < $count; $i++){
echo "Bip44 ETH account $i ".PHP_EOL;
// 設置路徑account
$hardened = $master->derivePath("44'/60'/$i'/0/0");
echo " - m/44'/60'/$i'/0/0 " .PHP_EOL;
echo " public key: " . $hardened->getPublicKey()->getHex().PHP_EOL;
echo " private key: " . $hardened->getPrivateKey()->getHex().PHP_EOL;
echo " address: " . $util->publicKeyToAddress($util->privateKeyToPublicKey($hardened->getPrivateKey()->getHex())) . PHP_EOL .PHP_EOL;
}
5. 輸出結果
[root@localhost hdwallet]# php index.php
mnemonic: plug cruel online phone truck nerve demand install output banner argue curtain
seed: 421971b801198a558019b8125f265d97a6e49e2b7417f7bd62d5a4b605105e0906826464fab6b692ad142ab9bdfdfbc66a20dc90c8cf907116bd90be8ed77990
master private key: 3fe8ed9915bb004d8b5c382ea7c3ac9b1a24ae6b3e22b2220c1e9199a6f05f27
master public key: 023c9e0f243b20294c72faf50a7cc5377c8d90a1f981637274c7aba58c09593145
Bip44 ETH account 0
- m/44'/60'/0'/0/0
public key: 03e987f0785c348f769b2985e8f6c5c0c9a7dc446d801e523fa34416734f6f64e0
private key: 41244ee7454c55e42ba0415b32c429019b89749669ba6261cc37918dc3c4ae9e
address: 0xe641616129b110793c4948e98fb3640df30843bf
Bip44 ETH account 1
- m/44'/60'/1'/0/0
public key: 026cd01553c9a6ca4d0ce9fc5dfaddd28f4650acd39bb9ee8d4d3dde3468cc0a47
private key: 39d6458463d8348dc122f865bebc4fc569109c60bd9b30597230abfbb5feb23b
address: 0xe062b7b81760cc1e868248609e3427fbb537d8b7
Bip44 ETH account 2
- m/44'/60'/2'/0/0
public key: 03d30cd704d44f0e9d7a0fc98d0a1a09c4c112cff8f82f05decbe242cd30cf6190
private key: ef44777c281bf53e03c545da42f4208c9430b8b97347ac6917260ca5f09991fe
address: 0x2aa967ce81255060d8399f4c5d37971f7c35d3cb
Bip44 ETH account 3
- m/44'/60'/3'/0/0
public key: 0249cdbb22f026a1b2fa63974c6d2fdcadda265f446233f410b2ea815fc19a7a87
private key: acb2d47f8cec828432bc88053cb290cd128088b9a3242ace0f877eeba2750d6f
address: 0x7edf10c54db8875f902f1a2b454025e6bb613ec2
Bip44 ETH account 4
- m/44'/60'/4'/0/0
public key: 034cc0f9198c72593011273adc9be8e230b68a98d45db2de708dc4cf0afd8ab1d2
private key: d286f55c0e9351c904bdfef0609d2930b8b52d0f8b824943afbc9370aead9460
address: 0x895b6e9555f784b73d4458e263acc04d7b4232ba
5.總結
通過HD Wallet,可以方便的生成海量賬戶,具體應用在虛擬貨幣交易所,去中心化錢包等場景,方便備份私鑰。通過冷錢包的方式,主私鑰不與外網接觸,利用主公鑰來生成多個子公鑰以及對應的地址,能夠大大提高資產的安全性,降低風險。
6.參考
https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
https://github.com/web3p/ethereum-tx
https://github.com/Bit-Wasp/bitcoin-php
https://github.com/satoshilabs/slips/blob/master/slip-0044.md