Android 关于区块链私钥、助记词生成、导入成功(后面还有大钥匙包导入小钥匙包出问题的解决方案)

可以查看github源代码:https://github.com/wangjinggithub/wallet
原博文:https://blog.csdn.net/u012846783/article/details/82775643

个人使用处理:

  1. 导入包:

    implementation ‘org.web3j:core:3.3.1-android’
    implementation ‘org.bitcoinj:bitcoinj-core:0.14.7’

  2. 网上找到bip44文件,在电脑磁盘中,将其放到app同级文件路径下;

在这里插入图片描述

  1. 在Android studio中,导入“model”,将bip44导入到工程中,再打开projectstructuer,将这个model设置为依赖

public class MyWalletBIP44 {
    private static final String TAG = "MyWalletBIP44";
    private static WordList wordList = CN.INSTANCE;
    private static CoinTypes coinTypes = CoinTypes.Bitcoin;
    private static List<String> strings = new ArrayList<>();
    
    /**
     * 默认为中文、bitcon(m/44'/0'/0'/0),也可以进行设置成中文英文;
     */
    public static ECKeyPair createKey() {

        //1.通过bip44生成助记词
        byte[] random = RandomSeed.random(WordCount.TWELVE);
        strings = new MnemonicGenerator(wordList).createMnemonic(random);
//        StringBuilder sb = new StringBuilder();
//        byte[] entropy = new byte[Words.TWELVE.byteLength()];
//        new SecureRandom().nextBytes(entropy);
//        new MnemonicGenerator(io.github.novacrypto.bip39.wordlists.English.INSTANCE).createMnemonic(entropy, sb::append);
        String mnemonic = strings.toString();
//        String mnemonics = sb.toString();
        mnemonic=mnemonic.replace(",","");
        mnemonic=mnemonic.replace("[","");
        mnemonic=mnemonic.replace("]","");

        Log.e("+++", "生成的助记词:" + mnemonic);
        //2.生成种子
        byte[] seed = generateSeed(mnemonic, null);
        //3. 生成根私钥 root private key 树顶点的master key ;bip32
        DeterministicKey rootPrivateKey = HDKeyDerivation.createMasterPrivateKey(seed);
        // 4. 由根私钥生成 第一个HD 钱包
        DeterministicHierarchy dh = new DeterministicHierarchy(rootPrivateKey);
        // 5. 定义父路径 H则是加强 imtoken中的eth钱包进过测试发现使用的是此方式生成 bip44
        List<ChildNumber> parentPath = HDUtils.parsePath("M/44H/60H/0H/0");
        // 6. 由父路径,派生出第一个子私钥 "new ChildNumber(0)" 表示第一个 (m/44'/60'/0'/0/0)
        DeterministicKey child = dh.deriveChild(parentPath, true, true, new ChildNumber(0));
        byte[] privateKeyByte = child.getPrivKeyBytes();
        ECKeyPair keyPair = ECKeyPair.create(privateKeyByte);
        Log.i(TAG, "generateBip44Wallet: 钥匙对  私钥 = " + Numeric.toHexStringNoPrefix(keyPair.getPrivateKey()));
        Log.i(TAG, "generateBip44Wallet: 钥匙对  公钥 = " + Numeric.toHexStringNoPrefix(keyPair.getPublicKey()));
        Log.i(TAG, "generateBip44Wallet: 钥匙对  公钥 = " + (keyPair.getPublicKey()));
        Log.i(TAG, "generateBip44Wallet: 钥匙对  私钥 = " + (keyPair.getPrivateKey()));
        return keyPair;
    }

    /**
     * 设置创建账号类型的助记词为:中文
     */
    public static void setChineseLanguage() {
        wordList = CN.INSTANCE;
    }


    /**
     * 设置创建账号类型的助记词为:英文
     */
    public static void setEnglishLanguage() {
        wordList = English.INSTANCE;
    }

    /**
     * 设置创建账号类型的币种为:btcoin
     * 路径为:0,拼接为:m/44'/0'/0'/0
     * 生成的私钥为64位或+0x为66位
     */
    public static void setBitcoiTypes() {
        coinTypes = CoinTypes.Bitcoin;
    }

    /**
     * 设置创建账号类型的币种为:Ethcoin
     * 路径为:0,拼接为:m/44'/60'/0'/0
     * 生成的私钥为64位或+0x为66位
     */
    public static void setEthereumTypes() {
        coinTypes = CoinTypes.Ethereum;
    }

    public static CoinTypes getCoinTypes() {
        return coinTypes;
    }

    public static WordList getWordList() {
        return wordList;
    }

    public static List<String> getStrings() {
        return strings;
    }

    public static void setStrings(List<String> strings) {
        MyWalletBIP44.strings = strings;
    }
}

外部类调用时:

public class WalletUtils3 {
            中文/英文助记词
    public static boolean ChineseZhuJiCi=true;//一般放在Const类中,方便管理
    private static final String TAG = "WalletUtils3";
    private static String address;
//    private static final SecureRandom secureRandom = new SecureRandom();

    public static Bip39Wallet generateBip39Wallet(String password, File destinationDirectory)
            throws CipherException, IOException {
        MyWalletBIP44 myWalletBIP44 = new MyWalletBIP44();

        if (ChineseZhuJiCi) {
            myWalletBIP44.setChineseLanguage();
        } else {
            myWalletBIP44.setEnglishLanguage();
        }
        myWalletBIP44.setEthereumTypes();

        ECKeyPair ecKeyPair = myWalletBIP44.createKey();
        Wallet.createLight(password, ecKeyPair);
        String mnemonic = myWalletBIP44.getStrings().toString();
        mnemonic = mnemonic.replace(",", "");
        mnemonic = mnemonic.replace("[", "");
        mnemonic = mnemonic.replace("]", "");
        Log.e(TAG, "generateBip39Wallet: " + mnemonic);
//        ECKeyPair privateKey = ECKeyPair.create(sha256(seed));
        String walletFile = generateWalletFile(password, ecKeyPair, destinationDirectory, false);
        return new Bip39Wallet(walletFile, mnemonic);
    }

    private static final ObjectMapper objectMapper = new ObjectMapper();

    static {
        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    public static String generateWalletFile(
            String password, ECKeyPair ecKeyPair, File destinationDirectory, boolean useFullScrypt)
            throws CipherException, IOException {

        WalletFile walletFile;
        if (useFullScrypt) {
            walletFile = Wallet.createStandard(password, ecKeyPair);
        } else {
            walletFile = Wallet.createLight(password, ecKeyPair);
        }
        address = Keys.toChecksumAddress(walletFile.getAddress());
        Log.e(TAG, "generateWalletFile address: " + address);
        String fileName = getWalletFileName();
        File destination = new File(destinationDirectory, fileName);
        objectMapper.writeValue(destination, walletFile);

        return fileName;
    }

    private static final int CURRENT_VERSION = 3;
    private static final String CIPHER = "aes-128-ctr";
    static final String AES_128_CTR = "pbkdf2";
    static final String SCRYPT = "scrypt";

    private static byte[] generateDerivedScryptKey(
            byte[] password, byte[] salt, int n, int r, int p, int dkLen) {
        try {
            return SCrypt.scrypt(password, salt, n, r, p, dkLen);
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static String getWalletFileName() {
        return System.currentTimeMillis() + ".json";
    }

    public static String getAddress() {
        return address;
    }

    public static void setAddress(String address) {
        WalletUtils3.address = address;
    }
}

场景生成助记词:

Bip39Wallet wallet = null;
        File ff = new File(MyConst.ETH_KEYSTORE_PATH);
        if (!ff.exists()) {
            ff.mkdirs();
        }
        try {
            //  wallet = WalletUtils.generateBip39Wallet(passwordtwo.getText().toString(), new File(MyConst.ETH_KEYSTORE_PATH));
            wallet = walletUtils3.generateBip39Wallet(passwordtwo.getText().toString(), new File(MyConst.ETH_KEYSTORE_PATH));
        } catch (CipherException e) {
            e.printStackTrace();
            Log.e("wallet", "CipherException=" + e.getMessage());
        } catch (NoClassDefFoundError e) {
            e.printStackTrace();
            Log.e("wallet", "NoClassDefFoundError=" + e.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
            Log.e("wallet", "IOException=" + e.getMessage());
        }
        //keyStore文件名
        Log.e("wallet", "getFilename=" + wallet.getFilename());
        //12个单词的助记词
        Log.e("wallet", "getMnemonic=" + wallet.getMnemonic());
        Credentials credentials = WalletUtils.loadBip39Credentials(passwordtwo.getText().toString(), wallet.getMnemonic());
        String keyStore = null;
        try {
            InputStream inputStream = new FileInputStream(MyConst.ETH_KEYSTORE_PATH + "/" + wallet.getFilename());
            keyStore = myGetString(inputStream);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        String other= WalletSPUtils.getPrivateKey(keyStore,passwordone.getText().toString());
        Log.e(TAG, "load other: "+other );
        String address = walletUtils3.getAddress();
        Log.e(TAG, "address=" + address);
        if (other.length() == 64|| other.length() !=66) {
            handler.sendEmptyMessage(ShowCreateToast);
            List<WalletInfoBean> mList = WalletSPUtils.mList;
            if (mList.size() > 0) {
                for (int i = 0; i < mList.size(); i++) {
                    WalletInfoBean walletInfoBean = mList.get(i);
                    walletInfoBean.setClick(false);
                }
                WalletSPUtils.saveList(mList);
            }
            WalletInfoBean walletInfoBean = new WalletInfoBean();
            walletInfoBean.setKeyStorePath(wallet.getFilename());
            walletInfoBean.setMemoryCharacter(wallet.getMnemonic());
            walletInfoBean.setWalletName(et_name.getText().toString());
            walletInfoBean.setAddress(address);
            walletInfoBean.setkeyStore(keyStore);
            walletInfoBean.setClick(true);

            WalletSPUtils.saveWalletInfo(walletInfoBean);
            startActivity(new Intent(context, WalletKeystoreActivity.class)
                    .putExtra("password", passwordone.getText().toString())
                    .putExtra("file", walletInfoBean)
                    .putExtra("type", "create")
            );
            finish();

导入账号时:

//keystore导入时:
    private void importKeyStore(String password, String keystore) {
        try {

//            判断大小store
            JSONObject jsonObject=new JSONObject(keystore);
            if (jsonObject!=null){
                String n=jsonObject.getJSONObject("crypto").getJSONObject("kdfparams").getString("n");
                Log.e(TAG, "importKeyStore: "+n );
                if (n.length()>5) {
                    handlerSuccess.sendEmptyMessage(ShowLoad);
                    BigToSmall(keystore, password);
                    return;
                }
            }

            ObjectMapper objectMapper = ObjectMapperFactory.getObjectMapper();
            WalletFile walletFile = objectMapper.readValue(keystore, WalletFile.class);
            ECKeyPair ecKeyPair = Wallet.decrypt(password, walletFile);

            String publicKey = ecKeyPair.getPublicKey().toString(16);
            String address = "0x" + Keys.getAddress(publicKey);

            File ff = new File(MyConst.ETH_KEYSTORE_PATH);
            if (!ff.exists()) {
                ff.mkdirs();
            }
            String generateWalletFile = walletUtils3.generateWalletFile(password, ecKeyPair,
                    new File(MyConst.ETH_KEYSTORE_PATH), false);

            setNumState();//退出当前用户

            WalletInfoBean walletInfoBean = new WalletInfoBean();
            walletInfoBean.setKeyStorePath(generateWalletFile);
            walletInfoBean.setWalletName(import_name.getText().toString());
            walletInfoBean.setkeyStore(keystore);
            walletInfoBean.setAddress(address);
            walletInfoBean.setClick(true);
            WalletSPUtils.saveWalletInfo(walletInfoBean);
            show("导入成功");
            getActivity().finish();

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (OutOfMemoryError e) {
            showToast("导入失败");
            e.printStackTrace();
        } catch (CipherException e) {
            show("KEYSTORE或节点密码密码不正确");
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            e.printStackTrace();
        }

    }

    private void BigToSmall(String keystore,String password) {
        Flowable
                .just(keystore)
                .filter(s -> validateInput(s,password))
                .flatMap(s -> InitWalletManager.shared().importKeystore(context,s,password))
                .compose(ScheduleCompat.apply()).subscribe();//必填
//                .subscribe((FlowableSubscriber<? super HLWallet>) this);
    }
    private boolean validateInput(String privateKey, String password) {
        // validate empty
        TextView textView=null;
        if (TextUtils.isEmpty(privateKey) || TextUtils.isEmpty(password)){
            ScheduleCompat.snackInMain(textView,"please input data");
            return false;
        }
        return true;
    }


  //  私钥导入
    private void importPrivateKey(String passwd, String privateKey) {
        Log.e("tag", "importPrivateKey: " + privateKey);

        BigInteger pk = Numeric.toBigInt(privateKey);
        byte[] privateKeyByte = pk.toByteArray();
        ECKeyPair keyPair = ECKeyPair.create(privateKeyByte);
        WalletFile walletFile = null;
        try {
            walletFile = Wallet.createLight(passwd, keyPair);
        } catch (CipherException e) {
            show("密码错误");
            e.printStackTrace();
        }
        String address = Keys.toChecksumAddress(walletFile.getAddress());
        Log.e(TAG, "importPrivateKey address: " + address);
        try {
            File ff = new File(MyConst.ETH_KEYSTORE_PATH);
            if (!ff.exists()) {
                ff.mkdirs();
            }
//
            String generateWalletFile = walletUtils3.generateWalletFile(passwd, keyPair,
                    new File(MyConst.ETH_KEYSTORE_PATH), false);

            WalletInfoBean walletInfoBean = new WalletInfoBean();


            try {
                InputStream inputStream = new FileInputStream(MyConst.ETH_KEYSTORE_PATH + "/" + generateWalletFile);
                String keyStore = myGetString(inputStream);
                Log.e("tag", "load: " + keyStore);
                walletInfoBean.setkeyStore(keyStore);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }



    // 助记词
    private void importAuxiliaries(String passwd, String menmory) {
        byte[] seed = generateSeed(menmory, null);
        DeterministicKey rootPrivateKey = HDKeyDerivation.createMasterPrivateKey(seed);
        // 4. 由根私钥生成 第一个HD 钱包
        DeterministicHierarchy dh = new DeterministicHierarchy(rootPrivateKey);
        // 5. 定义父路径 H则是加强 imtoken中的eth钱包进过测试发现使用的是此方式生成 bip44
        List<ChildNumber> parentPath = HDUtils.parsePath("M/44H/60H/0H/0");
        // 6. 由父路径,派生出第一个子私钥 "new ChildNumber(0)" 表示第一个 (m/44'/60'/0'/0/0)
        DeterministicKey child = dh.deriveChild(parentPath, true, true, new ChildNumber(0));
        byte[] privateKeyByte = child.getPrivKeyBytes();

        ECKeyPair keyPair = ECKeyPair.create(privateKeyByte);
        Log.i(TAG, "generateBip44Wallet: 钥匙对  私钥 = " + Numeric.toHexStringNoPrefix(keyPair.getPrivateKey()));
        Log.i(TAG, "generateBip44Wallet: 钥匙对  公钥 = " + Numeric.toHexStringNoPrefix(keyPair.getPublicKey()));
        WalletFile walletFile = null;
        try {
            walletFile = Wallet.createLight(passwd, keyPair);
        } catch (CipherException e) {
            e.printStackTrace();
        }
        String address = Keys.toChecksumAddress(walletFile.getAddress());
        Log.e(TAG, "importAuxiliaries: " + address);
        try {
            File ff = new File(MyConst.ETH_KEYSTORE_PATH);
            if (!ff.exists()) {
                ff.mkdirs();
            }

            String generateWalletFile = WalletUtils.generateWalletFile(passwd, keyPair,
                    new File(MyConst.ETH_KEYSTORE_PATH), false);

            setNumState();//退出当前用户

            WalletInfoBean walletInfoBean = new WalletInfoBean();
            walletInfoBean.setKeyStorePath(generateWalletFile);
            walletInfoBean.setMemoryCharacter("");
            walletInfoBean.setWalletName(import_name.getText().toString());
            walletInfoBean.setAddress(address);
            walletInfoBean.setClick(true);
            WalletSPUtils.saveWalletInfo(walletInfoBean);
            show("导入成功");
            getActivity().finish();
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jian11058

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值