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 bitcoinj+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to