<p>For P2WPKH inputs, the <code>scriptCode</code> accepted by <a href="https://bitcoinj.org/javadoc/0.16.3/org/bitcoinj/core/Transaction.html#hashForWitnessSignature(int,org.bitcoinj.script.Script,org.bitcoinj.core.Coin,org.bitcoinj.core.Transaction.SigHash,boolean)" rel="nofollow noreferrer"><code>ScriptBuilder.hashForWitnessSignature</code></a> is not the <code>scriptPubKey</code> but a P2PKH script with the hash of your public key. You can generate it using <a href="https://bitcoinj.org/javadoc/0.16/org/bitcoinj/script/ScriptBuilder.html#createP2PKHOutputScript(org.bitcoinj.core.ECKey)" rel="nofollow noreferrer"><code>ScriptBuilder.createP2PKHOutputScript</code></a>.</p>
<p>See <a href="https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki" rel="nofollow noreferrer">BIP143</a> for more information on signature verification in SegWit inputs.</p>

CC BY-SA 4.0
2024-11-29T04:47:49.267Z
2024-11-29T04:47:49.267Z
Vojtěch Strnad
<p>I’m working on a SegWit Bitcoin transaction, and I'm encountering an error when trying to broadcast it:</p>
<blockquote>
<p>Code: -26, Error: mandatory-script-verify-flag-failed (Signature must
be zero for failed CHECK(MULTI)SIG operation)</p>
</blockquote>
<p>Here’s the code I’m using to sign the transaction:</p>
<pre class="lang-java prettyprint-override"><code>private static void signInputsOfTransaction(Address sourceAddress, Transaction tx, ECKey key) {
    for (int i = 0; i &lt; tx.getInputs().size(); i++) {
        Script scriptPubKey = ScriptBuilder.createP2WPKHOutputScript(key);

        Coin inputValue = tx.getInput(i).getValue();

        Sha256Hash hash = tx.hashForWitnessSignature(
            i, scriptPubKey, inputValue, Transaction.SigHash.ALL, false
        );

        ECKey.ECDSASignature ecdsaSignature = key.sign(hash);
        TransactionSignature txSignature = new TransactionSignature(ecdsaSignature, Transaction.SigHash.ALL, false);

        TransactionWitness witness = new TransactionWitness(2);
        witness.setPush(0, txSignature.encodeToBitcoin());
        witness.setPush(1, key.getPubKey());
        tx.getInput(i).setWitness(witness);

        tx.getInput(i).setScriptSig(ScriptBuilder.createEmpty());
    }
}
</code></pre>
<p>Here’s the raw transaction hex I’m trying to broadcast:</p>
<blockquote>
<p>010000000001011a34c12133e07aceb6b0cd254e2d9e12fde095b5a3afece4907945e36254e0d40100000000ffffffff02e803000000000000160014c9bf27c413655f5894a6a095ccfb5f1d291123f185170000000000001600146edda921d055dece3a894e39fd91a0c50faf675c02473044022000e9341c7c137529db50f706bc2bc1c1057674cda3bc33be5c559a45731b9c2802201a0f435a70e0f3a89d272efa407e0817e964f4c14ee9f9e3e4b5961fa658fc1d01210336069ac77986a9de47f0c371b682906149e43c2f51853b30d31132d1ec33b76900000000</p>
</blockquote>
<p>I’ve decoded it using a Bitcoin transaction API (BlockCypher), and here’s the output:</p>
<pre class="lang-json prettyprint-override"><code>{
    &quot;outputs&quot;: [
        {
            &quot;addresses&quot;: [&quot;bc1qexlj03qnv404399x5z2ue76lr553zgl3kfx7va&quot;],
            &quot;script_type&quot;: &quot;pay-to-witness-pubkey-hash&quot;,
            &quot;value&quot;: 1000,
            &quot;script&quot;: &quot;0014c9bf27c413655f5894a6a095ccfb5f1d291123f1&quot;
        },
        {
            &quot;addresses&quot;: [&quot;bc1qdmw6jgws2h0vuw5ffculmydqc5867e6ulzzm97&quot;],
            &quot;script_type&quot;: &quot;pay-to-witness-pubkey-hash&quot;,
            &quot;value&quot;: 6021,
            &quot;script&quot;: &quot;00146edda921d055dece3a894e39fd91a0c50faf675c&quot;
        }
    ],
    &quot;addresses&quot;: [
        &quot;bc1qdmw6jgws2h0vuw5ffculmydqc5867e6ulzzm97&quot;,
        &quot;bc1qexlj03qnv404399x5z2ue76lr553zgl3kfx7va&quot;
    ],
    &quot;fees&quot;: 1130,
    &quot;ver&quot;: 1,
    &quot;vsize&quot;: 141,
    &quot;inputs&quot;: [{
        &quot;sequence&quot;: 4294967295,
        &quot;witness&quot;: [
            &quot;3044022000e9341c7c137529db50f706bc2bc1c1057674cda3bc33be5c559a45731b9c2802201a0f435a70e0f3a89d272efa407e0817e964f4c14ee9f9e3e4b5961fa658fc1d01&quot;,
            &quot;0336069ac77986a9de47f0c371b682906149e43c2f51853b30d31132d1ec33b769&quot;
        ],
        &quot;addresses&quot;: [&quot;bc1qdmw6jgws2h0vuw5ffculmydqc5867e6ulzzm97&quot;],
        &quot;prev_hash&quot;: &quot;d4e05462e3457990e4ecafa3b595e0fd129e2d4e25cdb0b6ce7ae03321c1341a&quot;,
        &quot;output_value&quot;: 8151,
        &quot;script_type&quot;: &quot;pay-to-witness-pubkey-hash&quot;,
        &quot;output_index&quot;: 1,
        &quot;age&quot;: 698646
    }],
    &quot;preference&quot;: &quot;low&quot;,
    &quot;received&quot;: &quot;2024-11-28T15:26:00.690177102Z&quot;,
    &quot;block_height&quot;: -1,
    &quot;confirmations&quot;: 0,
    &quot;relayed_by&quot;: &quot;189.37.69.88&quot;,
    &quot;total&quot;: 7021,
    &quot;size&quot;: 222,
    &quot;block_index&quot;: -1,
    &quot;double_spend&quot;: false,
    &quot;vin_sz&quot;: 1,
    &quot;hash&quot;: &quot;0cafb57866d9a412e6cd0f806e03363baab1bdbf6434181ea5a927aa62930f77&quot;,
    &quot;vout_sz&quot;: 2
}
</code></pre>
<p>Is there something wrong with the way I’m signing or setting up the TransactionWitness?</p>

<transactions><segregated-witness><signature><bitcoinj><java>
Signing a Bitcoin SegWit transaction using bitcoinj
viniciussss
# Signing a Bitcoin SegWit transaction using bitcoinj

(Asked by: username_0 on 2024-11-28)

I’m working on a SegWit Bitcoin transaction, and I'm encountering an error when trying to broadcast it:

Code: -26, Error: mandatory-script-verify-flag-failed (Signature must
be zero for failed CHECK(MULTI)SIG operation)

Here’s the code I’m using to sign the transaction:
private static void signInputsOfTransaction(Address sourceAddress, Transaction tx, ECKey key) {
    for (int i = 0; i < tx.getInputs().size(); i++) {
        Script scriptPubKey = ScriptBuilder.createP2WPKHOutputScript(key);

        Coin inputValue = tx.getInput(i).getValue();

        Sha256Hash hash = tx.hashForWitnessSignature(
            i, scriptPubKey, inputValue, Transaction.SigHash.ALL, false
        );

        ECKey.ECDSASignature ecdsaSignature = key.sign(hash);
        TransactionSignature txSignature = new TransactionSignature(ecdsaSignature, Transaction.SigHash.ALL, false);

        TransactionWitness witness = new TransactionWitness(2);
        witness.setPush(0, txSignature.encodeToBitcoin());
        witness.setPush(1, key.getPubKey());
        tx.getInput(i).setWitness(witness);

        tx.getInput(i).setScriptSig(ScriptBuilder.createEmpty());
    }
}

Here’s the raw transaction hex I’m trying to broadcast:

010000000001011a34c12133e07aceb6b0cd254e2d9e12fde095b5a3afece4907945e36254e0d40100000000ffffffff02e803000000000000160014c9bf27c413655f5894a6a095ccfb5f1d291123f185170000000000001600146edda921d055dece3a894e39fd91a0c50faf675c02473044022000e9341c7c137529db50f706bc2bc1c1057674cda3bc33be5c559a45731b9c2802201a0f435a70e0f3a89d272efa407e0817e964f4c14ee9f9e3e4b5961fa658fc1d01210336069ac77986a9de47f0c371b682906149e43c2f51853b30d31132d1ec33b76900000000

I’ve decoded it using a Bitcoin transaction API (BlockCypher), and here’s the output:
{
    "outputs": [
        {
            "addresses": ["bc1qexlj03qnv404399x5z2ue76lr553zgl3kfx7va"],
            "script_type": "pay-to-witness-pubkey-hash",
            "value": 1000,
            "script": "0014c9bf27c413655f5894a6a095ccfb5f1d291123f1"
        },
        {
            "addresses": ["bc1qdmw6jgws2h0vuw5ffculmydqc5867e6ulzzm97"],
            "script_type": "pay-to-witness-pubkey-hash",
            "value": 6021,
            "script": "00146edda921d055dece3a894e39fd91a0c50faf675c"
        }
    ],
    "addresses": [
        "bc1qdmw6jgws2h0vuw5ffculmydqc5867e6ulzzm97",
        "bc1qexlj03qnv404399x5z2ue76lr553zgl3kfx7va"
    ],
    "fees": 1130,
    "ver": 1,
    "vsize": 141,
    "inputs": [{
        "sequence": 4294967295,
        "witness": [
            "3044022000e9341c7c137529db50f706bc2bc1c1057674cda3bc33be5c559a45731b9c2802201a0f435a70e0f3a89d272efa407e0817e964f4c14ee9f9e3e4b5961fa658fc1d01",
            "0336069ac77986a9de47f0c371b682906149e43c2f51853b30d31132d1ec33b769"
        ],
        "addresses": ["bc1qdmw6jgws2h0vuw5ffculmydqc5867e6ulzzm97"],
        "prev_hash": "d4e05462e3457990e4ecafa3b595e0fd129e2d4e25cdb0b6ce7ae03321c1341a",
        "output_value": 8151,
        "script_type": "pay-to-witness-pubkey-hash",
        "output_index": 1,
        "age": 698646
    }],
    "preference": "low",
    "received": "2024-11-28T15:26:00.690177102Z",
    "block_height": -1,
    "confirmations": 0,
    "relayed_by": "189.37.69.88",
    "total": 7021,
    "size": 222,
    "block_index": -1,
    "double_spend": false,
    "vin_sz": 1,
    "hash": "0cafb57866d9a412e6cd0f806e03363baab1bdbf6434181ea5a927aa62930f77",
    "vout_sz": 2
}

Is there something wrong with the way I’m signing or setting up the TransactionWitness?

**Tags:** transactions, segregated-witness, signature, bitcoinj, java


---

## 1 answers

### Answer by username_1 on 2024-11-29. Score: 3 | Accepted answer

For P2WPKH inputs, the `scriptCode` accepted by [`ScriptBuilder.hashForWitnessSignature`](https://bitcoinj.org/javadoc/0.16.3/org/bitcoinj/core/Transaction.html#hashForWitnessSignature(int,org.bitcoinj.script.Script,org.bitcoinj.core.Coin,org.bitcoinj.core.Transaction.SigHash,boolean)) is not the `scriptPubKey` but a P2PKH script with the hash of your public key. You can generate it using [`ScriptBuilder.createP2PKHOutputScript`](https://bitcoinj.org/javadoc/0.16/org/bitcoinj/script/ScriptBuilder.html#createP2PKHOutputScript(org.bitcoinj.core.ECKey)).

See [BIP143](https://github.com/bitcoin/bips/blob/master/bip-0143.mediawiki) for more information on signature verification in SegWit inputs.


---

