Bitcoinj

如何在 Android 上創建僅用於簽署交易的離線錢包

  • May 23, 2018

我是比特幣新手,我想在 Android 上創建一個離線錢包,從線上桌面錢包掃描交易二維碼,在我的離線錢包上用私鑰簽署該交易。

1 創建離線錢包。2.使用私鑰離線簽署交易。

我想簽署交易並從該簽名交易中生成 QR 碼。但在簽署後,我得到了一個 sha256,格式為“MEQCIGBVDN/PkbESZdWkG6/KzrDRAEpDXVdsjKMzErBfFIWYAiA8JJOv97Dlp8Acg/L8JHI3RzoW eYNxPW1Lx4wQaORNNQ==”,那麼我將如何處理。所以請幫助並查看我的程式碼。我的簽名過程好嗎?如果不是,請提供一些程式碼。謝謝

所以我做了以下事情。

// 用於創建錢包

私人無效初始化錢包()

拋出 IOException {

   BriefLogFormatter.init();

   params = TestNet3Params.get();

   filePrefix = "forwarding-service-testnet";

   walletAppKit = new WalletAppKit(params, getCacheDir(), filePrefix) {
       @Override
       protected void onSetupCompleted() {

          if (wallet().getKeyChainGroupSize() < 1)
               wallet().importKey(new ECKey());

           deterministicKey = wallet().getWatchingKey().dropPrivateBytes();
           deterministicKey = HDKeyDerivation.createMasterPubKeyFromBytes(deterministicKey.getPubKey(), deterministicKey.getChainCode());
           xPublicKey = deterministicKey.serializePubB58(params);    privateKey=wallet().getKeyByPath(DeterministicKeyChain.ACCOUNT_ZERO_PATH).getPrivateKeyAsWiF(params);
           Log.e("key", xPublicKey.toString());
           Log.e("privatekey", privateKey.toString());

       }
   };


   if (params == RegTestParams.get()) {
       // Regression test mode is designed for testing and development only, so there's no public network for it.
       // If you pick this mode, you're expected to be running a local "bitcoind -regtest" instance.
       walletAppKit.connectToLocalHost();
   }
   // Download the block chain and wait until it's done.


   walletAppKit.startAsync();
   walletAppKit.awaitRunning();

}

對於簽署交易,我執行以下操作。

公共無效Createtransictionhash(字元串收件人地址,字元串金額){

   try {

         // i am getting address and coins from QR code

       SendRequest request = SendRequest.to(Address.fromBase58(params, 
       recipientAddress), Coin.parseCoin(amount));
           Signingtrasaction(MainActivity.privateKey,request.tx.getHashAsString());

       Log.e("txhash", request.tx.getHashAsString());

   } catch (Exception e) {
       Log.e("msgError", e.getMessage().toString());
       Toast.makeText(getApplicationContext(), " Version code of address did not match", Toast.LENGTH_SHORT).show();

   }
}

public void Signingtrasaction(String wif, String msg) {
   try {


       // message (hash) to be signed with private key
       //String msg = "15953935a135031bfec37d36a9d662aea43e1deb0ea463d6932ac6e537cb3e81";
       //my hash = 09b14f746bd0a93b71907ba0070a103adbee7b1a260e053a21aa0b660ad8de57
       // an example of WiF for private key (taken from 'Mastering Bitcoin')
      // wif ="KxFC1jmwwCoACiCAWZ3eXa96mBM6tb3TYzGmf6YwgdGWZgawvrtJ";

       // creating a key object from WiF
       DumpedPrivateKey dpk = DumpedPrivateKey.fromBase58(params, wif);
       ECKey key = dpk.getKey();

       // checking our key object
      // NetworkParameters main = MainNetParams.get();
       String check = key.getPrivateKeyAsWiF(params);
       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());
   }
}

你從一開始就做錯了,不要使用 WalletAppKit 使用簡單的 Wallet 類,它的離線錢包不線上,WalletAppKit 需要網際網路與區塊鏈同步

public void wallet()
{
   wallet = new Wallet(params);
   try
   {
       if(isDirCreated())
       {
           System.out.print("New Wallet");
           wallet.saveToFile(walletPath);
           System.out.println(wallet.currentReceiveAddress());
       }
       else
       {
           System.out.println("Load Wallet");
           // do something here
       }
   }
   catch (IOException e)
   {
       e.printStackTrace();
   } catch (Exception e) {
       e.printStackTrace();
   }
}

引用自:https://bitcoin.stackexchange.com/questions/68313