本文首发于深刻浅出区块链社区 原文连接:以太坊(安卓)钱包系列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 备注:钱包。