Пример #1
0
        private static JoinSplit ParseJoinSplit(BlockMemoryStreamReader blockMemoryStreamReader)
        {
            JoinSplit joinSplit = new JoinSplit();

            joinSplit.AmountIn  = blockMemoryStreamReader.ReadUInt64();
            joinSplit.AmountOut = blockMemoryStreamReader.ReadUInt64();
            joinSplit.Anchor    = new ByteArray(blockMemoryStreamReader.ReadBytes(32));

            for (int i = 0; i < joinSplit.Nullifiers.Length; ++i)
            {
                joinSplit.Nullifiers[i] = new ByteArray(blockMemoryStreamReader.ReadBytes(32));
            }

            for (int i = 0; i < joinSplit.Commitments.Length; ++i)
            {
                joinSplit.Commitments[i] = new ByteArray(blockMemoryStreamReader.ReadBytes(32));
            }

            joinSplit.EphemeralKey = new ByteArray(blockMemoryStreamReader.ReadBytes(32));
            joinSplit.RandomSeed   = new ByteArray(blockMemoryStreamReader.ReadBytes(32));

            for (int i = 0; i < joinSplit.MACs.Length; ++i)
            {
                joinSplit.MACs[i] = new ByteArray(blockMemoryStreamReader.ReadBytes(32));
            }

            joinSplit.Proof = BlockchainParser.ParseZCProof(blockMemoryStreamReader);

            for (int i = 0; i < joinSplit.Ciphertexts.Length; ++i)
            {
                joinSplit.Ciphertexts[i] = new ByteArray(blockMemoryStreamReader.ReadBytes(ZcashConstants.ZC_NOTECIPHERTEXT_SIZE));
            }

            return(joinSplit);
        }
Пример #2
0
        /// <summary>
        /// Parses a Bitcoin transaction.
        /// </summary>
        /// <param name="blockMemoryStreamReader">
        /// Provides access to a section of the Bitcoin blockchain file.
        /// </param>
        /// <returns>
        /// The Bitcoin transaction that was parsed.
        /// </returns>
        private static Transaction ParseTransaction(BlockMemoryStreamReader blockMemoryStreamReader)
        {
            Transaction transaction = new Transaction();

            int positionInBaseStreamAtTransactionStart = (int)blockMemoryStreamReader.BaseStream.Position;

            transaction.TransactionVersion = blockMemoryStreamReader.ReadUInt32();

            int inputsCount = (int)blockMemoryStreamReader.ReadVariableLengthInteger();

            for (int inputIndex = 0; inputIndex < inputsCount; inputIndex++)
            {
                TransactionInput transactionInput = BlockchainParser.ParseTransactionInput(blockMemoryStreamReader);
                transaction.AddInput(transactionInput);
            }

            int outputsCount = (int)blockMemoryStreamReader.ReadVariableLengthInteger();

            for (int outputIndex = 0; outputIndex < outputsCount; outputIndex++)
            {
                TransactionOutput transactionOutput = BlockchainParser.ParseTransactionOutput(blockMemoryStreamReader);
                transaction.AddOutput(transactionOutput);
            }

            // TODO: Need to find out more details about the semantic of TransactionLockTime.
            transaction.TransactionLockTime = blockMemoryStreamReader.ReadUInt32();

            if (transaction.TransactionVersion >= 2)
            {
                int joinSplitCount = (int)blockMemoryStreamReader.ReadVariableLengthInteger();

                for (int jsIndex = 0; jsIndex < joinSplitCount; ++jsIndex)
                {
                    JoinSplit joinSplit = BlockchainParser.ParseJoinSplit(blockMemoryStreamReader);
                    transaction.AddJoinSplit(joinSplit);
                }

                if (joinSplitCount > 0)
                {
                    transaction.JoinSplitPublicKey = new ByteArray(blockMemoryStreamReader.ReadBytes(32));
                    transaction.JoinSplitSignature = new ByteArray(blockMemoryStreamReader.ReadBytes(64));
                }
            }

            int positionInBaseStreamAfterTransactionEnd = (int)blockMemoryStreamReader.BaseStream.Position;

            using (SHA256Managed sha256 = new SHA256Managed())
            {
                //// We need to calculate the double SHA256 hash of this transaction.
                //// We need to access the buffer that contains the transaction that we jut read through.
                //// Here we take advantage of the fact that the entire block was loaded as an in-memory buffer.
                //// The base stream of blockMemoryStreamReader is that in-memory buffer.

                byte[] baseBuffer = blockMemoryStreamReader.GetBuffer();

                int    transactionBufferSize = positionInBaseStreamAfterTransactionEnd - positionInBaseStreamAtTransactionStart;
                byte[] hash1 = sha256.ComputeHash(baseBuffer, positionInBaseStreamAtTransactionStart, transactionBufferSize);

                transaction.TransactionHash = new ByteArray(sha256.ComputeHash(hash1).ReverseByteArray());
            }

            return(transaction);
        }