P2SH-P2WPKH support (segwit compatible, 3* addresses)

300 views
Skip to first unread message

Přemysl Vyhnal

unread,
May 17, 2019, 7:22:15 AM5/17/19
to bitcoinj
Hi, 
is generating and receiving to P2SH-P2WPKH (segwit compatible, 3* addresses) not supported in bitcoinj 0.15.x?
Is it safe to assume that everyone will be able to send to bech32 (bc1) addresses these days? Most SW and mobile wallets should already support it, but not all exchanges and HW wallets does support it probably just with Electrum.

Is it possible to implement it in client code? 

Thanks

Regards
Premek

Andreas Schildbach

unread,
May 18, 2019, 5:47:55 AM5/18/19
to bitc...@googlegroups.com
I decided to skip P2SH-P2WPKH. Virtually all wallets support at least
sending to Bech32, only a couple of ATMs and exchanges are left. In
these cases, you still can use classic P2PKH.
> --
> 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+u...@googlegroups.com
> <mailto:bitcoinj+u...@googlegroups.com>.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/bitcoinj/0accc4bf-a75f-4d39-9597-8e86afcfe572%40googlegroups.com
> <https://groups.google.com/d/msgid/bitcoinj/0accc4bf-a75f-4d39-9597-8e86afcfe572%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.


Přemysl Vyhnal

unread,
May 20, 2019, 4:15:45 AM5/20/19
to bitc...@googlegroups.com
Thanks for your response. How difficult you think it would be to implement P2SH-P2WPKH? Can the bech32 segwit address be somehow converted to legacy and receive transactions to it?

Thank you
P.


You received this message because you are subscribed to a topic in the Google Groups "bitcoinj" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/bitcoinj/pHv4XyMbhZo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to bitcoinj+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bitcoinj/qbokc3%241480%241%40blaine.gmane.org.

Přemysl Vyhnal

unread,
May 28, 2019, 10:34:54 AM5/28/19
to bitc...@googlegroups.com
FYI if anyone interested this is how I ended up generating P2WPKH-P2SH (3* segwit compatible) addresses and spending them (receiving / forwarding) them. Please let me know if anyone sees some issue with my approach. Thanks!

 
    public static LegacyAddress getAddressFromPubKey(ECKey key) {
        // Address receiveAddress1 = Address.fromKey(netParams, key, Script.ScriptType.P2PKH); // legacy 1*
        // receiveAddressBc1 = Address.fromKey(netParams, key, Script.ScriptType.P2WPKH); // bech32 bc1* native segwit - enable this in future
        return LegacyAddress.fromScriptHash(MainNetParams.get(), Utils.sha256hash160(ScriptBuilder.createP2WPKHOutputScript(key.getPubKeyHash()).getProgram())); // P2WPKH-P2SH (3* segwit compatible)
    }

    private void addSignedInput(Transaction tx, TransactionOutput sourceOutput, ECKey key) {
            if (ScriptPattern.isP2SH(sourceOutput.getScriptPubKey())) { // 3* segwit addr
                TransactionInput input = new TransactionInput(tx.getParams(), tx, new byte[0], sourceOutput.getOutPointFor(), sourceOutput.getValue());
                tx.addInput(input);
                int inputIndex = tx.getInputs().size() - 1;
                Script scriptCode = new ScriptBuilder().data(ScriptBuilder.createP2PKHOutputScript(key).getProgram()).build();
                TransactionSignature signature = tx.calculateWitnessSignature(inputIndex, key, scriptCode, input.getValue(), Transaction.SigHash.ALL, false);
                input.setScriptSig(new ScriptBuilder().data(ScriptBuilder.createP2WPKHOutputScript(key).getProgram()).build());
                input.setWitness(TransactionWitness.redeemP2WPKH(signature, key));
            } else { // 1* addr or bc1* addr
                tx.addSignedInput(sourceOutput, key);
            }
    }


Message has been deleted
Message has been deleted

Lt Awper

unread,
Sep 11, 2019, 6:38:21 AM9/11/19
to bitcoinj
Hi bro, I'm trying to sign alone P2SH output (prevTx) like your example but it's not working. May you help me a bit, thanks so much bro.
Here is my code:
NetworkParameters network = new TestNet3Params().get();
String fromAddress = "2N8qKVKuR3QAy2cA5fF2QbuCpBGfGCmbUHx";
String toAddress = "mxHqrQBWuCndNaubTYUbcEVzeNPsT34TP6";
String changeAddress = fromAddress;
String privateKey = "c5964e19634e473e9c8fed3b149c4d44b6d62d62724035aad3eb911a1495ae27";
String inputAmount = "0.00773516";
String inputScriptPubKeyHash = "a914aafc9f09b99cbb1ba46001ec4868ba4fb32543ca87";
String prevTxHash = "bb49e7c6da6b35845a798cc6c18e9cf959daf30d9a5e5b82e983757246092f50";
long prevTxIndex = 0;

BigDecimal inputAmountToBigDecimal = new BigDecimal(inputAmount).multiply(BTC_TO_SATS);
long inputAmountToLong = inputAmountToBigDecimal.longValue();
long outputAmountToLong = 1000;
long feeAmountToLong = 1000;
long changeAmountToLong = inputAmountToLong - outputAmountToLong - feeAmountToLong;

Transaction tx = new Transaction(network);
ecKey = ECKey.fromPrivate(new BigInteger(privateKey, 16));

tx.addOutput(Coin.valueOf(outputAmountToLong), Address.fromString(network, toAddress));
tx.addOutput(Coin.valueOf(changeAmountToLong), Address.fromString(network, changeAddress));

Script script = new Script(Hex.decode(inputScriptPubKeyHash.getBytes()));
System.out.println("isP2SH: " + ScriptPattern.isP2SH(script));

TransactionOutPoint prevTx = new TransactionOutPoint(
network,
prevTxIndex,
Sha256Hash.wrap(prevTxHash)
);

if (ScriptPattern.isP2SH(script)) {
System.out.println("This is P2SH input.");
TransactionInput input = new TransactionInput(
tx.getParams(),
            tx,
new byte[0],
            prevTx,
Coin.valueOf(inputAmountToLong)
);
tx.addInput(input);
Script scriptCode = new ScriptBuilder().data(ScriptBuilder.createP2PKHOutputScript(ecKey).getProgram()).build();
TransactionSignature signature = tx.calculateWitnessSignature(0, ecKey, scriptCode, input.getValue(), Transaction.SigHash.ALL, true);
input.setScriptSig(new ScriptBuilder().data(ScriptBuilder.createP2WPKHOutputScript(ecKey).getProgram()).build());
input.setWitness(TransactionWitness.redeemP2WPKH(signature, ecKey));
}
else {
tx.addSignedInput(prevTx, script, ecKey);
}

System.out.println("tx serialized: " + Hex.toHexString(tx.bitcoinSerialize()));

> To view this discussion on the web visit
> https://groups.google.com/d/msgid/bitcoinj/0accc4bf-a75f-4d39-9597-8e86afcfe572%40googlegroups.com
> <https://groups.google.com/d/msgid/bitcoinj/0accc4bf-a75f-4d39-9597-8e86afcfe572%40googlegroups.com?utm_medium=email&utm_source=footer>.
> For more options, visit https://groups.google.com/d/optout.


--
You received this message because you are subscribed to a topic in the Google Groups "bitcoinj" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/bitcoinj/pHv4XyMbhZo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to bitc...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages