此项目为以前个人区块链钱包项目抽出的部分,其中包含ETH钱包生成、导入等基础功能,以及BTC钱包地址生成过程和使用的算法。感谢前人的探索,这里只是总结,希望对你有所帮助。
此项目基于web3j开发的一个android的ETHWallet,其中包含了助记词生成、创建钱包、导入钱包等基础方法。 使用原生web3j生成ECKeyPair的时候 低端机型(华为P6)会闪退,原因是算法复杂度高,CPU使用过高,java运行的速度慢。解决方法把当需要调用web3j 调用SCrypt.scrypt()方法的时候把java算法换成使用JNI C库中的代码
EthWalletManager wManager = new EthWalletManager(); wManager.createWallet(walletName, password, passwordHit, false, new EthWalletCallBack() { @Override public void onSuccessCallBack(EthWallet ethWallet, String fileName, String walletAddress, String storeText) throws Exception { } @Override public void onErrorCallBack(Exception e) { } });
//三种方法导入 EthWalletManager wManager = new EthWalletManager(); ECKeyPair ecKeyPair = wManager.generateECKeyPairByMnemonicWords(mnemonicWordsInAList, password);//助记词导入钱包 ECKeyPair ecKeyPair = wManager.generateECKeyPairByKeyStore(keystore_content, password) //keystore导入钱包 ECKeyPair ecKeyPair = wManager.generateECKeyPairByPK(pk_text, password);//私钥导入钱包 wManager.importWallet(ecKeyPair, walletName, password, passwordHit, mnemonicWords, new EthWalletCallBack() { @Override public void onSuccessCallBack(EthWallet ethWallet, String fileName, String walletAddress, String storeText) throws Exception { } @Override public void onErrorCallBack(Exception e) { } });
如果想把助记词换成日文、法文、中文等(自己在BIP39,wordlists包创建),Japanese.INSTANCE 或者 French.INSTANCE
//随机生成助记词 StringBuilder sb = new StringBuilder(); byte[] entropy = new byte[Words.TWELVE.byteLength()];// 12个 英文单词 new SecureRandom().nextBytes(entropy); new MnemonicGenerator(English.INSTANCE).createMnemonic(entropy, sb::append); System.out.println(sb.toString()); String[] parts = sb.toString().split(" ");
BtcWallet btcWallet = new BtcWallet(); //助记词种子 byte byte[] seed = getSeed(mnemonicWordsInAList); DeterministicSeed deterministicSeed = new DeterministicSeed(mnemonicWordsInAList, seed, "", 0); DeterministicKeyChain deterministicKeyChain = DeterministicKeyChain.builder().seed(deterministicSeed).build(); //这里运用了BIP44里面提到的算法, 44'是固定的, 后面的一个0'代表的是币种BTC //EIP85 提议 以太坊 路径为 : m/44'/60'/a'/0/n //这里 的 a 表示帐号,n 是第 n 生成的地址,60 是在 SLIP44 提案中暂定的,因为 BIP44 只定义到 0 - 31。 byte[] privKeyBTC = deterministicKeyChain.getKeyByPath(parsePath("M/44/0/0/0/" + n), true).getPrivKeyBytes(); // 比特币创建的钱包 与连接的网有关,如果选TestNet生成的地址一般是以 N \M 开头,MainNet生成的地址是以 1 \ 3开头 ECKey ecKey = ECKey.fromPrivate(privKeyBTC); String publickey = Numeric.toHexStringNoPrefixZeroPadded(new BigInteger(ecKey.getPubKey()), 66); String privateKey = ecKey.getPrivateKeyEncoded(MainNetParams.get()).toString(); System.out.println(" ----------------主钱包的 主公私钥 和地址---------------------------"); System.out.println("主 address:" + ecKey.toAddress(MainNetParams.get()).toBase58()); System.out.println("测 address:" + ecKey.toAddress(TestNet3Params.get()).toBase58()); System.out.println(" publickey:" + publickey.length()); System.out.println(" publickey:" + publickey); System.out.println(" privateKey:" + privateKey.length()); System.out.println(" privateKey:" + privateKey); System.out.println("head=" + MainNetParams.get().getAddressHeader()); System.out.println("-----------------通过公钥获取地址--------------------------"); String testNetAddress = getAddress(publickey, true, false); System.out.println("-----------------Testnet pub key n/m开头--------------------------"); String mainNetAddress_Standard_Public = getAddress(publickey, false, false); System.out.println("-----------------P2PKH address 1开头--------------------------"); String mainNetAddress_Multi_Signature = getAddress(publickey, false, true); System.out.println("-----------------P2SH address 3开头--------------------------");