/// <summary>
        /// Parses a block file from the specified stream.
        /// </summary>
        /// <param name="stream">A BlockchainStream to read data from.</param>
        /// <exception cref="System.ArgumentException">The specified stream is NULL or invalid.</exception>
        /// <exception cref="System.InvalidOperationException">The block file could not be parsed from the specified stream.</exception>
        /// <returns>A BlockFile parsed from the stream.</returns>
        internal static BlockFile Parse(BlockchainStream stream)
        {
            BlockFile returnValue;

            // Verify params
            if (stream == null)
            {
                throw new ArgumentException("The specified stream is NULL", nameof(stream));
            }

            try
            {
                // Defaults
                returnValue = new BlockFile();

                // Load all blocks from the stream
                while (BlockParser.TryParse(stream, out Block block))
                {
                    returnValue.Blocks.Add(block);
                }
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("Unable to load the block file from the specified stream", ex);
            }

            return(returnValue);
        }
        /// <summary>
        /// Parses a transaction from the specified stream.
        /// </summary>
        /// <param name="stream">A BlockchainStream containing the data to load.</param>
        /// <exception cref="System.ArgumentException">The specified stream is NULL or invalid.</exception>
        /// <exception cref="System.InvalidOperationException">The transaction could not be parsed from the specified stream.</exception>
        /// <returns>A Transaction parsed from the stream.</returns>
        internal static Transaction Parse(BlockchainStream stream)
        {
            Transaction returnValue;

            // Verify params
            if (stream == null)
            {
                throw new ArgumentException("The specified stream is NULL", nameof(stream));
            }

            // Get the transaction version
            if (stream.TryReadInt(out int version))
            {
                // Get number of inputs
                if (stream.TryReadVarInt(out VarInt inputCount) && inputCount.AsInt64 > 0)
                {
                    InputList inputs;

                    // Load inputs
                    inputs = new InputList();
                    for (long i = 0; i < inputCount.AsInt64; i++)
                    {
                        Input nextInput;

                        nextInput = InputParser.Parse(stream);
                        inputs.Add(nextInput);
                    }

                    // Get number of outputs
                    if (stream.TryReadVarInt(out VarInt outputCount) && outputCount.AsInt64 > 0)
                    {
                        OutputList outputs;

                        // Load outputs
                        outputs = new OutputList();
                        for (long i = 0; i < outputCount.AsInt64; i++)
                        {
                            Output nextOutput;

                            nextOutput = OutputParser.Parse(stream);
                            outputs.Add(nextOutput);
                        }

                        if (stream.TryReadUInt(out uint rawLockTime))
                        {
                            LockTime lockTime;

                            lockTime    = ParseLockTime(rawLockTime);
                            returnValue = new Transaction(version, lockTime, inputs, outputs);
                        }
                        else
                        {
                            throw new InvalidOperationException("The locktime could not be parsed");
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException("The number of outputs could not be parsed");
                    }
                }
Exemple #3
0
        /// <summary>
        /// Parses a T from the specified stream.
        /// </summary>
        /// <param name="stream">A Stream containing the data to parse.</param>
        /// <exception cref="System.ArgumentException">The specified stream is NULL or invalid.</exception>
        /// <exception cref="System.InvalidOperationException">The object could not be parsed from the specified stream.</exception>
        /// <returns>A T parsed from the stream.</returns>
        internal T Parse(Stream stream)
        {
            T returnValue = default;

            // Verify params
            if (stream == null)
            {
                throw new ArgumentException("The specified stream is NULL", nameof(stream));
            }

            try
            {
                BlockchainStream blockDataStream;

                // Wrap the stream
                using (blockDataStream = new BlockchainStream(stream))
                    returnValue = _parser(blockDataStream);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"Unable to parse the {_objectName} from the specified stream", ex);
            }

            return(returnValue);
        }
Exemple #4
0
        /// <summary>
        /// Parses an input from the specified stream.
        /// </summary>
        /// <param name="stream">A BlockDataStream containing the data to load.</param>
        /// <exception cref="System.ArgumentException">The specified stream is NULL or invalid.</exception>
        /// <exception cref="System.InvalidOperationException">The input could not be parsed from the specified stream.</exception>
        /// <returns>An Input parsed from the stream.</returns>
        internal static Input Parse(BlockchainStream stream)
        {
            Input returnValue;

            // Verify params
            if (stream == null)
            {
                throw new ArgumentException("The specified stream is NULL", nameof(stream));
            }

            // Get the previous transaction
            if (stream.TryReadBytes(32, out byte[] transaction))
Exemple #5
0
        /// <summary>
        /// Parses a variable integer from the specified stream.
        /// </summary>
        /// <param name="stream">A BlockDataStream to pasre the variable integer from.</param>
        /// <returns>A VarInt pasred from the stream.</returns>
        internal static VarInt Parse(BlockchainStream stream)
        {
            VarInt returnValue;

            // Verify params
            if (stream == null)
            {
                throw new ArgumentException("The specified stream is NULL", nameof(stream));
            }

            // Get the leading byte
            if (stream.TryReadBytes(1, out byte[] data))
Exemple #6
0
        /// <summary>
        /// Parses a block from the specified stream.
        /// </summary>
        /// <param name="stream">A BlockchainStream to read data from.</param>
        /// <exception cref="System.ArgumentException">The specified stream is NULL or invalid.</exception>
        /// <exception cref="System.InvalidOperationException">The block could not be parsed from the specified stream.</exception>
        /// <returns>A Block parsed from the stream.</returns>
        internal static Block Parse(BlockchainStream stream)
        {
            Block returnValue;

            // Verify params
            if (stream == null)
            {
                throw new ArgumentException("The specified stream is NULL", nameof(stream));
            }

            // Read the magic number
            if (stream.TryReadUInt(out uint magicNumber))
            {
                BitcoinNetwork network;

                // Test the magic number
                network = ParseMagicNumber(magicNumber);
                if (network != BitcoinNetwork.Undefined)
                {
                    // Get block data
                    if (stream.TryReadInt(out int blockSize) && blockSize > 80)
                    {
                        // Try to load the block header
                        if (TryParseBlockHeader(stream, network, blockSize, out returnValue))
                        {
                            // Get transaction count
                            if (stream.TryReadVarInt(out VarInt transactionCount) && transactionCount.AsInt64 > 0)
                            {
                                // Process transactions
                                for (long i = 0; i < transactionCount.AsInt64; i++)
                                {
                                    Transaction nextTransaction;

                                    nextTransaction = TransactionParser.Parse(stream);
                                    returnValue.Transactions.Add(nextTransaction);
                                }
                            }
                            else
                            {
                                throw new InvalidOperationException("The transaction count is invalid");
                            }
                        }
                        else
                        {
                            throw new InvalidOperationException("The block header is invalid");
                        }
                    }
                    else
                    {
                        throw new InvalidOperationException("The stream does not contain a valid block");
                    }
                }
Exemple #7
0
        /// <summary>
        /// Tries to parse a T from the specified stream.
        /// </summary>
        /// <param name="stream">A BlockchainStream to read data from.</param>
        /// <param name="output">A T that will be set to the parsed object.</param>
        /// <returns>A bool indicating whether the T was parsed from the stream.</returns>
        internal bool TryParse(BlockchainStream stream, out T output)
        {
            bool returnValue = false;

            // Defaults
            output = default;

            try
            {
                output      = _parser(stream);
                returnValue = true;
            }
            catch (Exception)
            { }

            return(returnValue);
        }
Exemple #8
0
        /// <summary>
        /// Parses an output from the specified stream.
        /// </summary>
        /// <param name="stream">A BlockDataStream containing the data to load.</param>
        /// <exception cref="System.ArgumentException">The specified stream is NULL or invalid.</exception>
        /// <exception cref="System.InvalidOperationException">The output could not be parsed from the specified stream.</exception>
        /// <returns>An Output parsed from the stream.</returns>
        internal static Output Parse(BlockchainStream stream)
        {
            Output returnValue;

            // Verify params
            if (stream == null)
            {
                throw new ArgumentException("The specified stream is NULL", nameof(stream));
            }

            // Get the value of the output
            if (stream.TryReadLong(out long value))
            {
                // Get the size of the redeem script
                if (stream.TryReadVarInt(out VarInt scriptPubKeySize) && scriptPubKeySize.AsInt32 > 0)
                {
                    // Get the signature script
                    if (stream.TryReadBytes(scriptPubKeySize.AsInt32, out byte[] scriptPubKey))
                    {
                        returnValue = new Output(value, scriptPubKey);
                    }
 /// <summary>
 /// Tries to parse a block file from the specified stream.
 /// </summary>
 /// <param name="stream">A BlockchainStream to read data from.</param>
 /// <param name="parsedObject">A BlockFile that will be set to the parsed block file.</param>
 /// <returns>A bool indicating whether the block file was parsed from the stream.</returns>
 internal static bool TryParse(BlockchainStream stream, out BlockFile parsedObject)
 {
     return(_parserCore.TryParse(stream, out parsedObject));
 }