Bitcoinj
如何在 Android 上創建僅用於簽署交易的離線錢包
我是比特幣新手,我想在 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(); } }