Created
May 22, 2020 14:13
-
-
Save bitbug42/ea1de1db26280a906620087d39df6060 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Newtonsoft.Json; | |
using System; | |
using System.Collections.Generic; | |
using System.Net.Http; | |
using System.Threading.Tasks; | |
using System.Linq; | |
using System.IO; | |
using System.Text; | |
using System.Threading; | |
namespace AddressScan | |
{ | |
class Utxo | |
{ | |
public string Txid; | |
public int Vout; | |
public long Value; | |
} | |
class Program | |
{ | |
static HttpClient _client = new HttpClient(); | |
static async Task Main(string[] args) | |
{ | |
long totalSats = 0; | |
var countValid = 0; | |
var countInvalid = 0; | |
Directory.CreateDirectory("cache"); | |
var list = new HashSet<string>(); | |
LoadList(list, "addresses/tulipaddresslist1.txt"); | |
LoadList(list, "addresses/tulipaddresslist2.txt"); | |
foreach(var addr in list) | |
{ | |
if (addr.StartsWith("2")) | |
{ | |
countInvalid++; | |
} | |
else | |
{ | |
var amount = await GetUnspentSum(addr); | |
totalSats += amount; | |
Console.WriteLine($"addr={addr}\tunspent={amount}\ttotal={(totalSats / 100_000_000m)} BTC"); | |
countValid++; | |
} | |
} | |
Console.WriteLine($"Valid: {countValid} | Invalid: {countInvalid}"); | |
} | |
private static void LoadList(HashSet<string> list, string filepath) | |
{ | |
foreach(var i in File.ReadAllLines(filepath)) | |
{ | |
if(i != "") | |
list.Add(i); | |
} | |
} | |
static async Task<long> GetUnspentSum(string address) | |
{ | |
var utxos = await GetUtxosCached(address); | |
return utxos.Sum(i => i.Value); | |
} | |
private static async Task<IList<Utxo>> GetUtxosCached(string address) | |
{ | |
string cacheFilepath = ToCacheFilepath(address); | |
if (File.Exists(cacheFilepath)) | |
return JsonConvert.DeserializeObject<IList<Utxo>>(File.ReadAllText(cacheFilepath)); | |
else | |
{ | |
var o = await GetUtxos(address); | |
File.WriteAllText(cacheFilepath+".tmp", JsonConvert.SerializeObject(o)); | |
File.Move(cacheFilepath + ".tmp", cacheFilepath); | |
return o; | |
} | |
} | |
private static string ToCacheFilepath(string address) | |
{ | |
var hex = BitConverter.ToString(Encoding.UTF8.GetBytes(address)).Replace("-", "").ToLower(); | |
var cacheFilepath = Path.Combine("cache", hex); | |
return cacheFilepath; | |
} | |
static async Task<IList<Utxo>> GetUtxos(string address) | |
{ | |
var url = $"https://blockstream.info/api/address/{address}/utxo"; | |
Thread.Sleep(250); | |
var response = await _client.SendAsync(new HttpRequestMessage(HttpMethod.Get, url)); | |
var text = await response.Content.ReadAsStringAsync(); | |
if (response.StatusCode != System.Net.HttpStatusCode.OK) | |
{ | |
Console.Error.WriteLine($"{response.StatusCode}: {text}"); | |
throw new InvalidOperationException(response.StatusCode.ToString()); | |
} | |
var o = JsonConvert.DeserializeObject<IList<Utxo>>(text); | |
return o; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment