/**
  * Creates a new transaction using the provided inputs
  *
  * @param inputs List of signed inputs
  * @param outputs List of outputs
  * @throws ECException Unable to sign transaction
  * @throws ScriptException Script processing error
  * @throws VerificationException Transaction verification failure
  */
 public Transaction(List<SignedInput> inputs, List<TransactionOutput> outputs)
     throws ECException, ScriptException, VerificationException {
   SerializedBuffer outBuffer = new SerializedBuffer(1024);
   txVersion = 1;
   txOutputs = outputs;
   txLockTime = 0;
   coinBase = false;
   //
   // Create the transaction inputs
   //
   txInputs = new ArrayList<>(inputs.size());
   for (int i = 0; i < inputs.size(); i++)
     txInputs.add(new TransactionInput(this, i, inputs.get(i).getOutPoint()));
   //
   // Now sign each input and create the input scripts
   //
   for (int i = 0; i < inputs.size(); i++) {
     SignedInput input = inputs.get(i);
     ECKey key = input.getKey();
     byte[] contents;
     //
     // Serialize the transaction for signing using the SIGHASH_ALL hash type
     //
     outBuffer.rewind();
     serializeForSignature(i, ScriptOpCodes.SIGHASH_ALL, input.getScriptBytes(), outBuffer);
     outBuffer.putInt(ScriptOpCodes.SIGHASH_ALL);
     contents = outBuffer.toByteArray();
     //
     // Create the DER-encoded signature
     //
     ECDSASignature sig = key.createSignature(contents);
     byte[] encodedSig = sig.encodeToDER();
     //
     // Create the input script using the SIGHASH_ALL hash type
     //   <sig> <pubKey>
     //
     byte[] pubKey = key.getPubKey();
     byte[] scriptBytes = new byte[1 + encodedSig.length + 1 + 1 + pubKey.length];
     scriptBytes[0] = (byte) (encodedSig.length + 1);
     System.arraycopy(encodedSig, 0, scriptBytes, 1, encodedSig.length);
     int offset = encodedSig.length + 1;
     scriptBytes[offset++] = (byte) ScriptOpCodes.SIGHASH_ALL;
     scriptBytes[offset++] = (byte) pubKey.length;
     System.arraycopy(pubKey, 0, scriptBytes, offset, pubKey.length);
     txInputs.get(i).setScriptBytes(scriptBytes);
   }
   //
   // Serialize the entire transaction
   //
   outBuffer.rewind();
   getBytes(outBuffer);
   txData = outBuffer.toByteArray();
   //
   // Calculate the transaction hash using the serialized data
   //
   txHash = new Sha256Hash(Utils.reverseBytes(Utils.doubleDigest(txData)));
   //
   // Calculate the normalized transaction ID
   //
   List<byte[]> bufferList = new ArrayList<>(txInputs.size() + txOutputs.size());
   txInputs
       .stream()
       .forEach(
           (txInput) -> {
             bufferList.add(txInput.getOutPoint().getBytes());
           });
   txOutputs
       .stream()
       .forEach(
           (txOutput) -> {
             bufferList.add(txOutput.getBytes());
           });
   normID = new Sha256Hash(Utils.reverseBytes(Utils.doubleDigest(bufferList)));
 }