上週我開源了一款錢包,反映很好,一週時間不到已經快到100 Star。接下來我會幾篇系列文章把開發以太坊錢包的核心要點寫出來,也算是對代碼的一個解讀。
## 寫在前面 錢包是使用Android安卓平臺編寫,使用的是原生代碼Java 語言編寫, 是基於Java 1.8 版本,也使用了Java 1.8 中一些較新的語言特性,如 Lambda表達式等;另外還較多使用了[ReactiveX/RxAndroid](https://github.com/ReactiveX/RxAndroid/)響應式編程用法。 在本系列文章中,重點是介紹以太坊錢包賬號、交易等邏輯,有時可能會假定讀者已經瞭解Android開發等相關知識,因爲這些內容不是文章的重點,因此不會過多介紹,請海涵。 ## 錢包包含的功能 通常一個錢包會包含以下功能: - [x] 支持通過生成助記詞、Keystore文件、私鑰 創建錢包賬號。 - [x] 支持導出錢包賬號助記詞、私鑰、Keystore文件。 - [x] 支持多個錢包賬號管理 - [x] 賬戶餘額查詢及轉賬功能(二維碼掃描支持)。 - [x] 支持ERC20 代幣(餘額顯示、轉賬、代幣幣價顯示) - [x] 支持用法幣(美元和人民幣)實時顯示幣價。 - [x] 歷史交易列表顯示 ## 創建賬號預備知識 我們先來介紹第一個功能:通過生成助記詞、Keystore文件、私鑰創建錢包賬號。 本系列中,錢包都是指分層確定性錢包,(HD錢包 Hierarchical Deterministic Wallets), 之前博客有一篇文章[分層錢包](https://learnblockchain.cn/2018/09/28/hdwallet/)進行了詳細的介紹,還不熟悉的可以讀一下。 爲了保持本文的完整,這裏做一個總結性回顧:以太坊及比特幣的**地址是由隨機生成的私鑰經過橢圓曲線等算法單向推倒而來** ,BIP32及BIP44是爲方便管理私鑰提出的分層推倒方案,BIP39 定義助記詞讓分層種子的備份更方便。 而KeyStore文件是用來解密以太坊保存私鑰的一種方式,大家可以閱讀下[這篇文章: 賬號Keystore文件導入導出](https://learnblockchain.cn/2018/10/25/eth-web-wallet_2/)瞭解更多。 實現完成的,界面如下圖: ![](https://learnblockchain.cn/images/1551843006.png) 這是一張導入錢包賬號的截圖(導入和創建,其實原理一樣),界面仿照ImToken,不過本文將不會介紹UI部分的編寫。 ### Web3j & bitcoinj 爲了完成創建賬號功能,我們需要使用到兩個庫:[Web3j](https://github.com/web3j/web3j/) 和 [bitcoinj](https://github.com/bitcoinj/bitcoinj) Web3是一套和以太坊通信的封裝庫,Web3j是Java版本的實現,例如發起交易和智能合約進行交互,下圖很好的表達了其作用。 ![](https://learnblockchain.cn/images/15525530768209.jpg) 不過本文中的功能,主要是使用了web3j中橢圓曲線加密及KeyStore文件的生成與解密。 bitcoinj 的功能和web3類似,它是比特幣協議的Java實現,他實現了 BIP32、BIP44及BIP39 相關協議。 Android使用Gradle來構建,直接在`app/build.gradle`文件中加入: ``` implementation 'org.web3j:core:4.1.0-android' implementation 'org.bitcoinj:bitcoinj-core:0.14.7' ``` > 提示: 實踐中遇到的一個問題,由於bitcoinj 中引入了 `com.lambdaworks:scrypt`加密庫, 它包含的`lib/x86_64/darwin/libscrypt.dylib`文件,會導致在進行Android App Bundle 編譯時會出現錯誤(好像也會導致某些機型沒法安裝),解決辦法是在 build.gradle 加入一下語句,把這個文件在打包時排除掉。 > packagingOptions { > exclude 'lib/x86_64/darwin/libscrypt.dylib' > } ## 創建賬號實現 ### 通過助記詞常見錢包賬號 這是目前錢包客戶端,最常見的一種爲用戶常見賬號的方式,這裏會包含一下幾個核心步驟: 1. 生成一個隨機數種子; 2. 通過隨機數種子得到助記詞; 3. 通過 種子 + 路徑 派生生成私鑰; 4. 使用KeyStore保存私鑰; 5. 私鑰推倒出賬號地址。 大家可以在再次閱讀[分層錢包](https://learnblockchain.cn/2018/09/28/hdwallet/),理解爲何這麼做的原因。 理解了上面幾點,那麼代碼就容易明白了,代碼在[代碼庫](https://github.com/xilibi2003/Upchain-wallet)中的`app/src/pro/upchain/wallet/utils/ETHWalletUtils.java`中,關鍵代碼邏輯如下: ```java // 創建錢包對象入口函數 public static ETHWallet generateMnemonic(String walletName, String pwd) { String[] pathArray = "m/44'/60'/0'/0/0".split("/"); long creationTimeSeconds = System.currentTimeMillis() / 1000; SecureRandom secureRandom = SecureRandomUtils.secureRandom(); DeterministicSeed ds = new DeterministicSeed(secureRandom, 128, "", creationTimeSeconds); return generateWalletByMnemonic(walletName, ds, pathArray, pwd); } /** * @param walletName 錢包名稱 * @param ds 助記詞加密種子 * @param pathArray 助記詞標準 * @param pwd 密碼 * @return */ @Nullable public static ETHWallet generateWalletByMnemonic(String walletName, DeterministicSeed ds, String[] pathArray, String pwd) { //種子 byte[] seedBytes = ds.getSeedBytes(); //助記詞 List如何開發一款以太坊(安卓)錢包系列1 - 通過助記詞創建賬號
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.