Advertisement
Guest User

Untitled

a guest
Dec 28th, 2017
492
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.60 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Net;
  7. using System.IO;
  8. using System.Text.RegularExpressions;
  9. using System.Security.Cryptography;
  10.  
  11. namespace ConsoleApp1
  12. {
  13.     class Utils
  14.     {
  15.         public static byte[] ToBytes(string input)
  16.         {
  17.             byte[] bytes = new byte[input.Length / 2];
  18.             for (int i = 0, j = 0; i < input.Length; j++, i += 2)
  19.                 bytes[j] = byte.Parse(input.Substring(i, 2), System.Globalization.NumberStyles.HexNumber);
  20.  
  21.             return bytes;
  22.         }
  23.  
  24.         public static string ToString(byte[] input)
  25.         {
  26.             string result = "";
  27.             foreach (byte b in input)
  28.                 result += b.ToString("x2");
  29.  
  30.             return result;
  31.         }
  32.  
  33.         public static string ToString(uint value)
  34.         {
  35.             string result = "";
  36.             foreach (byte b in BitConverter.GetBytes(value))
  37.                 result += b.ToString("x2");
  38.  
  39.             return result;
  40.         }
  41.  
  42.         public static string EndianFlip32BitChunks(string input)
  43.         {
  44.             //32 bits = 4*4 bytes = 4*4*2 chars
  45.             string result = "";
  46.             for (int i = 0; i < input.Length; i += 8)
  47.                 for (int j = 0; j < 8; j += 2)
  48.                 {
  49.                     //append byte (2 chars)
  50.                     result += input[i - j + 6];
  51.                     result += input[i - j + 7];
  52.                 }
  53.             return result;
  54.         }
  55.  
  56.         public static string RemovePadding(string input)
  57.         {
  58.             //payload length: final 64 bits in big-endian - 0x0000000000000280 = 640 bits = 80 bytes = 160 chars
  59.             return input.Substring(0, 160);
  60.         }
  61.  
  62.         public static string AddPadding(string input)
  63.         {
  64.             //add the padding to the payload. It never changes.
  65.             return input + "000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000";
  66.         }
  67.     }
  68.  
  69.     class Work
  70.     {
  71.         public Work(byte[] data)
  72.         {
  73.             Data = data;
  74.             Current = (byte[])data.Clone();
  75.             _nonceOffset = Data.Length - 4;
  76.             _ticks = DateTime.Now.Ticks;
  77.             _hasher = new SHA256Managed();
  78.  
  79.         }
  80.         private SHA256Managed _hasher;
  81.         private long _ticks;
  82.         private long _nonceOffset;
  83.         public byte[] Data;
  84.         public byte[] Current;
  85.  
  86.         internal bool FindShare(ref uint nonce, uint batchSize)
  87.         {
  88.             for (; batchSize > 0; batchSize--)
  89.             {
  90.                 BitConverter.GetBytes(nonce).CopyTo(Current, _nonceOffset);
  91.                 byte[] doubleHash = Sha256(Sha256(Current));
  92.  
  93.                 //count trailing bytes that are zero
  94.                 int zeroBytes = 0;
  95.                 for (int i = 31; i >= 28; i--, zeroBytes++)
  96.                     if (doubleHash[i] > 0)
  97.                         break;
  98.  
  99.                 //standard share difficulty matched! (target:ffffffffffffffffffffffffffffffffffffffffffffffffffffffff00000000)
  100.                 if (zeroBytes == 4)
  101.                     return true;
  102.  
  103.                 //increase
  104.                 if (++nonce == uint.MaxValue)
  105.                     nonce = 0;
  106.             }
  107.             return false;
  108.         }
  109.  
  110.         private byte[] Sha256(byte[] input)
  111.         {
  112.             byte[] crypto = _hasher.ComputeHash(input, 0, input.Length);
  113.             return crypto;
  114.         }
  115.  
  116.         public byte[] Hash
  117.         {
  118.             get { return Sha256(Sha256(Current)); }
  119.         }
  120.  
  121.         public long Age
  122.         {
  123.             get { return DateTime.Now.Ticks - _ticks; }
  124.         }
  125.     }
  126.  
  127.     class Pool
  128.     {
  129.         public Uri Url;
  130.         public string User;
  131.         public string Password;
  132.  
  133.         public Pool(string login)
  134.         {
  135.             int urlStart = login.IndexOf('@');
  136.             int passwordStart = login.IndexOf(':');
  137.             string user = login.Substring(0, passwordStart);
  138.             string password = login.Substring(passwordStart + 1, urlStart - passwordStart - 1);
  139.             string url = "http://" + login.Substring(urlStart + 1);
  140.             Url = new Uri(url);
  141.             User = user;
  142.             Password = password;
  143.         }
  144.  
  145.         private string InvokeMethod(string method, string paramString = null)
  146.         {
  147.             HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(Url);
  148.             webRequest.Credentials = new NetworkCredential(User, Password);
  149.             webRequest.ContentType = "application/json-rpc";
  150.             webRequest.Method = "POST";
  151.  
  152.             string jsonParam = (paramString != null) ? "\"" + paramString + "\"" : "";
  153.             string request = "{\"id\": 0, \"method\": \"" + method + "\", \"params\": [" + jsonParam + "]}";
  154.  
  155.             // serialize json for the request
  156.             byte[] byteArray = Encoding.UTF8.GetBytes(request);
  157.             webRequest.ContentLength = byteArray.Length;
  158.             using (Stream dataStream = webRequest.GetRequestStream())
  159.                 dataStream.Write(byteArray, 0, byteArray.Length);
  160.  
  161.             string reply = "";
  162.             using (WebResponse webResponse = webRequest.GetResponse())
  163.             using (Stream str = webResponse.GetResponseStream())
  164.             using (StreamReader reader = new StreamReader(str))
  165.                 reply = reader.ReadToEnd();
  166.  
  167.             return reply;
  168.         }
  169.  
  170.         public Work GetWork(bool silent = false)
  171.         {
  172.             return new Work(ParseData(InvokeMethod("getwork")));
  173.         }
  174.  
  175.         private byte[] ParseData(string json)
  176.         {
  177.             Match match = Regex.Match(json, "\"data\": \"([A-Fa-f0-9]+)");
  178.             if (match.Success)
  179.             {
  180.                 string data = Utils.RemovePadding(match.Groups[1].Value);
  181.                 data = Utils.EndianFlip32BitChunks(data);
  182.                 return Utils.ToBytes(data);
  183.             }
  184.             throw new Exception("Didn't find valid 'data' in Server Response");
  185.         }
  186.  
  187.         public bool SendShare(byte[] share)
  188.         {
  189.             string data = Utils.EndianFlip32BitChunks(Utils.ToString(share));
  190.             string paddedData = Utils.AddPadding(data);
  191.             string jsonReply = InvokeMethod("getwork", paddedData);
  192.             Match match = Regex.Match(jsonReply, "\"result\": true");
  193.             return match.Success;
  194.         }
  195.     }
  196.  
  197.     class Program
  198.     {
  199.         static Pool _pool = null;
  200.         static Work _work = null;
  201.         static uint _nonce = 0;
  202.         static long _maxAgeTicks = 20000 * TimeSpan.TicksPerMillisecond;
  203.         static uint _batchSize = 100000;
  204.  
  205.         static void Main(string[] args)
  206.         {
  207.             while (true)
  208.             {
  209.                 try
  210.                 {
  211.                     _pool = SelectPool();
  212.                     _work = GetWork();
  213.                     while (true)
  214.                     {
  215.                         if (_work == null || _work.Age > _maxAgeTicks)
  216.                             _work = GetWork();
  217.  
  218.                         if (_work.FindShare(ref _nonce, _batchSize))
  219.                         {
  220.                             SendShare(_work.Current);
  221.                             _work = null;
  222.                         }
  223.                         else
  224.                             PrintCurrentState();
  225.                     }
  226.                 }
  227.                 catch (Exception e)
  228.                 {
  229.                     Console.WriteLine();
  230.                     Console.Write("ERROR: ");
  231.                     Console.WriteLine(e.Message);
  232.                 }
  233.                 Console.WriteLine();
  234.                 Console.Write("Hit 'Enter' to try again...");
  235.                 Console.ReadLine();
  236.             }
  237.         }
  238.  
  239.  
  240.         private static void ClearConsole()
  241.         {
  242.             Console.Clear();
  243.             Console.WriteLine("*****************************");
  244.             Console.WriteLine("*** Minimal Bitcoin Miner ***");
  245.             Console.WriteLine("*****************************");
  246.             Console.WriteLine();
  247.         }
  248.  
  249.         private static Pool SelectPool()
  250.         {
  251.             ClearConsole();
  252.             Print("Chose a Mining Pool 'user:password@url:port' or leave empty to skip.");
  253.             Console.Write("Select Pool: ");
  254.             string login = ReadLineDefault("lithander_2:foo@btcguild.com:8332");
  255.             return new Pool(login);
  256.         }
  257.  
  258.         private static Work GetWork()
  259.         {
  260.             ClearConsole();
  261.             Print("Requesting Work from Pool...");
  262.             Print("Server URL: " + _pool.Url.ToString());
  263.             Print("User: " + _pool.User);
  264.             Print("Password: " + _pool.Password);
  265.             return _pool.GetWork();
  266.         }
  267.  
  268.         private static void SendShare(byte[] share)
  269.         {
  270.             ClearConsole();
  271.             Print("*** Found Valid Share ***");
  272.             Print("Share: " + Utils.ToString(_work.Current));
  273.             Print("Nonce: " + Utils.ToString(_nonce));
  274.             Print("Hash: " + Utils.ToString(_work.Hash));
  275.             Print("Sending Share to Pool...");
  276.             if (_pool.SendShare(share))
  277.                 Print("Server accepted the Share!");
  278.             else
  279.                 Print("Server declined the Share!");
  280.  
  281.             Console.Write("Hit 'Enter' to continue...");
  282.             Console.ReadLine();
  283.         }
  284.  
  285.         private static DateTime _lastPrint = DateTime.Now;
  286.         private static void PrintCurrentState()
  287.         {
  288.             ClearConsole();
  289.             Print("Data: " + Utils.ToString(_work.Data));
  290.             string current = Utils.ToString(_nonce);
  291.             string max = Utils.ToString(uint.MaxValue);
  292.             double progress = ((double)_nonce / uint.MaxValue) * 100;
  293.             Print("Nonce: " + current + "/" + max + " " + progress.ToString("F2") + "%");
  294.             Print("Hash: " + Utils.ToString(_work.Hash));
  295.             TimeSpan span = DateTime.Now - _lastPrint;
  296.             Print("Speed: " + (int)(((_batchSize) / 1000) / span.TotalSeconds) + "Kh/s");
  297.             _lastPrint = DateTime.Now;
  298.         }
  299.  
  300.         private static void Print(string msg)
  301.         {
  302.             Console.WriteLine(msg);
  303.             Console.WriteLine();
  304.         }
  305.  
  306.         private static string ReadLineDefault(string defaultValue)
  307.         {
  308.             //Allow Console.ReadLine with a default value
  309.             string userInput = Console.ReadLine();
  310.             Console.WriteLine();
  311.             if (userInput == "")
  312.                 return defaultValue;
  313.             else
  314.                 return userInput;
  315.         }
  316.     }
  317. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement