本文首發於深刻淺出區塊鏈社區 原文連接:以太坊(安卓)錢包系列2 - 導入帳號及帳號管理原文已更新,請讀者前往原文閱讀java
這是如何開發一款以太坊(安卓)錢包系列第2篇,如何導入帳號。有時用戶可能已經有一個帳號,這篇文章接來介紹下,如何實現導入用戶已經存在的帳號。git
從用戶需求上來說,導入用戶已經存在的帳號是有必要的。 不過從安全性考慮,當你以前使用的是一個非官方、非開源的錢包產品時(尤爲是小衆錢包),或者以前沒有對私鑰、助記詞、Keysotre文件當心保存時。 正確的作法是提示用戶:github
導入帳號有3種方式:web
關鍵是用用戶輸入的私鑰建立一個橢圓曲線祕鑰對,而後用這個祕鑰對建立錢包,代碼以下: (代碼在代碼庫中的app/src/pro/upchain/wallet/utils/ETHWalletUtils.java
文件中)數據庫
public static ETHWallet loadWalletByPrivateKey(String privateKey, String pwd) {
Credentials credentials = null;
ECKeyPair ecKeyPair = ECKeyPair.create(Numeric.toBigInt(privateKey));
return generateWallet(generateNewWalletName(), pwd, ecKeyPair);
}
複製代碼
返回語句中的 generateWallet(),在系列1-經過助記詞建立帳號 已經介紹過,經過橢圓曲線祕鑰對建立錢包。編程
loadWalletByPrivateKey()中第2個參數密碼pwd,在私鑰生成帳號這個過程並不須要pwd,它是用來加密保存私鑰,即爲了生成keystore文件。json
關於KeyStore文件,不瞭解的能夠閱讀下帳號Keystore文件導入導出。安全
關鍵步驟:bash
/** * @param keystore 原json文件內容 * @param pwd keystore解密密碼 * @return */
public static ETHWallet loadWalletByKeystore(String keystore, String pwd) {
try {
WalletFile walletFile = null;
walletFile = objectMapper.readValue(keystore, WalletFile.class);
return generateWallet(generateNewWalletName(), pwd, Wallet.decrypt(pwd, walletFile));
} catch (IOException e) {
} catch (CipherException e) {
}
return null;
}
複製代碼
導入和上一篇中,建立很是類似,不一樣的是,種子由用戶提供的助記詞生成。微信
使用助記詞導入帳號時,還須要用戶選擇(或輸入)一個推倒路徑(參考BIP44),關鍵步驟是:
/** * 經過導入助記詞,導入錢包 * * @param path bip44路徑 * @param list 助記詞 * @param pwd 密碼 * @return */
public static ETHWallet importMnemonic(String path, String mnemonic, String pwd) {
List<String> list = Arrays.asList(mnemonic.split(" "));
if (!path.startsWith("m") && !path.startsWith("M")) {
//參數非法
return null;
}
String[] pathArray = path.split("/");
if (pathArray.length <= 1) {
//內容不對
return null;
}
String passphrase = "";
long creationTimeSeconds = System.currentTimeMillis() / 1000;
DeterministicSeed ds = new DeterministicSeed(list, null, passphrase, creationTimeSeconds);
return generateWalletByMnemonic(generateNewWalletName(), ds, pathArray, pwd);
}
複製代碼
generateWalletByMnemonic在上一篇中已經介紹過,
不少同窗確定已經注意到, 無論經過什麼方式構造的帳號,都會最終構造爲一個ETHWallet 錢包對象,他的定義以下:
@Entity
public class ETHWallet {
@Id(autoincrement = true)
private Long id;
public String address;
private String name;
private String password; // 通過加密後的pwd
private String keystorePath;
private String mnemonic;
private boolean isCurrent; // 是不是當前選中的錢包
private boolean isBackup; // 是否備份過
}
複製代碼
前面構造的ETHWallet是隻存在於內容之中, 在應用程序退出以後,這個數據將丟失, 所以咱們須要把它序列化到 序列化數據庫中存儲起來,在下一次進入應用的時候加載數據庫還原出帳號。
greenDAO 是一個將對象映射到 SQLite 數據庫中的輕量且快速的 ORM 解決方案,如下是一個greenDAO的做用示意圖:
這裏咱們也使用了 greenDAO 來把ETHWallet對象映射到 SQLite 數據庫, greenDAO的用法這裏只簡單說明,不詳細闡述,你們能夠跟隨官方提供的introduction 和 how-to-get-started。
把ETHWallet映射的到數據庫,須要給類加上@Entity註解,這樣greenDAO會生成幾個類:DaoMaster
、DaoSession
及 ETHWalletDao
幫咱們完成構建數據庫表等操做。
在使用ETHWalletDao插入到數據庫以前須要先進行一個初始化,一般初始化放在應用程序入口中進行,如:pro.upchain.wallet.UpChainWalletApp的onCreate()中執行,初始化代碼以下:
protected void init() {
DaoMaster.DevOpenHelper mHelper = new DaoMaster.DevOpenHelper(this, "wallet", null);
SQLiteDatabase db = mHelper.getWritableDatabase();
DaoSession daoSession = new DaoMaster(db).newSession();
ETHWalletDao ethWalletDao = daoSession.getETHWalletDao();
}
複製代碼
有了greenDAO爲咱們生成的輔助類,插入到數據庫就很簡單了,一行代碼:
ethWalletDao.insert(ethWallet); //
複製代碼
ethWallet爲ETHWallet實例, 前面不論是新建立仍是導入的帳號都會構造這樣一個實例。
考慮到用戶可能會建立多個帳號,所以須要肯定一個當前選定的帳號,通常狀況下,用戶新建立的帳號應該做爲當前選中的的帳號,同時其餘帳號應該取消選中, 咱們完善下帳號存儲邏輯, 以下: (代碼在代碼庫中的app/src/pro/upchain/wallet/utils/WalletDaoUtils.java
文件中)
/** * 插入新建立錢包 * * @param ethWallet 錢 */
public static void insertNewWallet(ETHWallet ethWallet) {
updateCurrent(-1); // 取消其餘站帳號選中狀態
ethWallet.setCurrent(true);
ethWalletDao.insert(ethWallet);
}
/** * 更新選中錢包 * * @param id 錢包ID */
public static ETHWallet updateCurrent(long id) {
// 加載全部錢包帳號
List<ETHWallet> ethWallets = ethWalletDao.loadAll();
ETHWallet currentWallet = null;
for (ETHWallet ethwallet : ethWallets) {
if (id != -1 && ethwallet.getId() == id) {
ethwallet.setCurrent(true);
currentWallet = ethwallet;
} else {
ethwallet.setCurrent(false);
}
ethWalletDao.update(ethwallet);
}
return currentWallet;
}
複製代碼
以經過私鑰導入帳號進行保存爲例,把建立帳號和保存帳號打通,這裏咱們使用響應式編程 ReactiveX, 這部分做爲訂閱者福利,發表在個人小專欄,趁還未漲價,趕忙訂閱吧,超值的!
我建立了一個專門討論錢包開發的微信羣,加微信:xlbxiong 備註:錢包。