Bitcoinj开发 WalletAppKit 生成钱包,恢复钱包,发送btc

1.测试网络 获取btc https://testnet.coinfaucet.eu/en/

https://live.blockcypher.com/

btc:
https://github.com/Samourai-Wallet/samourai-wallet-android
eth:
https://gitter.im/web3j/web3j
eos:
https://eos.io/

2.引入库

implementation 'org.bitcoinj:bitcoinj-core:0.14.7' //btc

3.主要代码

public class BitUtil {
    public static final String passphrase = "";
    /**
     * 通过Wallet 获取 助记词
     * @param wallet
     * @return
     */
    public static List<String> getSeedWordsFromWallet(Wallet wallet){
        DeterministicSeed seed = wallet.getKeyChainSeed();
        return  seed.getMnemonicCode();
    }

    /**
     * 通过私钥获取ECKey
     * @param priKey
     * @return
     */
    public static ECKey getECKeyFromPriKey(String priKey){
        ECKey ecKey = ECKey.fromPrivate(Numeric.toBigInt(priKey));
        return ecKey;
    }
    public  static String getPubKeyFrom(ECKey ecKey){
        NetworkParameters params =getParams();
       return ecKey.toAddress(params).toBase58().toString();
    }


    //通过speed 获取钱包
    public static Wallet getFromSpeed(String seedCode){
        NetworkParameters params = getParams();
        DeterministicSeed seed;
        try {
            seed = new DeterministicSeed(seedCode, null, passphrase,Utils.currentTimeSeconds() );

            Wallet restoredWallet = Wallet.fromSeed(params, seed);
            return  restoredWallet;
        } catch (UnreadableWalletException e) {
            e.printStackTrace();
        }
        return  null;
    }



    //通过本地文件获取Wallet
    public static  Wallet getWalletFromFile(String filePath){
        try {
            return  Wallet.loadFromFile(new File(filePath));
        } catch (UnreadableWalletException e) {
            e.printStackTrace();
        }
        return null;
    }


    //发送交易
    public static void send(Wallet wallet,String recipientAddress, String amount){
        NetworkParameters params = getParams();
       Address targetAddress  = Address.fromBase58(params, recipientAddress);
    // Do the send of 1 BTC in the background. This could throw InsufficientMoneyException.
        SPVBlockStore blockStore = null;
        try {
            blockStore = new SPVBlockStore(params, getBLockFile());
        } catch (BlockStoreException e) {
            e.printStackTrace();
        }
        BlockChain chain = null;
        try {
            chain = new BlockChain(params, wallet,blockStore);
            PeerGroup peerGroup = new PeerGroup(params, chain);
            try {
                Wallet.SendResult result = wallet.sendCoins(peerGroup, targetAddress, Coin.parseCoin(amount));
                // Save the wallet to disk, optional if using auto saving (see below).
                //wallet.saveToFile(....);
                    // Wait for the transaction to propagate across the P2P network, indicating acceptance.
                try {
                    Transaction transaction = result.broadcastComplete.get();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
                return;
            } catch (InsufficientMoneyException e) {
                e.printStackTrace();
            }
        } catch (BlockStoreException e) {
            e.printStackTrace();
        }

    }

    public static  String send(WalletAppKit walletAppKit,String recipientAddress, String amount){
        NetworkParameters params = getParams();
        String err = "";
        if(TextUtils.isEmpty(recipientAddress) || recipientAddress.equals("Scan recipient QR")) {
            err = "Select recipient";
            return err;
        }
        if(TextUtils.isEmpty(amount) | Double.parseDouble(amount) <= 0) {
            err = "Select valid amount";
            return err;

        }
        if(walletAppKit.wallet().getBalance().isLessThan(Coin.parseCoin(amount))) {
            err = "You got not enough coins";
            return err;
        }
        SendRequest request = SendRequest.to(Address.fromBase58(params, recipientAddress), Coin.parseCoin(amount));
        try {
            walletAppKit.wallet().completeTx(request);
            walletAppKit.wallet().commitTx(request.tx);
            walletAppKit.peerGroup().broadcastTransaction(request.tx).broadcast();
            return "";
        } catch (InsufficientMoneyException e) {
            e.printStackTrace();
            return  e.getMessage();
        }
    }



    public static File getBLockFile(){
        File file = new File("/tmp/bitcoin-blocks");
        if(!file.exists()){
            try {
                boolean newFile = file.createNewFile();
                if(newFile){
                    return file;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return file;
    }

   public static void getWallet(){
       NetworkParameters params = getParams();
       Wallet wallet = new Wallet(params);

       List<ECKey> keys = new ArrayList<>();
       ECKey ecKey = new ECKey();
       //加密eckey
       ecKey.encrypt(wallet.getKeyCrypter(),wallet.getKeyCrypter().deriveKey("123456"));
       keys.add(ecKey);


       wallet.importKeysAndEncrypt(keys,"123456");
       try {
           SPVBlockStore blockStore = new SPVBlockStore(params, getBLockFile());
           BlockChain chain = new BlockChain(params, wallet,blockStore);
           PeerGroup peerGroup = new PeerGroup(params, chain);
           peerGroup.addWallet(wallet);
           peerGroup.startAsync();
           peerGroup.downloadBlockChain();
           //startAndWait()
       } catch (BlockStoreException e) {
           e.printStackTrace();
       }
   }


   public static void testAddress(Wallet wallet){
       Address a = wallet.currentReceiveAddress();
       ECKey b = wallet.currentReceiveKey();
       Address c = wallet.freshReceiveAddress();
   }




   public static void userSPeed(Wallet wallet){

       NetworkParameters params = getParams();
       DeterministicSeed seed = wallet.getKeyChainSeed();
       println("Seed words are: " + Joiner.on(" ").join(seed.getMnemonicCode()));
       println("Seed birthday is: " + seed.getCreationTimeSeconds());


       //通过speed 获取Wallet
       String seedCode = "yard impulse luxury drive today throw farm pepper survey wreck glass federal";
       String seedCode2 = "liberty identify erase shuffle dignity armed produce mention actual you top vendor";
       long creationtime = 1409478661L;
       DeterministicSeed seed2;
       try {
           seed2 = new DeterministicSeed(seedCode, null, "", creationtime);
           Wallet restoredWallet = Wallet.fromSeed(params, seed2);
       } catch (UnreadableWalletException e) {
           e.printStackTrace();
       }

   }

   public static NetworkParameters getParams(){
        return Constant.IS_PRODUCTION ? MainNetParams.get() : TestNet3Params.get();
   }


   public static void t(Wallet wallet,String recipientAddress,String password,String mount){
       Address a =Address.fromBase58(getParams(), recipientAddress);
       SendRequest req = SendRequest.to(a, Coin.parseCoin(mount));
       req.aesKey = wallet.getKeyCrypter().deriveKey(password);
       try {
           wallet.sendCoins(req);
       } catch (InsufficientMoneyException e) {
           e.printStackTrace();
       }
   }

   public static void watchAddress(){
       Wallet toWatch = null;
       DeterministicKey watchingKey = toWatch.getWatchingKey();
       String s = watchingKey.serializePubB58(getParams());
       long creationTimeSeconds = watchingKey.getCreationTimeSeconds();


       DeterministicKey key = DeterministicKey.deserializeB58(null, "key data goes here",getParams());

       Wallet wallet = Wallet.fromWatchingKey(getParams(), key);


       NetworkParameters params = TestNet3Params.get();

       DeterministicSeed seed = new DeterministicSeed(new SecureRandom(),128,"password", Utils.currentTimeSeconds());
       wallet = Wallet.fromSeed(params,seed);

        //tobytes
       byte[] bytes = MnemonicCode.toSeed(new ArrayList<>(), passphrase);

   }

   public static void test(){
       NetworkParameters params = TestNet3Params.get();
       DeterministicSeed seed = new DeterministicSeed(new SecureRandom(),128,"123456",Utils.currentTimeSeconds());
       List<String> mnemonicCode = seed.getMnemonicCode();
       LogUtil.e("mnemonicCode"+mnemonicCode);
//       byte[] bytes = MnemonicCode.toSeed(mnemonicCode, "123456");
       Wallet wallet = Wallet.fromSeed(params,seed);
   }

   public static void test2(ECKey ceKey){
       NetworkParameters params =getParams();
       String s = ceKey.toAddress(params).toBase58().toString();
       String privateKeyAsWiF = ceKey.getPrivateKeyAsWiF(params);// 私钥, WIF(Wallet Import Format)
       LogUtil.e(privateKeyAsWiF+"=========="+s);
   }



   //通过私钥拿到eckey
   public static ECKey getECkey(String prikey){
       ECKey key = DumpedPrivateKey.fromBase58(getParams(), prikey).getKey();
       return key;
   }


   //通过助记词导入新钱包
   public static Wallet createWallet(String seedCode,String password) {
        KeyChainGroup kcg;
        DeterministicSeed deterministicSeed = null;
        try {
            deterministicSeed = new DeterministicSeed(seedCode, null, password, Utils.currentTimeSeconds());
        } catch (UnreadableWalletException e) {
            e.printStackTrace();
        }
        kcg = new KeyChainGroup(getParams(), deterministicSeed);
        Wallet wallet = new Wallet(getParams(), kcg);
        return wallet;
    }

    //创建新钱包。
    public static Wallet createWallet2() {
        KeyChainGroup kcg = new KeyChainGroup(getParams());
        Wallet wallet = new Wallet(getParams(), kcg);
        wallet.getParams().getId();
        return wallet;

    }

    //通过助记词
    public static WalletAppKit getWalletKit(Context context,String seedcode){
        WalletAppKit walletAppKit = new WalletAppKit(getParams(), context.getCacheDir(), Constant.WALLET_NAME) {
            @Override
            protected void onSetupCompleted() {
                if (wallet().getImportedKeys().size() < 1) wallet().importKey(new ECKey());
                wallet().allowSpendingUnconfirmedTransactions();
                setupWalletListeners(wallet());
                ECKey ecKey = wallet().getImportedKeys().get(0);
                LogUtil.e(getPubKeyFrom(ecKey));
//                test2(ecKey);
//                //打印助记词
                List<String> seedWordsFromWallet = getSeedWordsFromWallet(wallet());
                LogUtil.e(seedWordsFromWallet.toString());
                //当前地址
                String s1 = wallet().currentReceiveAddress().toBase58();

               // String s2 = wallet().currentChangeAddress().toBase58();
                String privateKeyAsWiF = wallet().currentReceiveKey().getPrivateKeyAsWiF(getParams());
                LogUtil.e("currentReceiveAddress="+s1+"===privateKeyAsWiF="+privateKeyAsWiF);
                //LogUtil.e("freshReceiveAddress="+s+"==="+"currentReceiveAddress="+s1);
            }
        };


        walletAppKit.setAutoSave(true);
        walletAppKit.setBlockingStartup(false);

        setDownListener(walletAppKit);
        if (getParams() == RegTestParams.get()) {
            AppContext.walletAppKit.connectToLocalHost();
        }
        if(!StringUtils.isEmpty(seedcode)){
            try {
                DeterministicSeed seed = new DeterministicSeed(seedcode, null, passphrase,Utils.currentTimeSeconds());
                walletAppKit.restoreWalletFromSeed(seed);
            } catch (UnreadableWalletException e) {
                e.printStackTrace();
            }

        }
        walletAppKit.startAsync();
        walletAppKit.awaitRunning();
        return  walletAppKit;
    }

    //加载本地文件
    public static WalletAppKit getWalletKit(Context context){
        return getWalletKit(context,"");
    }


    public static void setDownListener(WalletAppKit walletAppKit){
        walletAppKit.setDownloadListener(new DownloadProgressTracker() {
            @Override
            protected void progress(double pct, int blocksSoFar, Date date) {
                super.progress(pct, blocksSoFar, date);
                int percentage = (int) pct;
                LogUtil.e(percentage+"percentage");
            }

            @Override
            protected void doneDownload() {
                super.doneDownload();
                String myAddress = walletAppKit.wallet().currentReceiveAddress().toBase58();
                String s = walletAppKit.wallet().getBalance().toFriendlyString();
                BtcData btcData = new BtcData(myAddress,s);
                RxBus.getInstance().send(new MessageModel(BTC_DATA,btcData));
                LogUtil.e(myAddress+"=="+s);

            }
        });
    }

    public  static void  setupWalletListeners(Wallet wallet) {
        wallet.addCoinsReceivedEventListener((wallet1, tx, prevBalance, newBalance) -> {
            String s = wallet.getBalance().toFriendlyString();
            String s1 = "";
            if(tx.getPurpose() == Transaction.Purpose.UNKNOWN) {
                 s1 = newBalance.minus(prevBalance).toFriendlyString();
            }
            LogUtil.e(s+"==="+s1);
        });
        wallet.addCoinsSentEventListener((wallet12, tx, prevBalance, newBalance) -> {
            String s = wallet.getBalance().toFriendlyString();
            String s1 = "Sent "+prevBalance.minus(newBalance).minus(tx.getFee()).toFriendlyString();
            LogUtil.e(s+"==="+s1);
        });


    }

    public void Test() {

        ECKey k1 = new ECKey(); // some random key

        // encrypting a key
        KeyCrypter crypter1 = new KeyCrypterScrypt();

        KeyParameter aesKey1 = crypter1.deriveKey("some arbitrary passphrase");
        ECKey k2 = k1.encrypt(crypter1, aesKey1);
            //System.out.println(k2.isEncrypted()); // true

        // decrypting a key
        KeyCrypter crypter2 = k2.getKeyCrypter();
        KeyParameter aesKey2 = crypter2.deriveKey("some arbitrary passphrase");
        ECKey k3 = k2.decrypt(aesKey2);

        //System.out.println(k1.equals(k3));  // true
    }


    public static void closedWallet(){
        AppContext.walletAppKit.stopAsync();
        AppContext.walletAppKit.awaitTerminated();
    }

    public static void test2(){
        DeterministicKey deterministicKey = AppContext.walletAppKit.wallet().getWatchingKey().dropPrivateBytes();
        deterministicKey = HDKeyDerivation.createMasterPubKeyFromBytes(deterministicKey.getPubKey(), deterministicKey.getChainCode());
        String xPublicKey = deterministicKey.serializePubB58(getParams());
        String  privateKey= AppContext.walletAppKit.wallet().getKeyByPath(DeterministicKeyChain.ACCOUNT_ZERO_PATH).getPrivateKeyAsWiF(getParams());
        Log.e("key", xPublicKey.toString());
        Log.e("privatekey", privateKey.toString());
        if (getParams() == RegTestParams.get()) {
            AppContext.walletAppKit.connectToLocalHost();
        }
    }

    public static void si(String privateKey,String recipientAddress,String amount){
        SendRequest request = SendRequest.to(Address.fromBase58(getParams(),
                recipientAddress), Coin.parseCoin(amount));
        Signingtrasaction(privateKey,request.tx.getHashAsString());
    }

    public static  void Signingtrasaction(String wif, String msg) {
        try {
            // creating a key object from WiF
            DumpedPrivateKey dpk = DumpedPrivateKey.fromBase58(getParams(), wif);
            ECKey key = dpk.getKey();
            // checking our key object
            // NetworkParameters main = MainNetParams.get();
            String check = key.getPrivateKeyAsWiF(getParams());
            System.out.println(wif.equals(check));  // true
            Log.e("wif check", String.valueOf(wif.equals(check)));
            // creating Sha object from string
            Sha256Hash hash = Sha256Hash.wrap(msg);
            // creating signature
            ECKey.ECDSASignature sig = key.sign(hash);
            // encoding
            byte[] res = sig.encodeToDER();
            // converting to hex
            //String hex = DatatypeConverter.printHexBinary(res);
            // String hex = new String(res);
            String hex = android.util.Base64.encodeToString(res, 16);
            Log.e("sigendTransiction", hex.toString());
            Log.e("decrypttx",""+ Hex.decode(sig.encodeToDER()));
        } catch (Exception e) {   //signingkey = ecdsa.from_string(privateKey.decode('hex'), curve=ecdsa.SECP256k1)
            Log.e("signing exception", e.getMessage().toString());
        }
    }


}

猜你喜欢

转载自blog.csdn.net/yujunlong3919/article/details/81035278