BlockData FetchStartingBlock(WebClient wc, LatestBlock lb) { string fetchHash = lb.hash; if (Directory.Exists("Cache")) { string[] files = Directory.GetFiles("Cache", "*.cache"); long newest = 0; string newestFile = null; foreach (string file in files) { string ticksStr = Path.GetFileNameWithoutExtension(file); long ticks = Convert.ToInt64(ticksStr); if (ticks > newest) { newest = ticks; newestFile = file; } } if (newestFile != null) { FileStream fs = File.OpenRead(newestFile); BinaryReader br = new BinaryReader(fs); fetchHash = br.ReadString(); br.Close(); } } string uri = string.Format("https://blockchain.info/block-index/{0}?format=json", fetchHash); Debug.WriteLine("Fetching latest: " + uri); string blockDataJSON = wc.DownloadString(uri); BlockData bd = JsonConvert.DeserializeObject<BlockData>(blockDataJSON); return bd; }
BlockData FetchStartingBlock(WebClient wc, LatestBlock lb) { string fetchHash = lb.hash; if (Directory.Exists("Cache")) { string[] files = Directory.GetFiles("Cache", "*.cache"); long newest = 0; string newestFile = null; foreach (string file in files) { string ticksStr = Path.GetFileNameWithoutExtension(file); long ticks = Convert.ToInt64(ticksStr); if (ticks > newest) { newest = ticks; newestFile = file; } } if (newestFile != null) { FileStream fs = File.OpenRead(newestFile); BinaryReader br = new BinaryReader(fs); fetchHash = br.ReadString(); br.Close(); } } string uri = string.Format("https://blockchain.info/block-index/{0}?format=json", fetchHash); Debug.WriteLine("Fetching latest: " + uri); string blockDataJSON = wc.DownloadString(uri); BlockData bd = JsonConvert.DeserializeObject<BlockData>(blockDataJSON); return bd; }
void FindTheBitcoins() { // Get the latest block id WebClient wc = new WebClient(); string latestBlockJSON = wc.DownloadString("https://blockchain.info/latestblock"); LatestBlock lb = JsonConvert.DeserializeObject<LatestBlock>(latestBlockJSON); // Make sure there is actually work to be done here if (lb.hash != _lastBlock) { // Fetch the starting block data BlockData bd = FetchStartingBlock(wc, lb); // Fetch backwards until we get to our marker List<Transaction> transactions = new List<Transaction>(); while (bd.hash != _lastBlock) { Debug.WriteLine("Parsing block: {0}", bd.height); // Process transactions for( int j = bd.tx.Count - 1; j >= 0; j-- ) { Tx t = bd.tx[j]; List<MoneyPlace> dests = new List<MoneyPlace>(); foreach (Out o in t.@out) { MoneyPlace d = new MoneyPlace(); d.Address = o.addr; d.Value = o.value; dests.Add(d); } Transaction trans = new Transaction(); trans.Hash = t.hash; if (t.inputs[0].prev_out != null) { trans.Sources = new MoneyPlace[t.inputs.Count]; for (int i = 0; i < t.inputs.Count; i++) { trans.Sources[i] = new MoneyPlace(); trans.Sources[i].Address = t.inputs[i].prev_out.addr; trans.Sources[i].Value = t.inputs[i].prev_out.value; } } else trans.Sources = null; trans.Destinations = dests.ToArray(); transactions.Add(trans); } // Cache transactions for now if (transactions.Count > 100000) { CacheTransactions(transactions, bd); transactions.Clear(); } // go backwards bd = PrevBlock(wc, bd.prev_block); } // Cache remaining transactions CacheTransactions(transactions, bd); /* // Track coins through the block chain for (int i = transactions.Count - 1; i >= 0; i--) { Transaction t = transactions[i]; if (t.Sources != null) { // coins are taken from sources and given to destinations foreach (MoneyPlace source in t.Sources) { _coinData[source.Address] -= source.Value; if (_coinData[source.Address] < 0) { // Problem! Debug.WriteLine("ERROR: gave away more than we knew about!?"); throw new System.Exception("WTF!"); } else if (_coinData[source.Address] == 0) { // All out of money - toss this address out _coinData.Remove(source.Address); } } } // Give to the destinations foreach (MoneyPlace dest in t.Destinations) { if (!_coinData.ContainsKey(dest.Address)) _coinData[dest.Address] = dest.Value; else _coinData[dest.Address] += dest.Value; } } // Save the coin data SaveCoinData(); */ } }