今天和大家說說創(chuàng)建錢包的2種方式的對比蚕脏。
關(guān)于BIP
在創(chuàng)建錢包之前,我建議你先了解一下BIP32
,BIP39
,BIP44
.
這一部分,我先不細講回挽,后面會專門寫一篇關(guān)于BIP協(xié)議的,大家先簡單了解下猩谊。
BIP 全名是 Bitcoin Improvement Proposals千劈,是提出 Bitcoin 的新功能或改進措施的文件∨平荩可由任何人提出墙牌,經(jīng)過審核后公布在 bitcoin/bips 上。BIP 和 Bitcoin 的關(guān)系暗甥,就像是 RFC 之于 Internet喜滨。
而其中的 BIP32
,BIP39
,BIP44
共同定義了目前被廣泛使用的 HD Wallet。
創(chuàng)建錢包的步驟
創(chuàng)建的錢包的流程為:
- 1撤防、隨機生成一組助記詞
- 2虽风、生成 一個種子seed
- 3、根據(jù)seed生成公鑰、私鑰辜膝、地址
- 4陌凳、根據(jù)公鑰、 私鑰内舟、 密碼生成錢包文件合敦,也就是Keystore
/**
* generate a random group of mnemonics
* 生成一組隨機的助記詞
*/
private String generateMnemonics() {
StringBuilder sb = new StringBuilder();
byte[] entropy = new byte[Words.TWELVE.byteLength()];
new SecureRandom().nextBytes(entropy);
new MnemonicGenerator(English.INSTANCE)
.createMnemonic(entropy, sb::append);
return sb.toString();
}
/**
*
* 根據(jù)助記詞和密碼生成種子seed
*/
byte[] seed = new SeedCalculator().calculateSeed(generateMnemonics(), "");
/**
*
* 根據(jù)seed生成公鑰充岛、私鑰等
*/
ECKeyPair ecKeyPair = ECKeyPair.create(Sha256.sha256(seed));
Numeric.toHexStringWithPrefix(ecKeyPair.getPrivateKey());
Numeric.toHexStringWithPrefix(ecKeyPair.getPublicKey());
//根據(jù)公鑰或者ECKeyPair獲取錢包地址
String address = Keys.getAddress(ecKeyPair);
/**
*
* 根據(jù)公鑰 私鑰 密碼 得到 生成錢包文件keystore
*/
WalletFile walletFile = Wallet.createLight(password, keyPair);
第1,2步參考BIP39
這種方案算是正規(guī)流程中較為簡潔的一種耕蝉,很多項目大概也是這種思路,最多生成ECKeyPair那里略有差異垒在。
另外一種簡潔的方案
但是我在網(wǎng)上很多博客充斥著另外一種方案蒜魄,這種方案生成錢包文件特別簡單,但是我研究一番场躯,發(fā)現(xiàn)是有問題的谈为。
//第一個參數(shù)是密碼,第二個參數(shù)是錢包存放的路徑
Bip39Wallet wallet = WalletUtils.generateBip39Wallet("password",file)
//生成12個單詞的助記詞
String memorizingWords = wallet.getMnemonic();
//通過錢包密碼與助記詞獲得錢包地址踢关、公鑰及私鑰信息
Credentials credentials = WalletUtils.loadBip39Credentials(walletPwd,
wallet.getMnemonic());
String address = credentials.getAddress()伞鲫;
String publicKey = credentials.getEcKeyPair().getPublicKey().toString(16);
因為大多平臺生成錢包時,在seed這里對其設(shè)置均為空字符串.签舞,如果使用用戶輸入的密碼作為其密碼,這將使得錢包不能通用
通過查閱generateBip39Wallet()
這個方法的源碼發(fā)現(xiàn)在生成種子seed的時候秕脓,它使用了生成助記詞(也就是我們創(chuàng)建錢包)的那個密碼,這就有問題了儒搭。
大家可以對比一下吠架,通過助記詞生成種子seed的那句代碼,我的第二個參數(shù)搂鲫,也就是密碼傍药,設(shè)置的是空字符串
/**
*
* 根據(jù)助記詞和密碼生成種子seed
*/
byte[] seed = new SeedCalculator().calculateSeed(generateMnemonics(), "");
這里有個注意點:
byte[] seed = new SeedCalculator().calculateSeed(mnemonics, "")
這里的""是BIP39的密碼,.目前大多平臺生成錢包時對其設(shè)置均為空字符串,只有少數(shù)平臺生成錢包使用用戶輸入的密碼作為其密碼,這將使得錢包不能通用。
說到這里大家懂了吧默穴,為了保證錢包的通用性怔檩,也就是說生成的助記詞、私鑰可以在別的錢包導入使用蓄诽,那么你需要在生成seed的時候薛训,把這個bip39密碼設(shè)置為空密碼。
也正是因為目前大多平臺生成錢包時對其設(shè)置均為空字符串,所以我們通過助記詞仑氛、私鑰導入錢包的時候乙埃,是不需要密碼的闸英,讓你填寫的那個密碼是重新設(shè)置的一個新密碼。
好像突然間知道為什么私鑰和助記詞那么重要了介袜,因為別人不需要密碼就能控制你錢包的資產(chǎn)甫何。