BitcoinJ manually sign P2SH output
BitcoinJ manually sign P2SH output
I'm trying to create, with BitcoinJ, something similar as the one stated in BIP16:
scriptSig: [signature] {[pubkey] OP_CHECKSIG} scriptPubKey: OP_HASH160 [20-byte-hash of {[pubkey] OP_CHECKSIG} ] OP_EQUAL
No problems in creating the ScriptPubKey, however I'm not able to create a valid signature for the scriptSig, I get:
org.bitcoinj.core.RejectedTransactionException: Reject: tx d15fc079d0abfdcde23946dea5add84e268c71a8545d988044dbc013a84acb8d for reason 'mandatory-script-verify-flag-failed (Signature must be zero for failed CHECK(MULTI)SIG operation)' (16)
Here is my code:
Transaction tx = new Transaction(this.params); Transaction orphanTx = new Transaction(this.params); Coin toBurn = MIN_AMOUNT; ECKey key = new ECKey(); this.kit.wallet().importKey(key); rs = createRedeemScript(key); Script p2sh = ScriptBuilder.createP2SHOutputScript(rs); TransactionOutput to = tx.addOutput(toBurn, p2sh); to.setValue(to.getMinNonDustValue(this.feePerKb)); try { LOGGER.info("Broadcasting transactions..."); broadcastTransaction(tx, false); //Waiting for tx to appear... //Adding change input and output from previous tx Transaction tTemp = new Transaction(this.params); SendRequest req = SendRequest.forTx(tTemp); req.signInputs = false; kit.wallet().completeTx(req); orphanTx.addOutput(tTemp.getOutput(tTemp.getOutput(0))); orphanTx.addInput(tx.getOutput(1)); //Adding input referencing P2SH outputs from prevTx orphanTx.addInput(tx.getHash(), 0, tx.getOutput(0).getScriptPubKey()); //Signing input except the one added by completeTx signInput(orphanTx, orphanTx.getInput(1), key, tx.getOutput(0).getScriptPubKey(), new ScriptBuilder().data(rs.getProgram()).build()), 1); broadcastTransaction(orphanTx, true); LOGGER.info("Broadcast completed."); } catch (Exception e) { throw new TransactionException(e.getMessage()); } private void signInput(Transaction tx, TransactionInput ti, ECKey key, Script scriptPubKey, Script scriptSig, int index){ Sha256Hash hash = tx.hashForSignature(index, scriptPubKey, Transaction.SigHash.ALL, false); ECKey.ECDSASignature ecSig = key.sign(hash); TransactionSignature txSig = new TransactionSignature(ecSig, Transaction.SigHash.ALL, false); ScriptBuilder sb = new ScriptBuilder(scriptSig); sb.data(0, txSig.encodeToBitcoin()); ti.setScriptSig(sb.build()); } private Script createRedeemScript(ECKey key){ sb.data(key.getPubKey()); sb.addChunk(new ScriptChunk(ScriptOpCodes.OP_CHECKSIG, null)); return sb.build(); } private void broadcastTransaction(Transaction tx, boolean orphan) throws ExecutionException, InterruptedException, InsufficientMoneyException { SendRequest request = SendRequest.forTx(tx); request.feePerKb = this.feePerKb; request.shuffleOutputs = false; if(!orphan) this.kit.wallet().completeTx(request); else this.kit.wallet().signTransaction(request); this.kit.peerGroup().broadcastTransaction(request.tx).future().get(); }
What am I doing wrong ? Thank you very much.
http://bit.ly/2CGKYts
Comments
Post a Comment