/**
  * Creates a new transaction from the serialized data in the byte stream
  *
  * @param inBuffer Serialized buffer
  * @throws EOFException Byte stream is too short
  * @throws VerificationException Verification error
  */
 public Transaction(SerializedBuffer inBuffer) throws EOFException, VerificationException {
   //
   // Mark our current position within the input stream
   //
   int segmentStart = inBuffer.getSegmentStart();
   inBuffer.setSegmentStart();
   //
   // Get the transaction version
   //
   txVersion = inBuffer.getInt();
   //
   // Get the transaction inputs
   //
   int inCount = inBuffer.getVarInt();
   if (inCount < 0) throw new VerificationException("Transaction input count is negative");
   txInputs = new ArrayList<>(Math.max(inCount, 1));
   for (int i = 0; i < inCount; i++) txInputs.add(new TransactionInput(this, i, inBuffer));
   //
   // A coinbase transaction has a single unconnected input with a transaction hash of zero
   // and an output index of -1
   //
   if (txInputs.size() == 1) {
     OutPoint outPoint = txInputs.get(0).getOutPoint();
     coinBase = (outPoint.getHash().equals(Sha256Hash.ZERO_HASH) && outPoint.getIndex() == -1);
   } else {
     coinBase = false;
   }
   //
   // Get the transaction outputs
   //
   int outCount = inBuffer.getVarInt();
   if (outCount < 0) throw new EOFException("Transaction output count is negative");
   txOutputs = new ArrayList<>(Math.max(outCount, 1));
   for (int i = 0; i < outCount; i++) txOutputs.add(new TransactionOutput(i, inBuffer));
   //
   // Get the transaction lock time
   //
   txLockTime = inBuffer.getUnsignedInt();
   //
   // Save a copy of the serialized transaction
   //
   txData = inBuffer.getSegmentBytes();
   //
   // 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)));
   //
   // Restore the previous segment (if any)
   //
   inBuffer.setSegmentStart(segmentStart);
 }