org.bitcoinj.script.ScriptOpCodes Java Examples

The following examples show how to use org.bitcoinj.script.ScriptOpCodes. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: BlockTest.java    From bcm-android with GNU General Public License v3.0 5 votes vote down vote up
@Test
public void testUpdateLength() {
    Block block = UNITTEST.getGenesisBlock().createNextBlockWithCoinbase(Block.BLOCK_VERSION_GENESIS, new ECKey().getPubKey(), Block.BLOCK_HEIGHT_GENESIS);
    assertEquals(block.bitcoinSerialize().length, block.length);
    final int origBlockLen = block.length;
    Transaction tx = new Transaction(UNITTEST);
    // this is broken until the transaction has > 1 input + output (which is required anyway...)
    //assertTrue(tx.length == tx.bitcoinSerialize().length && tx.length == 8);
    byte[] outputScript = new byte[10];
    Arrays.fill(outputScript, (byte) ScriptOpCodes.OP_FALSE);
    tx.addOutput(new TransactionOutput(UNITTEST, null, Coin.SATOSHI, outputScript));
    tx.addInput(new TransactionInput(UNITTEST, null, new byte[]{(byte) ScriptOpCodes.OP_FALSE},
            new TransactionOutPoint(UNITTEST, 0, Sha256Hash.of(new byte[]{1}))));
    int origTxLength = 8 + 2 + 8 + 1 + 10 + 40 + 1 + 1;
    assertEquals(tx.unsafeBitcoinSerialize().length, tx.length);
    assertEquals(origTxLength, tx.length);
    block.addTransaction(tx);
    assertEquals(block.unsafeBitcoinSerialize().length, block.length);
    assertEquals(origBlockLen + tx.length, block.length);
    block.getTransactions().get(1).getInputs().get(0).setScriptBytes(new byte[]{(byte) ScriptOpCodes.OP_FALSE, (byte) ScriptOpCodes.OP_FALSE});
    assertEquals(block.length, origBlockLen + tx.length);
    assertEquals(tx.length, origTxLength + 1);
    block.getTransactions().get(1).getInputs().get(0).clearScriptBytes();
    assertEquals(block.length, block.unsafeBitcoinSerialize().length);
    assertEquals(block.length, origBlockLen + tx.length);
    assertEquals(tx.length, origTxLength - 1);
    block.getTransactions().get(1).addInput(new TransactionInput(UNITTEST, null, new byte[]{(byte) ScriptOpCodes.OP_FALSE},
            new TransactionOutPoint(UNITTEST, 0, Sha256Hash.of(new byte[]{1}))));
    assertEquals(block.length, origBlockLen + tx.length);
    assertEquals(tx.length, origTxLength + 41); // - 1 + 40 + 1 + 1
}
 
Example #2
Source File: ContractBuilder.java    From guarda-android-wallets with GNU General Public License v3.0 5 votes vote down vote up
public Script createMethodScript(String abiParams, int gasLimitInt, int gasPriceInt, String _contractAddress) throws RuntimeException {
    byte[] version = Hex.decode("04000000");
    byte[] arrayGasLimit = org.spongycastle.util.Arrays.reverse((new BigInteger(String.valueOf(gasLimitInt))).toByteArray());
    byte[] gasLimit = new byte[]{0, 0, 0, 0, 0, 0, 0, 0};
    System.arraycopy(arrayGasLimit, 0, gasLimit, 0, arrayGasLimit.length);
    byte[] arrayGasPrice = org.spongycastle.util.Arrays.reverse((new BigInteger(String.valueOf(gasPriceInt))).toByteArray());
    byte[] gasPrice = new byte[]{0, 0, 0, 0, 0, 0, 0, 0};
    System.arraycopy(arrayGasPrice, 0, gasPrice, 0, arrayGasPrice.length);
    byte[] data = Hex.decode(abiParams);
    byte[] contractAddress = Hex.decode(_contractAddress);
    byte[] program;
    ScriptChunk versionChunk = new ScriptChunk(OP_PUSHDATA_4, version);
    ScriptChunk gasLimitChunk = new ScriptChunk(OP_PUSHDATA_8, gasLimit);
    ScriptChunk gasPriceChunk = new ScriptChunk(OP_PUSHDATA_8, gasPrice);
    ScriptChunk dataChunk = new ScriptChunk(ScriptOpCodes.OP_PUSHDATA2, data);
    ScriptChunk contactAddressChunk = new ScriptChunk(ScriptOpCodes.OP_PUSHDATA2, contractAddress);
    ScriptChunk opExecChunk = new ScriptChunk(OP_EXEC_ASSIGN, null);
    List<ScriptChunk> chunkList = new ArrayList<>();
    chunkList.add(versionChunk);
    chunkList.add(gasLimitChunk);
    chunkList.add(gasPriceChunk);
    chunkList.add(dataChunk);
    chunkList.add(contactAddressChunk);
    chunkList.add(opExecChunk);
    try {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        for (ScriptChunk chunk : chunkList) {
            chunk.write(bos);
        }
        program = bos.toByteArray();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
    return new Script(program);
}
 
Example #3
Source File: BlockTest.java    From green_android with GNU General Public License v3.0 5 votes vote down vote up
@Test
public void testUpdateLength() {
    NetworkParameters params = UnitTestParams.get();
    Block block = params.getGenesisBlock().createNextBlockWithCoinbase(Block.BLOCK_VERSION_GENESIS, new ECKey().getPubKey(), Block.BLOCK_HEIGHT_GENESIS);
    assertEquals(block.bitcoinSerialize().length, block.length);
    final int origBlockLen = block.length;
    Transaction tx = new Transaction(params);
    // this is broken until the transaction has > 1 input + output (which is required anyway...)
    //assertTrue(tx.length == tx.bitcoinSerialize().length && tx.length == 8);
    byte[] outputScript = new byte[10];
    Arrays.fill(outputScript, (byte) ScriptOpCodes.OP_FALSE);
    tx.addOutput(new TransactionOutput(params, null, Coin.SATOSHI, outputScript));
    tx.addInput(new TransactionInput(params, null, new byte[] {(byte) ScriptOpCodes.OP_FALSE},
            new TransactionOutPoint(params, 0, Sha256Hash.of(new byte[] { 1 }))));
    int origTxLength = 8 + 2 + 8 + 1 + 10 + 40 + 1 + 1;
    assertEquals(tx.unsafeBitcoinSerialize().length, tx.length);
    assertEquals(origTxLength, tx.length);
    block.addTransaction(tx);
    assertEquals(block.unsafeBitcoinSerialize().length, block.length);
    assertEquals(origBlockLen + tx.length, block.length);
    block.getTransactions().get(1).getInputs().get(0).setScriptBytes(new byte[] {(byte) ScriptOpCodes.OP_FALSE, (byte) ScriptOpCodes.OP_FALSE});
    assertEquals(block.length, origBlockLen + tx.length);
    assertEquals(tx.length, origTxLength + 1);
    block.getTransactions().get(1).getInputs().get(0).clearScriptBytes();
    assertEquals(block.length, block.unsafeBitcoinSerialize().length);
    assertEquals(block.length, origBlockLen + tx.length);
    assertEquals(tx.length, origTxLength - 1);
    block.getTransactions().get(1).addInput(new TransactionInput(params, null, new byte[] {(byte) ScriptOpCodes.OP_FALSE},
            new TransactionOutPoint(params, 0, Sha256Hash.of(new byte[] { 1 }))));
    assertEquals(block.length, origBlockLen + tx.length);
    assertEquals(tx.length, origTxLength + 41); // - 1 + 40 + 1 + 1
}
 
Example #4
Source File: AbstractScriptBuilder.java    From balzac with Apache License 2.0 5 votes vote down vote up
private static ImmutableList<ScriptChunk> optimize(ImmutableList<ScriptChunk> scriptChunks) {
    if (scriptChunks.size() == 0 || scriptChunks.size() == 1) {
        return scriptChunks;
    }

    ScriptChunk ch1 = scriptChunks.get(0);
    ScriptChunk ch2 = scriptChunks.get(1);

    if (ch1.equalsOpCode(ScriptOpCodes.OP_TOALTSTACK) && ch2.equalsOpCode(ScriptOpCodes.OP_FROMALTSTACK)) {
        return optimize(scriptChunks.subList(2, scriptChunks.size()));
    }

    return ImmutableList.<ScriptChunk>builder().add(scriptChunks.get(0))
        .addAll(optimize(scriptChunks.subList(1, scriptChunks.size()))).build();
}
 
Example #5
Source File: HashTest.java    From balzac with Apache License 2.0 5 votes vote down vote up
private byte[] executeScript(Script s, HashAlgorithm alg) {
    int operation;

    switch (alg) {
    case HASH160:
        operation = ScriptOpCodes.OP_HASH160;
        break;
    case HASH256:
        operation = ScriptOpCodes.OP_HASH256;
        break;
    case RIPEMD160:
        operation = ScriptOpCodes.OP_RIPEMD160;
        break;
    case SHA256:
        operation = ScriptOpCodes.OP_SHA256;
        break;
    case SHA1:
        operation = ScriptOpCodes.OP_SHA1;
        break;
    default:
        throw new IllegalArgumentException("unexpected class " + alg);
    }

    LinkedList<byte[]> stack = new LinkedList<>();
    Script.executeScript(null, 0, new ScriptBuilder(s).op(operation).build(), stack, Script.ALL_VERIFY_FLAGS);
    byte[] res = stack.getLast();
    return res;
}
 
Example #6
Source File: BlockTest.java    From GreenBits with GNU General Public License v3.0 5 votes vote down vote up
@Test
public void testUpdateLength() {
    NetworkParameters params = UnitTestParams.get();
    Block block = params.getGenesisBlock().createNextBlockWithCoinbase(Block.BLOCK_VERSION_GENESIS, new ECKey().getPubKey(), Block.BLOCK_HEIGHT_GENESIS);
    assertEquals(block.bitcoinSerialize().length, block.length);
    final int origBlockLen = block.length;
    Transaction tx = new Transaction(params);
    // this is broken until the transaction has > 1 input + output (which is required anyway...)
    //assertTrue(tx.length == tx.bitcoinSerialize().length && tx.length == 8);
    byte[] outputScript = new byte[10];
    Arrays.fill(outputScript, (byte) ScriptOpCodes.OP_FALSE);
    tx.addOutput(new TransactionOutput(params, null, Coin.SATOSHI, outputScript));
    tx.addInput(new TransactionInput(params, null, new byte[] {(byte) ScriptOpCodes.OP_FALSE},
            new TransactionOutPoint(params, 0, Sha256Hash.of(new byte[] { 1 }))));
    int origTxLength = 8 + 2 + 8 + 1 + 10 + 40 + 1 + 1;
    assertEquals(tx.unsafeBitcoinSerialize().length, tx.length);
    assertEquals(origTxLength, tx.length);
    block.addTransaction(tx);
    assertEquals(block.unsafeBitcoinSerialize().length, block.length);
    assertEquals(origBlockLen + tx.length, block.length);
    block.getTransactions().get(1).getInputs().get(0).setScriptBytes(new byte[] {(byte) ScriptOpCodes.OP_FALSE, (byte) ScriptOpCodes.OP_FALSE});
    assertEquals(block.length, origBlockLen + tx.length);
    assertEquals(tx.length, origTxLength + 1);
    block.getTransactions().get(1).getInputs().get(0).clearScriptBytes();
    assertEquals(block.length, block.unsafeBitcoinSerialize().length);
    assertEquals(block.length, origBlockLen + tx.length);
    assertEquals(tx.length, origTxLength - 1);
    block.getTransactions().get(1).addInput(new TransactionInput(params, null, new byte[] {(byte) ScriptOpCodes.OP_FALSE},
            new TransactionOutPoint(params, 0, Sha256Hash.of(new byte[] { 1 }))));
    assertEquals(block.length, origBlockLen + tx.length);
    assertEquals(tx.length, origTxLength + 41); // - 1 + 40 + 1 + 1
}
 
Example #7
Source File: Transaction.java    From bcm-android with GNU General Public License v3.0 4 votes vote down vote up
/**
 * This is required for signatures which use a sigHashType which cannot be represented using SigHash and anyoneCanPay
 * See transaction c99c49da4c38af669dea436d3e73780dfdb6c1ecf9958baa52960e8baee30e73, which has sigHashType 0
 */
public Sha256Hash hashForSignature(int inputIndex, byte[] connectedScript, byte sigHashType) {
    // The SIGHASH flags are used in the design of contracts, please see this page for a further understanding of
    // the purposes of the code in this method:
    //
    //   https://en.bitcoin.it/wiki/Contracts

    try {
        // Create a copy of this transaction to operate upon because we need make changes to the inputs and outputs.
        // It would not be thread-safe to change the attributes of the transaction object itself.
        Transaction tx = this.params.getDefaultSerializer().makeTransaction(this.bitcoinSerialize());

        // Clear input scripts in preparation for signing. If we're signing a fresh
        // transaction that step isn't very helpful, but it doesn't add much cost relative to the actual
        // EC math so we'll do it anyway.
        for (int i = 0; i < tx.inputs.size(); i++) {
            tx.inputs.get(i).clearScriptBytes();
        }

        // This step has no purpose beyond being synchronized with Bitcoin Core's bugs. OP_CODESEPARATOR
        // is a legacy holdover from a previous, broken design of executing scripts that shipped in Bitcoin 0.1.
        // It was seriously flawed and would have let anyone take anyone elses money. Later versions switched to
        // the design we use today where scripts are executed independently but share a stack. This left the
        // OP_CODESEPARATOR instruction having no purpose as it was only meant to be used internally, not actually
        // ever put into scripts. Deleting OP_CODESEPARATOR is a step that should never be required but if we don't
        // do it, we could split off the main chain.
        connectedScript = Script.removeAllInstancesOfOp(connectedScript, ScriptOpCodes.OP_CODESEPARATOR);

        // Set the input to the script of its output. Bitcoin Core does this but the step has no obvious purpose as
        // the signature covers the hash of the prevout transaction which obviously includes the output script
        // already. Perhaps it felt safer to him in some way, or is another leftover from how the code was written.
        TransactionInput input = tx.inputs.get(inputIndex);
        input.setScriptBytes(connectedScript);

        if ((sigHashType & 0x1f) == SigHash.NONE.value) {
            // SIGHASH_NONE means no outputs are signed at all - the signature is effectively for a "blank cheque".
            tx.outputs = new ArrayList<>(0);
            // The signature isn't broken by new versions of the transaction issued by other parties.
            for (int i = 0; i < tx.inputs.size(); i++)
                if (i != inputIndex)
                    tx.inputs.get(i).setSequenceNumber(0);
        } else if ((sigHashType & 0x1f) == SigHash.SINGLE.value) {
            // SIGHASH_SINGLE means only sign the output at the same index as the input (ie, my output).
            if (inputIndex >= tx.outputs.size()) {
                // The input index is beyond the number of outputs, it's a buggy signature made by a broken
                // Bitcoin implementation. Bitcoin Core also contains a bug in handling this case:
                // any transaction output that is signed in this case will result in both the signed output
                // and any future outputs to this public key being steal-able by anyone who has
                // the resulting signature and the public key (both of which are part of the signed tx input).

                // Bitcoin Core's bug is that SignatureHash was supposed to return a hash and on this codepath it
                // actually returns the constant "1" to indicate an error, which is never checked for. Oops.
                return Sha256Hash.wrap("0100000000000000000000000000000000000000000000000000000000000000");
            }
            // In SIGHASH_SINGLE the outputs after the matching input index are deleted, and the outputs before
            // that position are "nulled out". Unintuitively, the value in a "null" transaction is set to -1.
            tx.outputs = new ArrayList<>(tx.outputs.subList(0, inputIndex + 1));
            for (int i = 0; i < inputIndex; i++)
                tx.outputs.set(i, new TransactionOutput(tx.params, tx, Coin.NEGATIVE_SATOSHI, new byte[]{}));
            // The signature isn't broken by new versions of the transaction issued by other parties.
            for (int i = 0; i < tx.inputs.size(); i++)
                if (i != inputIndex)
                    tx.inputs.get(i).setSequenceNumber(0);
        }

        if ((sigHashType & SigHash.ANYONECANPAY.value) == SigHash.ANYONECANPAY.value) {
            // SIGHASH_ANYONECANPAY means the signature in the input is not broken by changes/additions/removals
            // of other inputs. For example, this is useful for building assurance contracts.
            tx.inputs = new ArrayList<TransactionInput>();
            tx.inputs.add(input);
        }

        ByteArrayOutputStream bos = new UnsafeByteArrayOutputStream(tx.length == UNKNOWN_LENGTH ? 256 : tx.length + 4);
        tx.bitcoinSerialize(bos);
        // We also have to write a hash type (sigHashType is actually an unsigned char)
        uint32ToByteStreamLE(0x000000ff & sigHashType, bos);
        // Note that this is NOT reversed to ensure it will be signed correctly. If it were to be printed out
        // however then we would expect that it is IS reversed.
        Sha256Hash hash = Sha256Hash.twiceOf(bos.toByteArray());
        bos.close();

        return hash;
    } catch (IOException e) {
        throw new RuntimeException(e);  // Cannot happen.
    }
}
 
Example #8
Source File: Transaction.java    From green_android with GNU General Public License v3.0 4 votes vote down vote up
/**
 * This is required for signatures which use a sigHashType which cannot be represented using SigHash and anyoneCanPay
 * See transaction c99c49da4c38af669dea436d3e73780dfdb6c1ecf9958baa52960e8baee30e73, which has sigHashType 0
 */
public Sha256Hash hashForSignature(int inputIndex, byte[] connectedScript, byte sigHashType) {
    // The SIGHASH flags are used in the design of contracts, please see this page for a further understanding of
    // the purposes of the code in this method:
    //
    //   https://en.bitcoin.it/wiki/Contracts

    try {
        // Create a copy of this transaction to operate upon because we need make changes to the inputs and outputs.
        // It would not be thread-safe to change the attributes of the transaction object itself.
        Transaction tx = this.params.getDefaultSerializer().makeTransaction(this.bitcoinSerialize());

        // Clear input scripts in preparation for signing. If we're signing a fresh
        // transaction that step isn't very helpful, but it doesn't add much cost relative to the actual
        // EC math so we'll do it anyway.
        for (int i = 0; i < tx.inputs.size(); i++) {
            tx.inputs.get(i).clearScriptBytes();
        }

        // This step has no purpose beyond being synchronized with Bitcoin Core's bugs. OP_CODESEPARATOR
        // is a legacy holdover from a previous, broken design of executing scripts that shipped in Bitcoin 0.1.
        // It was seriously flawed and would have let anyone take anyone elses money. Later versions switched to
        // the design we use today where scripts are executed independently but share a stack. This left the
        // OP_CODESEPARATOR instruction having no purpose as it was only meant to be used internally, not actually
        // ever put into scripts. Deleting OP_CODESEPARATOR is a step that should never be required but if we don't
        // do it, we could split off the main chain.
        connectedScript = Script.removeAllInstancesOfOp(connectedScript, ScriptOpCodes.OP_CODESEPARATOR);

        // Set the input to the script of its output. Bitcoin Core does this but the step has no obvious purpose as
        // the signature covers the hash of the prevout transaction which obviously includes the output script
        // already. Perhaps it felt safer to him in some way, or is another leftover from how the code was written.
        TransactionInput input = tx.inputs.get(inputIndex);
        input.setScriptBytes(connectedScript);

        if ((sigHashType & 0x1f) == SigHash.NONE.value) {
            // SIGHASH_NONE means no outputs are signed at all - the signature is effectively for a "blank cheque".
            tx.outputs = new ArrayList<>(0);
            // The signature isn't broken by new versions of the transaction issued by other parties.
            for (int i = 0; i < tx.inputs.size(); i++)
                if (i != inputIndex)
                    tx.inputs.get(i).setSequenceNumber(0);
        } else if ((sigHashType & 0x1f) == SigHash.SINGLE.value) {
            // SIGHASH_SINGLE means only sign the output at the same index as the input (ie, my output).
            if (inputIndex >= tx.outputs.size()) {
                // The input index is beyond the number of outputs, it's a buggy signature made by a broken
                // Bitcoin implementation. Bitcoin Core also contains a bug in handling this case:
                // any transaction output that is signed in this case will result in both the signed output
                // and any future outputs to this public key being steal-able by anyone who has
                // the resulting signature and the public key (both of which are part of the signed tx input).

                // Bitcoin Core's bug is that SignatureHash was supposed to return a hash and on this codepath it
                // actually returns the constant "1" to indicate an error, which is never checked for. Oops.
                return Sha256Hash.wrap("0100000000000000000000000000000000000000000000000000000000000000");
            }
            // In SIGHASH_SINGLE the outputs after the matching input index are deleted, and the outputs before
            // that position are "nulled out". Unintuitively, the value in a "null" transaction is set to -1.
            tx.outputs = new ArrayList<>(tx.outputs.subList(0, inputIndex + 1));
            for (int i = 0; i < inputIndex; i++)
                tx.outputs.set(i, new TransactionOutput(tx.params, tx, Coin.NEGATIVE_SATOSHI, new byte[] {}));
            // The signature isn't broken by new versions of the transaction issued by other parties.
            for (int i = 0; i < tx.inputs.size(); i++)
                if (i != inputIndex)
                    tx.inputs.get(i).setSequenceNumber(0);
        }

        if ((sigHashType & SigHash.ANYONECANPAY.value) == SigHash.ANYONECANPAY.value) {
            // SIGHASH_ANYONECANPAY means the signature in the input is not broken by changes/additions/removals
            // of other inputs. For example, this is useful for building assurance contracts.
            tx.inputs = new ArrayList<TransactionInput>();
            tx.inputs.add(input);
        }

        ByteArrayOutputStream bos = new UnsafeByteArrayOutputStream(tx.length == UNKNOWN_LENGTH ? 256 : tx.length + 4);
        tx.transactionOptions = TransactionOptions.NONE;
        tx.bitcoinSerialize(bos);
        // We also have to write a hash type (sigHashType is actually an unsigned char)
        uint32ToByteStreamLE(0x000000ff & sigHashType, bos);
        // Note that this is NOT reversed to ensure it will be signed correctly. If it were to be printed out
        // however then we would expect that it is IS reversed.
        Sha256Hash hash = Sha256Hash.twiceOf(bos.toByteArray());
        bos.close();

        return hash;
    } catch (IOException e) {
        throw new RuntimeException(e);  // Cannot happen.
    }
}
 
Example #9
Source File: Transaction.java    From GreenBits with GNU General Public License v3.0 4 votes vote down vote up
/**
 * This is required for signatures which use a sigHashType which cannot be represented using SigHash and anyoneCanPay
 * See transaction c99c49da4c38af669dea436d3e73780dfdb6c1ecf9958baa52960e8baee30e73, which has sigHashType 0
 */
public Sha256Hash hashForSignature(int inputIndex, byte[] connectedScript, byte sigHashType) {
    // The SIGHASH flags are used in the design of contracts, please see this page for a further understanding of
    // the purposes of the code in this method:
    //
    //   https://en.bitcoin.it/wiki/Contracts

    try {
        // Create a copy of this transaction to operate upon because we need make changes to the inputs and outputs.
        // It would not be thread-safe to change the attributes of the transaction object itself.
        Transaction tx = this.params.getDefaultSerializer().makeTransaction(this.bitcoinSerialize());

        // Clear input scripts in preparation for signing. If we're signing a fresh
        // transaction that step isn't very helpful, but it doesn't add much cost relative to the actual
        // EC math so we'll do it anyway.
        for (int i = 0; i < tx.inputs.size(); i++) {
            tx.inputs.get(i).clearScriptBytes();
        }

        // This step has no purpose beyond being synchronized with Bitcoin Core's bugs. OP_CODESEPARATOR
        // is a legacy holdover from a previous, broken design of executing scripts that shipped in Bitcoin 0.1.
        // It was seriously flawed and would have let anyone take anyone elses money. Later versions switched to
        // the design we use today where scripts are executed independently but share a stack. This left the
        // OP_CODESEPARATOR instruction having no purpose as it was only meant to be used internally, not actually
        // ever put into scripts. Deleting OP_CODESEPARATOR is a step that should never be required but if we don't
        // do it, we could split off the main chain.
        connectedScript = Script.removeAllInstancesOfOp(connectedScript, ScriptOpCodes.OP_CODESEPARATOR);

        // Set the input to the script of its output. Bitcoin Core does this but the step has no obvious purpose as
        // the signature covers the hash of the prevout transaction which obviously includes the output script
        // already. Perhaps it felt safer to him in some way, or is another leftover from how the code was written.
        TransactionInput input = tx.inputs.get(inputIndex);
        input.setScriptBytes(connectedScript);

        if ((sigHashType & 0x1f) == SigHash.NONE.value) {
            // SIGHASH_NONE means no outputs are signed at all - the signature is effectively for a "blank cheque".
            tx.outputs = new ArrayList<>(0);
            // The signature isn't broken by new versions of the transaction issued by other parties.
            for (int i = 0; i < tx.inputs.size(); i++)
                if (i != inputIndex)
                    tx.inputs.get(i).setSequenceNumber(0);
        } else if ((sigHashType & 0x1f) == SigHash.SINGLE.value) {
            // SIGHASH_SINGLE means only sign the output at the same index as the input (ie, my output).
            if (inputIndex >= tx.outputs.size()) {
                // The input index is beyond the number of outputs, it's a buggy signature made by a broken
                // Bitcoin implementation. Bitcoin Core also contains a bug in handling this case:
                // any transaction output that is signed in this case will result in both the signed output
                // and any future outputs to this public key being steal-able by anyone who has
                // the resulting signature and the public key (both of which are part of the signed tx input).

                // Bitcoin Core's bug is that SignatureHash was supposed to return a hash and on this codepath it
                // actually returns the constant "1" to indicate an error, which is never checked for. Oops.
                return Sha256Hash.wrap("0100000000000000000000000000000000000000000000000000000000000000");
            }
            // In SIGHASH_SINGLE the outputs after the matching input index are deleted, and the outputs before
            // that position are "nulled out". Unintuitively, the value in a "null" transaction is set to -1.
            tx.outputs = new ArrayList<>(tx.outputs.subList(0, inputIndex + 1));
            for (int i = 0; i < inputIndex; i++)
                tx.outputs.set(i, new TransactionOutput(tx.params, tx, Coin.NEGATIVE_SATOSHI, new byte[] {}));
            // The signature isn't broken by new versions of the transaction issued by other parties.
            for (int i = 0; i < tx.inputs.size(); i++)
                if (i != inputIndex)
                    tx.inputs.get(i).setSequenceNumber(0);
        }

        if ((sigHashType & SigHash.ANYONECANPAY.value) == SigHash.ANYONECANPAY.value) {
            // SIGHASH_ANYONECANPAY means the signature in the input is not broken by changes/additions/removals
            // of other inputs. For example, this is useful for building assurance contracts.
            tx.inputs = new ArrayList<TransactionInput>();
            tx.inputs.add(input);
        }

        ByteArrayOutputStream bos = new UnsafeByteArrayOutputStream(tx.length == UNKNOWN_LENGTH ? 256 : tx.length + 4);
        tx.transactionOptions = TransactionOptions.NONE;
        tx.bitcoinSerialize(bos);
        // We also have to write a hash type (sigHashType is actually an unsigned char)
        uint32ToByteStreamLE(0x000000ff & sigHashType, bos);
        // Note that this is NOT reversed to ensure it will be signed correctly. If it were to be printed out
        // however then we would expect that it is IS reversed.
        Sha256Hash hash = Sha256Hash.twiceOf(bos.toByteArray());
        bos.close();

        return hash;
    } catch (IOException e) {
        throw new RuntimeException(e);  // Cannot happen.
    }
}