/// <summary> /// Decode - Decodes a raw bitcoin block header /// </summary> private void Decode() { // block version number BlockVersion = ReadUInt(); // previous block hash PrevBlockHash = ByteToHex.ByteArrayToHex(ReadSlice(32).Reverse().ToArray()); // merkle root hash MerkleRootHash = ReadSlice(32); // block timestamp (seconds since 1970-01-01T00:00 UTC) TimeStamp = ReadUInt(); // difficulty target in compact format DiffTarget = ReadUInt(); // nonce Nonce = ReadUInt(); // strict validation - we should be at the end of the header LengthMatch = Offset == ByteData.Length; // block hash = sha256(sha256(header_data)) -> reverse byte data -> convert to hex SHA256 sha256 = new SHA256Managed(); BlockHashHex = ByteToHex.ByteArrayToHex(sha256.ComputeHash(sha256.ComputeHash(ByteData)).Reverse().ToArray()); }
/// <inheritdoc /> /// <summary> /// Constructor /// - decodes the transaction data /// </summary> /// <param name="txBytes">raw transaction as byte array</param> public Transaction(IEnumerable <byte> txBytes) : base(txBytes) { var sha256 = new SHA256Managed(); // double sha256 hash, reverse bytes, then convert to hex TXIDHex = ByteToHex.ByteArrayToHex(sha256.ComputeHash(sha256.ComputeHash(ByteData)).Reverse().ToArray()); Decode(); }
/// <summary> /// Processes raw bitcoin transactions /// - decodes the transaction, output scripts, and output addresses /// </summary> /// <param name="data">raw transaction byte array</param> public override void DoWork(byte[] data) { // hex version of the transaction var txHex = ByteToHex.ByteArrayToHex(data); // attempt to decode the transaction (also decodes output scripts and addresses) Transaction transaction; try { transaction = new Transaction(data) { FirstSeen = DateTimeOffset.UtcNow.ToUnixTimeSeconds(), LastUpdated = DateTimeOffset.UtcNow.ToUnixTimeSeconds() }; } catch (Exception e) { Console.WriteLine("Unable to decode transaction: \n" + txHex); return; } // check all outputs of the transaction SubscriptionCheck.CheckForSubscription(transaction); /* * Console.WriteLine("Received Transaction with " + transaction.Outputs.Length + " outputs and " + transaction.Inputs.Length + " inputs. HasWitness = " + + (transaction.HasWitness ? "YES" : "NO") + + ". Output Scripts:"); + + + // iterate over each output in the transaction + foreach (var output in transaction.Outputs) + { + // write out the raw output script as hex + Console.WriteLine(ByteToHex.ByteArrayToHex(output.Script)); + var script = new Script(output.Script); + var dataCount = 0; + // write out the ASM version of the output + foreach (var opCode in script.OpCodes) + if (opCode == OpCodeType.OP_DATA) + Console.Write(" " + ByteToHex.ByteArrayToHex(script.DataChunks[dataCount++])); + else + Console.Write(" " + opCode); + Console.WriteLine(); + // write out the type and address (if the output is a known payment type) + Console.WriteLine(" Type = " + output.Type + (output.Address == "" ? "" : ". Address = " + output.Address)); + } + Console.WriteLine(); */ }
/// <inheritdoc /> /// <summary> /// Constructor /// - creates a transaction object given transaction properties /// - used for transactions found in blocks /// </summary> public Transaction(IEnumerable <byte> txBytes, string inclusionBlockHex, uint txVersion, bool hasWitness, TXInput[] inputs, TXOutput[] outputs, uint lockTime) : base(txBytes) { var sha256 = new SHA256Managed(); TXIDHex = ByteToHex.ByteArrayToHex(sha256.ComputeHash(sha256.ComputeHash(ByteData)).Reverse().ToArray()); IncludedInBlockHex = inclusionBlockHex; TXVersion = txVersion; HasWitness = hasWitness; Inputs = inputs; Outputs = outputs; LockTime = lockTime; LengthMatch = true; }