Lakshitha Kanchana
Lakshitha Kanchana

Reputation: 1235

Generate P2SH bitcoin address from WIF in BitcoinJ Java

I'm trying to create P2SH-Segwit bitcoin address from the WIF private key. I'm using the BitcoinJ library in Java. See the following code.

String base58PrivateKeyString = "KyyJ5vVWjZck5nsAgDWvoN1u7Q8qp5FzE8WiCq97MbnRgdLesqJZ";

NetworkParameters params = MainNetParams.get();
ECKey key;

if (base58PrivateKeyString.length() == 51 || base58PrivateKeyString.length() == 52) {
    DumpedPrivateKey dumpedPrivateKey = DumpedPrivateKey.fromBase58(params, base58PrivateKeyString);
    key = dumpedPrivateKey.getKey();
} else {
    BigInteger privKey = Base58.decodeToBigInteger(base58PrivateKeyString);
    key = ECKey.fromPrivate(privKey);
}

// Getting the public key
String pubKeyStr = key.getPublicKeyAsHex();
System.out.println("Public key is: " + pubKeyStr + "\n");

// Getting the P2SH address
List<ECKey> eckeyAList = new ArrayList<>();
eckeyAList.add(key);
Script redeemScript = ScriptBuilder.createRedeemScript(1, eckeyAList);
Script script = ScriptBuilder.createP2SHOutputScript(redeemScript);
byte[] scriptHash = ScriptPattern.extractHashFromP2SH(script);
LegacyAddress legacyAddress = LegacyAddress.fromScriptHash(params, scriptHash);
System.out.println("P2S address from the WIF pivate key is: " + legacyAddress.toString()); //3Az5wdibtPRGac41aGtyqzT1ejtobvb6qW
    

Its output public key is 03b5319c83adf4a2e274c37401623c7bf0ba453cee3e119f3bc2c523d27059b64f. Its output P2SH address is 3Az5wdibtPRGac41aGtyqzT1ejtobvb6qW which is far different from the correct P2SH address 38SGXvkMvq8Tsop8rFx2K4JnaFKYZkjd5z.

If any of you know to rectifying the issue I'm happy to take your opinion.

Upvotes: 1

Views: 1634

Answers (3)

Lakshitha Kanchana
Lakshitha Kanchana

Reputation: 1235

After spending very much of time I found the solution.

// Getting P2SH address
LegacyAddress p2shAddressObj = LegacyAddress.fromScriptHash(PARAMS,
                                Utils.sha256hash160(ScriptBuilder
                                .createP2WPKHOutputScript(key.getPubKeyHash())
                                .getProgram())); // P2WPKH-P2SH (3* segwit compatible)
String p2shAddress = p2shAddressObj.toString();

Upvotes: 1

Mehran Jalili
Mehran Jalili

Reputation: 705

This is the right code by using Mikhail's suggestion in kotlin:

val params: NetworkParameters = MainNetParams.get()
val key: ECKey = ECKey.fromPrivate(BigInteger("2"))
val redeemScript: Script = ScriptBuilder.createP2WPKHOutputScript(key)
val script = ScriptBuilder.createP2SHOutputScript(redeemScript)
val scriptHash = ScriptPattern.extractHashFromP2SH(script)
val legacyAddress = LegacyAddress.fromScriptHash(params, scriptHash)
println("P2S address from the WIF private key is: $legacyAddress")

Upvotes: -1

Mikhail R
Mikhail R

Reputation: 71

As a Redeem Script you must use P2WPKH (Pay to Witness Public Key Hash) And then the creation of the Redeem Script will look like:

Script redeemScript = ScriptBuilder.createP2WPKHOutputScript(key);

Upvotes: 2

Related Questions