Hello, I'm trying to build an offline transaction signer; full code here: package org.bitcoinj.examples;
import org.bitcoinj.core.*; import org.bitcoinj.crypto.TransactionSignature; import org.bitcoinj.params.TestNet3Params; import org.bitcoinj.script.Script; import org.bitcoinj.script.ScriptBuilder; import org.bitcoinj.script.ScriptOpCodes; import javax.xml.bind.DatatypeConverter; /** * SignTx on testnet ... does not work yet */ public class TxSigner { public static void main(String[] args) throws Exception { NetworkParameters params; params = TestNet3Params.get(); // Initial data containing destination and unspent output address hashes String destinationPubKeyHash = "mrB5ZczDEMJtJ7xGXuD2tE2Qn4XX8RDRjX"; String wif = "cRvcTPJtAxsYvn7Jnxw4BnymC7VfYF1HifVMh6uf7HbhsBXfyDqM"; // Transaction containing the UTXO String originTxId = "8e213ee647d60de7bcb145cbf5f75527e892a459423b248c4ef610c2183b86b8"; // Build the ECKey from the Wallet Interchange Format (wif) string DumpedPrivateKey dpk = DumpedPrivateKey.fromBase58(null, wif); ECKey key = dpk.getKey(); String check = key.getPrivateKeyAsWiF(params); System.out.println(check); // Building addresses Address destinationAddress = Address.fromString(params, destinationPubKeyHash); // Initialize testnet transaction Transaction tx = new Transaction(params); // Add output spending the UTXO Long amount = new Long(8800000); tx.addOutput(Coin.valueOf(amount - 5000), destinationAddress); // Add some data in a second non-standard output String msg = "https://arxiv.org/abs/quant-ph/0012067"; tx.addOutput(Coin.ZERO, ScriptBuilder.createOpReturnScript(msg.getBytes())); // Previous script ScriptBuilder redeemScriptBuilder = new ScriptBuilder(); redeemScriptBuilder.op(ScriptOpCodes.OP_DUP) .op(ScriptOpCodes.OP_HASH160) .data(key.getPubKeyHash()) .op(ScriptOpCodes.OP_EQUALVERIFY) .op(ScriptOpCodes.OP_CHECKSIG); Script redeemScript = redeemScriptBuilder.build(); // Add originTxId as input with redeem script tx.addInput(Sha256Hash.wrap(originTxId), 0, redeemScript); TransactionSignature txSignature = tx.calculateSignature( 0, key, key.getPubKey(), Transaction.SigHash.ALL, false); Script scriptSig = new ScriptBuilder() .data(txSignature.encodeToBitcoin()) .data(key.getPubKey()) .build(); assert (TransactionSignature.isEncodingCanonical(txSignature.encodeToBitcoin())); tx.getInput(0).setScriptSig(scriptSig); tx.verify(); // Obtaining the hexadecimal raw transaction (does not validate) String tx_hex = DatatypeConverter.printHexBinary(tx.bitcoinSerialize()); System.out.println(tx_hex); } } I was already achieving to properly validate a transaction like that built using BitcoinJS: https://chain.so/tx/BTCTEST/8e213ee647d60de7bcb145cbf5f75527e892a459423b248c4ef610c2183b86b8 But not achieving it with previously posted Java code; main difference between both transactions is the signing script: Correct signing script hex representation (generated with BitcoinJS): 483045022100ff8d4a710af05feaabdf313b38508985d899b7919bc3728e18e686ed8a8b2ab90220420876e4cb022716b2b523caa930d44e5baac59343f4c0b18805eb83f74b1f5801210384a4dcd4429e8fc5cf3f9f942e133b5b580022f89824e70515b0d2de21d435b7 Incorrect one hex representation (with previous code using bitcoinj): 47304402205ff33d777afbfcd40ff05a768781b87d10a6661ec723ac09bc4922e41ee7fba6022063b94f2169ca3e00aae3d753b6ebd1759dfe38b0bef6d24ee44cc575bee3fc4c03210384a4dcd4429e8fc5cf3f9f942e133b5b580022f89824e70515b0d2de21d435b7 It seems that the signature size is different by one byte (incorrect one 47, correct one 48). Public Key Hex representation is: 0384a4dcd4429e8fc5cf3f9f942e133b5b580022f89824e70515b0d2de21d435b7 Can someone provide some hint/help about the issue or point me about what I'm doing wrong? Many thanks in advance. -- 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. To view this discussion on the web visit https://groups.google.com/d/msgid/bitcoinj/c2fe29f5-381d-4a6e-9562-2485e9aae4bb%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.