/// <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"); } }
/// <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); }
/// <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))
/// <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))
/// <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"); } }
/// <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); }
/// <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)); }