/// <summary> /// Attempts to mine the block with the next range of nonce values. /// </summary> /// <returns>True if the block is successfully mined.</returns> public bool Attempt() { int nonceRange = int.MaxValue - _startingNonce; if (nonceRange > _nonceRange) { nonceRange = _nonceRange; } for (int n = _startingNonce, c = _startingNonce + nonceRange; n < c; ++n) { HexUtils.AppendHexFromInt(_headerStreamWriter, n); _headerStreamWriter.Flush(); var hash = Pow.Hash(_headerStream); if (Pow.IsValidHash(hash, _difficulty)) { Block.Nonce = n; Block.Hash = HexUtils.HexFromByteArray(hash); return(true); } _headerStream.Seek(_streamOrgPosition, SeekOrigin.Begin); } _startingNonce += nonceRange; if (_startingNonce == int.MaxValue) { _maxNonceReached = true; } return(false); }
/// <summary> /// Calculates and returns the ID of the transaction. /// ID is actually a hash computed from all the inputs and outputs. /// </summary> /// <remarks> /// This method will not assign the computed value to <see cref="Id"/> /// nor will it return the value of said field. It has to compute /// the hash from what are actually in the inputs and outputs so that /// validation of transactions can compare the computed value with /// <see cref="Id"/> to check for its correctness. /// </remarks> public string GetId() { string hash; using (var stream = new MemoryStream()) { using var streamWriter = new StreamWriter(stream); for (int i = 0, c = Inputs.Count; i < c; ++i) { var txIn = Inputs[i]; streamWriter.Write(txIn.TxId); HexUtils.AppendHexFromInt(streamWriter, txIn.TxOutIndex); } for (int i = 0, c = Outputs.Count; i < c; ++i) { var txOut = Outputs[i]; streamWriter.Write(txOut.Address); HexUtils.AppendHexFromLong(streamWriter, txOut.AmountInNekoshi); } streamWriter.Flush(); hash = HashUtils.SHA256(stream); } return(hash); }
/// <summary> /// Prepares header of the block to serve PoW hashing. /// This is similar to `getblocktemplate` in Bitcoin protocol. /// </summary> /// <param name="writer">Writer of a stream that will receive the block header.</param> public void PrepareForPowHash(TextWriter writer) { HexUtils.AppendHexFromInt(writer, Index); HexUtils.AppendHexFromLong(writer, Timestamp); writer.Write(MerkleHash); writer.Write(PreviousBlockHash); writer.Flush(); }