Hello everyone, Im having problem with completing a transaction from a P2SH
wallet.
Basically I've created a Multi Signature wallet (2 of 3 signatures are
required). Im signing the transaction with two of the private keys (client
and server)
and for some reason i cant complete the transaction.
I pretty much tried to follow this tutorial:
https://bitcoinj.github.io/working-with-contracts
Here is the code:
public static void createP2SHTransaction() throws BlockStoreException,
ExecutionException, InterruptedException, InsufficientMoneyException {
NetworkParameters params = TestNet3Params.get(); // Set the network to
testnet
// Initialize Walllets. The transaction will be 2of3 signatures
(client,server,multisig). and the reciever is the testWallet
WalletAppKit client = new WalletAppKit(params, new File("C:\\Matan\\"),
"client");
WalletAppKit server = new WalletAppKit(params, new File("C:\\Matan\\"),
"server");
WalletAppKit multisig = new WalletAppKit(params, new
File("C:\\Matan\\"), "p2sh");
WalletAppKit testWallet = new WalletAppKit(params, new
File("C:\\Matan\\"), "test");
// Sync to the blockchain.
testWallet.startAsync();
testWallet.awaitRunning();
multisig.startAsync();
multisig.awaitRunning();
client.startAsync();
server.startAsync();
client.awaitRunning();
server.awaitRunning();
// get all the multisig wallet keys.
List<ECKey> keys = ImmutableList.of(client.wallet().getWatchingKey(),
server.wallet().getWatchingKey(),multisig.wallet().getWatchingKey());
// prepare the transaction
Transaction contract = new Transaction(params);
Script script = ScriptBuilder.createP2SHOutputScript(2, keys); //
create the locking script
Coin amount = Coin.valueOf(1000);
contract.addOutput(amount, script);
Script redeem = ScriptBuilder.createRedeemScript(2, keys); // create
the redeem script.
System.out.println(multisig.wallet().getBalance());
System.out.println(multisig.wallet().getTransactions(true));
TransactionOutput multisigOutput = contract.getOutput(0);
// prepare a transaction to be signed by the server key
Transaction spendTx = new Transaction(params);
Coin value = multisigOutput.getValue();
spendTx.addOutput(value, testWallet.wallet().getWatchingKey());
spendTx.addInput(multisigOutput);
// server signs the transaction
Sha256Hash sighash = spendTx.hashForSignature(0, redeem,
Transaction.SigHash.ALL, false);
ECKey.ECDSASignature serverSignature =
server.wallet().getWatchingKey().sign(sighash);
// prepare a transaction to be signed by the client key
Transaction clientTx = new Transaction(params);
clientTx.addOutput(value, testWallet.wallet().getWatchingKey());
TransactionInput input = clientTx.addInput(multisigOutput);
// client signs the transaction
Sha256Hash sighashClient = clientTx.hashForSignature(0, redeem,
Transaction.SigHash.ALL, false);
ECKey.ECDSASignature clientSignature =
client.wallet().getWatchingKey().sign(sighashClient);
// generate a TransactionSignature object
TransactionSignature clientTxSig = new
TransactionSignature(clientSignature, Transaction.SigHash.ALL, false);
TransactionSignature serverTxSig = new
TransactionSignature(serverSignature, Transaction.SigHash.ALL, false);
// create the unlocking script
Script inputScript =
ScriptBuilder.createP2SHMultiSigInputScript(ImmutableList.of(serverTxSig,
clientTxSig),redeem);
input.setScriptSig(inputScript);
// verify the locking script against the unlocking script.
// basiclly this method checks if the unlocking script can really
unlock the locking script
input.verify(multisigOutput);
// prepare a send request
SendRequest request = SendRequest.forTx(clientTx);
// complete the transaction by linking it to an unspent transation
multisig.wallet().completeTx(request);
}
And Here is the exception:
Exception in thread "main" java.lang.NullPointerException
at
org.bitcoinj.wallet.DecryptingKeyBag.maybeDecrypt(DecryptingKeyBag.java:58)
at
org.bitcoinj.wallet.DecryptingKeyBag.findRedeemDataFromScriptHash(DecryptingKeyBag.java:79)
at
org.bitcoinj.core.TransactionOutPoint.getConnectedRedeemData(TransactionOutPoint.java:175)
at
org.bitcoinj.core.TransactionInput.getConnectedRedeemData(TransactionInput.java:298)
at org.bitcoinj.wallet.Wallet.signTransaction(Wallet.java:4061)
at org.bitcoinj.wallet.Wallet.completeTx(Wallet.java:3998)
at Testing.BitcoinJ.createP2SHAccount(BitcoinJ.java:113)
at Testing.BitcoinJ.main(BitcoinJ.java:146)
When i debugged the code i saw that in the completeTx method it searches for
the redeemScript hash in the wallet.
But when it doesn't find it, it returns null hence the NullPointerException.
I don't really understand why it needs to search for the redeemScript hash in
the wallet (maybe it want to verify that the hash is really matches the wallet
public keys).
And also why it doesn't find the redeemScript hash in the wallet
Please let me know if something is unclear.
Thanks a lot.
--
You received this message because you are subscribed to the Google Groups
"bitcoinj" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.